@guildofgleks/ui 21.10.0 → 21.12.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
@@ -49,6 +49,11 @@
49
49
  --gog-font-body: system-ui, -apple-system, 'Segoe UI', sans-serif;
50
50
  --gog-font-mono: ui-monospace, SFMono-Regular, 'JetBrains Mono', monospace;
51
51
 
52
+ /* 11px, below `xs`. The chip and the tag both wrote it as a literal at `xsm` — the same value
53
+ chosen twice, independently, which is a missing rung rather than two opinions, exactly as
54
+ `slg` was. Moving them to `xs` instead would have made `xsm` and `sm` the same size, which
55
+ is the one thing `xsm` exists to avoid. */
56
+ --gog-text-2xs: 0.6875rem;
52
57
  --gog-text-xs: 0.75rem;
53
58
  --gog-text-sm: 0.875rem;
54
59
  --gog-text-md: 1rem;
@@ -209,6 +214,54 @@
209
214
  --gog-field-float-label-in-top: 6px;
210
215
  --gog-field-float-label-over-reserve: 1.4em;
211
216
 
217
+ /* ── Elevation ───────────────────────────────────────────────
218
+ A ladder of six heights, `--gog-elevation-0` through `-5`, generated in the derived block
219
+ below from the knobs here. Z doubles: 0, 1, 2, 4, 8, 16. No theme writes a step; a theme
220
+ turns these knobs and every step follows, which is the whole reason the family exists --
221
+ before it, eleven themes hand-authored 22 shadow values with no relationship to each other,
222
+ and two of them gave a modal dialog the elevation of a card because restating the second
223
+ value was work.
224
+
225
+ A step is two lights. The **contact shadow** hugs the object and does not grow with height:
226
+ that is what ambient occlusion does, and it is what this library already did in the three
227
+ places it wrote two soft layers (`0 1px 2px` to `0 1px 3px`, every time). The **key light**
228
+ is the one that moves -- its offset is Z and its blur is three times it.
229
+
230
+ **Three, not two, and the number was measured rather than adopted.** The ruleset this comes
231
+ from (`docs/component-geometry.md`, L10) specifies blur = 2Z. Every shadow the library
232
+ shipped disagreed: across 26 layers the ratio runs 1.33 to 6.00 with a median of exactly
233
+ 3.00, and 16 of the 26 are 3.00 on the nose. The rule was written from the physics and the
234
+ library was written from looking at it; on this one the library was consistent and the rule
235
+ was not, so 3 it is. It falls out well -- at the top step the blur is 48px, which is the
236
+ dialog's own shipped blur to the pixel.
237
+
238
+ The three geometry knobs are multipliers per unit of Z, and between them they cover every
239
+ style a theme in this repo actually uses. Soft (the default) drops the key straight down.
240
+ A hard-offset theme -- `bevel`, `ledger` -- sets x and y to a fraction and blur to 0. A glow
241
+ theme -- `terminal` -- sets y to 0 and keeps blur, and the key light becomes a halo without
242
+ the ladder knowing anything about halos.
243
+
244
+ What is deliberately *not* in a step: the hairline ring and the top-edge catch light. Both
245
+ are below as their own tokens, because they belong to particular surfaces rather than to
246
+ height -- a dark theme's overlay wants the ring and its in-flow `elevated` card must not have
247
+ it, or `elevated` and `outlined` render identically, which is a defect 21.7.1 already fixed
248
+ once. A component composes them: `var(--gog-elevation-ring), var(--gog-elevation-3)`. */
249
+ --gog-elevation-ink: 23 18 12;
250
+ --gog-elevation-key-alpha: 0.08;
251
+ /* Half the key, which is the ratio the light theme's own two-layer panel already held
252
+ (0.04 against 0.08). A theme states both, so a theme that wants a different ratio -- and
253
+ `material` does, its contact being stronger than its key -- just writes it. */
254
+ --gog-elevation-ambient-alpha: 0.04;
255
+ --gog-elevation-contact-blur: 3px;
256
+ --gog-elevation-key-x: 0;
257
+ --gog-elevation-key-y: 1;
258
+ --gog-elevation-key-blur: 3;
259
+ /* Inert by default: a 0px spread paints nothing, and a 0 alpha costs nothing to composite.
260
+ A theme whose surfaces read by their contour rather than by their shadow turns them on. */
261
+ --gog-elevation-ring-width: 0px;
262
+ --gog-elevation-highlight-ink: 255 255 255;
263
+ --gog-elevation-highlight-alpha: 0;
264
+
212
265
  /* ── Icon & spinner ───────────────────────────────────────────────────────── */
213
266
  --gog-icon-size: 1.2em;
214
267
  --gog-icon-stroke-width: 2;
@@ -221,10 +274,11 @@
221
274
 
222
275
  /* ── Toast stack ──────────────────────────────────────────────────────────── */
223
276
  --gog-toast-min-width: 280px;
224
- --gog-toast-max-width: 400px;
277
+ /* --gog-toast-max-width lives in the :root, [data-theme] block below — it derives from
278
+ --gog-toast-stack-padding, and a derived value cannot live in this literals-only block (it
279
+ would not follow a scoped theme). */
225
280
  --gog-toast-z-index: 9999;
226
281
  --gog-toast-enter-distance: 110%;
227
- --gog-toast-shadow: 0 4px 24px rgba(0, 0, 0, 0.25);
228
282
 
229
283
  /* ── Overlay stacking ───────────────────────────────────────────────────────
230
284
  Baseline for dropdown panels. gog-dialog re-declares this on its own panel so
@@ -266,8 +320,17 @@
266
320
  --gog-warning-color: #c45100; /* Dark amber */
267
321
  --gog-info-color: #2b5c8f; /* Lapis */
268
322
 
269
- /* Soft, deep shadow old leather */
270
- --gog-panel-shadow: 0 4px 20px rgba(23, 18, 12, 0.08), 0 1px 3px rgba(23, 18, 12, 0.04);
323
+ /* The boundary that identifies a control, as distinct from `--gog-border-color`, which is the
324
+ decorative hairline this library draws dividers, table rules and panel outlines with and
325
+ deliberately keeps faint. Three controls -- `gog-chip`, `gog-toggle`, `gog-button-toggle` --
326
+ had been reading the decorative one as their own edge, and the boundary sweep in 21.12.0
327
+ measured them at 1.18 to 2.17:1 in every shipped theme, against the 3:1 SC 1.4.11 requires.
328
+ Neither their border nor their fill carried it; the sweep checks the better of the two.
329
+
330
+ Computed, not chosen: `npm run suggest:color -- --gog-border-color <ground> 3.2` per theme,
331
+ holding hue and chroma so each theme's neutral stays its own, then the value that clears both
332
+ the page and the surface. */
333
+ --gog-control-boundary-color: #96866d;
271
334
  --gog-spinner-overlay-bg: rgba(247, 243, 235, 0.85);
272
335
  }
273
336
 
@@ -304,9 +367,34 @@
304
367
  --gog-warning-color: #c45100; /* Dark amber */
305
368
  --gog-info-color: #2b5c8f; /* Lapis */
306
369
 
307
- /* Soft, deep shadow old leather */
308
- --gog-panel-shadow: 0 4px 20px rgba(23, 18, 12, 0.08), 0 1px 3px rgba(23, 18, 12, 0.04);
370
+ /* The boundary that identifies a control, as distinct from `--gog-border-color`, which is the
371
+ decorative hairline this library draws dividers, table rules and panel outlines with and
372
+ deliberately keeps faint. Three controls -- `gog-chip`, `gog-toggle`, `gog-button-toggle` --
373
+ had been reading the decorative one as their own edge, and the boundary sweep in 21.12.0
374
+ measured them at 1.18 to 2.17:1 in every shipped theme, against the 3:1 SC 1.4.11 requires.
375
+ Neither their border nor their fill carried it; the sweep checks the better of the two.
376
+
377
+ Computed, not chosen: `npm run suggest:color -- --gog-border-color <ground> 3.2` per theme,
378
+ holding hue and chroma so each theme's neutral stays its own, then the value that clears both
379
+ the page and the surface. */
380
+ --gog-control-boundary-color: #96866d;
309
381
  --gog-spinner-overlay-bg: rgba(247, 243, 235, 0.85);
382
+
383
+ /* Restated rather than inherited, and every knob of the set rather than the ones that differ
384
+ from the default. A custom property inherits, so a `data-theme="light"` subtree nested inside
385
+ a dark page picks up whatever the outer theme left set — that is how this block came to carry
386
+ its own copy of `--gog-panel-shadow` before the ladder existed. A theme owns all ten or it
387
+ owns none; `check:elevation` enforces the set. */
388
+ --gog-elevation-ink: 23 18 12;
389
+ --gog-elevation-key-alpha: 0.08;
390
+ --gog-elevation-ambient-alpha: 0.04;
391
+ --gog-elevation-contact-blur: 3px;
392
+ --gog-elevation-key-x: 0;
393
+ --gog-elevation-key-y: 1;
394
+ --gog-elevation-key-blur: 3;
395
+ --gog-elevation-ring-width: 0px;
396
+ --gog-elevation-highlight-ink: 255 255 255;
397
+ --gog-elevation-highlight-alpha: 0;
310
398
  }
311
399
 
312
400
  :root[data-theme='dark'],
@@ -341,24 +429,27 @@
341
429
  --gog-warning-color: #fbbf24; /* Amber */
342
430
  --gog-info-color: #38bdf8; /* Sapphire */
343
431
 
344
- --gog-panel-shadow: 0 10px 30px rgba(0, 0, 0, 0.7), 0 0 0 1px var(--gog-border-color);
345
- /* `elevated` drops the 1px ring `--gog-panel-shadow` carries for real overlays (dialog,
346
- dropdown, tooltip), because that ring is exactly what `outlined` draws with it, the two
347
- card/panel variants render identically on a dark ground. The blur stays; the ring goes,
348
- so outlined has an edge and elevated does not. Light themes need none of this: their
349
- shadow has no ring and reads on its own. */
350
- /* `elevated` cannot use `--gog-panel-shadow` here. That shadow carries a `0 0 0 1px` ring so
351
- overlays keep an edge against the page, and the ring is exactly what `outlined` draws with
352
- it the two variants render identically. Dropping the ring and keeping the 30px black blur was
353
- worse: black blurred over a near-black page reads as smudge rather than lift.
354
-
355
- So elevation is stated the way a dark UI actually states it — a hairline of light along the
356
- top edge, where a raised surface would catch it, over a tighter, darker shadow that stays
357
- close to the element instead of hazing the page. */
358
- --gog-card-elevated-shadow:
359
- inset 0 1px 0 rgba(255, 255, 255, 0.07), 0 2px 6px rgba(0, 0, 0, 0.55);
360
- --gog-panel-elevated-shadow:
361
- inset 0 1px 0 rgba(255, 255, 255, 0.07), 0 2px 6px rgba(0, 0, 0, 0.55);
432
+ /* Elevation, as this theme states it. The long note in the literal block explains the knobs;
433
+ what is specific here is why a dark ground needs all three of them. Black blurred over a
434
+ near-black page reads as smudge rather than lift, so the shadow stays tight and dark and the
435
+ *edges* do the work: a hairline of light along the top, where a raised surface would catch
436
+ it, and a hairline ring for overlays that have to sit apart from the page.
437
+
438
+ The ring is not on the ladder, deliberately. `elevated` must not have one -- a ring is
439
+ exactly what `outlined` draws, and with it the two card and panel variants render
440
+ identically on a dark ground. That was a real defect, fixed in 21.7.1, and folding the ring
441
+ into a step would have reintroduced it. Overlays compose it; `elevated` does not. */
442
+ --gog-elevation-ink: 0 0 0;
443
+ --gog-elevation-key-alpha: 0.55;
444
+ --gog-elevation-ambient-alpha: 0.28;
445
+ --gog-elevation-contact-blur: 3px;
446
+ --gog-elevation-key-x: 0;
447
+ --gog-elevation-key-y: 1;
448
+ --gog-elevation-key-blur: 3;
449
+ --gog-elevation-ring-width: 1px;
450
+ --gog-elevation-highlight-ink: 255 255 255;
451
+ --gog-elevation-highlight-alpha: 0.07;
452
+ --gog-control-boundary-color: #716353;
362
453
  --gog-spinner-overlay-bg: rgba(13, 11, 8, 0.85);
363
454
  }
364
455
 
@@ -373,6 +464,68 @@
373
464
  Split out of the literal block above because they read other tokens: they have
374
465
  to re-resolve inside each theme scope. */
375
466
 
