@threadlabs/looma 0.41.1 → 0.42.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 (101) hide show
  1. package/components/ui-button/ui-button.html +33 -12
  2. package/components/ui-button/ui-button.js +2 -2
  3. package/components/ui-callout/ui-callout.html +1 -1
  4. package/components/ui-card/ui-card.html +7 -7
  5. package/components/ui-checkbox/ui-checkbox.html +1 -1
  6. package/components/ui-dialog/ui-dialog.html +8 -10
  7. package/components/ui-editor-mention-menu/ui-editor-mention-menu.html +1 -1
  8. package/components/ui-editor-mention-menu-item/ui-editor-mention-menu-item.html +1 -1
  9. package/components/ui-editor-table-context-menu/ui-editor-table-context-menu.html +1 -1
  10. package/components/ui-editor-table-toolbar/ui-editor-table-toolbar.html +2 -2
  11. package/components/ui-icon-button/ui-icon-button.html +45 -10
  12. package/components/ui-light-editor/ui-light-editor.html +1 -1
  13. package/components/ui-menu/ui-menu.html +8 -10
  14. package/components/ui-menu-item/ui-menu-item.html +1 -1
  15. package/components/ui-popover/ui-popover.html +9 -11
  16. package/components/ui-radio/ui-radio.html +53 -1
  17. package/components/ui-section/ui-section.html +1 -1
  18. package/components/ui-site-header/ui-site-header.html +6 -2
  19. package/components/ui-status-message/ui-status-message.html +1 -1
  20. package/components/ui-switch/ui-switch.html +5 -2
  21. package/components/ui-tabs/ui-tabs.html +3 -3
  22. package/components/ui-text/ui-text.html +2 -2
  23. package/components/ui-tooltip/ui-tooltip.html +8 -10
  24. package/dist/index.js +1 -1
  25. package/docs/README.md +5 -1
  26. package/docs/catalog.json +410 -35
  27. package/docs/customizer-render.mjs +9 -5
  28. package/docs/customizer.js +2 -0
  29. package/docs/fonts.mjs +1 -1
  30. package/docs/theme.mjs +136 -35
  31. package/package.json +1 -1
  32. package/styles/ui-button.css +33 -12
  33. package/styles/ui-callout.css +1 -1
  34. package/styles/ui-card.css +6 -6
  35. package/styles/ui-checkbox.css +1 -1
  36. package/styles/ui-dialog.css +17 -21
  37. package/styles/ui-editor-mention-menu-item.css +1 -1
  38. package/styles/ui-editor-mention-menu.css +1 -1
  39. package/styles/ui-editor-table-context-menu.css +1 -1
  40. package/styles/ui-editor-table-toolbar.css +2 -2
  41. package/styles/ui-icon-button.css +45 -10
  42. package/styles/ui-light-editor.css +2 -2
  43. package/styles/ui-menu-item.css +1 -1
  44. package/styles/ui-menu.css +9 -11
  45. package/styles/ui-popover.css +10 -12
  46. package/styles/ui-radio.css +62 -1
  47. package/styles/ui-section.css +1 -1
  48. package/styles/ui-site-header.css +6 -2
  49. package/styles/ui-status-message.css +1 -1
  50. package/styles/ui-switch.css +5 -2
  51. package/styles/ui-tabs.css +3 -3
  52. package/styles/ui-text.css +2 -2
  53. package/styles/ui-tooltip.css +9 -11
  54. package/theme-system.css +10 -8
  55. package/tokens.css +23 -0
  56. package/vue/UiButton.vue +45 -12
  57. package/vue/UiCallout.vue +1 -1
  58. package/vue/UiCard.vue +7 -13
  59. package/vue/UiCheckbox.vue +1 -1
  60. package/vue/UiDialog.vue +21 -45
  61. package/vue/UiEditorMentionMenu.vue +1 -1
  62. package/vue/UiEditorMentionMenuItem.vue +1 -1
  63. package/vue/UiEditorTableContextMenu.vue +1 -1
  64. package/vue/UiEditorTableToolbar.vue +2 -2
  65. package/vue/UiIconButton.vue +45 -10
  66. package/vue/UiLightEditor.vue +2 -2
  67. package/vue/UiMenu.vue +11 -21
  68. package/vue/UiMenuItem.vue +1 -1
  69. package/vue/UiPopover.vue +12 -22
  70. package/vue/UiRadio.vue +57 -1
  71. package/vue/UiSection.vue +1 -1
  72. package/vue/UiSiteHeader.vue +6 -2
  73. package/vue/UiStatusMessage.vue +1 -1
  74. package/vue/UiSwitch.vue +5 -2
  75. package/vue/UiTabs.vue +3 -3
  76. package/vue/UiText.vue +2 -2
  77. package/vue/UiTooltip.vue +11 -21
  78. package/vue/chunks/UiButton.js +1 -1
  79. package/vue/chunks/UiCallout.js +1 -1
  80. package/vue/chunks/UiCard.js +2 -2
  81. package/vue/chunks/UiCheckbox.js +1 -1
  82. package/vue/chunks/UiDialog.js +1 -1
  83. package/vue/chunks/UiEditorMentionMenu.js +1 -1
  84. package/vue/chunks/UiEditorMentionMenuItem.js +1 -1
  85. package/vue/chunks/UiEditorTableContextMenu.js +1 -1
  86. package/vue/chunks/UiEditorTableToolbar.js +1 -1
  87. package/vue/chunks/UiIconButton.js +1 -1
  88. package/vue/chunks/UiLightEditor.js +1 -1
  89. package/vue/chunks/UiMenu.js +1 -1
  90. package/vue/chunks/UiMenuItem.js +1 -1
  91. package/vue/chunks/UiPopover.js +1 -1
  92. package/vue/chunks/UiRadio.js +1 -1
  93. package/vue/chunks/UiSection.js +1 -1
  94. package/vue/chunks/UiSiteHeader.js +1 -1
  95. package/vue/chunks/UiStatusMessage.js +1 -1
  96. package/vue/chunks/UiSwitch.js +1 -1
  97. package/vue/chunks/UiTabs.js +1 -1
  98. package/vue/chunks/UiText.js +1 -1
  99. package/vue/chunks/UiTooltip.js +1 -1
  100. package/vue/components.css +348 -235
  101. package/vue/editor/index.js +1 -1
