@usefragments/ui 1.3.3 → 1.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 (152) hide show
  1. package/dist/assets/ui.css +1212 -798
  2. package/dist/chart.cjs +60 -24
  3. package/dist/chart.js +38 -24
  4. package/dist/colorpicker.cjs +56 -9
  5. package/dist/colorpicker.js +34 -9
  6. package/dist/components/Badge/Badge.module.scss.cjs +23 -16
  7. package/dist/components/Badge/Badge.module.scss.js +23 -16
  8. package/dist/components/Badge/index.cjs +8 -1
  9. package/dist/components/Badge/index.d.ts +3 -0
  10. package/dist/components/Badge/index.d.ts.map +1 -1
  11. package/dist/components/Badge/index.js +8 -1
  12. package/dist/components/Button/Button.module.scss.cjs +16 -13
  13. package/dist/components/Button/Button.module.scss.js +16 -13
  14. package/dist/components/Button/index.d.ts +2 -1
  15. package/dist/components/Button/index.d.ts.map +1 -1
  16. package/dist/components/Card/index.cjs +2 -2
  17. package/dist/components/Card/index.d.ts +4 -1
  18. package/dist/components/Card/index.d.ts.map +1 -1
  19. package/dist/components/Card/index.js +2 -2
  20. package/dist/components/Chart/index.d.ts +3 -0
  21. package/dist/components/Chart/index.d.ts.map +1 -1
  22. package/dist/components/CodeBlock/CodeBlock.module.scss.cjs +21 -21
  23. package/dist/components/CodeBlock/CodeBlock.module.scss.js +21 -21
  24. package/dist/components/ColorPicker/index.d.ts +4 -0
  25. package/dist/components/ColorPicker/index.d.ts.map +1 -1
  26. package/dist/components/Combobox/Combobox.module.scss.cjs +23 -23
  27. package/dist/components/Combobox/Combobox.module.scss.js +23 -23
  28. package/dist/components/Command/Command.module.scss.cjs +11 -11
  29. package/dist/components/Command/Command.module.scss.js +11 -11
  30. package/dist/components/ConversationList/ConversationList.module.scss.cjs +13 -10
  31. package/dist/components/ConversationList/ConversationList.module.scss.js +14 -11
  32. package/dist/components/ConversationList/index.cjs +26 -22
  33. package/dist/components/ConversationList/index.d.ts +5 -1
  34. package/dist/components/ConversationList/index.d.ts.map +1 -1
  35. package/dist/components/ConversationList/index.js +27 -23
  36. package/dist/components/DataTable/index.d.ts +4 -1
  37. package/dist/components/DataTable/index.d.ts.map +1 -1
  38. package/dist/components/DatePicker/index.d.ts +3 -0
  39. package/dist/components/DatePicker/index.d.ts.map +1 -1
  40. package/dist/components/Editor/index.d.ts +4 -1
  41. package/dist/components/Editor/index.d.ts.map +1 -1
  42. package/dist/components/Listbox/Listbox.module.scss.cjs +8 -8
  43. package/dist/components/Listbox/Listbox.module.scss.js +8 -8
  44. package/dist/components/Markdown/Markdown.module.scss.cjs +1 -1
  45. package/dist/components/Markdown/Markdown.module.scss.js +1 -1
  46. package/dist/components/Markdown/index.d.ts +16 -0
  47. package/dist/components/Markdown/index.d.ts.map +1 -1
  48. package/dist/components/Menu/Menu.module.scss.cjs +14 -14
  49. package/dist/components/Menu/Menu.module.scss.js +14 -14
  50. package/dist/components/Message/Message.module.scss.cjs +23 -20
  51. package/dist/components/Message/Message.module.scss.js +24 -21
  52. package/dist/components/Message/index.cjs +5 -1
  53. package/dist/components/Message/index.d.ts.map +1 -1
  54. package/dist/components/Message/index.js +5 -1
  55. package/dist/components/NavigationMenu/NavigationMenu.module.scss.cjs +28 -28
  56. package/dist/components/NavigationMenu/NavigationMenu.module.scss.js +28 -28
  57. package/dist/components/Pagination/Pagination.module.scss.cjs +7 -7
  58. package/dist/components/Pagination/Pagination.module.scss.js +7 -7
  59. package/dist/components/Progress/Progress.module.scss.cjs +28 -25
  60. package/dist/components/Progress/Progress.module.scss.js +28 -25
  61. package/dist/components/Progress/index.cjs +3 -0
  62. package/dist/components/Progress/index.d.ts +8 -8
  63. package/dist/components/Progress/index.d.ts.map +1 -1
  64. package/dist/components/Progress/index.js +3 -0
  65. package/dist/components/Prompt/Prompt.module.scss.cjs +52 -22
  66. package/dist/components/Prompt/Prompt.module.scss.js +52 -22
  67. package/dist/components/Prompt/index.cjs +197 -2
  68. package/dist/components/Prompt/index.d.ts +98 -3
  69. package/dist/components/Prompt/index.d.ts.map +1 -1
  70. package/dist/components/Prompt/index.js +198 -3
  71. package/dist/components/Select/Select.module.scss.cjs +29 -17
  72. package/dist/components/Select/Select.module.scss.js +30 -18
  73. package/dist/components/Select/index.cjs +45 -8
  74. package/dist/components/Select/index.d.ts +17 -2
  75. package/dist/components/Select/index.d.ts.map +1 -1
  76. package/dist/components/Select/index.js +45 -8
  77. package/dist/components/Sidebar/Sidebar.module.scss.cjs +45 -42
  78. package/dist/components/Sidebar/Sidebar.module.scss.js +45 -42
  79. package/dist/components/Sidebar/index.cjs +2 -0
  80. package/dist/components/Sidebar/index.d.ts +6 -1
  81. package/dist/components/Sidebar/index.d.ts.map +1 -1
  82. package/dist/components/Sidebar/index.js +2 -0
  83. package/dist/components/Text/Text.module.scss.cjs +63 -51
  84. package/dist/components/Text/Text.module.scss.js +63 -51
  85. package/dist/components/Text/index.d.ts +4 -2
  86. package/dist/components/Text/index.d.ts.map +1 -1
  87. package/dist/data-table.cjs +210 -28
  88. package/dist/data-table.js +189 -29
  89. package/dist/datepicker.cjs +63 -14
  90. package/dist/datepicker.js +41 -14
  91. package/dist/editor.cjs +67 -16
  92. package/dist/editor.js +45 -16
  93. package/dist/index.cjs +1 -0
  94. package/dist/index.d.ts +1 -1
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +2 -1
  97. package/dist/markdown.cjs +63 -19
  98. package/dist/markdown.js +41 -19
  99. package/fragments.json +1 -1
  100. package/package.json +2 -2
  101. package/src/components/Badge/Badge.contract.json +28 -5
  102. package/src/components/Badge/Badge.module.scss +21 -0
  103. package/src/components/Badge/index.tsx +10 -1
  104. package/src/components/Button/Button.contract.json +9 -3
  105. package/src/components/Button/Button.module.scss +34 -0
  106. package/src/components/Button/index.tsx +11 -1
  107. package/src/components/Card/Card.contract.json +5 -0
  108. package/src/components/Card/index.tsx +6 -3
  109. package/src/components/Chart/Chart.contract.json +7 -0
  110. package/src/components/Chart/index.tsx +44 -27
  111. package/src/components/CodeBlock/CodeBlock.contract.json +7 -0
  112. package/src/components/CodeBlock/CodeBlock.module.scss +7 -2
  113. package/src/components/ColorPicker/ColorPicker.contract.json +9 -1
  114. package/src/components/ColorPicker/index.tsx +42 -12
  115. package/src/components/Combobox/Combobox.module.scss +4 -13
  116. package/src/components/ConversationList/ConversationList.contract.json +16 -1
  117. package/src/components/ConversationList/ConversationList.module.scss +12 -0
  118. package/src/components/ConversationList/index.tsx +40 -26
  119. package/src/components/DataTable/DataTable.contract.json +8 -1
  120. package/src/components/DataTable/index.tsx +282 -51
  121. package/src/components/DatePicker/DatePicker.contract.json +8 -1
  122. package/src/components/DatePicker/index.tsx +51 -22
  123. package/src/components/Editor/Editor.contract.json +19 -1
  124. package/src/components/Editor/index.tsx +67 -23
  125. package/src/components/Listbox/Listbox.module.scss +3 -11
  126. package/src/components/Markdown/Markdown.contract.json +15 -1
  127. package/src/components/Markdown/Markdown.module.scss +18 -1
  128. package/src/components/Markdown/index.tsx +58 -24
  129. package/src/components/Menu/Menu.module.scss +12 -2
  130. package/src/components/Message/Message.contract.json +3 -0
  131. package/src/components/Message/Message.module.scss +33 -4
  132. package/src/components/Message/index.tsx +7 -1
  133. package/src/components/Pagination/Pagination.contract.json +1 -0
  134. package/src/components/Pagination/Pagination.module.scss +5 -4
  135. package/src/components/Progress/Progress.contract.json +9 -27
  136. package/src/components/Progress/Progress.module.scss +5 -1
  137. package/src/components/Progress/index.tsx +56 -62
  138. package/src/components/Prompt/Prompt.contract.json +40 -1
  139. package/src/components/Prompt/Prompt.module.scss +351 -4
  140. package/src/components/Prompt/index.tsx +324 -0
  141. package/src/components/Select/Select.contract.json +11 -1
  142. package/src/components/Select/Select.module.scss +80 -13
  143. package/src/components/Select/index.tsx +73 -7
  144. package/src/components/Sidebar/Sidebar.contract.json +1 -0
  145. package/src/components/Sidebar/Sidebar.module.scss +10 -0
  146. package/src/components/Sidebar/index.tsx +7 -0
  147. package/src/components/Text/Text.contract.json +7 -4
  148. package/src/components/Text/Text.module.scss +18 -0
  149. package/src/components/Text/index.tsx +4 -2
  150. package/src/index.ts +1 -0
  151. package/src/tokens/_mixins.scss +39 -4
  152. package/src/tokens/_variables.scss +30 -0