467
+ /* ── The elevation ladder ────────────────────────────────────────────────────
468
+ Generated from the knobs in the literal block above; see the long note there for why the
469
+ key light's blur is three times its offset and why the ring and the highlight are not part
470
+ of a step. Every step but 0 is the same two layers with one number changed, which is the
471
+ property that makes the arithmetic assertable by reading rather than by a check.
472
+
473
+ The heights, and what the library puts on each:
474
+
475
+ 0 -- flat. Every button at rest, and the `outlined` and `filled` card and panel.
476
+ 1 -- a mark riding on a control: the toggle's thumb.
477
+ 2 -- a surface raised in normal flow: the `elevated` card and panel.
478
+ 4 -- an overlay anchored to a control: the four dropdown panels, the tooltip, the menu.
479
+ 8 -- an overlay floating free of one: the toast.
480
+ 16 -- a modal that owns the screen: the dialog.
481
+
482
+ `gog-menu` is the one whose height *changes* here rather than being restated. It aliased
483
+ `--gog-dialog-shadow`, so a dropdown menu carried a modal's shadow while the four dropdown
484
+ panels beside it carried a panel's -- two overlays of one kind, four steps apart, and the
485
+ alias is why nobody saw it. */
486
+ --gog-elevation-contact: 0 1px var(--gog-elevation-contact-blur)
487
+ rgb(var(--gog-elevation-ink) / var(--gog-elevation-ambient-alpha));
488
+ /* Composable character layers, not steps. A component that wants one prepends it. */
489
+ --gog-elevation-ring: 0 0 0 var(--gog-elevation-ring-width) var(--gog-border-color);
490
+ --gog-elevation-highlight: inset 0 1px 0
491
+ rgb(var(--gog-elevation-highlight-ink) / var(--gog-elevation-highlight-alpha));
492
+ --gog-elevation-0: none;
493
+ --gog-elevation-1:
494
+ var(--gog-elevation-contact),
495
+ calc(1px * var(--gog-elevation-key-x)) calc(1px * var(--gog-elevation-key-y))
496
+ calc(1px * var(--gog-elevation-key-blur))
497
+ rgb(var(--gog-elevation-ink) / var(--gog-elevation-key-alpha));
498
+ --gog-elevation-2:
499
+ var(--gog-elevation-contact),
500
+ calc(2px * var(--gog-elevation-key-x)) calc(2px * var(--gog-elevation-key-y))
501
+ calc(2px * var(--gog-elevation-key-blur))
502
+ rgb(var(--gog-elevation-ink) / var(--gog-elevation-key-alpha));
503
+ --gog-elevation-3:
504
+ var(--gog-elevation-contact),
505
+ calc(4px * var(--gog-elevation-key-x)) calc(4px * var(--gog-elevation-key-y))
506
+ calc(4px * var(--gog-elevation-key-blur))
507
+ rgb(var(--gog-elevation-ink) / var(--gog-elevation-key-alpha));
508
+ --gog-elevation-4:
509
+ var(--gog-elevation-contact),
510
+ calc(8px * var(--gog-elevation-key-x)) calc(8px * var(--gog-elevation-key-y))
511
+ calc(8px * var(--gog-elevation-key-blur))
512
+ rgb(var(--gog-elevation-ink) / var(--gog-elevation-key-alpha));
513
+ --gog-elevation-5:
514
+ var(--gog-elevation-contact),
515
+ calc(16px * var(--gog-elevation-key-x)) calc(16px * var(--gog-elevation-key-y))
516
+ calc(16px * var(--gog-elevation-key-blur))
517
+ rgb(var(--gog-elevation-ink) / var(--gog-elevation-key-alpha));
518
+
519
+ /* The library's own surfaces, placed on the ladder. These stay the public names a consumer
520
+ overrides — what changed in 21.12.0 is that their *value* is a step rather than a hand-written
521
+ shadow, so a theme moves all of them by turning one knob. Overriding any single one still
522
+ works exactly as before. */
523
+ --gog-panel-shadow: var(--gog-elevation-ring), var(--gog-elevation-3);
524
+ --gog-panel-elevated-shadow: var(--gog-elevation-highlight), var(--gog-elevation-2);
525
+ --gog-toast-shadow: var(--gog-elevation-ring), var(--gog-elevation-4);
526
+ --gog-dialog-shadow: var(--gog-elevation-ring), var(--gog-elevation-5);
527
+ --gog-toggle-thumb-shadow: var(--gog-elevation-1);
528
+
376
529
  /* ── Text on a status fill ───────────────────────────────────────────────────
377
530
  `--gog-accent-text-color` means "text on the accent fill" and flips with the theme, which
378
531
  made it the obvious label for a status fill too — `gogBadge` used it for all four. It is
@@ -413,44 +566,56 @@
413
566
  /* The blocking overlay outranks everything, including a dialog it may be covering. */
414
567
  --gog-spinner-overlay-z: calc(var(--gog-z-base) + 8000);
415
568
 
416
- --gog-space-2: calc(2px * var(--gog-density));
417
569
  --gog-space-4: calc(4px * var(--gog-density));
418
- --gog-space-6: calc(6px * var(--gog-density));
419
570
  --gog-space-8: calc(8px * var(--gog-density));
420
- --gog-space-10: calc(10px * var(--gog-density));
421
571
  --gog-space-12: calc(12px * var(--gog-density));
422
- --gog-space-14: calc(14px * var(--gog-density));
423
572
  --gog-space-16: calc(16px * var(--gog-density));
424
- --gog-space-18: calc(18px * var(--gog-density));
425
573
  --gog-space-20: calc(20px * var(--gog-density));
426
574
  --gog-space-24: calc(24px * var(--gog-density));
427
575
  --gog-space-28: calc(28px * var(--gog-density));
428
576
  --gog-space-32: calc(32px * var(--gog-density));
577
+ /* 21.11.0. Added because the optical ratio requires it, not because a design asked: a control
578
+ with 20px of vertical padding needs exactly 40px horizontal, and `slg` is that control on
579
+ `gog-button`, `gog-inputfield` and every field that shares their tier. The scale had 32 and
580
+ then jumped to 48. */
581
+ --gog-space-40: calc(40px * var(--gog-density));
429
582
  --gog-space-48: calc(48px * var(--gog-density));
430
583
  --gog-space-xs: var(--gog-space-4);
431
584
  --gog-space-sm: var(--gog-space-8);
432
585
  --gog-space-md: var(--gog-space-16);
433
586
  --gog-space-lg: var(--gog-space-24);
434
587
  --gog-space-2xl: var(--gog-space-48);
435
- --gog-control-padding-y: var(--gog-space-10);
436
- --gog-control-padding-x: var(--gog-space-14);
437
- --gog-control-checkbox-padding: var(--gog-space-6);
588
+ /* The shared control tier, on the 4px grid at a ratio of exactly 2.0 (styling.instructions.md,
589
+ law 3). It was 10/14, a ratio of 1.40; `--gog-field-md-padding-*` derives from it, so this
590
+ pair is what an `md` input, select, multiselect, autocomplete and datepicker are padded by. */
591
+ --gog-control-padding-y: var(--gog-space-12);
592
+ --gog-control-padding-x: var(--gog-space-24);
593
+ /* One value, all four sides: this is the padding a checkable control's `<label>` carries around
594
+ its box, and it is part of the pointer target — a 12px `xsm` box inside 8px of padding is a
595
+ 28px target, which is how the smallest checkbox clears WCAG 2.5.8 without growing. */
596
+ --gog-control-checkbox-padding: var(--gog-space-8);
438
597
  --gog-field-xsm-padding-y: var(--gog-space-4);
439
598
  --gog-field-xsm-padding-x: var(--gog-space-8);
440
- --gog-field-sm-padding-y: var(--gog-space-6);
441
- --gog-field-sm-padding-x: var(--gog-space-10);
442
- --gog-field-lg-padding-y: var(--gog-space-14);
443
- --gog-field-lg-padding-x: var(--gog-space-18);
444
- --gog-field-slg-padding-y: var(--gog-space-18);
445
- --gog-field-slg-padding-x: var(--gog-space-20);
599
+ --gog-field-sm-padding-y: var(--gog-space-8);
600
+ --gog-field-sm-padding-x: var(--gog-space-16);
601
+ --gog-field-lg-padding-y: var(--gog-space-16);
602
+ --gog-field-lg-padding-x: var(--gog-space-32);
603
+ --gog-field-slg-padding-y: var(--gog-space-20);
604
+ --gog-field-slg-padding-x: var(--gog-space-40);
446
605
  --gog-field-float-label-over-gap: var(--gog-space-8);
447
- --gog-toast-gap: var(--gog-space-10);
606
+ --gog-toast-gap: var(--gog-space-12);
448
607
  --gog-toast-stack-padding: var(--gog-space-16);
449
- --gog-field-xsm-icon-offset: var(--gog-space-6);
608
+ /* L9 (docs/component-geometry.md, "D7 — taken"): the message wraps, so its cap is a measure —
609
+ 53ch at --gog-toast-message-font-size (14px), the nearest whole character to today's 400px so
610
+ this changes robustness to a font-size change, not the pixels anyone sees today. L8's viewport
611
+ exception is layered on top: the margin reads --gog-toast-stack-padding above, the container's
612
+ own edge inset, rather than a new number. */
613
+ --gog-toast-max-width: min(53ch, calc(100vw - var(--gog-toast-stack-padding) * 2));
614
+ --gog-field-xsm-icon-offset: var(--gog-space-8);
450
615
  --gog-field-sm-icon-offset: var(--gog-space-8);
451
- --gog-field-lg-icon-offset: var(--gog-space-14);
452
- --gog-field-slg-icon-offset: var(--gog-space-18);
453
- --gog-control-icon-offset: var(--gog-space-10);
616
+ --gog-field-lg-icon-offset: var(--gog-space-16);
617
+ --gog-field-slg-icon-offset: var(--gog-space-20);
618
+ --gog-control-icon-offset: var(--gog-space-12);
454
619
  --gog-elevated-surface-color: var(--gog-surface-color);
455
620
  --gog-panel-radius: calc(var(--gog-radius) + 8px);
456
621
  --gog-field-xsm-font-size: var(--gog-text-xs);
@@ -460,6 +625,16 @@
460
625
  literals-only `:root` freezes to that scope's scale (rule C). */
461
626
  --gog-field-slg-font-size: var(--gog-text-slg);
462
627
 
628
+ /* Leading for the three kinds of text every field renders, declared once and aliased by each
629
+ component the way the padding and float-label tiers above already are. A block that sets a
630
+ font size sets its leading (law 4): inheriting it while changing the size moves the ratio
631
+ silently, which is the thing the law guards. Roles, from
632
+ `docs/component-geometry.md` — the value in the field itself is one UI line whose box is the
633
+ row height; a label and an error message may both wrap beside their control. */
634
+ --gog-field-line-height: var(--gog-line-height-normal);
635
+ --gog-field-label-line-height: var(--gog-line-height-snug);
636
+ --gog-field-error-line-height: var(--gog-line-height-snug);
637
+
463
638
  --gog-field-md-padding-y: var(--gog-control-padding-y);
464
639
  --gog-field-md-padding-x: var(--gog-control-padding-x);
465
640
 
@@ -508,6 +683,9 @@
508
683
  --gog-accordion-hover-color: var(--gog-accordion-text-color);
509
684
  --gog-accordion-press-bg: var(--gog-border-color);
510
685
  --gog-accordion-hover-ring: var(--gog-accent-dim);
686
+ /* Its own token. The header's `:focus-visible` outline read `--gog-accordion-hover-ring`, so a
687
+ hover-weight colour was doing focus duty and failed 3:1 in all eleven themes. */
688
+ --gog-accordion-focus-ring-color: var(--gog-accent-color);
511
689
  --gog-accordion-focus-ring-width: var(--gog-focus-ring-width);
512
690
  --gog-accordion-body-color: var(--gog-text-color);
513
691
  --gog-accordion-body-line-height: var(--gog-line-height-loose);
@@ -535,41 +713,59 @@
535
713
  --gog-accordion-xsm-padding-y: var(--gog-space-4);
536
714
  --gog-accordion-xsm-padding-x: var(--gog-space-8);
537
715
  --gog-accordion-xsm-font-size: var(--gog-text-xs);
716
+ /* The header label is one UI line whose box is the row height (law 4, role ui-line). */
717
+ --gog-accordion-line-height: var(--gog-line-height-normal);
538
718
  --gog-accordion-xsm-letter-spacing: 0.2px;
539
- --gog-accordion-xsm-content-gap: var(--gog-space-2);
719
+ --gog-accordion-xsm-content-gap: var(--gog-space-4);
540
720
  --gog-accordion-xsm-body-font-size: var(--gog-text-xs);
541
721
  --gog-accordion-xsm-body-line-height: var(--gog-line-height-relaxed);
542
722
  --gog-accordion-xsm-body-padding-top: var(--gog-space-4);
543
- --gog-accordion-xsm-body-padding-bottom: var(--gog-space-6);
544
- --gog-accordion-xsm-chevron-size: 11px;
545
- --gog-accordion-xsm-chevron-font-size: 10px;
546
-
547
- --gog-accordion-sm-padding-y: var(--gog-space-6);
548
- --gog-accordion-sm-padding-x: var(--gog-space-10);
723
+ --gog-accordion-xsm-body-padding-bottom: var(--gog-space-8);
724
+ --gog-accordion-xsm-chevron-size: 1.4em;
725
+ /* The chevron is a ratio of the header's own type, not a px ladder of its own. It had been
726
+ 10/12/14/16/18px of glyph basis inside an 11/13/15/18/20px box, beside a label in rem -- so
727
+ raising the browser's text size grew the label and left the chevron where it was, and the
728
+ box/label ratio drifted 0.92 to 1.29 across the five sizes.
729
+
730
+ Two bugs came out of writing it as a ratio. The box was *smaller than its glyph at every
731
+ size*: `gog-icon` renders at `--gog-icon-size: 1.2em` of this font size, so the mark was
732
+ 12/14.4/16.8/19.2/21.6px inside a box of 11/13/15/18/20 and overflowed it everywhere. And
733
+ the five sizes had five ratios where they needed one.
734
+
735
+ `1em` makes this the em basis rather than the glyph size, so the mark is 1.2em of the header
736
+ and the 1.4em box surrounds it. All five steps hold the same ratio and still render five
737
+ different sizes, because the header's type differs -- the tokens stay per-size so an override
738
+ keeps working. */
739
+ --gog-accordion-xsm-chevron-font-size: 1em;
740
+ /* A glyph in its own box: leading would push it off the centre it is placed on. */
741
+ --gog-accordion-chevron-line-height: var(--gog-line-height-none);
742
+
743
+ --gog-accordion-sm-padding-y: var(--gog-space-8);
744
+ --gog-accordion-sm-padding-x: var(--gog-space-16);
549
745
  --gog-accordion-sm-font-size: var(--gog-text-xs);
550
746
  --gog-accordion-sm-letter-spacing: 0.4px;
551
- --gog-accordion-sm-content-gap: var(--gog-space-2);
747
+ --gog-accordion-sm-content-gap: var(--gog-space-4);
552
748
  --gog-accordion-sm-body-font-size: var(--gog-text-xs);