@@ -52,9 +52,9 @@
52
52
  }
53
53
 
54
54
  :scope:where([data-component~="ui-card"])[data-ui-card-state~="treatment=expressive"] {
55
- --_ui-panel-glass: calc(clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4));
55
+ --_ui-panel-glass: clamp(0, var(--ui-glassiness, 0), 1);
56
56
  --_ui-panel-separation: clamp(0, var(--ui-surface-separation, 0), 1);
57
- --_ui-panel-rim: calc((var(--_ui-panel-separation) + var(--_ui-panel-glass) * 0.25) * 0.65 * 8px);
57
+ --_ui-panel-rim: calc(var(--_ui-panel-separation) * 8px);
58
58
  border-width: calc(var(--ui-border-width) + var(--_ui-panel-rim));
59
59
  border-color: transparent;
60
60
  background:
@@ -66,8 +66,8 @@
66
66
  var(--_ui-card-elevation),
67
67
  var(--ui-material-glow, 0 0 transparent),
68
68
  inset 0 0 0 var(--ui-border-width) var(--ui-material-edge, var(--ui-border-strong));
69
- backdrop-filter: blur(calc(var(--_ui-panel-glass) * 0.65 * 18px)) saturate(calc(1 + var(--_ui-panel-glass) * 0.65 * 0.18));
70
- -webkit-backdrop-filter: blur(calc(var(--_ui-panel-glass) * 0.65 * 18px)) saturate(calc(1 + var(--_ui-panel-glass) * 0.65 * 0.18));
69
+ -webkit-backdrop-filter: blur(calc(var(--_ui-panel-glass) * 32px));
70
+ backdrop-filter: blur(calc(var(--_ui-panel-glass) * 32px));
71
71
  }
72
72
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
73
73
  :scope:where([data-component~="ui-card"])[data-ui-card-state~="treatment=expressive"] {
@@ -79,8 +79,8 @@
79
79
  background: var(--_ui-card-surface);
80
80
  border-width: var(--ui-border-width);
81
81
  border-color: var(--ui-border-strong);
82
- backdrop-filter: none;
83
82
  -webkit-backdrop-filter: none;
83
+ backdrop-filter: none;
84
84
  }
85
85
  }
86
86
  @media (forced-colors: active) {
@@ -89,8 +89,8 @@
89
89
  color: CanvasText;
90
90
  border: var(--ui-border-width) solid CanvasText;
91
91
  box-shadow: none;
92
- backdrop-filter: none;
93
92
  -webkit-backdrop-filter: none;
93
+ backdrop-filter: none;
94
94
  }
95
95
  }
96
96
 
@@ -114,7 +114,7 @@
114
114
  border-color: var(--ui-accent-solid);
115
115
  background-color: var(--ui-accent-solid);
116
116
  background-image: var(--ui-accent-highlight, none);
117
- box-shadow: var(--ui-control-inset);
117
+ box-shadow: none;
118
118
  }
119
119
 
120
120
  /* The SVG's painted bounds are centred in its viewBox, including its round stroke.
@@ -72,12 +72,12 @@
72
72
  }
73
73
 
74
74
  /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
75
- transparency, saturation and edge light belong to the surrounding decorative material. */
75
+ transparency, frosting and edge light belong to the surrounding decorative material. */
76
76
  :scope:where([data-component~="ui-dialog"]) {
77
- --_ui-material-glassiness: calc(clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4));
77
+ --_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
78
78
  --_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
