@surflane/ui 0.4.0 → 0.5.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.
Files changed (136) hide show
  1. package/README.md +1 -1
  2. package/dist/{disclosure.d.ts → accordion.d.ts} +1 -17
  3. package/dist/{disclosure.js → accordion.js} +3 -17
  4. package/dist/alert-dialog.d.ts +31 -0
  5. package/dist/alert-dialog.js +22 -0
  6. package/dist/app-shell.js +9 -9
  7. package/dist/{input-extensions.d.ts → autocomplete.d.ts} +4 -42
  8. package/dist/{input-extensions.js → autocomplete.js} +7 -26
  9. package/dist/avatar.js +3 -5
  10. package/dist/badge.d.ts +20 -0
  11. package/dist/badge.js +16 -0
  12. package/dist/{navigation.d.ts → breadcrumbs.d.ts} +2 -6
  13. package/dist/breadcrumbs.js +31 -0
  14. package/dist/button.d.ts +11 -0
  15. package/dist/button.js +27 -4
  16. package/dist/{content.d.ts → card.d.ts} +6 -24
  17. package/dist/card.js +26 -0
  18. package/dist/chart.d.ts +19 -0
  19. package/dist/chart.js +24 -6
  20. package/dist/checkbox-group.d.ts +2 -0
  21. package/dist/checkbox-group.js +16 -0
  22. package/dist/checkbox.d.ts +9 -0
  23. package/dist/checkbox.js +29 -0
  24. package/dist/choice-label.d.ts +25 -0
  25. package/dist/choice-label.js +14 -0
  26. package/dist/choice.d.ts +7 -0
  27. package/dist/choice.js +3 -0
  28. package/dist/code.d.ts +21 -0
  29. package/dist/{content.js → code.js} +5 -30
  30. package/dist/collapsible.d.ts +18 -0
  31. package/dist/collapsible.js +21 -0
  32. package/dist/{advanced-forms.d.ts → combobox.d.ts} +5 -25
  33. package/dist/{advanced-forms.js → combobox.js} +13 -49
  34. package/dist/{context-overlays.d.ts → context-menu.d.ts} +6 -28
  35. package/dist/{context-overlays.js → context-menu.js} +5 -25
  36. package/dist/date-picker.js +3 -2
  37. package/dist/dialog.d.ts +6 -24
  38. package/dist/dialog.js +7 -20
  39. package/dist/{panels.d.ts → drawer.d.ts} +3 -34
  40. package/dist/drawer.js +47 -0
  41. package/dist/empty-state.d.ts +29 -0
  42. package/dist/empty-state.js +19 -0
  43. package/dist/field.d.ts +42 -0
  44. package/dist/field.js +21 -0
  45. package/dist/fieldset.d.ts +14 -0
  46. package/dist/fieldset.js +10 -0
  47. package/dist/file-upload.d.ts +3 -1
  48. package/dist/file-upload.js +7 -5
  49. package/dist/filter-bar.js +1 -1
  50. package/dist/form.d.ts +2 -0
  51. package/dist/form.js +7 -0
  52. package/dist/icon.d.ts +10 -0
  53. package/dist/icon.js +18 -3
  54. package/dist/index.d.ts +56 -29
  55. package/dist/index.js +70 -32
  56. package/dist/{messages.d.ts → inline-message.d.ts} +0 -28
  57. package/dist/{messages.js → inline-message.js} +3 -18
  58. package/dist/input.js +2 -2
  59. package/dist/{foundations.d.ts → layout.d.ts} +5 -23
  60. package/dist/{foundations.js → layout.js} +4 -19
  61. package/dist/link.d.ts +6 -0
  62. package/dist/link.js +17 -0
  63. package/dist/list.d.ts +33 -0
  64. package/dist/list.js +21 -0
  65. package/dist/markdown.js +4 -5
  66. package/dist/menu.d.ts +7 -5
  67. package/dist/menu.js +12 -8
  68. package/dist/menubar.d.ts +4 -0
  69. package/dist/menubar.js +4 -0
  70. package/dist/meter.d.ts +29 -0
  71. package/dist/meter.js +13 -0
  72. package/dist/native-select.d.ts +8 -0
  73. package/dist/native-select.js +54 -0
  74. package/dist/navigation-menu.js +8 -5
  75. package/dist/number-field.d.ts +23 -0
  76. package/dist/number-field.js +33 -0
  77. package/dist/page-header.d.ts +12 -0
  78. package/dist/page-header.js +9 -0
  79. package/dist/pagination.js +3 -4
  80. package/dist/panel.d.ts +13 -0
  81. package/dist/panel.js +13 -0
  82. package/dist/parts.d.ts +19 -1
  83. package/dist/parts.js +32 -6
  84. package/dist/popover.d.ts +23 -6
  85. package/dist/popover.js +17 -7
  86. package/dist/preview-card.d.ts +29 -0
  87. package/dist/preview-card.js +27 -0
  88. package/dist/progress.d.ts +29 -0
  89. package/dist/progress.js +13 -0
  90. package/dist/radio-group.d.ts +16 -0
  91. package/dist/radio-group.js +31 -0
  92. package/dist/scroll-area.js +3 -4
  93. package/dist/select.d.ts +8 -8
  94. package/dist/select.js +19 -54
  95. package/dist/separator.d.ts +4 -0
  96. package/dist/separator.js +8 -0
  97. package/dist/sheet.d.ts +29 -0
  98. package/dist/sheet.js +39 -0
  99. package/dist/skeleton.d.ts +8 -0
  100. package/dist/skeleton.js +8 -0
  101. package/dist/slider.d.ts +40 -0
  102. package/dist/slider.js +27 -0
  103. package/dist/spinner.d.ts +13 -0
  104. package/dist/spinner.js +10 -0
  105. package/dist/status.d.ts +1 -19
  106. package/dist/status.js +10 -14
  107. package/dist/switch.d.ts +13 -0
  108. package/dist/switch.js +25 -0
  109. package/dist/syntax-highlighter.js +2 -1
  110. package/dist/{data.d.ts → table.d.ts} +8 -32
  111. package/dist/{data.js → table.js} +15 -30
  112. package/dist/textarea.d.ts +7 -0
  113. package/dist/textarea.js +12 -0
  114. package/dist/toast.js +7 -6
  115. package/dist/toggle-group.d.ts +5 -0
  116. package/dist/toggle-group.js +7 -0
  117. package/dist/toggle.d.ts +7 -0
  118. package/dist/toggle.js +9 -0
  119. package/dist/{commands.d.ts → toolbar.d.ts} +0 -13
  120. package/dist/toolbar.js +14 -0
  121. package/dist/tooltip.d.ts +3 -2
  122. package/dist/tooltip.js +2 -2
  123. package/dist/tree.js +4 -2
  124. package/dist/typography.d.ts +12 -0
  125. package/dist/typography.js +14 -0
  126. package/package.json +237 -21
  127. package/src/styles.css +359 -191
  128. package/dist/chevron.d.ts +0 -3
  129. package/dist/chevron.js +0 -6
  130. package/dist/commands.js +0 -27
  131. package/dist/feedback.d.ts +0 -76
  132. package/dist/feedback.js +0 -35
  133. package/dist/forms.d.ts +0 -91
  134. package/dist/forms.js +0 -109
  135. package/dist/navigation.js +0 -41
  136. package/dist/panels.js +0 -100
package/src/styles.css CHANGED
@@ -24,7 +24,9 @@
24
24
  border-radius: var(--control-radius);
25
25
  background: var(--control-background);
26
26
  color: var(--ink);
27
- font: 400 14px/22px var(--font-body);
27
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
28
+ var(--font-body);
29
+ letter-spacing: var(--type-body-tracking);
28
30
  outline: none;
29
31
  transition:
30
32
  background-color var(--duration-fast) var(--ease-out),
@@ -48,8 +50,7 @@
48
50
  .pui-select-trigger:focus-visible {
49
51
  background: var(--control-focus-background);
50
52
  border-color: var(--control-focus);
51
- box-shadow: 0 0 0 3px
52
- color-mix(in oklch, var(--control-focus) 18%, transparent);
53
+ box-shadow: 0 0 0 var(--control-focus-ring-size) var(--control-focus-ring);
53
54
  }
54
55
  .pui-input:disabled,