553
749
  --gog-accordion-sm-body-line-height: var(--gog-accordion-body-line-height);
554
- --gog-accordion-sm-body-padding-top: var(--gog-space-6);
750
+ --gog-accordion-sm-body-padding-top: var(--gog-space-8);
555
751
  --gog-accordion-sm-body-padding-bottom: var(--gog-space-8);
556
- --gog-accordion-sm-chevron-size: 13px;
557
- --gog-accordion-sm-chevron-font-size: 12px;
752
+ --gog-accordion-sm-chevron-size: 1.4em;
753
+ --gog-accordion-sm-chevron-font-size: 1em;
558
754
 
559
- --gog-accordion-md-padding-y: var(--gog-space-10);
560
- --gog-accordion-md-padding-x: var(--gog-space-14);
755
+ --gog-accordion-md-padding-y: var(--gog-space-12);
756
+ --gog-accordion-md-padding-x: var(--gog-space-24);
561
757
  --gog-accordion-md-font-size: var(--gog-text-xs);
562
758
  --gog-accordion-md-letter-spacing: 0.8px;
563
- --gog-accordion-md-content-gap: var(--gog-space-2);
759
+ --gog-accordion-md-content-gap: var(--gog-space-4);
564
760
  --gog-accordion-md-body-font-size: var(--gog-text-sm);
565
761
  --gog-accordion-md-body-line-height: var(--gog-accordion-body-line-height);
566
762
  --gog-accordion-md-body-padding-top: var(--gog-space-8);
567
763
  --gog-accordion-md-body-padding-bottom: var(--gog-space-12);
568
- --gog-accordion-md-chevron-size: 15px;
569
- --gog-accordion-md-chevron-font-size: 14px;
764
+ --gog-accordion-md-chevron-size: 1.4em;
765
+ --gog-accordion-md-chevron-font-size: 1em;
570
766
 
571
- --gog-accordion-lg-padding-y: var(--gog-space-14);
572
- --gog-accordion-lg-padding-x: var(--gog-space-16);
767
+ --gog-accordion-lg-padding-y: var(--gog-space-16);
768
+ --gog-accordion-lg-padding-x: var(--gog-space-32);
573
769
  --gog-accordion-lg-font-size: var(--gog-text-sm);
574
770
  --gog-accordion-lg-letter-spacing: 0.8px;
575
771
  --gog-accordion-lg-content-gap: var(--gog-space-4);
@@ -577,11 +773,11 @@
577
773
  --gog-accordion-lg-body-line-height: var(--gog-accordion-body-line-height);
578
774
  --gog-accordion-lg-body-padding-top: var(--gog-space-12);
579
775
  --gog-accordion-lg-body-padding-bottom: var(--gog-space-16);
580
- --gog-accordion-lg-chevron-size: 18px;
581
- --gog-accordion-lg-chevron-font-size: 16px;
776
+ --gog-accordion-lg-chevron-size: 1.4em;
777
+ --gog-accordion-lg-chevron-font-size: 1em;
582
778
 
583
- --gog-accordion-slg-padding-y: var(--gog-space-18);
584
- --gog-accordion-slg-padding-x: var(--gog-space-18);
779
+ --gog-accordion-slg-padding-y: var(--gog-space-20);
780
+ --gog-accordion-slg-padding-x: var(--gog-space-40);
585
781
  --gog-accordion-slg-font-size: var(--gog-text-md);
586
782
  --gog-accordion-slg-letter-spacing: 0.8px;
587
783
  --gog-accordion-slg-content-gap: var(--gog-space-4);
@@ -589,8 +785,8 @@
589
785
  --gog-accordion-slg-body-line-height: var(--gog-accordion-body-line-height);
590
786
  --gog-accordion-slg-body-padding-top: var(--gog-space-16);
591
787
  --gog-accordion-slg-body-padding-bottom: var(--gog-space-20);
592
- --gog-accordion-slg-chevron-size: 20px;
593
- --gog-accordion-slg-chevron-font-size: 18px;
788
+ --gog-accordion-slg-chevron-size: 1.4em;
789
+ --gog-accordion-slg-chevron-font-size: 1em;
594
790
 
595
791
  /* ── Collapsible ───────────────────────────────────────────────────────────
596
792
  No portal, no owned markup — see utilities.css for the actual `.gog-collapsible__*`
@@ -614,10 +810,10 @@
614
810
  `--gog-button-font-size` are intentionally NOT declared — they are the per-instance
615
811
  escape hatch the variant/size classes fall back through. */
616
812
  --gog-button-xsm-padding: var(--gog-space-4) var(--gog-space-8);
617
- --gog-button-sm-padding: var(--gog-space-8) var(--gog-space-14);
618
- --gog-button-md-padding: var(--gog-space-12) var(--gog-space-20);
619
- --gog-button-lg-padding: var(--gog-space-16) var(--gog-space-24);
620
- --gog-button-slg-padding: var(--gog-space-20) var(--gog-space-28);
813
+ --gog-button-sm-padding: var(--gog-space-8) var(--gog-space-16);
814
+ --gog-button-md-padding: var(--gog-space-12) var(--gog-space-24);
815
+ --gog-button-lg-padding: var(--gog-space-16) var(--gog-space-32);
816
+ --gog-button-slg-padding: var(--gog-space-20) var(--gog-space-40);
621
817
  --gog-button-xsm-font-size: var(--gog-text-xs);
622
818
  --gog-button-sm-font-size: var(--gog-text-sm);
623
819
  --gog-button-md-font-size: var(--gog-text-md);
@@ -823,7 +1019,7 @@
823
1019
  --gog-button-toggle-radius: var(--gog-radius);
824
1020
  --gog-button-toggle-border-width: var(--gog-control-border-width);
825
1021
  --gog-button-toggle-border-style: var(--gog-control-border-style);
826
- --gog-button-toggle-border-color: var(--gog-border-color);
1022
+ --gog-button-toggle-border-color: var(--gog-control-boundary-color);
827
1023
  --gog-button-toggle-rest-bg: transparent;
828
1024
  --gog-button-toggle-rest-color: var(--gog-text-color);
829
1025
  --gog-button-toggle-hover-bg: var(--gog-hover-color);
@@ -866,6 +1062,7 @@
866
1062
  --gog-calendar-weekday-padding: var(--gog-space-4) 0;
867
1063
  --gog-calendar-weekday-color: var(--gog-muted-text-color);
868
1064
  --gog-calendar-weekday-font-size: var(--gog-text-xs);
1065
+ --gog-calendar-weekday-line-height: var(--gog-line-height-none);
869
1066
  --gog-calendar-weekday-font-weight: var(--gog-font-weight-semibold);
870
1067
  --gog-calendar-weekday-text-transform: var(--gog-text-transform);
871
1068
  --gog-calendar-day-radius: calc(var(--gog-radius) - 2px);
@@ -895,12 +1092,12 @@
895
1092
  --gog-calendar-divider-width: 1px;
896
1093
  --gog-calendar-divider-style: solid;
897
1094
  --gog-calendar-divider-color: var(--gog-border-color);
898
- --gog-calendar-time-gap: var(--gog-space-6);
899
- --gog-calendar-time-margin: var(--gog-space-10);
1095
+ --gog-calendar-time-gap: var(--gog-space-8);
1096
+ --gog-calendar-time-margin: var(--gog-space-12);
900
1097
  --gog-calendar-time-input-width: 3.5rem;
901
- --gog-calendar-time-input-padding: var(--gog-space-4) var(--gog-space-6);
1098
+ --gog-calendar-time-input-padding: var(--gog-space-4) var(--gog-space-8);
902
1099
  --gog-calendar-time-input-bg: var(--gog-background-color);
903
- --gog-calendar-action-padding: var(--gog-space-4) var(--gog-space-10);
1100
+ --gog-calendar-action-padding: var(--gog-space-4) var(--gog-space-8);
904
1101
  --gog-calendar-footer-gap: var(--gog-space-8);
905
1102
  --gog-calendar-xsm-font-size: var(--gog-text-xs);
906
1103
  --gog-calendar-xsm-day-size: 24px;
@@ -911,6 +1108,7 @@
911
1108
  --gog-calendar-lg-font-size: var(--gog-text-md);
912
1109
  --gog-calendar-lg-day-size: 40px;
913
1110
  --gog-calendar-slg-font-size: var(--gog-text-lg);
1111
+ --gog-calendar-line-height: var(--gog-line-height-normal);
914
1112
  --gog-calendar-slg-day-size: 46px;
915
1113
 
916
1114
  /* ── Card ──────────────────────────────────────────────────────────────────
@@ -937,7 +1135,7 @@
937
1135
  --gog-card-elevated-border-color: transparent;
938
1136
  /* The shared surface shadow, so a card sits at the same elevation as a dialog or a
939
1137
  dropdown panel instead of inventing a second house style for "raised". */
940
- --gog-card-elevated-shadow: var(--gog-panel-shadow);
1138
+ --gog-card-elevated-shadow: var(--gog-elevation-highlight), var(--gog-elevation-2);
941
1139
  --gog-card-filled-bg: var(--gog-accent-pale);
942
1140
  --gog-card-filled-border-color: transparent;
943
1141
  --gog-card-filled-shadow: none;
@@ -955,17 +1153,17 @@
955
1153
  --gog-card-footer-padding-top: var(--gog-space-sm);
956
1154
 
957
1155
  --gog-card-xsm-padding-y: var(--gog-space-8);
958
- --gog-card-xsm-padding-x: var(--gog-space-10);
959
- --gog-card-xsm-gap: var(--gog-space-6);
1156
+ --gog-card-xsm-padding-x: var(--gog-space-12);
1157
+ --gog-card-xsm-gap: var(--gog-space-8);
960
1158
  --gog-card-sm-padding-y: var(--gog-space-12);
961
- --gog-card-sm-padding-x: var(--gog-space-14);
1159
+ --gog-card-sm-padding-x: var(--gog-space-16);
962
1160
  --gog-card-sm-gap: var(--gog-space-sm);
963
1161
  --gog-card-md-padding-y: var(--gog-space-md);
964
1162
  --gog-card-md-padding-x: var(--gog-space-20);
965
1163
  --gog-card-md-gap: var(--gog-space-12);
966
1164
  --gog-card-lg-padding-y: var(--gog-space-20);
967
1165
  --gog-card-lg-padding-x: var(--gog-space-lg);
968
- --gog-card-lg-gap: var(--gog-space-14);
1166
+ --gog-card-lg-gap: var(--gog-space-16);
969
1167
  --gog-card-slg-padding-y: var(--gog-space-28);
970
1168
  --gog-card-slg-padding-x: var(--gog-space-32);
971
1169
  --gog-card-slg-gap: var(--gog-space-md);
@@ -974,7 +1172,7 @@
974
1172
  Box/label/icon size and padding come from the `--gog-control-checkbox-*` scale;
975
1173
  checkbox.component.ts maps the `size` input onto the host. */
976
1174
  --gog-checkbox-font-family: var(--gog-font-body);
977
- --gog-checkbox-gap: var(--gog-space-10);
1175
+ --gog-checkbox-gap: var(--gog-space-12);
978
1176
  --gog-checkbox-radius: var(--gog-radius);
979
1177
  --gog-checkbox-border-width: var(--gog-control-border-width);
980
1178
  --gog-checkbox-border-style: var(--gog-control-border-style);
@@ -983,9 +1181,15 @@
983
1181
  --gog-checkbox-checked-bg: var(--gog-accent-color);
984
1182
  --gog-checkbox-checked-border: var(--gog-accent-color);
985
1183
  --gog-checkbox-icon-color: var(--gog-accent-text-color, var(--gog-primary-color));
1184
+ /* A glyph in its own box: role label-none, so the box is the glyph and not the font. */
1185
+ --gog-checkbox-icon-line-height: var(--gog-line-height-none);
986
1186
  --gog-checkbox-label-color: var(--gog-muted-text-color);
987
1187
  --gog-checkbox-label-line-height: var(--gog-line-height-snug);
988
- --gog-checkbox-focus-ring: var(--gog-accent-pale);
1188
+ /* The accent, not `--gog-accent-pale`. This outline is the *only* thing marking focus on this
1189
+ control, and a pale wash cannot carry that: measured 1.38:1 against the light page, against
1190
+ the 3:1 WCAG 2.4.11 and 1.4.11 both require. Fourteen of the library's focus rings already
1191
+ read `--gog-accent-color`; these were the outliers, found by the boundary sweep in 21.12.0. */
1192
+ --gog-checkbox-focus-ring: var(--gog-accent-color);
989
1193
  --gog-checkbox-focus-ring-width: var(--gog-focus-ring-width);
990
1194
  --gog-checkbox-focus-ring-offset: var(--gog-focus-ring-offset);
991
1195
  --gog-checkbox-disabled-opacity: var(--gog-disabled-opacity);
@@ -998,12 +1202,12 @@
998
1202
  Box/label size reuse the `--gog-control-checkbox-*` scale (see Checkbox above);
999
1203
  radio-group.component.ts maps the `size` input onto the host the same way. */
1000
1204
  --gog-radio-font-family: var(--gog-font-body);
1001
- --gog-radio-group-gap: var(--gog-space-10);
1205
+ --gog-radio-group-gap: var(--gog-space-12);
1002
1206
  --gog-radio-group-label-size: var(--gog-text-sm);
1003
1207
  --gog-radio-group-label-color: var(--gog-muted-text-color);
1004
1208
  --gog-radio-group-option-gap: var(--gog-space-8);
1005
1209
  --gog-radio-group-option-gap-horizontal: var(--gog-space-20);
1006
- --gog-radio-gap: var(--gog-space-10);
1210
+ --gog-radio-gap: var(--gog-space-12);
1007
1211
  --gog-radio-border-width: var(--gog-control-border-width);
1008
1212
  --gog-radio-border-style: var(--gog-control-border-style);
1009
1213
  --gog-radio-border-color: var(--gog-accent-dim);