79
- --_ui-material-active: clamp(0, calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000), 1);
80
- --_ui-material-rim: calc((var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25) * var(--_ui-material-scale, 1) * 8px);
79
+ --_ui-material-active: clamp(0, calc(var(--_ui-material-separation) * 100000), 1);
80
+ --_ui-material-rim: calc(var(--_ui-material-separation) * var(--_ui-material-scale, 1) * 8px);
81
81
  --_ui-material-content-color: var(--ui-dialog-surface, var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated))));
82
82
  --_ui-material-rim-color: color-mix(in srgb, var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%), transparent);
83
83
  background:
@@ -102,10 +102,8 @@
102
102
  var(--ui-elevation-dialog, var(--ui-shadow-xl))
103
103
  )
104
104
  );
105
- backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 18px))
106
- saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 0.18));
107
- -webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 18px))
108
- saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 0.18));
105
+ -webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 32px));
106
+ backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 32px));
109
107
  }
110
108
 
111
109
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
@@ -117,8 +115,8 @@
117
115
  @media (prefers-reduced-transparency: reduce) {
118
116
  :scope:where([data-component~="ui-dialog"]) {
119
117
  background: var(--_ui-material-content-color);
120
- backdrop-filter: none;
121
118
  -webkit-backdrop-filter: none;
119
+ backdrop-filter: none;
122
120
  }
123
121
  }
124
122
 
@@ -127,8 +125,8 @@
127
125
  background: Canvas;
128
126
  border-color: CanvasText;
129
127
  box-shadow: none;
130
- backdrop-filter: none;
131
128
  -webkit-backdrop-filter: none;
129
+ backdrop-filter: none;
132
130
  }
133
131
  }
134
132
 
@@ -256,7 +254,7 @@
256
254
  /* This component's hooks style the element they are set on, and never a nested one. */
257
255
 
258
256
  /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
259
- transparency, saturation and edge light belong to the surrounding decorative material. */
257
+ transparency, frosting and edge light belong to the surrounding decorative material. */
260
258
 
261
259
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
262
260
  }
@@ -339,12 +337,12 @@
339
337
  }
340
338
 
341
339
  /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
342
- transparency, saturation and edge light belong to the surrounding decorative material. */
340
+ transparency, frosting and edge light belong to the surrounding decorative material. */
343
341
  :where([data-component~="ui-dialog"]):where(:scope, :not([data-component], [data-slotted]:not([data-slotted~="ui-dialog"]))) {
344
- --_ui-material-glassiness: calc(clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4));
342
+ --_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
345
343
  --_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
346
- --_ui-material-active: clamp(0, calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000), 1);
347
- --_ui-material-rim: calc((var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25) * var(--_ui-material-scale, 1) * 8px);
344
+ --_ui-material-active: clamp(0, calc(var(--_ui-material-separation) * 100000), 1);
345
+ --_ui-material-rim: calc(var(--_ui-material-separation) * var(--_ui-material-scale, 1) * 8px);
348
346
  --_ui-material-content-color: var(--ui-dialog-surface, var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated))));
349
347
  --_ui-material-rim-color: color-mix(in srgb, var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%), transparent);
350
348
  background:
@@ -369,10 +367,8 @@
369
367
  var(--ui-elevation-dialog, var(--ui-shadow-xl))
370
368
  )
371
369
  );
372
- backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 18px))
373
- saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 0.18));
374
- -webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 18px))
375
- saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 0.18));
370
+ -webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 32px));
371
+ backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 1) * 32px));
376
372
  }
377
373
 
378
374
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
@@ -384,8 +380,8 @@
384
380
  @media (prefers-reduced-transparency: reduce) {
385
381
  :where([data-component~="ui-dialog"]):where(:scope, :not([data-component], [data-slotted]:not([data-slotted~="ui-dialog"]))) {
386
382
  background: var(--_ui-material-content-color);
387
- backdrop-filter: none;
388
383
  -webkit-backdrop-filter: none;
384
+ backdrop-filter: none;
389
385
  }
390
386
  }
391
387
 
@@ -394,8 +390,8 @@
394
390
  background: Canvas;
395
391
  border-color: CanvasText;
396
392
  box-shadow: none;
397
- backdrop-filter: none;
398
393
  -webkit-backdrop-filter: none;
394
+ backdrop-filter: none;
399
395
  }
400
396
  }
401
397
 
@@ -42,7 +42,7 @@
42
42
  inline-size: 32px;
43
43
  block-size: 32px;
44
44
  flex: 0 0 auto;
45
- color: var(--ui-accent-active);
45
+ color: var(--ui-accent-subtle-text);
46
46
  background: var(--ui-accent-soft);
47
47
  border-radius: var(--ui-radius-round);
48
48
  font-size: var(--ui-font-size-xs);
@@ -110,7 +110,7 @@
110
110
  width: 32px;
111
111
  height: 32px;
112
112
  flex: 0 0 auto;