55
56
  .pui-select-trigger:disabled {
@@ -113,7 +114,9 @@
113
114
  background: var(--menu-background);
114
115
  color: var(--ink);
115
116
  box-shadow: var(--shadow-float);
116
- font: 400 14px/22px var(--font-body);
117
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
118
+ var(--font-body);
119
+ letter-spacing: var(--type-body-tracking);
117
120
  outline: none;
118
121
  }
119
122
  .pui-tooltip-positioner {
@@ -133,7 +136,11 @@
133
136
  align-items: center;
134
137
  gap: var(--space-2);
135
138
  min-height: var(--control-height);
136
- padding: 6px var(--space-3) 6px 32px;
139
+ padding: max(var(--space-1), calc((var(--control-height) - 1lh) / 2))
140
+ var(--space-3);
141
+ padding-inline-start: calc(
142
+ var(--space-3) + var(--icon-size-sm) + var(--space-2)
143
+ );
137
144
  border-radius: var(--control-radius);
138
145
  cursor: default;
139
146
  outline: none;
@@ -143,21 +150,47 @@
143
150
  background: var(--menu-hover-background);
144
151
  }
145
152
  .pui-select-item[data-selected] {
146
- font-weight: 500;
153
+ font-weight: var(--weight-medium);
147
154
  }
148
155
  .pui-select-item[data-disabled] {
149
156
  opacity: var(--control-disabled-opacity);
150
157
  }
151
158
  .pui-select-check {
152
159
  position: absolute;
153
- left: 10px;
160
+ inset-inline-start: var(--space-3);
154
161
  display: flex;
162
+ width: var(--icon-size-sm);
155
163
  }
164
+ /* A popover fits its content up to its width, so long text wraps at a readable
165
+ measure instead of the viewport. */
156
166
  .pui-popover {
167
+ --popover-width: var(--size-popover-default);
168
+ width: max-content;
169
+ max-width: min(var(--popover-width), calc(100vw - var(--space-6)));
157
170
  padding: var(--space-4);
158
171
  max-height: var(--available-height);
159
172
  overflow: auto;
160
173
  }
174
+ .pui-popover[data-size='small'] {
175
+ --popover-width: var(--size-popover-small);
176
+ }
177
+ .pui-popover[data-size='large'] {
178
+ --popover-width: var(--size-popover-large);
179
+ }
180
+ .pui-popover-title {
181
+ margin: 0 0 var(--space-2);
182
+ color: var(--ink);
183
+ font: var(--weight-medium) var(--type-subsection-size) /
184
+ var(--type-subsection-leading) var(--font-body);
185
+ letter-spacing: var(--type-subsection-tracking);
186
+ }
187
+ .pui-popover-description {
188
+ margin: 0 0 var(--space-4);
189
+ color: var(--ink-body);
190
+ }
191
+ .pui-popover-description:last-child {
192
+ margin-bottom: 0;
193
+ }
161
194
  .pui-menu {
162
195
  padding: var(--space-1);
163
196
  min-width: 176px;
@@ -166,10 +199,11 @@
166
199
  border: 0;
167
200
  background: var(--tooltip-background);
168
201
  color: var(--tooltip-foreground);
169
- padding: 8px 12px;
202
+ padding: var(--space-2) var(--space-3);
170
203
  max-width: 256px;
171
- font-size: 12px;
172
- line-height: 18px;
204
+ font-size: var(--type-caption-size);
205
+ letter-spacing: var(--type-caption-tracking);
206
+ line-height: var(--type-caption-leading);
173
207
  }
174
208
  .pui-button {
175
209
  box-sizing: border-box;
@@ -179,10 +213,12 @@
179
213
  justify-content: center;
180
214
  gap: var(--space-2);
181
215
  min-height: var(--control-height);
182
- padding: 0 14px;
216
+ padding: 0 var(--size-button-padding-default);
183
217
  border: 1px solid transparent;
184
218
  border-radius: var(--radius-full);
185
- font: 500 14px/20px var(--font-body);
219
+ font: var(--weight-medium) var(--type-label-size)/var(--type-label-leading)
220
+ var(--font-body);
221
+ letter-spacing: var(--type-label-tracking);
186
222
  color: var(--ink);
187
223
  background: var(--canvas);
188
224
  /* A link rendered as a button drops the user-agent underline. */
@@ -217,8 +253,8 @@
217
253
  text-decoration-thickness: 2px;
218
254
  }
219
255
  .pui-button:focus-visible {
220
- outline: 2px solid var(--interaction-focus);
221
- outline-offset: 2px;
256
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
257
+ outline-offset: var(--focus-ring-offset);
222
258
  }
223
259
  .pui-button:is(:disabled, [data-disabled], [aria-disabled='true']) {
224
260
  opacity: var(--control-disabled-opacity);
@@ -375,17 +411,19 @@
375
411
  .pui-button[data-size='xs'] {
376
412
  height: 24px;
377
413
  min-height: 24px;
378
- padding-inline: 8px;
379
- font-size: 12px;
380
- gap: 4px;
414
+ padding-inline: var(--space-2);
415
+ font-size: var(--type-caption-size);
416
+ letter-spacing: var(--type-caption-tracking);
417
+ gap: var(--space-1);
381
418
  }
382
419
  .pui-button[data-size^='icon'] {
383
420
  width: var(--control-height);
384
421
  padding: 0;
385
422
  }
386
- @media (max-width: 760px) {
423
+ /* Touch targets grow on narrow screens and on touch, as --control-height does. */
424
+ @media (max-width: 760px), (pointer: coarse) {
387
425
  .pui-button {
388
- min-height: 44px;
426
+ min-height: var(--control-target-size);
389
427
  }
390
428
  }
391
429
 
@@ -432,9 +470,12 @@
432
470
  inset: 0;
433
471
  z-index: 1;
434
472
  display: flex;
435
- padding: 12px;
473
+ padding: var(--space-3);
436
474
  pointer-events: none;
437
475
  }
476
+ .pui-panel-viewport[data-flush] {
477
+ padding: 0;
478
+ }
438
479
  .pui-panel-viewport[data-side='right'] {
439
480
  justify-content: flex-end;
440
481
  }
@@ -450,7 +491,7 @@
450
491
  justify-content: center;
451
492
  }