@@ -1014,12 +1218,17 @@
1014
1218
  --gog-radio-dot-size-ratio: 0.45;
1015
1219
  --gog-radio-label-color: var(--gog-muted-text-color);
1016
1220
  --gog-radio-label-line-height: var(--gog-line-height-snug);
1017
- --gog-radio-focus-ring: var(--gog-accent-pale);
1221
+ /* The accent, not `--gog-accent-pale`. This outline is the *only* thing marking focus on this
1222
+ control, and a pale wash cannot carry that: measured 1.38:1 against the light page, against
1223
+ the 3:1 WCAG 2.4.11 and 1.4.11 both require. Fourteen of the library's focus rings already
1224
+ read `--gog-accent-color`; these were the outliers, found by the boundary sweep in 21.12.0. */
1225
+ --gog-radio-focus-ring: var(--gog-accent-color);
1018
1226
  --gog-radio-focus-ring-width: var(--gog-focus-ring-width);
1019
1227
  --gog-radio-focus-ring-offset: var(--gog-focus-ring-offset);
1020
1228
  --gog-radio-disabled-opacity: var(--gog-disabled-opacity);
1021
1229
  --gog-radio-transition-duration: var(--gog-duration-base);
1022
1230
  --gog-radio-error-font-size: var(--gog-text-xs);
1231
+ --gog-radio-error-line-height: var(--gog-field-error-line-height);
1023
1232
  --gog-radio-error-color: var(--gog-danger-color);
1024
1233
 
1025
1234
  /* ── Chip ──────────────────────────────────────────────────────────────────
@@ -1030,7 +1239,7 @@
1030
1239
  --gog-chip-bg: var(--gog-surface-color);
1031
1240
  --gog-chip-hover-bg: var(--gog-hover-color);
1032
1241
  --gog-chip-press-bg: var(--gog-border-color);
1033
- --gog-chip-border: var(--gog-border-color);
1242
+ --gog-chip-border: var(--gog-control-boundary-color);
1034
1243
  --gog-chip-border-width: var(--gog-border-width);
1035
1244
  --gog-chip-border-style: var(--gog-border-style);
1036
1245
  --gog-chip-color: var(--gog-text-color);
@@ -1053,48 +1262,75 @@
1053
1262
  --gog-chip-selected-ring-width: 2px;
1054
1263
  --gog-chip-selected-shadow: inset 0 0 0 var(--gog-chip-selected-ring-width)
1055
1264
  var(--gog-accent-color);
1265
+ /* The chip had a focus-ring width and offset but no colour, so `chip.component.scss` reached
1266
+ for `--gog-chip-border` — the decorative hairline, 1.18:1 in `primeng`. A focus indicator
1267
+ needs a colour of its own. */
1268
+ --gog-chip-focus-ring-color: var(--gog-accent-color);
1056
1269
  --gog-chip-focus-ring-width: 2px;
1057
1270
  --gog-chip-focus-ring-offset: var(--gog-focus-ring-offset);
1058
1271
 
1059
- --gog-chip-xsm-font-size: 0.6875rem;
1272
+ --gog-chip-xsm-font-size: var(--gog-text-2xs);
1060
1273
  --gog-chip-xsm-padding-block: var(--gog-space-4);
1061
- --gog-chip-xsm-padding-inline: var(--gog-space-6);
1274
+ --gog-chip-xsm-padding-inline: var(--gog-space-8);
1062
1275
  --gog-chip-xsm-gap: var(--gog-space-4);
1063
- --gog-chip-xsm-avatar-size: 0.875rem;
1064
- --gog-chip-xsm-icon-size: 0.6875rem;
1065
- --gog-chip-xsm-remove-size: 0.75rem;
1276
+ /* The avatar and the icon are ratios of the chip's own type, not px ladders of their own.
1277
+
1278
+ The icon already was one and nobody had written it down: 11/12/14/16/18px of glyph beside a
1279
+ label of exactly 11/12/14/16/18px, five sizes holding 1.00 five times by hand. `1em` states
1280
+ it, and it changes nothing rendered -- but it means an override of one size's font-size now
1281
+ carries the icon with it, which the rem ladder did not.
1282
+
1283
+ The avatar had no rule at all: 14/16/20/24/28px against that same type is 1.27, 1.33, 1.43,
1284
+ 1.50, 1.56 -- five opinions about one relationship, drifting monotonically, which is what a
1285
+ value picked by eye per size looks like. 1.5em is the ratio `lg` already held, and it keeps
1286
+ the intent the rest of the component is built around: the avatar is larger than the label
1287
+ and hugs the chip's leading edge, which is what `--gog-chip-avatar-inset-ratio` exists for.
1288
+ A chip with an avatar is still taller than one without, but now by one constant ratio
1289
+ instead of a gap that grew 0.8px to 6.4px across the five sizes.
1290
+
1291
+ The remove button's glyph is the third of the same family and now the same kind of rule:
1292
+ 1.125em, one number where there were five. Those five were 1.091, 1.167, 1.143, 1.125 and
1293
+ 1.111 of the label -- non-monotonic and inside a 7% band, which is a px ladder converted to
1294
+ rem rather than five judgements. 1.125 is the ratio `lg` already held, the same way 1.5 was
1295
+ the avatar's, and it keeps what all five values agreed on: the mark a reader can press
1296
+ reads a shade heavier than the one that only decorates. No size moves by more than half a
1297
+ pixel. The painted box stays `--gog-chip-remove-scale` of it -- see chip.component.scss,
1298
+ which had to stop writing that multiplication in `em`. */
1299
+ --gog-chip-xsm-avatar-size: 1.5em;
1300
+ --gog-chip-xsm-icon-size: 1em;
1301
+ --gog-chip-xsm-remove-size: 1.125em;
1066
1302
 
1067
1303
  --gog-chip-sm-font-size: var(--gog-text-xs);
1068
1304
  --gog-chip-sm-padding-block: var(--gog-space-4);
1069
1305
  --gog-chip-sm-padding-inline: var(--gog-space-8);
1070
- --gog-chip-sm-gap: var(--gog-space-6);
1071
- --gog-chip-sm-avatar-size: 1rem;
1072
- --gog-chip-sm-icon-size: 0.75rem;
1073
- --gog-chip-sm-remove-size: 0.875rem;
1306
+ --gog-chip-sm-gap: var(--gog-space-8);
1307
+ --gog-chip-sm-avatar-size: 1.5em;
1308
+ --gog-chip-sm-icon-size: 1em;
1309
+ --gog-chip-sm-remove-size: 1.125em;
1074
1310
 
1075
1311
  --gog-chip-md-font-size: var(--gog-text-sm);
1076
1312
  --gog-chip-md-padding-block: var(--gog-space-8);
1077
- --gog-chip-md-padding-inline: var(--gog-space-12);
1313
+ --gog-chip-md-padding-inline: var(--gog-space-16);
1078
1314
  --gog-chip-md-gap: var(--gog-space-8);
1079
- --gog-chip-md-avatar-size: 1.25rem;
1080
- --gog-chip-md-icon-size: 0.875rem;
1081
- --gog-chip-md-remove-size: 1rem;
1315
+ --gog-chip-md-avatar-size: 1.5em;
1316
+ --gog-chip-md-icon-size: 1em;
1317
+ --gog-chip-md-remove-size: 1.125em;
1082
1318
 
1083
1319
  --gog-chip-lg-font-size: var(--gog-text-md);
1084
- --gog-chip-lg-padding-block: var(--gog-space-10);
1085
- --gog-chip-lg-padding-inline: var(--gog-space-14);
1086
- --gog-chip-lg-gap: var(--gog-space-10);
1087
- --gog-chip-lg-avatar-size: 1.5rem;
1088
- --gog-chip-lg-icon-size: 1rem;
1089
- --gog-chip-lg-remove-size: 1.125rem;
1320
+ --gog-chip-lg-padding-block: var(--gog-space-12);
1321
+ --gog-chip-lg-padding-inline: var(--gog-space-24);
1322
+ --gog-chip-lg-gap: var(--gog-space-12);
1323
+ --gog-chip-lg-avatar-size: 1.5em;
1324
+ --gog-chip-lg-icon-size: 1em;
1325
+ --gog-chip-lg-remove-size: 1.125em;
1090
1326
 
1091
1327
  --gog-chip-slg-font-size: var(--gog-text-lg);
1092
1328
  --gog-chip-slg-padding-block: var(--gog-space-12);
1093
- --gog-chip-slg-padding-inline: var(--gog-space-16);
1329
+ --gog-chip-slg-padding-inline: var(--gog-space-24);
1094
1330
  --gog-chip-slg-gap: var(--gog-space-12);
1095
- --gog-chip-slg-avatar-size: 1.75rem;
1096
- --gog-chip-slg-icon-size: 1.125rem;
1097
- --gog-chip-slg-remove-size: 1.25rem;
1331
+ --gog-chip-slg-avatar-size: 1.5em;
1332
+ --gog-chip-slg-icon-size: 1em;
1333
+ --gog-chip-slg-remove-size: 1.125em;
1098
1334
 
1099
1335
  /* ── Dialog ────────────────────────────────────────────────────────────────── */
1100
1336
  --gog-dialog-font-family: var(--gog-font-heading);
@@ -1112,16 +1348,22 @@
1112
1348
  --gog-dialog-border-width: var(--gog-panel-border-width);
1113
1349
  --gog-dialog-border-style: var(--gog-panel-border-style);
1114
1350
  --gog-dialog-radius: var(--gog-radius);
1115
- --gog-dialog-shadow: 0 24px 48px rgba(0, 0, 0, 0.5);
1116
1351
  --gog-dialog-min-width: 320px;
1117
1352
  --gog-dialog-max-height: 90vh;
1118
- --gog-dialog-header-padding: var(--gog-space-16) var(--gog-space-20) var(--gog-space-14);
1353
+ --gog-dialog-header-padding: var(--gog-space-16) var(--gog-space-20) var(--gog-space-16);
1119
1354
  --gog-dialog-header-gap: var(--gog-space-12);
1120
1355
  --gog-dialog-header-border-color: var(--gog-border-color);
1356
+ /* `.gog-dialog__title` is the library's only <h2>; before this it rendered at the browser's
1357
+ default 24px bold rather than a stated size. --gog-text-xl is exactly today's rendered size,
1358
+ so this states an accident as a declaration rather than changing anything visible. `snug`
1359
+ (1.3) is law 4's `heading` role (docs/component-geometry.md, D4). */
1360
+ --gog-dialog-title-font-size: var(--gog-text-xl);
1361
+ --gog-dialog-title-line-height: var(--gog-line-height-snug);
1121
1362
  --gog-dialog-body-padding: var(--gog-space-20);
1122
1363
  --gog-dialog-body-max-height: calc(var(--gog-dialog-max-height) - 60px);
1123
1364
  --gog-dialog-close-size: 2rem;
1124
1365
  --gog-dialog-close-font-size: var(--gog-text-sm);
1366
+ --gog-dialog-close-line-height: var(--gog-line-height-none);
1125
1367
  --gog-dialog-close-color: var(--gog-muted-text-color);
1126
1368
  --gog-dialog-close-hover-color: var(--gog-text-color);
1127
1369
  --gog-dialog-close-hover-bg: var(--gog-hover-color);
@@ -1133,7 +1375,37 @@
1133
1375
  /* Confirmation dialog */
1134
1376
  --gog-confirmation-dialog-gap: var(--gog-space-12);
1135
1377
  --gog-confirmation-dialog-min-width: 320px;
1136
- --gog-confirmation-dialog-max-width: 440px;
1378
+ /* The title and description carried dead utility classes (`heading-md` / `body-sm`) with no
1379
+ CSS rule anywhere in the library, so both rendered at whatever the browser inherited rather
1380
+ than a step of the type scale (docs/backlog.md, fixed here). `lg` for the title rather than
1381
+ `md`: the dead class named `md`, but it never ran, so it is not evidence of intent — 18.72px
1382
+ is what actually rendered, and --gog-text-lg (18px) is the nearest step to that, so this
1383
+ states what shipped rather than silently shrinking every confirmation dialog. The description
1384
+ takes `sm`, the size every other muted secondary line in the library already uses. */
1385
+ --gog-confirmation-dialog-title-font-size: var(--gog-text-lg);
1386
+ --gog-confirmation-dialog-title-line-height: var(--gog-line-height-snug);
1387
+ --gog-confirmation-dialog-description-font-size: var(--gog-text-sm);
1388
+ --gog-confirmation-dialog-description-line-height: var(--gog-line-height-relaxed);
1389
+ /* L9 (docs/component-geometry.md, "D7 — taken"): the description wraps, so its cap is a
1390
+ measure — 51ch at 16px, the nearest whole character to today's 440px, so this changes
1391
+ robustness to a font-size change, not the pixels anyone sees today. The 16px is
1392
+ `.confirm-dialog`'s own inherited size (it declares no font-size of its own; see
1393
+ confirmation-dialog.component.scss), not the description's — the description now reads
1394
+ --gog-confirmation-dialog-description-font-size (14px, fixed above), but a `ch` cap resolves
1395
+ against the element `max-width` is declared on, never a descendant's, so that change does not
1396
+ move this number. What it changes is the *measure* the 440px produces against a 14px
1397
+ description: 439.9px ÷ (0.5391 × 14px) ≈ 58ch by hand (scripts/survey-measure.mjs's own
1398
+ `chCount` line is a tautology for this token — it resolves against `.confirm-dialog`'s 16px,
1399
+ not the description's font; see that script's reason string for the full account), still
1400
+ inside L9's 45–75 band, so no token value here needs to change.
1401
+
1402
+ L8's viewport clamp is deliberately NOT here, unlike the other three overlays: this renders
1403
+ inside .gog-dialog__panel, which already caps itself at 90vw (an inline style in
1404
+ dialog.component.html), and .gog-dialog__body spends --gog-dialog-body-padding a side inside
1405
+ that. The width available here is therefore `0.9 * 100vw - 40px`, tighter than any
1406
+ `100vw - margin` clamp at every viewport above 80px, so a second clamp on the child could
1407
+ never bind. An inert declaration is the thing this repo keeps finding rather than shipping. */
1408
+ --gog-confirmation-dialog-max-width: 51ch;
1137
1409
  --gog-confirmation-dialog-color: var(--gog-text-color);