113
- color: var(--ui-accent-active, var(--ui-accent-solid));
113
+ color: var(--ui-accent-subtle-text);
114
114
  background: var(--ui-accent-soft, var(--ui-accent-subtle));
115
115
  border-radius: var(--ui-radius-round);
116
116
  font-size: var(--ui-font-size-xs);
@@ -68,7 +68,7 @@
68
68
  }
69
69
 
70
70
  :scope:where([data-component~="ui-editor-table-context-menu"]) button.danger {
71
- color: var(--ui-danger);
71
+ color: var(--ui-danger-subtle-text);
72
72
  }
73
73
 
74
74
  /* Swatches wrap like words: the row asks for the menu's full width, and a narrower menu fits fewer. */
@@ -81,7 +81,7 @@
81
81
 
82
82
  :scope:where([data-component~="ui-editor-table-toolbar"]) button.active {
83
83
  background: var(--ui-accent-soft, var(--ui-accent-subtle));
84
- color: var(--ui-accent-active);
84
+ color: var(--ui-accent-subtle-text);
85
85
  }
86
86
 
87
87
  .group button {
@@ -98,7 +98,7 @@
98
98
  }
99
99
 
100
100
  :scope:where([data-component~="ui-editor-table-toolbar"]) button.danger {
101
- color: var(--ui-danger);
101
+ color: var(--ui-danger-subtle-text);
102
102
  }
103
103
 
104
104
  :scope:where([data-component~="ui-editor-table-toolbar"]) {
@@ -89,6 +89,10 @@
89
89
  /* Optional inherited action-group values keep text and icon actions under the same light.
90
90
  One fine top/start highlight follows the bottom/end lowlight at a joined action seam.
91
91
  The shared theme supplies reflections and glow independently of the resting lift. */
92
+ --_solid-border: var(--ui-accent-border, var(--ui-accent-solid));
93
+ --_solid-hover-border: var(--ui-accent-hover-border, var(--ui-accent-hover));
94
+ --_solid-active-border: var(--ui-accent-active-border, var(--ui-accent-active));
95
+ --_solid-active-surface: var(--ui-accent-active, var(--ui-accent-hover));
92
96
  --_tone-highlight: var(--ui-accent-highlight, none);
93
97
  --_tone-glow: var(--ui-accent-glow, 0 0 transparent);
94
98
  --_ui-action-start: 1px;
@@ -111,20 +115,28 @@
111
115
  }
112
116
 
113
117
  :scope:where([data-component~="ui-icon-button"])[data-tone="accent"] {
118
+ --_solid-border: var(--ui-accent-border, var(--ui-accent));
119
+ --_solid-hover-border: var(--ui-accent-hover-border, var(--ui-accent-hover));
120
+ --_solid-active-border: var(--ui-accent-active-border, var(--ui-accent-active));
121
+ --_solid-active-surface: var(--ui-accent-active, var(--ui-accent-hover));
114
122
  --_tone-highlight: var(--ui-accent-highlight, none);
115
123
  --_tone-glow: var(--ui-accent-glow, 0 0 transparent);
116
- --_icon-button-border: var(--ui-accent-solid);
117
- --_icon-button-hover-border: var(--ui-accent-hover);
124
+ --_icon-button-border: var(--ui-accent-subtle-text);
125
+ --_icon-button-hover-border: var(--ui-accent-subtle-text);
118
126
  --_icon-button-text: var(--ui-accent-subtle-text, var(--ui-accent-solid));
119
127
  --_icon-button-outline-surface: color-mix(in srgb, var(--ui-accent-solid) 5%, var(--ui-surface-default));
120
128
  color: var(--_icon-button-text);
121
129
  }
122
130
 
123
131
  :scope:where([data-component~="ui-icon-button"])[data-tone="danger"] {
132
+ --_solid-border: var(--ui-danger-border, var(--ui-danger));
133
+ --_solid-hover-border: var(--ui-danger-hover-border, var(--ui-danger-hover));
134
+ --_solid-active-border: var(--ui-danger-active-border, var(--ui-danger-active));
135
+ --_solid-active-surface: var(--ui-danger-active, var(--ui-danger-hover));
124
136
  --_tone-highlight: var(--ui-danger-highlight, none);
125
137
  --_tone-glow: var(--ui-danger-glow, 0 0 transparent);
126
- --_icon-button-border: var(--ui-danger);
127
- --_icon-button-hover-border: var(--ui-danger-hover);
138
+ --_icon-button-border: var(--ui-danger-subtle-text);
139
+ --_icon-button-hover-border: var(--ui-danger-subtle-text);
128
140
  --_icon-button-text: var(--ui-danger-subtle-text);
129
141
  --_icon-button-outline-surface: color-mix(in srgb, var(--ui-danger) 5%, var(--ui-surface-default));
130
142
  --_icon-button-solid-surface: var(--ui-danger);
@@ -134,10 +146,14 @@
134
146
  }
135
147
 