@@ -113,6 +113,198 @@
113
113
  transform: translateX(-50%);
114
114
  }
115
115
 
116
+ // ============================================
117
+ // Seamless appearance
118
+ // ============================================
119
+
120
+ // One continuous writing surface instead of a field with a footer.
121
+ //
122
+ // The whole point is that nothing inside the card announces itself: no rule
123
+ // under the toolbar, no stroke around the edge, no animated border. What is
124
+ // left is a single quiet sheet, lighter than the page, with the controls
125
+ // resting on it — which is what makes the text you are writing the only thing
126
+ // with any weight. Each selector below is one class deeper than the rule it
127
+ // replaces, so this wins wherever the stylesheet happens to land.
128
+ //
129
+ // One gutter runs down the card. `--_gutter` is the distance from the card's
130
+ // edge to the ink of everything in it, and every child is padded from it
131
+ // rather than given a number of its own, so the placeholder, the first glyph
132
+ // in the toolbar and any attachment chip all sit on the same line.
133
+ .seamless {
134
+ --_gutter: var(--fui-space-3, #{$fui-space-3});
135
+ // Every band is inset by its own children's padding, so what lands on the
136
+ // gutter is the ink — the first character of the placeholder, the first glyph
137
+ // in the toolbar, the first pixel of a thumbnail — and not the invisible box
138
+ // around it. Controls and chips carry different padding, so each band
139
+ // subtracts its own.
140
+ --_control-padding: var(--fui-space-2, #{$fui-space-2});
141
+ --_chip-padding: var(--fui-space-1, #{$fui-space-1});
142
+
143
+ // Composer controls are compact, but still need enough visual weight to read
144
+ // as one deliberate toolbar. The xs button token is the dense 32px control
145
+ // height in every density preset; scoping all three inputs to it keeps
146
+ // selects, attach, action and submit controls on one optical grid without a
147
+ // one-off dimension.
148
+ --fui-target-size-min: var(--fui-button-height-xs, #{$fui-button-height-xs});
149
+ --fui-button-height-sm: var(--fui-button-height-xs, #{$fui-button-height-xs});
150
+ --fui-input-height-sm: var(--fui-button-height-xs, #{$fui-button-height-xs});
151
+
152
+ border-color: transparent;
153
+ border-radius: var(--fui-radius-xl, $fui-radius-xl);
154
+
155
+ // The beam draws a 1px animated border by painting a gradient and masking
156
+ // out everything but the edge. Seamless has no edge to draw, so both layers
157
+ // go and the card paints its own surface instead of borrowing the mask's.
158
+ &::before,
159
+ &::after {
160
+ display: none;
161
+ }
162
+
163
+ // Focus lives in the caret and in the fact that the surface is the thing you
164
+ // are typing on. A ring here would be the loudest object on the page.
165
+ &:focus-within {
166
+ border-color: transparent;
167
+ }
168
+
169
+ .toolbar {
170
+ background-color: transparent;
171
+ border-top: none;
172
+ padding: 0 calc(var(--_gutter) - var(--_control-padding)) var(--_gutter);
173
+ }
174
+
175
+ // The message is the content of the card, not a field in it. The bottom is
176
+ // tight because the toolbar below is part of the same surface rather than a
177
+ // footer under it, and the top is tight for the same reason when a scope
178
+ // band sits above.
179
+ .textarea {
180
+ padding: var(--_gutter) var(--_gutter) var(--fui-space-1, $fui-space-1);
181
+ }
182
+
183
+ .attachments {
184
+ padding: var(--_gutter) calc(var(--_gutter) - var(--_chip-padding)) 0;
185
+ gap: var(--fui-space-1, $fui-space-1);
186
+ }
187
+
188
+ // Two bands in a row would otherwise stack their gutters into a gap twice
189
+ // the size of the one at the card's edge.
190
+ .attachments + .textarea,
191
+ .tabs + .attachments {
192
+ padding-top: var(--fui-space-1, $fui-space-1);
193
+ }
194
+
195
+ // In a panel the tabs are a strip the card is docked to, so they are centred
196
+ // and bordered like a folder tab. Seamless has no card edge for them to dock
197
+ // against, so they become the top band of the one surface: left-aligned on
198
+ // the gutter with the rest of it, and stripped of the chrome that only made
199
+ // sense as an edge.
200
+ .tabs {
201
+ margin-bottom: 0;
202
+ justify-content: flex-start;
203
+ padding: var(--_gutter) calc(var(--_gutter) - var(--_control-padding)) 0;
204
+ }
205
+
206
+ .tabsInner {
207
+ background-color: transparent;
208
+ border: none;
209
+ border-radius: 0;
210
+ padding: 0;
211
+ gap: var(--fui-space-1, $fui-space-1);
212
+ }
213
+
214
+ // The band above already sets the top of the card, so the message starts
215
+ // from the tighter of the two spacings rather than adding a second gutter.
216
+ .tabs + .textarea {
217
+ padding-top: var(--fui-space-1, $fui-space-1);
218
+ }
219
+
220
+ // A centred glyph in a square box puts its ink half a box in from the
221
+ // gutter, which reads as the one thing in the card that is out of line.
222
+ // Giving it the same inline padding as its neighbours puts the glyph where
223
+ // the placeholder above it starts, and costs only a wider hover.
224
+ .attach {
225
+ width: auto;
226
+ padding-inline: var(--_control-padding);
227
+
228
+ svg {
229
+ width: var(--fui-icon-md, $fui-icon-md);
230
+ height: var(--fui-icon-md, $fui-icon-md);
231
+ }
232
+ }
233
+
234
+ // Labels and glyphs share the body scale inside a seamless composer. The
235
+ // trigger still truncates at its cap, but no longer looks like caption text
236
+ // floating between larger attach and submit affordances.
237
+ .select,
238
+ .modeButton {
239
+ font-size: var(--fui-font-size-sm, $fui-font-size-sm);
240
+ }
241
+
242
+ .select {
243
+ svg {
244
+ width: var(--fui-icon-md, $fui-icon-md);
245
+ height: var(--fui-icon-md, $fui-icon-md);
246
+ }
247
+ }
248
+
249
+ // These are settings on the message, not a row of buttons. Preserve their
250
+ // full target boxes for hit testing, but keep those boxes visually absent.
251
+ // Send remains the only persistent shape in the composer.
252
+ .select,
253
+ .attach,
254
+ .modeButton {
255
+ &:hover:not(:disabled):not([data-disabled]),
256
+ &:active:not(:disabled):not([data-disabled]) {
257
+ background-color: transparent;
258
+ color: var(--fui-text-primary, $fui-text-primary);
259
+ }
260
+
261
+ // Keyboard focus still needs a visible location, but a restrained baseline
262
+ // reads as focus on inline content rather than another rounded button.
263
+ &:focus-visible {
264
+ outline: none;
265
+ box-shadow: inset 0 calc(var(--fui-space-px, #{$fui-space-px}) * -2) 0
266
+ var(--fui-text-primary, #{$fui-text-primary});
267
+ }
268
+ }
269
+
270
+ .select {
271
+ // Opening a menu identifies the active choice through its popup and text
272
+ // color. A held surface behind the trigger is unnecessary visual chrome.
273
+ &[data-popup-open] {
274
+ border-color: transparent;
275
+ background-color: transparent;
276
+ box-shadow: none;
277
+ color: var(--fui-text-primary, $fui-text-primary);
278
+ }
279
+
280
+ // Pointer focus must not inherit the field shell's accent treatment.
281
+ &:focus:not(:focus-visible) {
282
+ border-color: transparent;
283
+ box-shadow: none;
284
+ }
285
+ }
286
+
287
+ // Round affordances track the scoped target size rather than the 2rem they
288
+ // are given for a form.
289
+ .submit,
290
+ .actionButton {
291
+ width: var(--fui-target-size-min);
292
+ height: var(--fui-target-size-min);
293
+
294
+ svg {
295
+ width: var(--fui-icon-md, $fui-icon-md);
296
+ height: var(--fui-icon-md, $fui-icon-md);
297
+ }
298
+ }
299
+
300
+ // Attach's glyph reaches the leading ink gutter through its own control
301
+ // padding. Give the filled Submit shape the same inset at the trailing edge
302
+ // so the two visible affordances balance across the toolbar.
303
+ .submit {
304
+ margin-inline-end: var(--_control-padding);
305
+ }
306
+ }
307
+
116
308
  // ============================================
117
309
  // Textarea
118
310
  // ============================================
@@ -292,6 +484,159 @@
292
484
  background-color: var(--fui-bg-tertiary, $fui-bg-tertiary);
293
485
  }
294
486
 
487
+ // ============================================
488
+ // Attach (bare icon control)
489
+ // ============================================
490
+
491
+ // A `+` with nothing around it. ActionButton is a filled circle, which is the
492
+ // right weight for a primary affordance in the bar; attaching a file is not
493
+ // one — it should be findable and otherwise silent, so this is the mode button
494
+ // with a square footprint and no label.
495
+ .attach {
496
+ @include button-reset;
497
+ @include interactive-base;
498
+
499
+ display: flex;
500
+ align-items: center;
501
+ justify-content: center;
502
+ flex-shrink: 0;
503
+ // The target size rather than a spacing step, so it tracks whatever scale
504
+ // the surface around it has established.
505
+ width: var(--fui-target-size-min, $fui-target-size-min);
506
+ height: var(--fui-target-size-min, $fui-target-size-min);
507
+ border-radius: var(--fui-radius-md, $fui-radius-md);
508
+ background-color: transparent;
509
+ color: var(--fui-text-secondary, $fui-text-secondary);
510
+
511
+ &:hover:not(:disabled) {
512
+ background-color: var(--fui-bg-hover, $fui-bg-hover);
513
+ color: var(--fui-text-primary, $fui-text-primary);
514
+ }
515
+
516
+ &:active:not(:disabled) {
517
+ background-color: var(--fui-bg-active, $fui-bg-active);
518
+ }
519
+
520
+ &:disabled {
521
+ opacity: 0.5;
522
+ cursor: not-allowed;
523
+ }
524
+
525
+ svg {
526
+ width: var(--fui-icon-sm, $fui-icon-sm);
527
+ height: var(--fui-icon-sm, $fui-icon-sm);
528
+ }
529
+ }
530
+
531
+ // ============================================
532
+ // Attachments strip
533
+ // ============================================
534
+
535
+ .attachments {
536
+ display: flex;
537
+ flex-wrap: wrap;
538
+ gap: var(--fui-space-1, $fui-space-1);
539
+ margin: 0;
540
+ padding: var(--fui-space-2, $fui-space-2) var(--fui-space-3, $fui-space-3) 0;
541
+ list-style: none;
542
+ }
543
+
544
+ // What is attached, stated once and removable. Sits above the message rather
545
+ // than below the toolbar, because it is part of what you are sending, not a
546
+ // setting on the sending.
547
+ // Sized off the same target as everything else in the bar, so a chip and a
548
+ // control are the same height and the card has one horizontal rhythm.
549
+ .attachment {
550
+ --_chip-height: var(--fui-target-size-min, #{$fui-target-size-min});
551
+
552
+ display: inline-flex;
553
+ align-items: center;
554
+ gap: var(--fui-space-1, $fui-space-1);
555
+ height: var(--_chip-height);
556
+ max-width: 15rem;
557
+ padding-inline: var(--fui-space-1, $fui-space-1);
558
+ // Outlined rather than filled. A chip sits on whatever surface the prompt is
559
+ // using, and on an elevated card the raised fill is the same value as the
560
+ // card itself — so the object would disappear exactly where it is most
561
+ // likely to be used. An edge reads on any of them.
562
+ border: 1px solid var(--fui-border, $fui-border);
563
+ border-radius: var(--fui-radius-md, $fui-radius-md);
564
+ background-color: var(--fui-bg-tertiary, $fui-bg-tertiary);
565
+ font-size: var(--fui-font-size-xs, $fui-font-size-xs);
566
+ color: var(--fui-text-secondary, $fui-text-secondary);
567
+ }
568
+
569
+ // A screenshot is recognised by its picture, not by "Screenshot 2026-07-24 at
570
+ // 22.06.09.png", so an image attachment leads with a thumbnail. It fills the
571
+ // chip's height less the padding, which keeps it square without a second
572
+ // number to keep in step.
573
+ .attachmentThumb {
574
+ width: calc(var(--_chip-height) - var(--fui-space-1, #{$fui-space-1}));
575
+ height: calc(var(--_chip-height) - var(--fui-space-1, #{$fui-space-1}));
576
+ flex-shrink: 0;
577
+ border-radius: var(--fui-radius-sm, $fui-radius-sm);
578
+ object-fit: cover;
579
+ }
580
+
581
+ // The name is the only part worth the width, so it is the only part that grows
582
+ // — and the only part that gives way when there is none.
583
+ .attachmentName {
584
+ flex: 1;
585
+ min-width: 0;
586
+ overflow: hidden;
587
+ text-overflow: ellipsis;
588
+ white-space: nowrap;
589
+ }
590
+
591
+ .attachmentSize {
592
+ flex-shrink: 0;
593
+ color: var(--fui-text-tertiary, $fui-text-tertiary);
594
+ font-variant-numeric: tabular-nums;
595
+ }
596
+
597
+ .attachmentRemove {
598
+ @include button-reset;
599
+ @include interactive-base;
600
+
601
+ display: flex;
602
+ align-items: center;
603
+ justify-content: center;
604
+ flex-shrink: 0;
605
+ width: calc(var(--_chip-height) - var(--fui-space-1, #{$fui-space-1}));
606
+ height: calc(var(--_chip-height) - var(--fui-space-1, #{$fui-space-1}));
607
+ border-radius: var(--fui-radius-sm, $fui-radius-sm);
608
+ background-color: transparent;
609
+ color: var(--fui-text-tertiary, $fui-text-tertiary);
610
+
611
+ &:hover {
612
+ background-color: var(--fui-bg-hover, $fui-bg-hover);
613
+ color: var(--fui-text-primary, $fui-text-primary);
614
+ }
615
+
616
+ svg {
617
+ width: var(--fui-icon-xs, $fui-icon-xs);
618
+ height: var(--fui-icon-xs, $fui-icon-xs);
619
+ }
620
+ }
621
+
622
+ // Dropping a file anywhere on the card counts. The whole surface lights rather
623
+ // than a dashed rectangle appearing inside it, because the target is the
624
+ // composer, not some region of it.
625
+ .dragging {
626
+ background-color: var(--fui-bg-hover, $fui-bg-hover);
627
+ }
628
+
629
+ // ============================================
630
+ // Select (ghost Select, sized for the toolbar)
631
+ // ============================================
632
+
633
+ // The chosen value can be arbitrarily long — a model name, a file path — and
634
+ // must not push the submit button off the row. Select's ghost trigger already
635
+ // allows shrinking and ellipsises its value; this only caps how far it grows.
636
+ .select {
637
+ max-width: 15rem;
638
+ }
639
+
295
640
  // ============================================
296
641
  // Usage indicator
297
642
  // ============================================
@@ -315,15 +660,17 @@
315
660
  width: 2rem;
316
661
  height: 2rem;
317
662
  border-radius: var(--fui-radius-full, $fui-radius-full);
318
- background-color: var(--fui-color-accent, $fui-color-accent);
319
- color: var(--fui-color-on-accent, $fui-color-on-accent);
663
+ // A neutral inverse keeps send visibly primary without spending the product
664
+ // accent, which may already encode agent state.
665
+ background-color: var(--fui-text-primary, #{$fui-text-primary});
666
+ color: var(--fui-bg-elevated, #{$fui-bg-elevated});
320
667
 
321
668
  &:hover:not(:disabled) {
322
- background-color: var(--fui-color-accent-hover, $fui-color-accent-hover);
669
+ background-color: var(--fui-text-secondary, #{$fui-text-secondary});
323
670
  }
324
671
 
325
672
  &:active:not(:disabled) {
326
- background-color: var(--fui-color-accent-active, $fui-color-accent-active);
673
+ background-color: var(--fui-text-tertiary, #{$fui-text-tertiary});
327
674
  }
328
675
 
329
676
  &:disabled {