1138
1410
  --gog-confirmation-dialog-description-color: var(--gog-muted-text-color);
1139
1411
  --gog-confirmation-dialog-actions-gap: var(--gog-space-sm);
@@ -1150,6 +1422,7 @@
1150
1422
  --gog-autocomplete-gap: var(--gog-space-4);
1151
1423
  --gog-autocomplete-label-color: var(--gog-accent-color);
1152
1424
  --gog-autocomplete-label-font-size: var(--gog-text-sm);
1425
+ --gog-autocomplete-label-line-height: var(--gog-field-label-line-height);
1153
1426
  --gog-autocomplete-label-font-weight: var(--gog-font-weight-semibold);
1154
1427
  --gog-autocomplete-label-letter-spacing: var(--gog-letter-spacing);
1155
1428
  --gog-autocomplete-label-text-transform: var(--gog-text-transform);
@@ -1171,12 +1444,13 @@
1171
1444
  --gog-autocomplete-error-border-color: var(--gog-danger-color);
1172
1445
  --gog-autocomplete-error-font-family: var(--gog-font-body);
1173
1446
  --gog-autocomplete-error-font-size: var(--gog-text-xs);
1447
+ --gog-autocomplete-error-line-height: var(--gog-field-error-line-height);
1174
1448
  /* Floor for an auto-width field, so [fullWidth]="false" cannot collapse it to its chrome. */
1175
1449
  --gog-autocomplete-min-width: 120px;
1176
1450
  /* Trailing chrome: spinner and clear button, clear outermost — the arrangement the other
1177
1451
  dropdowns settled on, so all of them line up in a form. */
1178
1452
  --gog-autocomplete-actions-inset: var(--gog-control-icon-offset);
1179
- --gog-autocomplete-actions-gap: var(--gog-space-6);
1453
+ --gog-autocomplete-actions-gap: var(--gog-space-8);
1180
1454
  /* Right padding on the input, reserving room for the actions above. */
1181
1455
  --gog-autocomplete-actions-reserve: 40px;
1182
1456
  --gog-autocomplete-clear-color: var(--gog-autocomplete-placeholder-color);
@@ -1190,14 +1464,21 @@
1190
1464
  --gog-autocomplete-panel-border-style: var(--gog-panel-border-style);
1191
1465
  --gog-autocomplete-panel-border-color: var(--gog-border-color);
1192
1466
  --gog-autocomplete-panel-radius: var(--gog-radius);
1193
- --gog-autocomplete-panel-gap: var(--gog-space-2);
1467
+ --gog-autocomplete-panel-gap: var(--gog-space-4);
1194
1468
  --gog-autocomplete-panel-max-height: 260px;
1195
1469
  /* Ceiling for a content-sized panel, so one very long option cannot span the viewport. */
1196
1470
  --gog-autocomplete-panel-max-width: 420px;
1197
1471
  --gog-autocomplete-options-padding: var(--gog-space-4);
1198
- --gog-autocomplete-option-padding: var(--gog-space-8) var(--gog-space-10);
1199
- --gog-autocomplete-option-radius: calc(var(--gog-radius) - 4px);
1200
- --gog-autocomplete-option-gap: var(--gog-space-10);
1472
+ --gog-autocomplete-option-padding: var(--gog-space-8) var(--gog-space-16);
1473
+ /* Concentric with the panel: the option row is inset by the list's own padding, so its corner
1474
+ is the panel's corner minus that distance. Written as the two tokens rather than as
1475
+ `calc(var(--gog-radius) - 4px)`, which was right only at `--gog-density: 1` -- the padding
1476
+ scales with density and a restated `4px` does not. */
1477
+ --gog-autocomplete-option-radius: max(
1478
+ 0px,
1479
+ calc(var(--gog-autocomplete-panel-radius) - var(--gog-autocomplete-options-padding))
1480
+ );
1481
+ --gog-autocomplete-option-gap: var(--gog-space-12);
1201
1482
  --gog-autocomplete-option-color: var(--gog-text-color);
1202
1483
  --gog-autocomplete-option-hover-bg: var(--gog-hover-color);
1203
1484
  --gog-autocomplete-option-press-bg: var(--gog-border-color);
@@ -1214,6 +1495,7 @@
1214
1495
  --gog-autocomplete-option-height: 36px;
1215
1496
  --gog-autocomplete-empty-color: var(--gog-autocomplete-placeholder-color);
1216
1497
  --gog-autocomplete-empty-font-size: var(--gog-text-sm);
1498
+ --gog-autocomplete-empty-line-height: var(--gog-line-height-normal);
1217
1499
  --gog-autocomplete-float-label-reserve: var(--gog-field-float-label-reserve);
1218
1500
  --gog-autocomplete-float-label-in-top: var(--gog-field-float-label-in-top);
1219
1501
  --gog-autocomplete-float-label-over-gap: var(--gog-field-float-label-over-gap);
@@ -1230,8 +1512,12 @@
1230
1512
  --gog-badge-dot-size: 0.5rem;
1231
1513
  --gog-badge-padding-inline: var(--gog-space-4);
1232
1514
  --gog-badge-radius: 999px;
1233
- /* How far the badge hangs outside its host's corner. */
1234
- --gog-badge-offset: var(--gog-space-6);
1515
+ /* How far the badge hangs outside its host's corner. `space-8` rather than the `space-6` it
1516
+ was: every off-grid step this library had sat exactly halfway between two grid steps, so the
1517
+ 4px grid made the tie-break a real decision, and it rounds up (docs/component-geometry.md,
1518
+ D3b). Here that is also the better answer on its own terms — a 20px badge hanging 8px out
1519
+ clears the host's corner radius at `--gog-radius: 8px`, which 6px did not quite do. */
1520
+ --gog-badge-offset: var(--gog-space-8);
1235
1521
  --gog-badge-border-width: 0;
1236
1522
  --gog-badge-border-style: var(--gog-border-style);
1237
1523
  --gog-badge-border-color: transparent;
@@ -1259,6 +1545,7 @@
1259
1545
  --gog-datepicker-gap: var(--gog-space-4);
1260
1546
  --gog-datepicker-label-color: var(--gog-accent-color);
1261
1547
  --gog-datepicker-label-font-size: var(--gog-text-sm);
1548
+ --gog-datepicker-label-line-height: var(--gog-field-label-line-height);
1262
1549
  --gog-datepicker-label-letter-spacing: var(--gog-letter-spacing);
1263
1550
  --gog-datepicker-label-text-transform: var(--gog-text-transform);
1264
1551
  --gog-datepicker-field-bg: var(--gog-surface-color);
@@ -1279,9 +1566,10 @@
1279
1566
  --gog-datepicker-error-border-color: var(--gog-danger-color);
1280
1567
  --gog-datepicker-error-font-family: var(--gog-font-body);
1281
1568
  --gog-datepicker-error-font-size: var(--gog-text-xs);
1569
+ --gog-datepicker-error-line-height: var(--gog-field-error-line-height);
1282
1570
  --gog-datepicker-min-width: 150px;
1283
1571
  --gog-datepicker-actions-inset: var(--gog-control-icon-offset);
1284
- --gog-datepicker-actions-gap: var(--gog-space-6);
1572
+ --gog-datepicker-actions-gap: var(--gog-space-8);
1285
1573
  /* Right padding on the input, reserving room for the calendar and clear buttons. */
1286
1574
  --gog-datepicker-actions-reserve: 40px;
1287
1575
  --gog-datepicker-icon-color: var(--gog-accent-color);
@@ -1295,7 +1583,7 @@
1295
1583
  --gog-datepicker-panel-border-style: var(--gog-panel-border-style);
1296
1584
  --gog-datepicker-panel-border-color: var(--gog-border-color);
1297
1585
  --gog-datepicker-panel-radius: var(--gog-radius);
1298
- --gog-datepicker-panel-gap: var(--gog-space-2);
1586
+ --gog-datepicker-panel-gap: var(--gog-space-4);
1299
1587
  /* The dropdown surface. Inline mode is `gog-calendar` itself, so it sizes from
1300
1588
  `--gog-calendar-max-width` rather than from this. */
1301
1589
  --gog-datepicker-panel-width: max-content;
@@ -1334,6 +1622,7 @@
1334
1622
  --gog-input-gap: var(--gog-space-4);
1335
1623
  --gog-input-label-color: var(--gog-accent-color);
1336
1624
  --gog-input-label-font-size: var(--gog-text-sm);
1625
+ --gog-input-label-line-height: var(--gog-field-label-line-height);
1337
1626
  --gog-input-label-letter-spacing: var(--gog-letter-spacing);
1338
1627
  --gog-input-label-text-transform: var(--gog-text-transform);
1339
1628
  --gog-input-field-bg: var(--gog-surface-color);
@@ -1350,6 +1639,7 @@
1350
1639
  --gog-input-focus-ring-offset: var(--gog-focus-ring-offset);
1351
1640
  --gog-input-error-color: var(--gog-danger-color);
1352
1641
  --gog-input-error-font-size: var(--gog-text-xs);
1642
+ --gog-input-error-line-height: var(--gog-field-error-line-height);
1353
1643
  /* Extra space above the error line, *on top of* the host's own `--gog-input-gap`, which
1354
1644
  already separates every child of the field. It shipped as `2px` and put this field's error
1355
1645
  6px under it while `gog-select`, `gog-autocomplete` and `gog-datepicker` — same gap, no
@@ -1358,6 +1648,7 @@
1358
1648
  pushed further than the rest. */
1359
1649
  --gog-input-error-offset: 0px;
1360
1650
  --gog-input-icon-color: var(--gog-muted-text-color);
1651
+ --gog-input-icon-line-height: var(--gog-line-height-none);
1361
1652
  --gog-input-icon-hover-color: var(--gog-accent-color);
1362
1653
  --gog-input-icon-action-radius: calc(var(--gog-radius) - 4px);
1363
1654
  --gog-input-icon-focus-ring-width: 2px;
@@ -1380,12 +1671,16 @@
1380
1671
  `gog-toast` and `gog-accordion` keep their flat `0px` on purpose: those are a chosen shape,
1381
1672
  not a number that forgot where it came from. */
1382
1673
  --gog-input-clear-radius: calc(var(--gog-radius) / 4);
1674
+ --gog-input-clear-line-height: var(--gog-line-height-none);
1383
1675
  --gog-input-clear-icon-ratio: var(--gog-control-clear-icon-ratio);
1384
1676
  /*
1385
1677
  The textarea's clear button gets a full-size glyph. The 0.7 ratio above suits the dense
1386
1678
  single-line trigger of a dropdown; on a large multi-line box it reads as a speck.
1387
1679
  */
1388
1680
  --gog-textarea-clear-icon-ratio: 1;
1681
+ /* The field is the one place in the library that renders a paragraph the consumer typed:
1682
+ role prose. */
1683
+ --gog-textarea-line-height: var(--gog-line-height-relaxed);
1389
1684
  /* Custom resize grip — see the `::-webkit-resizer` comment in textarea.component.scss for
1390
1685
  why this replaces rather than restyles the native glyph. Colour follows the field's own
1391
1686
  border by default, not a fixed muted grey, so it reads as part of the field rather than a
@@ -1394,8 +1689,12 @@
1394
1689
  --gog-textarea-resize-grip-color: var(--gog-input-field-border);
1395
1690
  --gog-textarea-resize-grip-opacity: 0.8;
1396
1691
  --gog-textarea-resize-grip-stripe-width: 1.5px;
1397
- --gog-textarea-resize-grip-stripe-gap: var(--gog-space-2);
1398
- --gog-textarea-resize-grip-offset: 3px;
1692
+ /* The three hairlines of the resize grip and the gap between them: a length inside one painted
1693
+ mark, not spacing between two things, so it is off the 4px grid on purpose (OPTICAL_CHROME in
1694
+ check-geometry.mjs). At 4px the three stripes would be a 20px block in the corner of every
1695
+ textarea instead of a 9px hint. */
1696
+ --gog-textarea-resize-grip-stripe-gap: 2px;
1697
+ --gog-textarea-resize-grip-offset: var(--gog-space-4);
1399
1698
  /*
1400
1699
  Both default to 0 and are overwritten per instance, as an inline style on the field, from
1401
1700
  the component's own ResizeObserver — they close the gap that opens once the field has been
@@ -1429,6 +1728,7 @@
1429
1728
  --gog-multiselect-options-padding: var(--gog-space-4);
1430
1729
  --gog-multiselect-label-color: var(--gog-accent-color);
1431
1730
  --gog-multiselect-label-font-size: var(--gog-text-sm);
1731
+ --gog-multiselect-label-line-height: var(--gog-field-label-line-height);
1432
1732
  --gog-multiselect-label-letter-spacing: var(--gog-letter-spacing);
1433
1733
  --gog-multiselect-label-text-transform: var(--gog-text-transform);
1434
1734
  --gog-multiselect-field-bg: var(--gog-surface-color);
@@ -1440,28 +1740,46 @@
1440
1740
  --gog-multiselect-value-color: var(--gog-text-color);
1441
1741
  --gog-multiselect-placeholder-color: var(--gog-muted-text-color);
1442
1742
  --gog-multiselect-focus-border: var(--gog-accent-color);
1443
- --gog-multiselect-focus-ring: var(--gog-accent-pale);
1743
+ /* The accent, not `--gog-accent-pale`. This outline is the *only* thing marking focus on this
1744
+ control, and a pale wash cannot carry that: measured 1.38:1 against the light page, against
1745
+ the 3:1 WCAG 2.4.11 and 1.4.11 both require. Fourteen of the library's focus rings already
1746
+ read `--gog-accent-color`; these were the outliers, found by the boundary sweep in 21.12.0. */
1747
+ --gog-multiselect-focus-ring: var(--gog-accent-color);
1444
1748
  --gog-multiselect-focus-glow: 0 0 8px var(--gog-multiselect-focus-ring);