136
148
  :scope:where([data-component~="ui-icon-button"])[data-tone="success"] {
149
+ --_solid-border: var(--ui-success-border, var(--ui-success));
150
+ --_solid-hover-border: var(--ui-success-hover-border, var(--ui-success-hover));
151
+ --_solid-active-border: var(--ui-success-active-border, var(--ui-success-active));
152
+ --_solid-active-surface: var(--ui-success-active, var(--ui-success-hover));
137
153
  --_tone-highlight: var(--ui-success-highlight, none);
138
154
  --_tone-glow: var(--ui-success-glow, 0 0 transparent);
139
- --_icon-button-border: var(--ui-success);
140
- --_icon-button-hover-border: var(--ui-success-hover);
155
+ --_icon-button-border: var(--ui-success-subtle-text);
156
+ --_icon-button-hover-border: var(--ui-success-subtle-text);
141
157
  --_icon-button-text: var(--ui-success-subtle-text);
142
158
  --_icon-button-outline-surface: color-mix(in srgb, var(--ui-success) 5%, var(--ui-surface-default));
143
159
  --_icon-button-solid-surface: var(--ui-success);
@@ -147,10 +163,14 @@
147
163
  }
148
164
 
149
165
  :scope:where([data-component~="ui-icon-button"])[data-tone="warning"] {
166
+ --_solid-border: var(--ui-warning-border, var(--ui-warning));
167
+ --_solid-hover-border: var(--ui-warning-hover-border, var(--ui-warning-hover));
168
+ --_solid-active-border: var(--ui-warning-active-border, var(--ui-warning-active));
169
+ --_solid-active-surface: var(--ui-warning-active, var(--ui-warning-hover));
150
170
  --_tone-highlight: var(--ui-warning-highlight, none);
151
171
  --_tone-glow: var(--ui-warning-glow, 0 0 transparent);
152
- --_icon-button-border: var(--ui-warning);
153
- --_icon-button-hover-border: var(--ui-warning-hover);
172
+ --_icon-button-border: var(--ui-warning-subtle-text);
173
+ --_icon-button-hover-border: var(--ui-warning-subtle-text);
154
174
  --_icon-button-text: var(--ui-warning-subtle-text);
155
175
  --_icon-button-outline-surface: color-mix(in srgb, var(--ui-warning) 5%, var(--ui-surface-default));
156
176
  --_icon-button-solid-surface: var(--ui-warning);
@@ -160,10 +180,14 @@
160
180
  }
161
181
 
162
182
  :scope:where([data-component~="ui-icon-button"])[data-tone="info"] {
183
+ --_solid-border: var(--ui-info-border, var(--ui-info));
184
+ --_solid-hover-border: var(--ui-info-hover-border, var(--ui-info-hover));
185
+ --_solid-active-border: var(--ui-info-active-border, var(--ui-info-active));
186
+ --_solid-active-surface: var(--ui-info-active, var(--ui-info-hover));
163
187
  --_tone-highlight: var(--ui-info-highlight, none);
164
188
  --_tone-glow: var(--ui-info-glow, 0 0 transparent);
165
- --_icon-button-border: var(--ui-info);
166
- --_icon-button-hover-border: var(--ui-info-hover);
189
+ --_icon-button-border: var(--ui-info-subtle-text);
190
+ --_icon-button-hover-border: var(--ui-info-subtle-text);
167
191
  --_icon-button-text: var(--ui-info-subtle-text);
168
192
  --_icon-button-outline-surface: color-mix(in srgb, var(--ui-info) 5%, var(--ui-surface-default));
169
193
  --_icon-button-solid-surface: var(--ui-info);
@@ -174,6 +198,10 @@
174
198
 
175
199
  /* Neutral actions share the same quiet surface and border roles as fields. */
176
200
  :scope:where([data-component~="ui-icon-button"])[data-tone="neutral"] {
201
+ --_solid-border: var(--ui-neutral-border, var(--ui-neutral-surface));
202
+ --_solid-hover-border: var(--ui-neutral-hover-border, var(--ui-neutral-hover));
203
+ --_solid-active-border: var(--ui-neutral-active-border, var(--ui-neutral-active));
204
+ --_solid-active-surface: var(--ui-neutral-active, var(--ui-neutral-hover));
177
205
  --_tone-highlight: var(--ui-neutral-highlight, none);
178
206
  --_tone-glow: var(--ui-neutral-glow, 0 0 transparent);
179
207
  --_icon-button-outline-surface: transparent;
@@ -350,6 +378,7 @@
350
378
  }
351
379
 
352
380
  :scope:where([data-component~="ui-icon-button"])[data-appearance="solid"] {
381
+ border-color: var(--ui-icon-button-border, var(--_solid-border));
353
382
  background-color: var(--ui-icon-button-solid-surface, var(--_icon-button-solid-surface, var(--ui-accent-solid)));
354
383
  background-image: var(--_tone-highlight);
355
384
  color: var(--ui-icon-button-solid-text, var(--_icon-button-solid-text, var(--ui-text-on-accent)));
@@ -375,6 +404,7 @@
375
404
  }
376
405
 
377
406
  :scope:where([data-component~="ui-icon-button"])[data-appearance="solid"]:hover:enabled:not([aria-disabled="true"]) {
407
+ border-color: var(--ui-icon-button-hover-border, var(--_solid-hover-border));
378
408
  background-color: var(--ui-icon-button-solid-hover-surface, var(--_icon-button-solid-hover-surface, var(--ui-accent-hover)));
379
409
  }
380
410
 
@@ -436,6 +466,11 @@
436
466
  var(--ui-focus-halo);
437
467
  }