452
493
  .pui-panel {
453
- --panel-width: 440px;
494
+ --panel-width: var(--size-panel-default);
454
495
  --panel-enter-x: 0px;
455
496
  --panel-enter-y: 0px;
456
497
  position: relative;
@@ -466,7 +507,9 @@
466
507
  border-radius: var(--radius-sheet);
467
508
  box-shadow: var(--shadow-float);
468
509
  outline: none;
469
- font: 400 14px/22px var(--font-body);
510
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
511
+ var(--font-body);
512
+ letter-spacing: var(--type-body-tracking);
470
513
  transform: translate(
471
514
  var(--drawer-swipe-movement-x, 0px),
472
515
  calc(
@@ -476,11 +519,11 @@
476
519
  );
477
520
  transition: transform var(--duration-base) var(--ease-out);
478
521
  }
479
- .pui-panel[data-size='sm'] {
480
- --panel-width: 320px;
522
+ .pui-panel[data-size='small'] {
523
+ --panel-width: var(--size-panel-small);
481
524
  }
482
- .pui-panel[data-size='lg'] {
483
- --panel-width: 640px;
525
+ .pui-panel[data-size='large'] {
526
+ --panel-width: var(--size-panel-large);
484
527
  }
485
528
  .pui-panel[data-side='right'] {
486
529
  --panel-enter-x: calc(100% + 12px);
@@ -498,6 +541,23 @@
498
541
  --panel-enter-y: calc(100% + 12px);
499
542
  max-height: min(85dvh, 100%);
500
543
  }
544
+ /* A flush panel squares the corners on the edge it is attached to. */
545
+ .pui-panel[data-flush][data-side='bottom'] {
546
+ border-bottom-left-radius: 0;
547
+ border-bottom-right-radius: 0;
548
+ }
549
+ .pui-panel[data-flush][data-side='top'] {
550
+ border-top-left-radius: 0;
551
+ border-top-right-radius: 0;
552
+ }
553
+ .pui-panel[data-flush][data-side='right'] {
554
+ border-top-right-radius: 0;
555
+ border-bottom-right-radius: 0;
556
+ }
557
+ .pui-panel[data-flush][data-side='left'] {
558
+ border-top-left-radius: 0;
559
+ border-bottom-left-radius: 0;
560
+ }
501
561
  .pui-panel[data-starting-style],
502
562
  .pui-panel[data-ending-style] {
503
563
  transform: translate(var(--panel-enter-x), var(--panel-enter-y));
@@ -514,23 +574,28 @@
514
574
  }
515
575
  .pui-panel-header {
516
576
  flex: none;
517
- padding: 24px 68px 20px 24px;
577
+ padding-block: var(--space-6) var(--space-5);
578
+ padding-inline: var(--space-6)
579
+ calc(var(--control-height) + var(--space-4) * 2);
518
580
  }
519
581
  .pui-panel-title {
520
582
  margin: 0;
521
- font: 500 22px/28px var(--font-display);
522
- letter-spacing: var(--tracking);
583
+ font: var(--weight-medium)
584
+ var(--type-section-size)/var(--type-section-leading) var(--font-display);
585
+ letter-spacing: var(--type-section-tracking);
523
586
  }
524
587
  .pui-panel-description {
525
- margin: 8px 0 0;
588
+ margin: var(--space-2) 0 0;
526
589
  color: var(--ink-body);
527
- font: 400 14px/22px var(--font-body);
590
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
591
+ var(--font-body);
592
+ letter-spacing: var(--type-body-tracking);
528
593
  }
529
594
  .pui-panel-body {
530
595
  flex: 1 1 auto;
531
596
  min-height: 0;
532
597
  overflow: auto;
533
- padding: 0 24px 24px;
598
+ padding: 0 var(--space-6) var(--space-6);
534
599
  overscroll-behavior: contain;
535
600
  scrollbar-width: thin;
536
601
  scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
@@ -552,20 +617,21 @@
552
617
  justify-content: flex-end;
553
618
  flex-wrap: wrap;
554
619
  gap: var(--space-2);
555
- padding: 16px 24px max(20px, env(safe-area-inset-bottom));
620
+ padding: var(--space-4) var(--space-6)
621
+ max(var(--space-5), env(safe-area-inset-bottom));
556
622
  background: var(--surface);
557
623
  }
558
624
  .pui-panel-close {
559
625
  position: absolute;
560
- top: 16px;
561
- right: 16px;
626
+ inset-block-start: var(--space-4);
627
+ inset-inline-end: var(--space-4);
562
628
  z-index: 1;
563
629
  }
564
630
  .pui-drawer-handle {
565
631
  flex: none;
566
632
  width: 36px;
567
633
  height: 4px;
568
- margin: 10px auto 0;
634
+ margin: var(--space-3) auto 0;
569
635
  border-radius: var(--radius-full);
570
636
  background: var(--line);
571
637
  }
@@ -594,8 +660,8 @@
594
660
 
595
661
  .pui-dialog-close {
596
662
  position: absolute;
597
- top: 16px;
598
- right: 16px;
663
+ inset-block-start: var(--space-4);
664
+ inset-inline-end: var(--space-4);
599
665
  z-index: 1;
600
666
  }
601
667
 
@@ -604,7 +670,8 @@
604
670
  box-sizing: border-box;
605
671
  display: flex;
606
672
  flex-direction: column;
607
- width: min(640px, calc(100% - 32px));
673
+ --dialog-width: var(--size-dialog-default);
674
+ width: min(var(--dialog-width), calc(100% - var(--space-4) * 2));
608
675
  max-height: calc(100dvh - 32px);
609
676
  overflow: hidden;
610
677
  scrollbar-gutter: auto;
@@ -614,7 +681,9 @@
614
681
  background: var(--canvas);
615
682
  color: var(--ink);
616
683
  box-shadow: var(--shadow-float);
617
- font: 400 14px/22px var(--font-body);
684
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
685
+ var(--font-body);
686
+ letter-spacing: var(--type-body-tracking);
618
687
  }
619
688
  .pui-dialog-header,
620
689
  .pui-dialog-body,
@@ -628,22 +697,26 @@
628
697
  align-self: stretch;
629
698
  }
630
699
  .pui-dialog-header {
631
- padding: 24px 72px 20px 24px;
700
+ padding-block: var(--space-6) var(--space-5);
701
+ padding-inline: var(--space-6)
702
+ calc(var(--control-height) + var(--space-4) * 2);
632
703
  border-bottom: 1px solid var(--line);
633
704
  }
634
705
  .pui-dialog-header h2 {
635
706
  margin: 0;
636
- font: 500 22px/28px var(--font-display);
707
+ font: var(--weight-medium)
708
+ var(--type-section-size)/var(--type-section-leading) var(--font-display);
709
+ letter-spacing: var(--type-section-tracking);
637
710
  }
638
711
  .pui-dialog-header p {
639
- margin: 8px 0 0;
712
+ margin: var(--space-2) 0 0;
640
713
  color: var(--ink-body);
641
714
  }
642
715
  .pui-dialog-body {
643
716
  flex: 1 1 auto;
644
717
  min-height: 0;
645
718
  overflow: auto;
646
- padding: 24px;
719
+ padding: var(--space-6);
647
720
  overscroll-behavior: contain;
648
721
  scrollbar-width: thin;
649
722
  scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
@@ -664,7 +737,7 @@
664
737
  justify-content: flex-end;
665
738
  flex-wrap: wrap;
666
739
  gap: var(--space-2);
667
- padding: 20px 24px;
740
+ padding: var(--space-5) var(--space-6);
668
741
  border-top: 1px solid var(--line);
669
742
  }
670
743
  .pui-dialog-close:disabled {
@@ -673,15 +746,24 @@
673
746
  }
674
747
 
675
748
  .pui-confirm-content {
676
- width: min(420px, calc(100% - 32px));
749
+ --dialog-width: var(--size-dialog-small);
750
+ }
751
+ .pui-dialog-content[data-size='small'] {
752
+ --dialog-width: var(--size-dialog-small);
753
+ }
754
+ .pui-dialog-content[data-size='default'] {
755
+ --dialog-width: var(--size-dialog-default);
756
+ }
757
+ .pui-dialog-content[data-size='large'] {
758
+ --dialog-width: var(--size-dialog-large);
677
759
  }
678
760
  .pui-confirm-content .pui-dialog-header {
679
- padding-inline-end: 24px;
761
+ padding-inline-end: var(--space-6);
680
762
  border-bottom: 0;
681
763
  }
682
764
  .pui-confirm-content .pui-dialog-footer {
683
765
  border-top: 0;
684
- padding-top: 8px;
766
+ padding-top: var(--space-2);
685
767
  }
686
768
 
687
769
  /* Form and selection primitives: semantic labels, consistent control states. */
@@ -701,13 +783,14 @@
701
783
  display: block;
702
784
  margin: 0;
703
785
  color: var(--ink);
704
- font: 400 var(--type-body-size)/var(--type-body-leading) var(--font-body);
786
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
787
+ var(--font-body);
705
788
  }
706
789
  .pui-field-description,
707
790
  .pui-field-error {
708
791
  margin: 0;
709
- font: 400 var(--type-caption-size)/var(--type-caption-leading)
710
- var(--font-body);
792
+ font: var(--weight-regular)
793
+ var(--type-caption-size)/var(--type-caption-leading) var(--font-body);
711
794
  overflow-wrap: anywhere;
712
795
  }
713
796
  .pui-field-description {
@@ -729,7 +812,8 @@
729
812
  padding: 0;
730
813
  margin-bottom: var(--space-4);
731
814
  color: var(--ink);
732
- font: 500 var(--type-subsection-size)/var(--type-subsection-leading)
815
+ font: var(--weight-medium)
816
+ var(--type-subsection-size)/var(--type-subsection-leading)
733
817
  var(--font-body);
734
818
  }