1445
1749
  --gog-multiselect-focus-ring-width: var(--gog-focus-ring-width);
1446
1750
  --gog-multiselect-focus-ring-offset: var(--gog-focus-ring-offset);
1447
1751
  --gog-multiselect-error-color: var(--gog-danger-color);
1448
1752
  --gog-multiselect-error-font-size: var(--gog-text-xs);
1753
+ --gog-multiselect-error-line-height: var(--gog-field-error-line-height);
1449
1754
  /* Zero by default since 21.9.0 — see `--gog-input-error-offset` for why. */
1450
1755
  --gog-multiselect-error-offset: 0px;
1451
1756
  --gog-multiselect-border-color: var(--gog-accent-color);
1452
1757
  --gog-multiselect-panel-bg: var(--gog-surface-color);
1453
1758
  --gog-multiselect-panel-border: var(--gog-accent-color);
1454
1759
  --gog-multiselect-panel-shadow: var(--gog-panel-shadow);
1760
+ /* The panel's own corner, and the reason it is not `--gog-multiselect-radius`: that token
1761
+ shapes the *field*, and it shaped this box too until this release. One token painting two
1762
+ boxes meant a consumer rounding the field into a pill rounded the dropdown into one as well,
1763
+ and the two radii below derive from whatever it is, so the filter and the option rows
1764
+ followed. Same default, so nothing moves; `gog-autocomplete` and `gog-datepicker` already
1765
+ declared this token and this is the pair that did not. */
1766
+ --gog-multiselect-panel-radius: var(--gog-radius);
1455
1767
  --gog-multiselect-panel-max-height: 260px;
1456
- --gog-multiselect-panel-offset: var(--gog-space-2);
1768
+ --gog-multiselect-panel-offset: var(--gog-space-4);
1457
1769
  --gog-multiselect-option-hover-bg: var(--gog-hover-color);
1458
1770
  --gog-multiselect-option-press-bg: var(--gog-border-color);
1459
1771
  --gog-multiselect-option-color: var(--gog-text-color);
1460
- --gog-multiselect-option-gap-inline: var(--gog-space-10);
1772
+ --gog-multiselect-option-gap-inline: var(--gog-space-12);
1461
1773
  /* Estimated row height fed into the panel's up/down placement math; not itself a real
1462
1774
  layout property, so it has no effect unless the JS reads it. */
1463
1775
  --gog-multiselect-option-height: 40px;
1464
- --gog-multiselect-option-radius: calc(var(--gog-radius) - 2px);
1776
+ /* Concentric with the panel, which paints `--gog-multiselect-panel-radius` and insets its rows
1777
+ by the list padding, so the row's corner is that radius minus that padding. It had subtracted
1778
+ 2px against 4px of padding, and a restated literal also stops being true once density moves. */
1779
+ --gog-multiselect-option-radius: max(
1780
+ 0px,
1781
+ calc(var(--gog-multiselect-panel-radius) - var(--gog-multiselect-options-padding))
1782
+ );
1465
1783
  --gog-multiselect-option-disabled-opacity: var(--gog-disabled-opacity);
1466
1784
  --gog-multiselect-option-transition-duration: var(--gog-duration-fast);
1467
1785
  --gog-multiselect-checkbox-border: var(--gog-accent-dim);
@@ -1469,30 +1787,42 @@
1469
1787
  --gog-multiselect-checkbox-checked-bg: var(--gog-accent-color);
1470
1788
  --gog-multiselect-checkbox-checked-color: var(--gog-primary-color);
1471
1789
  --gog-multiselect-controls-gap: var(--gog-space-4);
1472
- --gog-multiselect-controls-padding: var(--gog-space-6) var(--gog-space-10);
1473
- --gog-multiselect-actions-gap: var(--gog-space-6);
1474
- --gog-multiselect-filter-padding: var(--gog-space-6);
1475
- --gog-multiselect-filter-input-padding-y: var(--gog-space-6);
1476
- --gog-multiselect-filter-input-padding-x: var(--gog-space-8);
1790
+ --gog-multiselect-controls-padding: var(--gog-space-8) var(--gog-space-12);
1791
+ --gog-multiselect-actions-gap: var(--gog-space-8);
1792
+ --gog-multiselect-filter-padding: var(--gog-space-8);
1793
+ --gog-multiselect-filter-input-padding-y: var(--gog-space-8);
1794
+ --gog-multiselect-filter-input-padding-x: var(--gog-space-16);
1477
1795
  --gog-multiselect-filter-input-bg: var(--gog-background-color);
1478
1796
  --gog-multiselect-filter-input-color: var(--gog-multiselect-field-color);
1479
1797
  --gog-multiselect-filter-input-border: var(--gog-multiselect-field-border);
1480
- --gog-multiselect-filter-input-radius: var(--gog-radius);
1798
+ /* Concentric with the panel, and the concentric answer here is a square corner. The filter is
1799
+ inset by `--gog-multiselect-filter-padding`, which equals the panel's radius -- and where the
1800
+ inset equals the radius, the inner box's corner point lands exactly on the centre of the
1801
+ outer arc, so a right angle is equidistant from the whole curve. It is the only shape that
1802
+ keeps the gap constant, not a value clamped to zero for want of a better one. */
1803
+ --gog-multiselect-filter-input-radius: max(
1804
+ 0px,
1805
+ calc(var(--gog-multiselect-panel-radius) - var(--gog-multiselect-filter-padding))
1806
+ );
1481
1807
  --gog-multiselect-filter-border-width: var(--gog-panel-border-width);
1482
1808
  --gog-multiselect-filter-border-style: var(--gog-panel-border-style);
1483
1809
  --gog-multiselect-filter-border-color: var(--gog-border-color);
1484
- --gog-multiselect-filter-empty-padding: var(--gog-space-10);
1810
+ --gog-multiselect-filter-empty-padding: var(--gog-space-12);
1485
1811
  --gog-multiselect-filter-empty-color: var(--gog-multiselect-placeholder-color);
1486
1812
  /* Matches --gog-select-chevron-inset; see the note there. */
1487
1813
  /* "+N" badge shown when the selection does not fit on one line. */
1488
1814
  --gog-multiselect-overflow-color: var(--gog-multiselect-placeholder-color);
1489
1815
  --gog-multiselect-overflow-font-size: var(--gog-text-sm);
1490
- --gog-multiselect-overflow-gap: var(--gog-space-6);
1816
+ /* It sits on the field values own baseline (align-self: baseline, 21.7.2), so it takes the
1817
+ field text leading rather than a mark leading. */
1818
+ --gog-multiselect-overflow-line-height: var(--gog-field-line-height);
1819
+ --gog-multiselect-overflow-gap: var(--gog-space-8);
1491
1820
  --gog-multiselect-min-width: 120px;
1492
1821
  --gog-multiselect-panel-max-width: 420px;
1493
1822
  --gog-multiselect-actions-inset: var(--gog-control-icon-offset);
1494
1823
  /* A quarter of the corner radius — see `--gog-input-clear-radius` for why. */
1495
1824
  --gog-multiselect-clear-radius: calc(var(--gog-radius) / 4);
1825
+ --gog-multiselect-clear-line-height: var(--gog-line-height-none);
1496
1826
  --gog-multiselect-disabled-opacity: var(--gog-disabled-opacity);
1497
1827
  --gog-multiselect-transition-duration: var(--gog-duration-base);
1498
1828
  --gog-multiselect-float-label-reserve: var(--gog-field-float-label-reserve);
@@ -1515,13 +1845,19 @@
1515
1845
  --gog-menu-border-width: var(--gog-control-border-width);
1516
1846
  --gog-menu-border-style: var(--gog-control-border-style);
1517
1847
  --gog-menu-radius: var(--gog-panel-radius);
1518
- --gog-menu-shadow: var(--gog-dialog-shadow);
1848
+ /* Step 3, with the dropdown panels it belongs beside — not step 5. This aliased
1849
+ `--gog-dialog-shadow` until 21.12.0, so a dropdown menu carried a modal's elevation. */
1850
+ --gog-menu-shadow: var(--gog-panel-shadow);
1519
1851
  --gog-menu-font-family: var(--gog-font-body);
1520
1852
  --gog-menu-padding: var(--gog-space-4);
1521
- --gog-menu-gap: var(--gog-space-2);
1853
+ --gog-menu-gap: var(--gog-space-4);
1522
1854
  --gog-menu-offset: var(--gog-space-4);
1523
1855
  --gog-menu-min-width: 180px;
1524
- --gog-menu-max-width: 320px;
1856
+ /* L8's viewport exception (docs/component-geometry.md, "D7 — taken"): a menu portals into
1857
+ <body> and floats over the viewport, not a container. Its items do not wrap (L9 does not
1858
+ apply — the width stays in px), but L8 still does: no edge-inset token exists on this
1859
+ component today, so the margin reads the scale directly. */
1860
+ --gog-menu-max-width: min(320px, calc(100vw - var(--gog-space-16) * 2));
1525
1861
  --gog-menu-max-height: 320px;
1526
1862
  --gog-menu-transition-duration: var(--gog-duration-base);
1527
1863
  --gog-menu-focus-ring: var(--gog-accent-color);
@@ -1535,8 +1871,11 @@
1535
1871
  --gog-menu-item-press-bg: var(--gog-border-color);
1536
1872
  --gog-menu-item-hover-color: var(--gog-text-color);
1537
1873
  --gog-menu-item-font-size: var(--gog-text-sm);
1538
- --gog-menu-item-padding: var(--gog-space-8) var(--gog-space-12);
1539
- --gog-menu-item-radius: var(--gog-radius);
1874
+ --gog-menu-item-padding: var(--gog-space-8) var(--gog-space-16);
1875
+ /* Concentric with the panel, which paints `--gog-panel-radius` (8px larger than the base) and
1876
+ insets its items by `--gog-menu-padding`. Repeating the base radius here made the first and
1877
+ last items visibly squarer than the corner they sit in. */
1878
+ --gog-menu-item-radius: max(0px, calc(var(--gog-menu-radius) - var(--gog-menu-padding)));
1540
1879
  --gog-menu-item-gap: var(--gog-space-sm);
1541
1880
  --gog-menu-item-disabled-opacity: var(--gog-disabled-opacity);
1542
1881
  --gog-menu-item-disabled-color: var(--gog-muted-text-color);
@@ -1547,6 +1886,7 @@
1547
1886
  --gog-paginator-gap: var(--gog-space-4);
1548
1887
  --gog-paginator-ellipsis-color: var(--gog-muted-text-color);
1549
1888
  --gog-paginator-ellipsis-font-size: var(--gog-text-sm);
1889
+ --gog-paginator-ellipsis-line-height: var(--gog-line-height-none);
1550
1890
  --gog-paginator-ellipsis-font-family: var(--gog-font-body);
1551
1891
  /* Enough for a three-digit page size plus the chevron, so the row doesn't shift on change. */
1552
1892
  --gog-paginator-page-size-min-width: 5rem;
@@ -1571,7 +1911,11 @@
1571
1911
  --gog-panel-heading-font-family: var(--gog-font-heading);
1572
1912
  --gog-panel-heading-font-size: var(--gog-text-xl);
1573
1913
  --gog-panel-heading-font-weight: var(--gog-font-weight-semibold);
1574
- --gog-panel-heading-line-height: 1.25;
1914
+ /* Role heading, the same step the card heading takes. It had been 1.25 -- the one leading in
1915
+ the library outside the scale, which runs 1.2 then 1.3 with nothing between. Two headings
1916
+ four steps apart differing by 0.05 is two people picking a nice number, not the inverse
1917
+ relationship law 4 describes; that one holds across the roles, where it is real. */
1918
+ --gog-panel-heading-line-height: var(--gog-line-height-snug);
1575
1919
 
1576
1920
  --gog-panel-outlined-bg: var(--gog-surface-color);
1577
1921
  --gog-panel-outlined-border-color: var(--gog-border-color);
@@ -1597,13 +1941,13 @@
1597
1941
  --gog-panel-footer-gap: var(--gog-space-sm);
1598
1942
  --gog-panel-footer-padding-top: var(--gog-space-sm);
1599
1943
 
1600
- --gog-panel-xsm-padding-y: var(--gog-space-10);
1944
+ --gog-panel-xsm-padding-y: var(--gog-space-12);
1601
1945
  --gog-panel-xsm-padding-x: var(--gog-space-12);
1602
1946
  --gog-panel-xsm-gap: var(--gog-space-sm);
1603
- --gog-panel-sm-padding-y: var(--gog-space-14);
1947
+ --gog-panel-sm-padding-y: var(--gog-space-16);
1604
1948
  --gog-panel-sm-padding-x: var(--gog-space-md);
1605
- --gog-panel-sm-gap: var(--gog-space-10);
1606
- --gog-panel-md-padding-y: var(--gog-space-18);
1949
+ --gog-panel-sm-gap: var(--gog-space-12);
1950
+ --gog-panel-md-padding-y: var(--gog-space-20);
1607
1951
  --gog-panel-md-padding-x: var(--gog-space-20);
1608
1952
  --gog-panel-md-gap: var(--gog-space-12);
1609
1953
  --gog-panel-lg-padding-y: var(--gog-space-lg);
@@ -1627,6 +1971,7 @@
1627
1971
  --gog-progressbar-value-color: var(--gog-muted-text-color);
1628
1972
  --gog-progressbar-value-font-family: var(--gog-font-body);
1629
1973
  --gog-progressbar-value-font-size: var(--gog-text-sm);
1974
+ --gog-progressbar-value-line-height: var(--gog-line-height-none);
1630
1975
  --gog-progressbar-indeterminate-duration: 1.6s;