438
468
 
469
+ :scope:where([data-component~="ui-icon-button"])[data-appearance="solid"]:active:enabled:not([aria-disabled="true"]) {
470
+ background-color: var(--ui-icon-button-active-surface, var(--_solid-active-surface));
471
+ border-color: var(--_solid-active-border);
472
+ }
473
+
439
474
  :scope:where([data-component~="ui-icon-button"]):is(:scope:where([data-component~="ui-icon-button"])[data-appearance="outline"], :scope:where([data-component~="ui-icon-button"])[data-appearance="solid"]):active:enabled:not([aria-disabled="true"]) {
440
475
  background-image: none;
441
476
  box-shadow: var(--ui-pressed);
@@ -67,7 +67,7 @@
67
67
  position: relative;
68
68
  z-index: 1;
69
69
  display: inline-flex !important;
70
- color: var(--ui-accent);
70
+ color: var(--ui-accent-subtle-text);
71
71
  font-size: var(--ui-font-size-lg);
72
72
  }
73
73
  .source:where(:not([data-component], [data-slotted]))::after {
@@ -182,7 +182,7 @@
182
182
  position: relative;
183
183
  z-index: 1;
184
184
  display: inline-flex !important;
185
- color: var(--ui-accent);
185
+ color: var(--ui-accent-subtle-text);
186
186
  font-size: var(--ui-font-size-lg);
187
187
  }
188
188
  .source:where(:not([data-component], [data-slotted]:not([data-slotted~="ui-light-editor"]))):where(:scope, :scope *)::after {
@@ -67,7 +67,7 @@
67
67
  }
68
68
 
69
69
  :scope:where([data-component~="ui-menu-item"])[data-ui-menu-item-state~="tone=danger"] {
70
- color: var(--ui-danger);
70
+ color: var(--ui-danger-subtle-text);
71
71
  }
72
72
 
73
73
  .label {
@@ -101,12 +101,12 @@
101
101
  }
102
102
 
103
103
  /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
104
- transparency, saturation and edge light belong to the surrounding decorative material. */
104
+ transparency, frosting and edge light belong to the surrounding decorative material. */
105
105
  :scope:where([data-component~="ui-menu"]):not([inline]) .surface {
106
- --_ui-material-glassiness: calc(clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4));
106
+ --_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
107
107
  --_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
108
- --_ui-material-active: clamp(0, calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000), 1);
109
- --_ui-material-rim: calc((var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25) * var(--_ui-material-scale, 0.28) * 8px);
108
+ --_ui-material-active: clamp(0, calc(var(--_ui-material-separation) * 100000), 1);
109
+ --_ui-material-rim: calc(var(--_ui-material-separation) * var(--_ui-material-scale, 0.28) * 8px);
110
110
  --_ui-material-content-color: var(--_ui-menu-surface, var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated))));
111
111
  --_ui-material-rim-color: color-mix(in srgb, var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%), transparent);
112
112
  background:
@@ -131,10 +131,8 @@
131
131
  var(--ui-elevation-overlay, var(--ui-shadow-lg))
132
132
  )
133
133
  );
134
- backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 18px))
135
- saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 0.18));
136
- -webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 18px))
137
- saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 0.18));
134
+ -webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 32px));
135
+ backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.28) * 32px));
138
136
  }
139
137
 
140
138
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
@@ -146,8 +144,8 @@
146
144
  @media (prefers-reduced-transparency: reduce) {
147
145
  :scope:where([data-component~="ui-menu"]):not([inline]) .surface {
148
146
  background: var(--_ui-material-content-color);
149
- backdrop-filter: none;
150
147
  -webkit-backdrop-filter: none;
148
+ backdrop-filter: none;
151
149
  }
152
150
  }
153
151
 
@@ -156,8 +154,8 @@
156
154
  background: Canvas;
157
155
  border-color: CanvasText;
158
156
  box-shadow: none;
159
- backdrop-filter: none;
160
157
  -webkit-backdrop-filter: none;
158
+ backdrop-filter: none;
161
159
  }
162
160
  }
163
161
 
@@ -219,7 +217,7 @@
219
217
  /* Small follows its trigger down: an item's own hooks still win. */
220
218
 
221
219
  /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
222
- transparency, saturation and edge light belong to the surrounding decorative material. */
220
+ transparency, frosting and edge light belong to the surrounding decorative material. */
223
221
 