735
819
  .pui-field-item {
@@ -833,8 +917,8 @@
833
917
  .pui-checkbox:focus-visible,
834
918
  .pui-radio:focus-visible,
835
919
  .pui-switch:focus-visible {
836
- outline: 2px solid var(--interaction-focus);
837
- outline-offset: 3px;
920
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
921
+ outline-offset: var(--focus-ring-offset);
838
922
  }
839
923
  .pui-checkbox[data-disabled],
840
924
  .pui-radio[data-disabled],
@@ -878,7 +962,9 @@
878
962
  .pui-switch {
879
963
  width: var(--control-switch-width);
880
964
  height: var(--control-switch-height);
881
- padding: 3px;
965
+ padding: calc(
966
+ (var(--control-switch-height) - var(--control-switch-thumb)) / 2 - 1px
967
+ );
882
968
  border-radius: var(--radius-full);
883
969
  justify-content: flex-start;
884
970
  }
@@ -895,14 +981,12 @@
895
981
  .pui-switch[data-checked] .pui-switch-thumb {
896
982
  background: var(--on-brand);
897
983
  transform: translateX(
898
- calc(var(--control-switch-width) - var(--control-switch-thumb) - 8px)
984
+ calc(var(--control-switch-width) - var(--control-switch-height))
899
985
  );
900
986
  }
901
987
  .pui-switch:dir(rtl)[data-checked] .pui-switch-thumb {
902
988
  transform: translateX(
903
- calc(
904
- -1 * (var(--control-switch-width) - var(--control-switch-thumb) - 8px)
905
- )
989
+ calc(var(--control-switch-height) - var(--control-switch-width))
906
990
  );
907
991
  }
908
992
  @media (prefers-reduced-motion: reduce) {
@@ -945,7 +1029,8 @@
945
1029
  max-width: 100%;
946
1030
  cursor: pointer;
947
1031
  color: var(--ink-body);
948
- font: 400 var(--type-body-size)/var(--type-body-leading) var(--font-body);
1032
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
1033
+ var(--font-body);
949
1034
  }
950
1035
  .pui-choice-label:has([data-disabled]) {
951
1036
  cursor: not-allowed;
@@ -954,6 +1039,29 @@
954
1039
  min-width: 0;
955
1040
  overflow-wrap: anywhere;
956
1041
  }
1042
+ /* ChoiceLabel: the control holds one line, so it centers on the first line of the text
1043
+ whether or not a description follows. */
1044
+ .pui-choice-label:has(> .pui-choice-text > .pui-choice-description) {
1045
+ align-items: flex-start;
1046
+ }
1047
+ .pui-choice-control {
1048
+ display: inline-flex;
1049
+ flex: none;
1050
+ align-items: center;
1051
+ min-block-size: 1lh;
1052
+ }
1053
+ .pui-choice-text {
1054
+ display: grid;
1055
+ gap: var(--space-1);
1056
+ min-width: 0;
1057
+ overflow-wrap: anywhere;
1058
+ }
1059
+ .pui-choice-description {
1060
+ color: var(--ink-muted);
1061
+ font-size: var(--type-caption-size);
1062
+ line-height: var(--type-caption-leading);
1063
+ letter-spacing: var(--type-caption-tracking);
1064
+ }
957
1065
 
958
1066
  .pui-choice-label:has([data-readonly]) {
959
1067
  cursor: default;
@@ -987,7 +1095,8 @@
987
1095
  padding: 0 var(--space-3);
988
1096
  background: transparent;
989
1097
  color: var(--ink-muted);
990
- font: 400 var(--type-body-size)/var(--type-body-leading) var(--font-body);
1098
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
1099
+ var(--font-body);
991
1100
  cursor: pointer;
992
1101
  white-space: nowrap;
993
1102
  outline: none;
@@ -1002,11 +1111,11 @@
1002
1111
  .pui-tabs-tab[data-active] {
1003
1112
  background: var(--canvas);
1004
1113
  color: var(--ink);
1005
- font-weight: 500;
1114
+ font-weight: var(--weight-medium);
1006
1115
  }
1007
1116
  .pui-tabs-tab:focus-visible {
1008
- outline: 2px solid var(--interaction-focus);
1009
- outline-offset: -3px;
1117
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
1118
+ outline-offset: var(--focus-ring-inset);
1010
1119
  }
1011
1120
  .pui-tabs-tab:is(:disabled, [data-disabled]) {
1012
1121
  opacity: var(--control-disabled-opacity);
@@ -1019,8 +1128,8 @@
1019
1128
  overflow-wrap: anywhere;
1020
1129
  }
1021
1130
  .pui-tabs-panel:focus-visible {
1022
- outline: 2px solid var(--interaction-focus);
1023
- outline-offset: 3px;
1131
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
1132
+ outline-offset: var(--focus-ring-offset);
1024
1133
  border-radius: var(--radius-md);
1025
1134
  }
1026
1135
  .pui-tabs-indicator {
@@ -1084,7 +1193,8 @@
1084
1193
  border-radius: var(--radius-md);
1085
1194
  background: transparent;
1086
1195
  color: var(--ink);
1087
- font: 500 var(--type-body-size)/var(--type-body-leading) var(--font-body);
1196
+ font: var(--weight-medium) var(--type-body-size)/var(--type-body-leading)
1197
+ var(--font-body);
1088
1198
  text-align: start;
1089
1199
  cursor: pointer;
1090
1200
  outline: none;
@@ -1100,8 +1210,8 @@
1100
1210
  background: var(--interaction-active-bg);
1101
1211
  }
1102
1212
  .pui-disclosure-trigger:focus-visible {
1103
- outline: 2px solid var(--interaction-focus);
1104
- outline-offset: -2px;
1213
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
1214
+ outline-offset: var(--focus-ring-inset);
1105
1215
  }
1106
1216
  .pui-disclosure-trigger:disabled {
1107
1217
  opacity: var(--control-disabled-opacity);
@@ -1109,16 +1219,15 @@
1109
1219
  }
1110
1220
  .pui-disclosure-chevron {
1111
1221
  flex: none;
1112
- transition: transform var(--duration-fast) var(--ease-out);
1222
+ transition: rotate var(--duration-fast) var(--ease-out);
1113
1223
  }
1224
+ /* The chevron mirrors itself in right-to-left text, so it turns the other way to
1225
+ point down when open. */
1114
1226
  .pui-disclosure-trigger[data-panel-open] > .pui-disclosure-chevron {
1115
- transform: rotate(90deg);
1116
- }
1117
- .pui-disclosure-trigger:dir(rtl) > .pui-disclosure-chevron {
1118
- transform: rotate(180deg);
1227
+ rotate: 90deg;
1119
1228
  }
1120
1229
  .pui-disclosure-trigger:dir(rtl)[data-panel-open] > .pui-disclosure-chevron {
1121
- transform: rotate(90deg);
1230
+ rotate: -90deg;
1122
1231
  }
1123
1232
  .pui-accordion-panel,
1124
1233
  .pui-collapsible-panel {
@@ -1313,8 +1422,7 @@
1313
1422
  .pui-combobox-group:focus-within,
1314
1423
  .pui-number-group:focus-within {
1315
1424
  border-color: var(--control-focus);
1316
- box-shadow: 0 0 0 3px
1317
- color-mix(in srgb, var(--control-focus) 18%, transparent);
1425
+ box-shadow: 0 0 0 var(--control-focus-ring-size) var(--control-focus-ring);
1318
1426
  }
1319
1427
  .pui-combobox-group > .pui-combobox-input {
1320
1428
  flex: 1;
@@ -1343,8 +1451,8 @@
1343
1451
  .pui-combobox-action:focus-visible,
1344
1452
  .pui-number-step:focus-visible,
1345
1453
  .pui-combobox-chip-remove:focus-visible {
1346
- outline: 2px solid var(--interaction-focus);
1347
- outline-offset: -3px;
1454
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
1455
+ outline-offset: var(--focus-ring-inset);
1348
1456
  }
1349
1457
  .pui-combobox-group[data-disabled],
1350
1458
  .pui-number-group[data-disabled] {
@@ -1369,7 +1477,9 @@
1369
1477
  background: var(--menu-background);
1370
1478
  color: var(--ink);
1371
1479
  box-shadow: var(--shadow-float);
1372
- font: 400 14px/22px var(--font-body);
1480
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
1481
+ var(--font-body);
1482
+ letter-spacing: var(--type-body-tracking);
1373
1483
  outline: none;
1374
1484
  transition:
1375
1485
  opacity var(--duration-fast) var(--ease-out),
@@ -1387,14 +1497,16 @@
1387
1497
  max-height: min(280px, var(--available-height));
1388
1498
  overflow: auto;
1389
1499
  }
1500
+ /* Select, Menu and Combobox items share one row: the control height. */
1390
1501
  .pui-combobox-item {
1391
1502
  display: flex;
1392
1503
  align-items: center;
1393
1504
  gap: var(--space-2);
1394
- padding: var(--space-2) var(--space-3);
1395
- min-height: 36px;
1505
+ padding: max(var(--space-1), calc((var(--control-height) - 1lh) / 2))
1506
+ var(--space-3);
1507
+ min-height: var(--control-height);
1396
1508
  box-sizing: border-box;
1397
- border-radius: var(--radius-md);
1509
+ border-radius: var(--control-radius);
1398
1510
  cursor: default;
1399
1511
  outline: none;
1400
1512
  overflow-wrap: anywhere;
@@ -1424,7 +1536,9 @@
1424
1536
  .pui-combobox-section-label {
1425
1537
  padding: var(--space-2) var(--space-3);
1426
1538
  color: var(--ink-muted);
1427
- font-size: 12px;
1539
+ font-size: var(--type-caption-size);
1540
+ line-height: var(--type-caption-leading);
1541
+ letter-spacing: var(--type-caption-tracking);
1428
1542
  }
1429
1543
  .pui-combobox-separator {
1430
1544
  height: 1px;
@@ -1455,7 +1569,9 @@
1455
1569
  border-radius: var(--radius-full);
1456
1570
  background: var(--selected);
1457
1571
  color: var(--ink);
1458
- font-size: 12px;
1572
+ font-size: var(--type-caption-size);
1573
+ line-height: var(--type-caption-leading);
1574
+ letter-spacing: var(--type-caption-tracking);
1459
1575
  }
1460
1576
  .pui-combobox-chip-remove {
1461
1577
  width: 28px;
@@ -1477,7 +1593,9 @@
1477
1593
  outline: none;
1478
1594
  background: transparent;
1479
1595
  color: var(--ink);
1480
- font: 400 14px/22px var(--font-body);
1596
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
1597
+ var(--font-body);
1598
+ letter-spacing: var(--type-body-tracking);
1481
1599
  text-align: center;
1482
1600
  font-variant-numeric: tabular-nums;
1483
1601
  }
@@ -1485,13 +1603,13 @@
1485
1603
  cursor: ew-resize;
1486
1604
  touch-action: none;
1487
1605
  }
1488
- @media (max-width: 760px) {
1606
+ @media (max-width: 760px), (pointer: coarse) {
1489
1607
  .pui-combobox-item {
1490
- min-height: 44px;
1608
+ min-height: var(--control-target-size);
1491
1609
  }
1492
1610
  .pui-combobox-chip-remove {
1493
- width: 44px;
1494
- height: 44px;
1611
+ width: var(--control-target-size);
1612
+ height: var(--control-target-size);
1495
1613
  }
1496
1614
  }
1497
1615
  @media (prefers-reduced-motion: reduce) {
@@ -1562,7 +1680,7 @@
1562
1680
  align-items: center;
1563
1681
  width: 100%;
1564
1682
  min-width: 0;
1565
- height: 44px;
1683
+ height: var(--control-target-size);
1566
1684
  touch-action: pan-y;
1567
1685
  user-select: none;
1568
1686
  cursor: pointer;
@@ -1586,8 +1704,8 @@
1586
1704
  background: var(--canvas);
1587
1705
  }
1588
1706
  .pui-slider-thumb:focus-within {
1589
- outline: 2px solid var(--interaction-focus);
1590
- outline-offset: 3px;
1707
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
1708
+ outline-offset: var(--focus-ring-offset);
1591
1709
  }
1592
1710
  .pui-slider[data-disabled] {
1593
1711
  opacity: var(--control-disabled-opacity);
@@ -1601,7 +1719,7 @@
1601
1719
  min-width: 120px;
1602
1720
  }
1603
1721
  .pui-slider-control[data-orientation='vertical'] {
1604
- width: 44px;
1722
+ width: var(--control-target-size);
1605
1723
  height: 192px;
1606
1724
  justify-content: center;
1607
1725
  justify-self: center;
@@ -1721,7 +1839,8 @@
1721
1839
  align-items: center;
1722
1840
  gap: var(--space-2);
1723
1841
  min-height: var(--control-height);
1724
- padding: var(--space-2) var(--space-3);
1842
+ padding: max(var(--space-1), calc((var(--control-height) - 1lh) / 2))
1843
+ var(--space-3);
1725
1844
  border-radius: var(--control-radius);
1726
1845
  color: var(--ink);
1727
1846
  outline: none;
@@ -1736,21 +1855,32 @@
1736
1855
  opacity: var(--control-disabled-opacity);
1737
1856
  }
1738
1857
  .pui-menu-check-item {
1739
- padding-inline-start: 36px;
1858
+ padding-inline-start: calc(
1859
+ var(--space-3) + var(--icon-size-sm) + var(--space-2)
1860
+ );
1740
1861
  }
1741
1862
  .pui-menu-indicator {
1742
1863
  position: absolute;
1743
1864
  inset-inline-start: var(--space-3);
1744
1865
  display: inline-flex;
1745
- width: 16px;
1866
+ width: var(--icon-size-sm);
1746
1867
  }
1747
1868
  .pui-menu-check-item[aria-checked='false'] > .pui-menu-indicator {
1748
1869
  visibility: hidden;
1749
1870
  }
1750
- .pui-menu-group-label {
1871
+ .pui-menu-group-label,
1872
+ .pui-select-group-label {
1751
1873
  padding: var(--space-2) var(--space-3);
1752
1874
  color: var(--ink-muted);
1753
- font-size: 12px;
1875
+ font-size: var(--type-caption-size);
1876
+ line-height: var(--type-caption-leading);
1877
+ letter-spacing: var(--type-caption-tracking);
1878
+ }
1879
+ /* A group heading starts where its options' text does, past the check column. */
1880
+ .pui-select-group-label {
1881
+ padding-inline-start: calc(
1882
+ var(--space-3) + var(--icon-size-sm) + var(--space-2)
1883
+ );
1754
1884
  }
1755
1885
  .pui-menu-separator {
1756
1886
  height: 1px;
@@ -1764,12 +1894,9 @@
1764
1894
  flex: none;
1765
1895
  margin-inline-start: var(--space-3);
1766
1896
  }
1767
- .pui-menu-submenu-trigger:dir(rtl) .pui-submenu-arrow {
1768
- transform: rotate(180deg);
1769
- }
1770
- @media (max-width: 760px) {
1897
+ @media (max-width: 760px), (pointer: coarse) {
1771
1898
  .pui-menu-item {
1772
- min-height: 44px;
1899
+ min-height: var(--control-target-size);
1773
1900
  }
1774
1901
  }
1775
1902
  @media (forced-colors: active) {
@@ -1833,7 +1960,9 @@
1833
1960
  background: var(--menu-background);
1834
1961
  color: var(--ink);
1835
1962
  box-shadow: var(--shadow-float);
1836
- font: 400 14px/22px var(--font-body);
1963
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
1964
+ var(--font-body);
1965
+ letter-spacing: var(--type-body-tracking);
1837
1966
  overflow-wrap: anywhere;
1838
1967
  outline: none;
1839
1968
  transform: translateY(0);
@@ -1890,7 +2019,7 @@
1890
2019
  }
1891
2020
  .pui-navigation-trigger {
1892
2021
  padding-inline: var(--space-3);
1893
- font-weight: 500;
2022
+ font-weight: var(--weight-medium);
1894
2023
  background: transparent;
1895
2024
  color: var(--ink-body);
1896
2025
  }
@@ -1918,7 +2047,9 @@
1918
2047
  border-radius: var(--radius-md);
1919
2048
  color: var(--ink-body);
1920
2049
  text-decoration: none;
1921
- font: 400 14px/22px var(--font-body);
2050
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
2051
+ var(--font-body);
2052
+ letter-spacing: var(--type-body-tracking);
1922
2053
  overflow-wrap: anywhere;
1923
2054
  }
1924
2055
  .pui-navigation-link:hover,
@@ -1928,11 +2059,11 @@
1928
2059
  .pui-navigation-link[aria-current='page'] {
1929
2060
  background: var(--selected);
1930
2061
  color: var(--ink);
1931
- font-weight: 500;
2062
+ font-weight: var(--weight-medium);
1932
2063
  }
1933
2064
  .pui-navigation-link:focus-visible {
1934
- outline: 2px solid var(--interaction-focus);
1935
- outline-offset: 2px;
2065
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
2066
+ outline-offset: var(--focus-ring-offset);
1936
2067
  }
1937
2068
  .pui-navigation-popup {
1938
2069
  box-sizing: border-box;
@@ -1946,7 +2077,9 @@
1946
2077
  background: var(--menu-background);
1947
2078
  color: var(--ink);
1948
2079
  box-shadow: var(--shadow-float);
1949
- font: 400 14px/22px var(--font-body);
2080
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
2081
+ var(--font-body);
2082
+ letter-spacing: var(--type-body-tracking);
1950
2083
  outline: none;
1951
2084
  opacity: 1;
1952
2085
  translate: 0 0;
@@ -1977,10 +2110,10 @@
1977
2110
  padding: var(--space-4);
1978
2111
  overflow-wrap: anywhere;
1979
2112
  }
1980
- @media (max-width: 760px) {
2113
+ @media (max-width: 760px), (pointer: coarse) {
1981
2114
  .pui-navigation-trigger,
1982
2115
  .pui-navigation-link {
1983
- min-height: 44px;
2116
+ min-height: var(--control-target-size);
1984
2117
  }
1985
2118
  }
1986
2119
  @media (prefers-reduced-motion: reduce) {
@@ -2026,13 +2159,15 @@
2026
2159
  flex: 1 1 auto;
2027
2160
  }
2028
2161
  .pui-otp-input {
2029
- flex: 0 1 44px;
2030
- width: 44px;
2031
- height: 44px;
2162
+ flex: 0 1 var(--control-target-size);
2163
+ width: var(--control-target-size);
2164
+ height: var(--control-target-size);
2032
2165
  min-width: 0;
2033
2166
  padding: 0;
2034
2167
  text-align: center;
2035
- font: 400 20px/24px var(--font-code);
2168
+ font: var(--weight-regular)
2169
+ var(--type-section-size)/var(--type-section-leading) var(--font-code);
2170
+ letter-spacing: var(--tracking-mono);
2036
2171
  font-variant-numeric: tabular-nums;
2037
2172
  caret-color: var(--control-focus);
2038
2173
  }
@@ -2057,7 +2192,7 @@
2057
2192
  }
2058
2193
  .pui-otp-input:focus-visible {
2059
2194
  outline: 2px solid Highlight;
2060
- outline-offset: 2px;
2195
+ outline-offset: var(--focus-ring-offset);
2061
2196
  }
2062
2197
  .pui-otp-input[aria-invalid='true'] {
2063
2198
  border-color: LinkText;
@@ -2101,7 +2236,9 @@
2101
2236
  background: var(--menu-background);
2102
2237
  color: var(--ink);
2103
2238
  box-shadow: var(--shadow-float);
2104
- font: 400 13px/20px var(--font-body);
2239
+ font: var(--weight-regular)
2240
+ var(--type-compact-size)/var(--type-compact-leading) var(--font-body);
2241
+ letter-spacing: var(--type-compact-tracking);
2105
2242
  overflow-wrap: anywhere;
2106
2243
  pointer-events: auto;
2107
2244
  opacity: 1;
@@ -2134,8 +2271,8 @@
2134
2271
  display: none;
2135
2272
  }
2136
2273
  .pui-toast:focus-visible {
2137
- outline: 2px solid var(--interaction-focus);
2138
- outline-offset: 2px;
2274
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
2275
+ outline-offset: var(--focus-ring-offset);
2139
2276
  }
2140
2277
  .pui-toast-content {
2141
2278
  display: flex;
@@ -2160,13 +2297,16 @@
2160
2297
  }
2161
2298
  .pui-toast-title {
2162
2299
  margin: 0;
2163
- font: 500 13px/20px var(--font-body);
2300
+ font: var(--weight-medium)
2301
+ var(--type-compact-size)/var(--type-compact-leading) var(--font-body);
2302
+ letter-spacing: var(--type-compact-tracking);
2164
2303
  }
2165
2304
  .pui-toast-description {
2166
2305
  margin: 2px 0 0;
2167
2306
  color: var(--ink-muted);
2168
- font-size: 13px;
2169
- line-height: 18px;
2307
+ font-size: var(--type-compact-size);
2308
+ letter-spacing: var(--type-compact-tracking);
2309
+ line-height: var(--type-compact-leading);
2170
2310
  }
2171
2311
  /* Close and Action are small Buttons (see toast.tsx); only their placement is set here. */
2172
2312
  .pui-toast-close {
@@ -2201,8 +2341,8 @@
2201
2341
 
2202
2342
  .pui-toast-viewport[data-layout='stack']:focus-visible {
2203
2343
  border-radius: var(--radius-lg);
2204
- outline: 2px solid var(--interaction-focus);
2205
- outline-offset: -2px;
2344
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
2345
+ outline-offset: var(--focus-ring-inset);
2206
2346
  }
2207
2347
  .pui-toast-viewport[data-layout='anchored'] {
2208
2348
  inset: 0;
@@ -2222,8 +2362,8 @@
2222
2362
  }
2223
2363
 
2224
2364
  .pui-toast-viewport[data-layout='anchored']:focus-visible .pui-toast {
2225
- outline: 2px solid var(--interaction-focus);
2226
- outline-offset: 2px;
2365
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
2366
+ outline-offset: var(--focus-ring-offset);
2227
2367
  }
2228
2368
 
2229
2369
  .pui-file-upload {
@@ -2258,16 +2398,17 @@
2258
2398
  flex-direction: row;
2259
2399
  width: fit-content;
2260
2400
  cursor: pointer;
2261
- font-size: 14px;
2262
- line-height: 22px;
2401
+ font-size: var(--type-body-size);
2402
+ letter-spacing: var(--type-body-tracking);
2403
+ line-height: var(--type-body-leading);
2263
2404
  }
2264
2405
  .pui-file-trigger[data-disabled] {
2265
2406
  opacity: var(--control-disabled-opacity);
2266
2407
  cursor: not-allowed;
2267
2408
  }
2268
2409
  .pui-file-upload:has(.pui-file-native:focus-visible) .pui-file-trigger {
2269
- outline: 2px solid var(--interaction-focus);
2270
- outline-offset: 2px;
2410
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
2411
+ outline-offset: var(--focus-ring-offset);
2271
2412
  }
2272
2413
  .pui-file-upload:has(.pui-file-native[aria-invalid='true'])
2273
2414
  .pui-file-dropzone {
@@ -2276,11 +2417,15 @@
2276
2417
  .pui-file-drop-hint {
2277
2418
  margin: 0;
2278
2419
  color: var(--ink-muted);
2279
- font-size: 13px;
2420
+ font-size: var(--type-compact-size);
2421
+ line-height: var(--type-compact-leading);
2422
+ letter-spacing: var(--type-compact-tracking);
2280
2423
  }
2281
2424
  .pui-file-errors {
2282
2425
  color: var(--status-danger-fg);
2283
- font: 400 13px/20px var(--font-body);
2426
+ font: var(--weight-regular)
2427
+ var(--type-compact-size)/var(--type-compact-leading) var(--font-body);
2428
+ letter-spacing: var(--type-compact-tracking);
2284
2429
  overflow-wrap: anywhere;
2285
2430
  }
2286
2431
  .pui-file-errors:empty {
@@ -2308,13 +2453,15 @@
2308
2453
  flex-wrap: wrap;
2309
2454
  align-items: center;
2310
2455
  gap: var(--space-2) var(--space-3);
2311
- font-size: 13px;
2456
+ font-size: var(--type-compact-size);
2457
+ line-height: var(--type-compact-leading);
2458
+ letter-spacing: var(--type-compact-tracking);
2312
2459
  }
2313
2460
  .pui-file-info > strong {
2314
2461
  min-width: 0;
2315
2462
  max-width: 100%;
2316
2463
  overflow-wrap: anywhere;
2317
- font-weight: 500;
2464
+ font-weight: var(--weight-medium);
2318
2465
  }
2319
2466
  .pui-file-info > span:not(.pui-badge) {
2320
2467
  color: var(--ink-muted);
@@ -2331,12 +2478,16 @@
2331
2478
  .pui-file-upload-error {
2332
2479
  margin: var(--space-2) 0 0;
2333
2480
  color: var(--status-danger-fg);
2334
- font-size: 13px;
2481
+ font-size: var(--type-compact-size);
2482
+ line-height: var(--type-compact-leading);
2483
+ letter-spacing: var(--type-compact-tracking);
2335
2484
  }
2336
- @media (max-width: 760px) {
2485
+ @media (max-width: 760px), (pointer: coarse) {
2337
2486
  .pui-file-trigger {
2338
- min-height: 44px;
2487
+ min-height: var(--control-target-size);
2339
2488
  }
2489
+ }
2490
+ @media (max-width: 760px) {
2340
2491
  .pui-file-dropzone {
2341
2492
  padding: var(--space-4);
2342
2493
  }
@@ -2384,7 +2535,7 @@
2384
2535
  /* An auto row adopts the tallest card while its height transitions, moving
2385
2536
  the bottom anchor during collapse when a behind-card has an action. */
2386
2537
  grid-template-rows: var(--toast-frontmost-height, 80px);
2387
- padding-top: 24px;
2538
+ padding-top: var(--space-6);
2388
2539
  height: calc(var(--toast-frontmost-height, 80px) + 48px);
2389
2540
  overflow: visible;
2390
2541
  }
@@ -2412,7 +2563,7 @@
2412
2563
  pointer-events: auto;
2413
2564
  height: min(calc(var(--toast-stack-height, 240px) + 48px), 100dvh);
2414
2565
  grid-template-rows: var(--toast-stack-height, auto);
2415
- padding-top: 24px;
2566
+ padding-top: var(--space-6);
2416
2567
  overflow: visible;
2417
2568
  }
2418
2569
  .pui-toast-viewport[data-layout='stack'][data-expanded][data-stack-overflow] {
@@ -2428,7 +2579,7 @@
2428
2579
  .pui-toast-viewport[data-layout='stack'] > .pui-toast[data-ending-style] {
2429
2580
  transition-duration: 0s;
2430
2581
  }
2431
- /* Touch targets grow to 44px with the small Button scheme; the close button stays centred
2582
+ /* Touch targets grow to the target size with the small Button scheme; the close button stays centred
2432
2583
  on the first line. */
2433
2584
  @media (max-width: 760px), (pointer: coarse) {
2434
2585
  .pui-toast-close {
@@ -2592,11 +2743,11 @@
2592
2743
  .pui-app-shell-link[aria-current='page'] {
2593
2744
  background: var(--selected);
2594
2745
  color: var(--ink);
2595
- font-weight: 500;
2746
+ font-weight: var(--weight-medium);
2596
2747
  }
2597
2748
  .pui-app-shell-link:focus-visible {
2598
- outline: 2px solid var(--control-focus);
2599
- outline-offset: -2px;
2749
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
2750
+ outline-offset: var(--focus-ring-inset);
2600
2751
  }
2601
2752
  .pui-app-shell-icon {
2602
2753
  display: grid;
@@ -2626,13 +2777,15 @@
2626
2777
  .pui-app-shell-sidebar {
2627
2778
  display: none;
2628
2779
  }
2629
- .pui-app-shell-link {
2630
- min-block-size: 44px;
2631
- }
2632
2780
  .pui-app-shell-content {
2633
2781
  padding: var(--space-4);
2634
2782
  }
2635
2783
  }
2784
+ @media (max-width: 760px), (pointer: coarse) {
2785
+ .pui-app-shell-link {
2786
+ min-block-size: var(--control-target-size);
2787
+ }
2788
+ }
2636
2789
  @media (prefers-reduced-motion: reduce) {
2637
2790
  .pui-app-shell-link {
2638
2791
  transition: none;
@@ -2754,7 +2907,7 @@
2754
2907
  border-radius: var(--radius-md);
2755
2908
  color: var(--ink);
2756
2909
  cursor: default;
2757
- outline-offset: -2px;
2910
+ outline-offset: var(--focus-ring-inset);
2758
2911
  transition: background-color var(--duration-fast) var(--ease-out);
2759
2912
  }
2760
2913
  .pui-tree-item:hover {
@@ -2764,7 +2917,7 @@
2764
2917
  background: var(--selected);
2765
2918
  }
2766
2919
  .pui-tree-item:focus-visible {
2767
- outline: 2px solid var(--control-focus);
2920
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
2768
2921
  }
2769
2922
  .pui-tree-item[aria-disabled='true'] {
2770
2923
  color: var(--ink-muted);
@@ -2793,8 +2946,8 @@
2793
2946
  .pui-tree-toggle svg[data-expanded] {
2794
2947
  rotate: 90deg;
2795
2948
  }
2796
- .pui-tree:dir(rtl) .pui-tree-toggle svg:not([data-expanded]) {
2797
- rotate: 180deg;
2949
+ .pui-tree:dir(rtl) .pui-tree-toggle svg[data-expanded] {
2950
+ rotate: -90deg;
2798
2951
  }
2799
2952
  .pui-tree-label {
2800
2953
  min-inline-size: 0;
@@ -2859,8 +3012,7 @@
2859
3012
  .pui-date-group:focus-within {
2860
3013
  background: var(--control-focus-background);
2861
3014
  border-color: var(--control-focus);
2862
- box-shadow: 0 0 0 3px
2863
- color-mix(in oklch, var(--control-focus) 18%, transparent);
3015
+ box-shadow: 0 0 0 var(--control-focus-ring-size) var(--control-focus-ring);
2864
3016
  }
2865
3017
  :is(.pui-date-picker, .pui-time-field)[data-invalid] .pui-date-group {
2866
3018
  border-color: var(--status-danger-fg);
@@ -2878,7 +3030,8 @@
2878
3030
  flex: 1;
2879
3031
  min-width: 0;
2880
3032
  padding-block: var(--space-1);
2881
- font: 400 var(--type-body-size)/var(--type-body-leading) var(--font-body);
3033
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
3034
+ var(--font-body);
2882
3035
  white-space: nowrap;
2883
3036
  }
2884
3037
  .pui-date-segment {
@@ -2935,8 +3088,8 @@
2935
3088
  background: var(--selected);
2936
3089
  }
2937
3090
  :is(.pui-date-trigger, .pui-calendar-nav)[data-focus-visible] {
2938
- outline: 2px solid var(--control-focus);
2939
- outline-offset: 2px;
3091
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
3092
+ outline-offset: var(--focus-ring-offset);
2940
3093
  }
2941
3094
  :is(.pui-date-trigger, .pui-calendar-nav)[data-disabled] {
2942
3095
  opacity: var(--control-disabled-opacity);
@@ -2962,7 +3115,8 @@
2962
3115
  .pui-calendar {
2963
3116
  width: 280px;
2964
3117
  max-width: 100%;
2965
- font: 400 var(--type-body-size)/var(--type-body-leading) var(--font-body);
3118
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
3119
+ var(--font-body);
2966
3120
  }
2967
3121
  .pui-calendar-header {
2968
3122
  display: flex;
@@ -2973,7 +3127,8 @@
2973
3127
  }
2974
3128
  .pui-calendar-heading {
2975
3129
  margin: 0;
2976
- font: 500 var(--type-body-size)/var(--type-body-leading) var(--font-body);
3130
+ font: var(--weight-medium) var(--type-body-size)/var(--type-body-leading)
3131
+ var(--font-body);
2977
3132
  text-align: center;
2978
3133
  }
2979
3134
  .pui-calendar-grid {
@@ -2985,8 +3140,10 @@
2985
3140
  }
2986
3141
  .pui-calendar-weekday {
2987
3142
  color: var(--ink-muted);
2988
- font-weight: 400;
3143
+ font-weight: var(--weight-regular);
2989
3144
  font-size: var(--type-caption-size);
3145
+ line-height: var(--type-caption-leading);
3146
+ letter-spacing: var(--type-caption-tracking);
2990
3147
  text-align: center;
2991
3148
  }
2992
3149
  .pui-calendar-day {
@@ -3018,8 +3175,8 @@
3018
3175
  color: var(--on-brand);
3019
3176
  }
3020
3177
  .pui-calendar-day[data-focus-visible] {
3021
- outline: 2px solid var(--control-focus);
3022
- outline-offset: -2px;
3178
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
3179
+ outline-offset: var(--focus-ring-inset);
3023
3180
  }
3024
3181
  .pui-calendar-day[data-today] {
3025
3182
  border-color: var(--control-border);
@@ -3080,9 +3237,6 @@
3080
3237
  .pui-calendar-day[data-focus-visible][data-selected] {
3081
3238
  outline-color: var(--ink);
3082
3239
  }
3083
- .pui-calendar:dir(rtl) .pui-calendar-nav svg {
3084
- transform: scaleX(-1);
3085
- }
3086
3240
 
3087
3241
  @media (prefers-reduced-motion: reduce) {
3088
3242
  .pui-file-dropzone {
@@ -3099,14 +3253,16 @@
3099
3253
  gap: var(--space-3);
3100
3254
  }
3101
3255
  .pui-chart-caption strong {
3102
- font: 500 var(--type-subsection-size)/var(--type-subsection-leading)
3256
+ font: var(--weight-medium)
3257
+ var(--type-subsection-size)/var(--type-subsection-leading)
3103
3258
  var(--font-body);
3104
3259
  }
3105
3260
  .pui-chart-caption p,
3106
3261
  .pui-chart-help {
3107
3262
  margin: var(--space-2) 0 0;
3108
3263
  color: var(--ink-muted);
3109
- font: 400 var(--type-body-size)/var(--type-body-leading) var(--font-body);
3264
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
3265
+ var(--font-body);
3110
3266
  }
3111
3267
  .pui-chart-legend {
3112
3268
  display: flex;
@@ -3127,7 +3283,8 @@
3127
3283
  border-radius: var(--radius-md);
3128
3284
  background: transparent;
3129
3285
  color: var(--ink-body);
3130
- font: 400 var(--type-body-size)/var(--type-body-leading) var(--font-body);
3286
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
3287
+ var(--font-body);
3131
3288
  cursor: pointer;
3132
3289
  text-align: start;
3133
3290
  }
@@ -3150,15 +3307,15 @@
3150
3307
  .pui-chart-legend-button:focus-visible,
3151
3308
  .pui-chart-plot .recharts-surface:focus-visible,
3152
3309
  .pui-chart-table summary:focus-visible {
3153
- outline: 2px solid var(--interaction-focus);
3154
- outline-offset: 2px;
3310
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
3311
+ outline-offset: var(--focus-ring-offset);
3155
3312
  border-radius: var(--radius-sm);
3156
3313
  }
3157
3314
  .pui-chart-axis-label {
3158
3315
  margin: 0;
3159
3316
  color: var(--ink-muted);
3160
- font: 400 var(--type-caption-size)/var(--type-caption-leading)
3161
- var(--font-body);
3317
+ font: var(--weight-regular)
3318
+ var(--type-caption-size)/var(--type-caption-leading) var(--font-body);
3162
3319
  overflow-wrap: anywhere;
3163
3320
  }
3164
3321
  .pui-chart-x-label {
@@ -3176,14 +3333,15 @@
3176
3333
  background: var(--surface);
3177
3334
  color: var(--ink-body);
3178
3335
  border-radius: var(--radius-md);
3179
- font: 400 var(--type-body-size)/var(--type-body-leading) var(--font-body);
3336
+ font: var(--weight-regular) var(--type-body-size)/var(--type-body-leading)
3337
+ var(--font-body);
3180
3338
  overflow-wrap: anywhere;
3181
3339
  }
3182
3340
  .pui-chart-inspector[hidden] {
3183
3341
  display: none;
3184
3342
  }
3185
3343
  .pui-chart-readout strong {
3186
- font-weight: 500;
3344
+ font-weight: var(--weight-medium);
3187
3345
  }
3188
3346
  .pui-chart-readout ul {
3189
3347
  display: flex;
@@ -3219,12 +3377,15 @@
3219
3377
  text-underline-offset: 3px;
3220
3378
  }
3221
3379
  .pui-chart-table .pui-scroll-root {
3222
- max-height: 320px;
3223
3380
  margin-top: var(--space-2);
3224
3381
  }
3382
+ /* The data table scrolls inside a bounded region, so long series stay compact. */
3383
+ .pui-chart-table .pui-scroll-viewport {
3384
+ max-block-size: 320px;
3385
+ }
3225
3386
  @media (max-width: 760px), (pointer: coarse) {
3226
3387
  .pui-chart-legend-button {
3227
- min-height: 44px;
3388
+ min-height: var(--control-target-size);
3228
3389
  }
3229
3390
  }
3230
3391
  @media (forced-colors: active) {
@@ -3444,7 +3605,7 @@
3444
3605
  padding-inline: var(--ui-card-padding);
3445
3606
  }
3446
3607
  :where([data-ui-size], [data-ui-size] *).pui-dialog-header {
3447
- padding-inline-end: calc(var(--ui-card-padding) + 48px);
3608
+ padding-inline-end: calc(var(--control-height) + var(--space-4) * 2);
3448
3609
  }
3449
3610
  :where([data-ui-size], [data-ui-size] *).pui-confirm-content
3450
3611
  .pui-dialog-header {
@@ -3523,8 +3684,11 @@
3523
3684
  /* Coarse pointers retain comfortable targets even with a compact visual scheme. */
3524
3685
  @media (max-width: 760px), (pointer: coarse) {
3525
3686
  [data-ui-size] {
3526
- --control-height: max(44px, var(--ui-control-height));
3527
- --ui-row: max(44px, var(--ui-control-height));
3687
+ --control-height: max(
3688
+ var(--control-target-size),
3689
+ var(--ui-control-height)
3690
+ );
3691
+ --ui-row: max(var(--control-target-size), var(--ui-control-height));
3528
3692
  }
3529
3693
  }
3530
3694
  @media (forced-colors: active) {
@@ -3562,10 +3726,10 @@
3562
3726
  }
3563
3727
  @media (max-width: 760px), (pointer: coarse) {
3564
3728
  :where([data-ui-size], [data-ui-size] *).pui-field-item {
3565
- min-block-size: 44px;
3729
+ min-block-size: var(--control-target-size);
3566
3730
  }
3567
3731
  :where([data-ui-size], [data-ui-size] *).pui-slider-control {
3568
- min-block-size: 44px;
3732
+ min-block-size: var(--control-target-size);
3569
3733
  }
3570
3734
  }
3571
3735
 
@@ -3595,15 +3759,19 @@
3595
3759
  font-size: var(--ui-font);
3596
3760
  }
3597
3761
  :where([data-ui-size], [data-ui-size] *).pui-avatar[data-ui-size] {
3598
- font-size: clamp(12px, calc(var(--ui-avatar) / 3), 16px);
3762
+ font-size: clamp(
3763
+ var(--type-caption-size),
3764
+ calc(var(--ui-avatar) / 3),
3765
+ var(--size-font-large)
3766
+ );
3599
3767
  }
3600
3768
  @media (max-width: 760px), (pointer: coarse) {
3601
3769
  :where([data-ui-size], [data-ui-size] *):is(
3602
3770
  .pui-date-trigger,
3603
3771
  .pui-calendar-nav
3604
3772
  ) {
3605
- inline-size: 44px;
3606
- block-size: 44px;
3773
+ inline-size: var(--control-target-size);
3774
+ block-size: var(--control-target-size);
3607
3775
  }
3608
3776
  }
3609
3777
 
@@ -3652,10 +3820,11 @@
3652
3820
  padding: var(--ui-surface-padding, var(--space-4));
3653
3821
  background: var(--code-bg);
3654
3822
  border-radius: var(--radius-md);
3655
- font: 400 13px/20px var(--font-code);
3823
+ font: var(--weight-regular) var(--type-code-size)/var(--type-code-leading)
3824
+ var(--font-code);
3656
3825
  /* Code shows the characters as typed, like the other code text: no === or => ligatures. */
3657
3826
  font-variant-ligatures: none;
3658
- letter-spacing: 0;
3827
+ letter-spacing: var(--tracking-mono);
3659
3828
  tab-size: 2;
3660
3829
  white-space: pre;
3661
3830
  }
@@ -3709,8 +3878,8 @@
3709
3878
  text-underline-offset: 3px;
3710
3879
  }
3711
3880
  .pui-markdown a:focus-visible {
3712
- outline: 2px solid var(--interaction-focus);
3713
- outline-offset: 2px;
3881
+ outline: var(--focus-ring-width) solid var(--interaction-focus);
3882
+ outline-offset: var(--focus-ring-offset);
3714
3883
  }
3715
3884
  .pui-markdown .contains-task-list {
3716
3885
  list-style: none;
@@ -3728,9 +3897,8 @@
3728
3897
  .pui-markdown-inline-code {
3729
3898
  padding: 2px 4px;
3730
3899
  background: var(--code-bg);
3731
- font-weight: 400;
3732
- line-height: 20px;
3733
- letter-spacing: 0;
3900
+ font-weight: var(--weight-regular);
3901
+ letter-spacing: var(--tracking-mono);
3734
3902
  }
3735
3903
  .pui-markdown .pui-table {
3736
3904
  min-inline-size: 480px;