1631
1976
  --gog-progressbar-indeterminate-easing: cubic-bezier(0.65, 0.05, 0.36, 1);
1632
1977
  /* The reduced-motion stand-in for the indeterminate animation. */
@@ -1680,7 +2025,19 @@
1680
2025
  --gog-scroll-thumb-bg: var(--gog-accent-dim);
1681
2026
  --gog-scroll-thumb-hover-bg: var(--gog-accent-color);
1682
2027
  --gog-scroll-thumb-active-bg: var(--gog-accent-bright);
1683
- --gog-scroll-thumb-radius: var(--gog-radius);
2028
+ /* Concentric with the track: the thumb is inset on every side by `--gog-scroll-thumb-inset`,
2029
+ so its corner is the track's minus that. Both radii exceed half the thumb's width at either
2030
+ track size (10px and 6px, less 2x2 of inset), so this changes no rendered pixel today -- it
2031
+ is here so that a theme raising `--gog-radius` on a wide scroller keeps the two curves
2032
+ parallel instead of letting the thumb match the track it sits inside. */
2033
+ --gog-scroll-thumb-radius: max(
2034
+ 0px,
2035
+ calc(var(--gog-scroll-track-radius) - var(--gog-scroll-thumb-inset))
2036
+ );
2037
+ /* The thumb's clearance inside its own track, off the 4px grid for the same reason
2038
+ `--gog-toggle-thumb-inset` is: a length inside a single painted mark defines that mark's
2039
+ shape rather than spacing two things apart, and 4px on a thin scrollbar would leave a thumb
2040
+ barely wider than the hairline it rides in. Listed in OPTICAL_CHROME. */
1684
2041
  --gog-scroll-thumb-inset: 2px;
1685
2042
  --gog-scroll-corner-bg: transparent;
1686
2043
  --gog-scroll-fade-duration: var(--gog-duration-base);
@@ -1697,7 +2054,7 @@
1697
2054
  `thin` variant gets more of it since its 6px track leaves the least visible thumb to aim
1698
2055
  at; both land the effective hit width in the ~22-24px range generally recommended for a
1699
2056
  comfortable pointer target. */
1700
- --gog-scroll-normal-thumb-hit-padding: var(--gog-space-6);
2057
+ --gog-scroll-normal-thumb-hit-padding: var(--gog-space-8);
1701
2058
  --gog-scroll-thin-thumb-hit-padding: var(--gog-space-8);
1702
2059
 
1703
2060
  /* ── Select ────────────────────────────────────────────────────────────────── */
@@ -1706,6 +2063,7 @@
1706
2063
  --gog-select-gap: var(--gog-space-4);
1707
2064
  --gog-select-label-color: var(--gog-accent-color);
1708
2065
  --gog-select-label-font-size: var(--gog-text-sm);
2066
+ --gog-select-label-line-height: var(--gog-field-label-line-height);
1709
2067
  --gog-select-label-letter-spacing: var(--gog-letter-spacing);
1710
2068
  --gog-select-label-text-transform: var(--gog-text-transform);
1711
2069
  --gog-select-field-bg: var(--gog-surface-color);
@@ -1722,6 +2080,7 @@
1722
2080
  --gog-select-focus-ring-offset: var(--gog-focus-ring-offset);
1723
2081
  --gog-select-error-color: var(--gog-danger-color);
1724
2082
  --gog-select-error-font-size: var(--gog-text-xs);
2083
+ --gog-select-error-line-height: var(--gog-field-error-line-height);
1725
2084
  --gog-select-chevron-color: var(--gog-accent-color);
1726
2085
  /*
1727
2086
  Distance from the trigger's right edge to the trailing chrome, matching the leading icon
@@ -1736,35 +2095,61 @@
1736
2095
  /* Ceiling for a content-sized panel, so one very long option cannot span the viewport. */
1737
2096
  --gog-select-panel-max-width: 420px;
1738
2097
  /* Filter box — only rendered when `filter` is on. */
1739
- --gog-select-filter-padding: var(--gog-space-6);
1740
- --gog-select-filter-input-padding-y: var(--gog-space-6);
1741
- --gog-select-filter-input-padding-x: var(--gog-space-8);
2098
+ --gog-select-filter-padding: var(--gog-space-8);
2099
+ --gog-select-filter-input-padding-y: var(--gog-space-8);
2100
+ --gog-select-filter-input-padding-x: var(--gog-space-16);
1742
2101
  --gog-select-filter-input-bg: var(--gog-background-color);
1743
2102
  --gog-select-filter-input-color: var(--gog-select-field-color);
1744
2103
  --gog-select-filter-input-border: var(--gog-select-field-border);
1745
- --gog-select-filter-input-radius: var(--gog-radius);
2104
+ /* Concentric with the panel, and the concentric answer here is a square corner. The filter is
2105
+ inset by `--gog-select-filter-padding`, which equals the panel's radius -- and where the inset
2106
+ equals the radius, the inner box's corner point lands exactly on the centre of the outer arc,
2107
+ so a right angle is equidistant from the whole curve. The same case as the multiselect's. */
2108
+ --gog-select-filter-input-radius: max(
2109
+ 0px,
2110
+ calc(var(--gog-select-panel-radius) - var(--gog-select-filter-padding))
2111
+ );
1746
2112
  --gog-select-filter-border-width: var(--gog-panel-border-width);
1747
2113
  --gog-select-filter-border-style: var(--gog-panel-border-style);
1748
2114
  --gog-select-filter-border-color: var(--gog-select-option-border-color, var(--gog-border-color));
1749
- --gog-select-filter-empty-padding: var(--gog-space-10);
2115
+ --gog-select-filter-empty-padding: var(--gog-space-12);
1750
2116
  --gog-select-filter-empty-color: var(--gog-select-placeholder-color);
1751
2117
  /* Clear button — only rendered once a value is selected, see `clearable`. */
1752
2118
  /* A quarter of the corner radius — see `--gog-input-clear-radius` for why. */
1753
2119
  --gog-select-clear-radius: calc(var(--gog-radius) / 4);
2120
+ --gog-select-clear-line-height: var(--gog-line-height-none);
1754
2121
  --gog-select-clear-icon-ratio: var(--gog-control-clear-icon-ratio);
1755
- --gog-select-clear-gap: var(--gog-space-6);
2122
+ --gog-select-clear-gap: var(--gog-space-8);
1756
2123
  --gog-select-clear-color: var(--gog-select-placeholder-color);
1757
2124
  --gog-select-clear-hover-color: var(--gog-select-label-color);
1758
2125
  --gog-select-control-gap: var(--gog-space-12);
1759
2126
  --gog-select-panel-bg: var(--gog-surface-color);
1760
2127
  --gog-select-panel-shadow: var(--gog-panel-shadow);
1761
2128
  --gog-select-panel-max-height: 260px;
1762
- --gog-select-panel-offset: var(--gog-space-2);
2129
+ --gog-select-panel-offset: var(--gog-space-4);
2130
+ /* The panel's own corner, and the reason it is not `--gog-select-radius`: that token shapes the
2131
+ *field*, and it shaped this box too until this release. One token painting two boxes meant a
2132
+ consumer rounding the field into a pill rounded the dropdown into one as well, and the filter
2133
+ radius below derives from whatever it is, so that followed too. Same default, so nothing
2134
+ moves; `gog-autocomplete` and `gog-datepicker` already declared this token and this is the
2135
+ pair that did not. */
2136
+ --gog-select-panel-radius: var(--gog-radius);
2137
+ /* The list's own gutter, so the rows sit inside the panel rather than bleeding to its border.
2138
+ `gog-autocomplete` and `gog-multiselect` both inset theirs by this amount; this panel had no
2139
+ interior at all, which is why its first and last rows were square inside a rounded corner --
2140
+ the same defect `--gog-menu-item-radius` records for the menu. */
2141
+ --gog-select-options-padding: var(--gog-space-4);
1763
2142
  --gog-select-option-hover-bg: var(--gog-hover-color);
1764
2143
  --gog-select-option-press-bg: var(--gog-border-color);
1765
2144
  --gog-select-option-selected-color: var(--gog-accent-color);
1766
2145
  --gog-select-option-color: var(--gog-text-color);
1767
- --gog-select-option-gap: var(--gog-space-10);
2146
+ --gog-select-option-gap: var(--gog-space-12);
2147
+ /* Concentric with the panel, which insets its rows by the list padding above. Derived rather
2148
+ than restated, so it stays true once `--gog-density` moves the padding. */
2149
+ --gog-select-option-radius: max(
2150
+ 0px,
2151
+ calc(var(--gog-select-panel-radius) - var(--gog-select-options-padding))
2152
+ );
1768
2153
  /* Estimated row height fed into the panel's up/down placement math; not itself a real
1769
2154
  layout property, so it has no effect unless the JS reads it. */
1770
2155
  --gog-select-option-height: 40px;
@@ -1816,13 +2201,15 @@
1816
2201
  --gog-slider-label-font-family: var(--gog-font-heading);
1817
2202
  --gog-slider-value-font-family: var(--gog-font-mono);
1818
2203
  --gog-slider-error-font-family: var(--gog-font-body);
1819
- --gog-slider-gap: var(--gog-space-6);
2204
+ --gog-slider-gap: var(--gog-space-8);
1820
2205
  --gog-slider-label-color: var(--gog-accent-color);
1821
2206
  --gog-slider-label-font-size: var(--gog-text-sm);
2207
+ --gog-slider-label-line-height: var(--gog-field-label-line-height);
1822
2208
  --gog-slider-label-letter-spacing: var(--gog-letter-spacing);
1823
2209
  --gog-slider-label-text-transform: var(--gog-text-transform);
1824
2210
  --gog-slider-value-color: var(--gog-accent-color);
1825
2211
  --gog-slider-value-font-size: var(--gog-text-sm);
2212
+ --gog-slider-value-line-height: var(--gog-line-height-none);
1826
2213
  --gog-slider-value-min-width: 40px;
1827
2214
  --gog-slider-track-height: 4px;
1828
2215
  --gog-slider-track-area-height: 20px;
@@ -1859,8 +2246,10 @@
1859
2246
  --gog-slider-focus-ring-width: var(--gog-focus-ring-width);
1860
2247
  --gog-slider-range-color: var(--gog-muted-text-color);
1861
2248
  --gog-slider-range-font-size: var(--gog-text-xs);
2249
+ --gog-slider-range-line-height: var(--gog-line-height-none);
1862
2250
  --gog-slider-error-color: var(--gog-danger-color);
1863
2251
  --gog-slider-error-font-size: var(--gog-text-xs);
2252
+ --gog-slider-error-line-height: var(--gog-field-error-line-height);
1864
2253
  --gog-slider-disabled-opacity: var(--gog-disabled-opacity);
1865
2254
 
1866
2255
  /* ── Spinner ──────────────────────────────────────────────────────────────── */
@@ -1923,37 +2312,43 @@
1923
2312
  --gog-table-header-letter-spacing: var(--gog-letter-spacing);
1924
2313
  --gog-table-header-text-transform: var(--gog-text-transform);
1925
2314
  --gog-table-num-col-width: 48px;
1926
- --gog-table-th-inner-gap: var(--gog-space-6);
2315
+ --gog-table-th-inner-gap: var(--gog-space-8);
1927
2316
  --gog-table-sort-icon-size: 0.9em;
1928
2317
  --gog-table-sort-icon-width: 1.1em;
1929
2318
  --gog-table-sort-icon-opacity: 0.6;
1930
- --gog-table-empty-padding: var(--gog-space-24) var(--gog-space-14);
2319
+ --gog-table-empty-padding: var(--gog-space-24) var(--gog-space-16);
1931
2320
  --gog-table-empty-font-size: var(--gog-text-md);
1932
- --gog-table-loading-padding: var(--gog-space-32) var(--gog-space-14);
2321
+ --gog-table-empty-line-height: var(--gog-line-height-normal);
2322
+ --gog-table-loading-padding: var(--gog-space-32) var(--gog-space-16);
1933
2323
  --gog-table-loading-opacity: 0.5;
1934
2324
  --gog-table-row-transition-duration: var(--gog-duration-fast);
1935
2325
  --gog-table-footer-gap: var(--gog-space-sm);
1936
2326
  --gog-table-footer-min-height: 32px;
1937
2327
  --gog-table-total-font-size: var(--gog-text-xs);
2328
+ --gog-table-total-line-height: var(--gog-line-height-normal);
1938
2329
  --gog-table-total-letter-spacing: 0.5px;
1939
2330
  --gog-table-total-text-transform: var(--gog-text-transform);
1940
2331
  --gog-table-num-font-size: var(--gog-text-xs);
1941
- --gog-table-padding-h: var(--gog-space-14);
1942
- --gog-table-xsm-padding-v: var(--gog-space-2);
2332
+ --gog-table-num-line-height: var(--gog-line-height-normal);
2333
+ --gog-table-padding-h: var(--gog-space-16);
2334
+ --gog-table-xsm-padding-v: var(--gog-space-4);
1943
2335
  --gog-table-xsm-th-font-size: var(--gog-text-xs);
1944
2336
  --gog-table-xsm-td-font-size: var(--gog-text-xs);
1945
- --gog-table-sm-padding-v: var(--gog-space-2);
2337
+ --gog-table-sm-padding-v: var(--gog-space-4);
1946
2338
  --gog-table-sm-th-font-size: var(--gog-text-xs);
1947
2339
  --gog-table-sm-td-font-size: var(--gog-text-xs);
1948
- --gog-table-md-padding-v: var(--gog-space-6);
2340
+ --gog-table-md-padding-v: var(--gog-space-8);
1949
2341
  --gog-table-md-th-font-size: var(--gog-text-xs);
1950
2342
  --gog-table-md-td-font-size: var(--gog-text-sm);
1951
- --gog-table-lg-padding-v: var(--gog-space-10);
2343
+ --gog-table-lg-padding-v: var(--gog-space-12);
1952
2344
  --gog-table-lg-th-font-size: var(--gog-text-sm);