224
222
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
225
223
  }
@@ -72,12 +72,12 @@
72
72
  }
73
73
 
74
74
  /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
75
- transparency, saturation and edge light belong to the surrounding decorative material. */
75
+ transparency, frosting and edge light belong to the surrounding decorative material. */
76
76
  .surface {
77
- --_ui-material-glassiness: calc(clamp(0, var(--ui-glassiness, 0), 1) + 2 * pow(clamp(0, var(--ui-glassiness, 0), 1), 4));
77
+ --_ui-material-glassiness: clamp(0, var(--ui-glassiness, 0), 1);
78
78
  --_ui-material-separation: clamp(0, var(--ui-surface-separation, 0), 1);
79
- --_ui-material-active: clamp(0, calc((var(--_ui-material-glassiness) + var(--_ui-material-separation)) * 100000), 1);
80
- --_ui-material-rim: calc((var(--_ui-material-separation) + var(--_ui-material-glassiness) * 0.25) * var(--_ui-material-scale, 0.55) * 8px);
79
+ --_ui-material-active: clamp(0, calc(var(--_ui-material-separation) * 100000), 1);
80
+ --_ui-material-rim: calc(var(--_ui-material-separation) * var(--_ui-material-scale, 0.55) * 8px);
81
81
  --_ui-material-content-color: var(--_ui-popover-surface, var(--ui-material-content, var(--ui-overlay-surface, var(--ui-surface-elevated))));
82
82
  --_ui-material-rim-color: color-mix(in srgb, var(--ui-material-glass, var(--ui-surface-elevated)) calc(var(--_ui-material-active) * 100%), transparent);
83
83
  background:
@@ -102,10 +102,8 @@
102
102
  var(--ui-elevation-overlay, var(--ui-shadow-lg))
103
103
  )
104
104
  );
105
- backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 18px))
106
- saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 0.18));
107
- -webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 18px))
108
- saturate(calc(1 + var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 0.18));
105
+ -webkit-backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 32px));
106
+ backdrop-filter: blur(calc(var(--_ui-material-glassiness) * var(--_ui-material-scale, 0.55) * 32px));
109
107
  }
110
108
 
111
109
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
@@ -117,8 +115,8 @@
117
115
  @media (prefers-reduced-transparency: reduce) {
118
116
  .surface {
119
117
  background: var(--_ui-material-content-color);
120
- backdrop-filter: none;
121
118
  -webkit-backdrop-filter: none;
119
+ backdrop-filter: none;
122
120
  }
123
121
  }
124
122
 
@@ -127,8 +125,8 @@
127
125
  background: Canvas;
128
126
  border-color: CanvasText;
129
127
  box-shadow: none;
130
- backdrop-filter: none;
131
128
  -webkit-backdrop-filter: none;
129
+ backdrop-filter: none;
132
130
  }
133
131
  }
134
132
 
@@ -139,8 +137,8 @@
139
137
  border: 0;
140
138
  background: transparent;
141
139
  box-shadow: none;
142
- backdrop-filter: none;
143
140
  -webkit-backdrop-filter: none;
141
+ backdrop-filter: none;
144
142
  }
145
143
 
146
144
  :scope:where([data-component~="ui-popover"]):not([data-ui-popover-state~="internalOpen"]) {
@@ -199,7 +197,7 @@
199
197
  /* This component's hooks style the element they are set on, and never a nested one. */
200
198
 
201
199
  /* Purpose and measured size shape one shared separation lever. The content plane stays opaque;
202
- transparency, saturation and edge light belong to the surrounding decorative material. */
200
+ transparency, frosting and edge light belong to the surrounding decorative material. */
203
201
 
204
202
  @supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
205
203
  }
@@ -70,10 +70,40 @@
70
70
  inline-size: var(--_ui-radio-size, 1.125rem);
71
71
  block-size: var(--_ui-radio-size, 1.125rem);
72
72
  margin: max(0px, calc((1lh - var(--_ui-radio-size, 1.125rem)) / 2)) 0 0 !important;
73
- accent-color: var(--ui-accent-solid);
73
+ -webkit-appearance: none;
74
+ appearance: none;
75
+ position: relative;
76
+ border: var(--ui-border-width) solid var(--ui-control-border, var(--ui-border-strong));
77
+ border-radius: var(--ui-radius-round);
78
+ background-color: var(--ui-control-surface, var(--ui-surface-default));
79
+ background-image: var(--ui-surface-highlight, none);
80
+ box-shadow: var(--ui-control-inset);
74
81
  cursor: pointer;
75
82
  }
76
83
 
84
+ /* The native radio retains grouping, validation and keyboard behavior.
85
+ Its empty well recedes; the filled selection and its dot stay crisp. */
86
+ input:where(:not([data-component], [data-slotted]))::after {
87
+ content: "";
88
+ position: absolute;
89
+ inset: 28%;
90
+ border-radius: var(--ui-radius-round);
91
+ background-color: var(--ui-text-on-accent);
92
+ opacity: 0;
93
+ transition: opacity var(--ui-motion-fast) var(--ui-motion-ease);
94
+ }
95
+
96
+ input:checked {
97
+ background-color: var(--ui-accent-solid);
98
+ background-image: var(--ui-accent-highlight, none);
99
+ border-color: var(--ui-accent-solid);
100
+ box-shadow: none;
101
+ }
102
+
103
+ input:checked:where(:not([data-component], [data-slotted]))::after {
104
+ opacity: 1;
105
+ }
106
+
77
107
  input:focus-visible {
78
108
  outline: var(--ui-focus-width) solid var(--ui-focus-ring, var(--ui-accent-solid));
79
109
  outline-offset: var(--ui-focus-width);
@@ -87,9 +117,31 @@
87
117
  color: var(--ui-disabled-text);
88
118
  }
89
119
  :scope:where([data-component~="ui-radio"])[data-ui-radio-state~="disabled"] input {
120
+ border-color: var(--ui-disabled-border);
121
+ background-color: var(--ui-disabled-surface);
122
+ background-image: none;
123
+ box-shadow: none;
90
124
  cursor: not-allowed;
91
125
  }
92
126
 
127
+ :scope:where([data-component~="ui-radio"])[data-ui-radio-state~="disabled"] input:where(:not([data-component], [data-slotted]))::after {
128
+ background-color: var(--ui-disabled-text);
129
+ }
130
+
131
+ @media (prefers-reduced-motion: reduce) {
132
+ input:where(:not([data-component], [data-slotted]))::after { transition: none; }
133
+ }
134
+
135
+ @media (forced-colors: active) {
136
+ input {
137
+ -webkit-appearance: auto;
138
+ appearance: auto;
139
+ background: none;
140
+ box-shadow: none;
141
+ }
142
+ input:where(:not([data-component], [data-slotted]))::after { display: none !important; }
143
+ }
144
+
93
145
  /* A sized choice keeps its box and aligns instead: the label takes that size's field type size,
94
146
  and the first line centres in that control height, so the label shares a row's baseline.
95
147
  Multi-line labels and descriptions still grow downward from that first line. */
@@ -120,6 +172,15 @@
120
172
 
121
173
  /* The label, and under it an optional line saying what the choice means. */
122
174
 
175
+ /* The native radio retains grouping, validation and keyboard behavior.
176
+ Its empty well recedes; the filled selection and its dot stay crisp. */
177
+
178
+ @media (prefers-reduced-motion: reduce) {
179
+ }
180
+
181
+ @media (forced-colors: active) {
182
+ }
183
+
123
184
  /* A sized choice keeps its box and aligns instead: the label takes that size's field type size,
124
185
  and the first line centres in that control height, so the label shares a row's baseline.
125
186
  Multi-line labels and descriptions still grow downward from that first line. */
@@ -75,7 +75,7 @@
75
75
  }
76
76
 
77
77
  :scope:where([data-component~="ui-section"])[data-ui-section-state~="tone=danger"] .heading {
78
- color: var(--ui-danger);
78
+ color: var(--ui-danger-subtle-text);
79
79
  }
80
80
 
81
81
  .description {
@@ -39,6 +39,7 @@
39
39
  align-items: center !important;
40
40
  align-content: center !important;
41
41
  gap: var(--ui-space-2) !important;
42
+ inline-size: 100%;
42
43
  min-inline-size: 0;
43
44
  min-block-size: var(--ui-site-header-compact-height, 3.75rem);
44
45
  padding: var(--ui-space-2) var(--ui-site-header-padding-inline, var(--ui-space-4)) !important;
@@ -60,13 +61,16 @@
60
61
  max-inline-size: 100%;
61
62
  }
62
63
  .actions {
63
- flex-wrap: wrap !important;
64
+ display: grid !important;
65
+ grid-auto-flow: column !important;
66
+ grid-auto-columns: minmax(max-content, var(--ui-control-min-block-size)) !important;
67
+ justify-items: center !important;
64
68
  margin-inline-start: auto !important;
65
69
  }
66
70
  /* Text shares a baseline inside one group; the group is centred beside any control height. */
67
71
  .identity {
68
72
  display: flex !important;
69
- flex: 1 1 auto;
73
+ flex: 1 1 0;
70
74
  flex-wrap: wrap !important;
71
75
  align-items: baseline !important;
72
76
  gap: var(--ui-space-2) var(--ui-space-6) !important;
@@ -21,7 +21,7 @@
21
21
  }
22
22
 
23
23
  :scope:where([data-component~="ui-status-message"])[data-ui-status-message-state~="kind=error"] {
24
- color: var(--ui-danger);
24
+ color: var(--ui-danger-subtle-text);
25
25
  }
26
26
 
27
27
  :scope:where([data-component~="ui-status-message"])[data-ui-status-message-state~="layout=panel"] {