1953
2345
  --gog-table-lg-td-font-size: var(--gog-text-md);
1954
- --gog-table-slg-padding-v: var(--gog-space-14);
2346
+ --gog-table-slg-padding-v: var(--gog-space-16);
1955
2347
  --gog-table-slg-th-font-size: var(--gog-text-md);
1956
2348
  --gog-table-slg-td-font-size: var(--gog-text-lg);
2349
+ /* One value for every size step: the role picks the leading and the size does not (D4). */
2350
+ --gog-table-td-line-height: var(--gog-line-height-normal);
2351
+ --gog-table-th-line-height: var(--gog-line-height-normal);
1957
2352
 
1958
2353
  /* ── Tabs ──────────────────────────────────────────────────────────────────
1959
2354
  `--gog-tabs-tab-bg`, `-tab-color`, `-tab-padding` and `-tab-font-size` are intentionally
@@ -1994,15 +2389,15 @@
1994
2389
  --gog-tabs-focus-ring-color: var(--gog-accent-color);
1995
2390
  --gog-tabs-panel-padding: var(--gog-space-md);
1996
2391
  --gog-tabs-panel-color: var(--gog-text-color);
1997
- --gog-tabs-xsm-padding: var(--gog-space-6) var(--gog-space-10);
2392
+ --gog-tabs-xsm-padding: var(--gog-space-8) var(--gog-space-16);
1998
2393
  --gog-tabs-xsm-font-size: var(--gog-text-xs);
1999
- --gog-tabs-sm-padding: var(--gog-space-8) var(--gog-space-14);
2394
+ --gog-tabs-sm-padding: var(--gog-space-8) var(--gog-space-16);
2000
2395
  --gog-tabs-sm-font-size: var(--gog-text-sm);
2001
- --gog-tabs-md-padding: var(--gog-space-12) var(--gog-space-18);
2396
+ --gog-tabs-md-padding: var(--gog-space-12) var(--gog-space-24);
2002
2397
  --gog-tabs-md-font-size: var(--gog-text-md);
2003
- --gog-tabs-lg-padding: var(--gog-space-16) var(--gog-space-24);
2398
+ --gog-tabs-lg-padding: var(--gog-space-16) var(--gog-space-32);
2004
2399
  --gog-tabs-lg-font-size: var(--gog-text-lg);
2005
- --gog-tabs-slg-padding: var(--gog-space-20) var(--gog-space-28);
2400
+ --gog-tabs-slg-padding: var(--gog-space-20) var(--gog-space-40);
2006
2401
  --gog-tabs-slg-font-size: var(--gog-text-xl);
2007
2402
 
2008
2403
  /* ── Tag ──────────────────────────────────────────────────────────────────
@@ -2038,10 +2433,10 @@
2038
2433
  --gog-tag-radius: max(var(--gog-radius), 2px);
2039
2434
  --gog-tag-pill-radius: 9999px;
2040
2435
 
2041
- --gog-tag-xsm-font-size: 0.6875rem;
2042
- --gog-tag-xsm-padding-block: var(--gog-space-2);
2043
- --gog-tag-xsm-padding-inline: var(--gog-space-6);
2044
- --gog-tag-xsm-gap: var(--gog-space-2);
2436
+ --gog-tag-xsm-font-size: var(--gog-text-2xs);
2437
+ --gog-tag-xsm-padding-block: var(--gog-space-4);
2438
+ --gog-tag-xsm-padding-inline: var(--gog-space-8);
2439
+ --gog-tag-xsm-gap: var(--gog-space-4);
2045
2440
  --gog-tag-xsm-icon-size: 0.6875rem;
2046
2441
 
2047
2442
  --gog-tag-sm-font-size: var(--gog-text-xs);
@@ -2051,21 +2446,21 @@
2051
2446
  --gog-tag-sm-icon-size: 0.75rem;
2052
2447
 
2053
2448
  --gog-tag-md-font-size: var(--gog-text-sm);
2054
- --gog-tag-md-padding-block: var(--gog-space-6);
2055
- --gog-tag-md-padding-inline: var(--gog-space-12);
2056
- --gog-tag-md-gap: var(--gog-space-6);
2449
+ --gog-tag-md-padding-block: var(--gog-space-8);
2450
+ --gog-tag-md-padding-inline: var(--gog-space-16);
2451
+ --gog-tag-md-gap: var(--gog-space-8);
2057
2452
  --gog-tag-md-icon-size: 0.875rem;
2058
2453
 
2059
2454
  --gog-tag-lg-font-size: var(--gog-text-md);
2060
2455
  --gog-tag-lg-padding-block: var(--gog-space-8);
2061
- --gog-tag-lg-padding-inline: var(--gog-space-14);
2456
+ --gog-tag-lg-padding-inline: var(--gog-space-16);
2062
2457
  --gog-tag-lg-gap: var(--gog-space-8);
2063
2458
  --gog-tag-lg-icon-size: 1rem;
2064
2459
 
2065
2460
  --gog-tag-slg-font-size: var(--gog-text-lg);
2066
- --gog-tag-slg-padding-block: var(--gog-space-10);
2067
- --gog-tag-slg-padding-inline: var(--gog-space-16);
2068
- --gog-tag-slg-gap: var(--gog-space-10);
2461
+ --gog-tag-slg-padding-block: var(--gog-space-12);
2462
+ --gog-tag-slg-padding-inline: var(--gog-space-24);
2463
+ --gog-tag-slg-gap: var(--gog-space-12);
2069
2464
  --gog-tag-slg-icon-size: 1.125rem;
2070
2465
 
2071
2466
  /* ── Toast ────────────────────────────────────────────────────────────────── */
@@ -2079,19 +2474,21 @@
2079
2474
  --gog-toast-warning-color: var(--gog-accent-bright);
2080
2475
  --gog-toast-info-color: var(--gog-accent-color);
2081
2476
  --gog-toast-accent-width: 4px;
2082
- --gog-toast-padding: var(--gog-space-12) var(--gog-space-14);
2477
+ --gog-toast-padding: var(--gog-space-12) var(--gog-space-16);
2083
2478
  --gog-toast-radius: 0px;
2084
- --gog-toast-content-gap: var(--gog-space-10);
2479
+ --gog-toast-content-gap: var(--gog-space-12);
2085
2480
  --gog-toast-main-gap: var(--gog-space-sm);
2086
- --gog-toast-actions-gap: var(--gog-space-6);
2481
+ --gog-toast-actions-gap: var(--gog-space-8);
2087
2482
  --gog-toast-message-font-size: var(--gog-text-sm);
2088
2483
  --gog-toast-message-line-height: var(--gog-line-height-relaxed);
2089
2484
  --gog-toast-icon-size: 1rem;
2090
2485
  --gog-toast-icon-line-height: var(--gog-line-height-normal);
2091
2486
  --gog-toast-action-padding: var(--gog-space-4) var(--gog-space-8);
2092
2487
  --gog-toast-action-font-size: var(--gog-text-xs);
2093
- --gog-toast-close-padding: var(--gog-space-2) var(--gog-space-4);
2488
+ --gog-toast-action-line-height: var(--gog-line-height-none);
2489
+ --gog-toast-close-padding: var(--gog-space-4) var(--gog-space-8);
2094
2490
  --gog-toast-close-font-size: var(--gog-text-xs);
2491
+ --gog-toast-close-line-height: var(--gog-line-height-none);
2095
2492
  --gog-toast-progress-height: 3px;
2096
2493
  --gog-toast-progress-opacity: 30%;
2097
2494
  --gog-toast-transition-duration: 0.25s;
@@ -2113,13 +2510,16 @@
2113
2510
  --gog-toggle-radius: 999px;
2114
2511
  --gog-toggle-border-width: var(--gog-border-width);
2115
2512
  --gog-toggle-border-style: var(--gog-border-style);
2116
- --gog-toggle-border-color: var(--gog-border-color);
2513
+ --gog-toggle-border-color: var(--gog-control-boundary-color);
2117
2514
  --gog-toggle-on-border-color: var(--gog-accent-color);
2118
2515
  --gog-toggle-track-off-bg: var(--gog-border-color);
2119
2516
  --gog-toggle-track-on-bg: var(--gog-accent-color);
2120
2517
  --gog-toggle-thumb-off-bg: var(--gog-surface-color);
2121
2518
  --gog-toggle-thumb-on-bg: var(--gog-accent-text-color, var(--gog-primary-color));
2122
- --gog-toggle-thumb-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
2519
+ /* The thumb's clearance inside its own track, and off the 4px grid on purpose: at 2px the
2520
+ thumb is 83% of a 24px track, which is what makes a switch read as a switch, and 4px would
2521
+ take it to 67%. A length inside a single painted mark is not spacing between two things —
2522
+ `check-geometry.mjs` lists it in OPTICAL_CHROME with that reason. */
2123
2523
  --gog-toggle-thumb-inset: 2px;
2124
2524
  --gog-toggle-transition-duration: var(--gog-duration-base);
2125
2525
  --gog-toggle-disabled-opacity: var(--gog-disabled-opacity);
@@ -2133,12 +2533,12 @@
2133
2533
  --gog-toggle-state-font-weight: var(--gog-font-weight-semibold);
2134
2534
  --gog-toggle-state-letter-spacing: 0.04em;
2135
2535
  --gog-toggle-state-padding-inline: var(--gog-space-4);
2136
- --gog-toggle-state-offset: var(--gog-space-6);
2536
+ --gog-toggle-state-offset: var(--gog-space-8);
2137
2537
  /* Gap between the wording and the thumb parked at the opposite end. The clearance itself
2138
2538
  (thumb size + this) is computed in the component stylesheet, not here: a `var(` to a
2139
2539
  size-class token is substituted where it is *declared*, so doing that calc on :root would
2140
2540
  freeze it to the md thumb and stop it scaling with `size`. */
2141
- --gog-toggle-state-thumb-gap: var(--gog-space-6);
2541
+ --gog-toggle-state-thumb-gap: var(--gog-space-8);
2142
2542
  --gog-toggle-xsm-track-width: 24px;
2143
2543
  --gog-toggle-xsm-track-height: 14px;
2144
2544
  --gog-toggle-xsm-thumb-size: 10px;
@@ -2164,14 +2564,21 @@
2164
2564
  --gog-toggle-slg-thumb-size: 34px;
2165
2565
  --gog-toggle-slg-label-size: var(--gog-control-checkbox-label-size-slg);
2166
2566
  --gog-toggle-slg-state-font-size: 0.8125rem;
2567
+ --gog-toggle-state-line-height: var(--gog-line-height-none);
2167
2568
 
2168
2569
  /* ── Tooltip ──────────────────────────────────────────────────────────────── */
2169
2570
  --gog-tooltip-font-family: var(--gog-font-body);
2170
2571
  --gog-tooltip-font-size: var(--gog-text-xs);
2171
2572
  --gog-tooltip-line-height: var(--gog-line-height-normal);
2172
- --gog-tooltip-padding: var(--gog-space-6) var(--gog-space-10);
2573
+ --gog-tooltip-padding: var(--gog-space-8) var(--gog-space-12);
2173
2574
  --gog-tooltip-radius: var(--gog-radius);
2174
- --gog-tooltip-max-width: 280px;
2575
+ /* L9 (docs/component-geometry.md, "D7 — taken"): the bubble wraps, so its cap is a measure —
2576
+ 43ch at --gog-tooltip-font-size (12px), the nearest whole character to today's 280px so this
2577
+ changes robustness to a font-size change, not the pixels anyone sees today. It sits under
2578
+ Bringhurst's 45ch floor even so; widening it is a pixel decision this law does not make (see
2579
+ "D7 — taken"). L8's viewport exception is layered on top: no edge-inset token exists on this
2580
+ component today, so the margin reads the scale directly. */
2581
+ --gog-tooltip-max-width: min(43ch, calc(100vw - var(--gog-space-16) * 2));
2175
2582
  /* Caps the gog-scroll wrapping the bubble's content — see tooltip-bubble.component.html.
2176
2583
  A cap, not a fixed height: shorter content stays exactly as tall as it needs to be, this
2177
2584
  only stops something unusually long (a multi-paragraph TemplateRef) from growing to
@@ -2332,8 +2739,6 @@
2332
2739
  --gog-calendar-range-bg: color-mix(in srgb, var(--gog-accent-color) 16%, transparent);
2333
2740
  --gog-card-filled-bg: color-mix(in srgb, var(--gog-accent-dim) 8%, var(--gog-surface-color));
2334
2741
  --gog-card-hover-border-color: color-mix(in srgb, var(--gog-accent-color) 45%, transparent);
2335
- --gog-checkbox-focus-ring: color-mix(in srgb, var(--gog-accent-color) 25%, transparent);
2336
- --gog-radio-focus-ring: color-mix(in srgb, var(--gog-accent-color) 25%, transparent);
2337
2742
  --gog-chip-bg: color-mix(in srgb, var(--gog-surface-color) 88%, var(--gog-hover-color));
2338
2743
  --gog-chip-hover-bg: color-mix(in srgb, var(--gog-hover-color) 45%, var(--gog-surface-color));
2339
2744
  --gog-dialog-close-hover-bg: color-mix(in srgb, var(--gog-hover-color) 70%, transparent);
@@ -2353,7 +2758,6 @@
2353
2758
  var(--gog-input-icon-hover-color) 12%,
2354
2759
  transparent
2355
2760
  );
2356
- --gog-multiselect-focus-ring: color-mix(in srgb, var(--gog-accent-color) 25%, transparent);
2357
2761
  --gog-multiselect-option-hover-bg: color-mix(in srgb, var(--gog-accent-color) 10%, transparent);
2358
2762
  --gog-panel-filled-bg: color-mix(in srgb, var(--gog-accent-dim) 8%, var(--gog-surface-color));
2359
2763
  --gog-panel-toggle-hover-bg: color-mix(in srgb, var(--gog-hover-color) 70%, transparent);