@crisp-ui-kit/crisp 0.56.0 → 0.57.1

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 (139) hide show
  1. package/dist/accentpicker.css +5 -0
  2. package/dist/accentpicker.d.ts +7 -0
  3. package/dist/accentpicker.layered.css +7 -0
  4. package/dist/avatar.css +1 -1
  5. package/dist/avatar.layered.css +1 -1
  6. package/dist/badge.css +2 -2
  7. package/dist/badge.layered.css +2 -2
  8. package/dist/button.css +3 -3
  9. package/dist/button.layered.css +3 -3
  10. package/dist/callout.css +6 -0
  11. package/dist/callout.d.ts +2 -2
  12. package/dist/callout.layered.css +6 -0
  13. package/dist/cjs/components/accentpicker/accentpicker.js +66 -0
  14. package/dist/cjs/components/accentpicker/accentpicker.recipe.js +25 -0
  15. package/dist/cjs/components/accentpicker/index.js +7 -0
  16. package/dist/cjs/components/avatar/avatar.recipe.js +4 -1
  17. package/dist/cjs/components/badge/badge.recipe.js +16 -2
  18. package/dist/cjs/components/button/button.recipe.js +16 -6
  19. package/dist/cjs/components/callout/callout.js +2 -2
  20. package/dist/cjs/components/callout/callout.recipe.js +15 -2
  21. package/dist/cjs/components/input/input.js +2 -2
  22. package/dist/cjs/components/input/input.recipe.js +14 -0
  23. package/dist/cjs/components/menu/menu.js +2 -2
  24. package/dist/cjs/components/menu/menu.recipe.js +8 -0
  25. package/dist/cjs/components/multiselect/multiselect.js +23 -10
  26. package/dist/cjs/components/multiselect/multiselect.recipe.js +104 -65
  27. package/dist/cjs/components/progress/progress.js +21 -4
  28. package/dist/cjs/components/progress/progress.recipe.js +30 -0
  29. package/dist/cjs/components/select/listbox-keyboard.js +7 -1
  30. package/dist/cjs/components/select/select.js +24 -11
  31. package/dist/cjs/components/select/select.recipe.js +177 -78
  32. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +3 -3
  33. package/dist/cjs/components/tabletoolbar/tabletoolbar.recipe.js +26 -1
  34. package/dist/cjs/components/tabs/tabs.js +63 -4
  35. package/dist/cjs/components/tabs/tabs.recipe.js +13 -0
  36. package/dist/cjs/components/text/text.recipe.js +8 -7
  37. package/dist/cjs/components/textarea/textarea.js +3 -2
  38. package/dist/cjs/components/textarea/textarea.recipe.js +2 -1
  39. package/dist/cjs/components/textlink/textlink.js +2 -2
  40. package/dist/cjs/components/textlink/textlink.recipe.js +24 -3
  41. package/dist/cjs/index.js +1 -0
  42. package/dist/cjs/product/recordpage/recordpage.js +61 -7
  43. package/dist/cjs/tokens/elevation.js +7 -0
  44. package/dist/cjs/tokens/palette.js +120 -25
  45. package/dist/cjs/tokens/scale.js +9 -0
  46. package/dist/cjs/tokens/semantic.js +42 -0
  47. package/dist/esm/components/accentpicker/accentpicker.js +30 -0
  48. package/dist/esm/components/accentpicker/accentpicker.recipe.js +22 -0
  49. package/dist/esm/components/accentpicker/index.js +2 -0
  50. package/dist/esm/components/avatar/avatar.recipe.js +4 -1
  51. package/dist/esm/components/badge/badge.recipe.js +16 -2
  52. package/dist/esm/components/button/button.recipe.js +16 -6
  53. package/dist/esm/components/callout/callout.js +2 -2
  54. package/dist/esm/components/callout/callout.recipe.js +15 -2
  55. package/dist/esm/components/input/input.js +3 -3
  56. package/dist/esm/components/input/input.recipe.js +14 -0
  57. package/dist/esm/components/menu/menu.js +2 -2
  58. package/dist/esm/components/menu/menu.recipe.js +8 -0
  59. package/dist/esm/components/multiselect/multiselect.js +23 -10
  60. package/dist/esm/components/multiselect/multiselect.recipe.js +104 -65
  61. package/dist/esm/components/progress/progress.js +22 -5
  62. package/dist/esm/components/progress/progress.recipe.js +30 -0
  63. package/dist/esm/components/select/listbox-keyboard.js +7 -1
  64. package/dist/esm/components/select/select.js +24 -11
  65. package/dist/esm/components/select/select.recipe.js +177 -78
  66. package/dist/esm/components/tabletoolbar/tabletoolbar.js +3 -3
  67. package/dist/esm/components/tabletoolbar/tabletoolbar.recipe.js +26 -1
  68. package/dist/esm/components/tabs/tabs.js +63 -4
  69. package/dist/esm/components/tabs/tabs.recipe.js +13 -0
  70. package/dist/esm/components/text/text.recipe.js +8 -7
  71. package/dist/esm/components/textarea/textarea.js +3 -2
  72. package/dist/esm/components/textarea/textarea.recipe.js +2 -1
  73. package/dist/esm/components/textlink/textlink.js +2 -2
  74. package/dist/esm/components/textlink/textlink.recipe.js +24 -3
  75. package/dist/esm/index.js +1 -0
  76. package/dist/esm/product/recordpage/recordpage.js +62 -8
  77. package/dist/esm/tokens/elevation.js +7 -0
  78. package/dist/esm/tokens/palette.js +120 -25
  79. package/dist/esm/tokens/scale.js +9 -0
  80. package/dist/esm/tokens/semantic.js +42 -0
  81. package/dist/input.css +11 -0
  82. package/dist/input.d.ts +2 -2
  83. package/dist/input.layered.css +11 -0
  84. package/dist/menu.css +8 -0
  85. package/dist/menu.layered.css +8 -0
  86. package/dist/multiselect.css +57 -29
  87. package/dist/multiselect.d.ts +3 -1
  88. package/dist/multiselect.layered.css +57 -29
  89. package/dist/native/tokens.d.ts +1 -1
  90. package/dist/native/tokens.js +82 -28
  91. package/dist/progress.css +3 -0
  92. package/dist/progress.layered.css +3 -0
  93. package/dist/select.css +100 -42
  94. package/dist/select.d.ts +3 -2
  95. package/dist/select.layered.css +100 -42
  96. package/dist/styles.css +268 -93
  97. package/dist/styles.layered.css +268 -93
  98. package/dist/tabletoolbar.css +8 -1
  99. package/dist/tabletoolbar.layered.css +8 -1
  100. package/dist/tabs.css +6 -0
  101. package/dist/tabs.layered.css +6 -0
  102. package/dist/text.css +1 -1
  103. package/dist/text.layered.css +1 -1
  104. package/dist/textarea.css +2 -1
  105. package/dist/textarea.layered.css +2 -1
  106. package/dist/textlink.css +11 -2
  107. package/dist/textlink.d.ts +2 -1
  108. package/dist/textlink.layered.css +11 -2
  109. package/dist/tokens.css +43 -11
  110. package/dist/tokens.json +82 -28
  111. package/dist/types/components/accentpicker/accentpicker.d.ts +23 -0
  112. package/dist/types/components/accentpicker/accentpicker.recipe.d.ts +3 -0
  113. package/dist/types/components/accentpicker/index.d.ts +2 -0
  114. package/dist/types/components/button/button.recipe.d.ts +2 -2
  115. package/dist/types/components/callout/callout.d.ts +9 -1
  116. package/dist/types/components/callout/callout.recipe.d.ts +12 -2
  117. package/dist/types/components/input/input.d.ts +14 -0
  118. package/dist/types/components/input/input.recipe.d.ts +3 -0
  119. package/dist/types/components/menu/menu.d.ts +7 -1
  120. package/dist/types/components/multiselect/multiselect.d.ts +25 -6
  121. package/dist/types/components/multiselect/multiselect.recipe.d.ts +27 -0
  122. package/dist/types/components/progress/progress.d.ts +16 -4
  123. package/dist/types/components/progress/progress.recipe.d.ts +22 -0
  124. package/dist/types/components/select/listbox-keyboard.d.ts +10 -1
  125. package/dist/types/components/select/select.d.ts +29 -6
  126. package/dist/types/components/select/select.recipe.d.ts +25 -10
  127. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +14 -0
  128. package/dist/types/components/tabs/tabs.d.ts +9 -1
  129. package/dist/types/components/textarea/textarea.d.ts +16 -0
  130. package/dist/types/components/textlink/textlink.d.ts +8 -1
  131. package/dist/types/components/textlink/textlink.recipe.d.ts +10 -0
  132. package/dist/types/index.d.ts +1 -0
  133. package/dist/types/product/recordpage/recordpage.d.ts +61 -1
  134. package/dist/types/tokens/contract.d.ts +16 -3
  135. package/dist/types/tokens/elevation.d.ts +7 -0
  136. package/dist/types/tokens/palette.d.ts +55 -11
  137. package/dist/types/tokens/scale.d.ts +6 -0
  138. package/dist/types/tokens/semantic.d.ts +33 -0
  139. package/package.json +6 -1
package/dist/styles.css CHANGED
@@ -27,14 +27,16 @@
27
27
  font-display: swap;
28
28
  }
29
29
  :root {
30
- --crisp-bg-brand-solid: #266df0;
31
- --crisp-bg-brand-solid-pressed: #1f5fd6;
30
+ --crisp-bg-brand-solid: #0298d9;
31
+ --crisp-bg-brand-solid-pressed: #0283bb;
32
+ --crisp-bg-brand-contrast: #0278ac;
33
+ --crisp-fg-brand-contrast: #0278ac;
32
34
  --crisp-fg-on-brand: #ffffff;
33
35
  --crisp-fg-on-tone: #101112;
34
36
  --crisp-bg-surface: #ffffff;
35
- --crisp-bg-raised: #f4f4f5;
37
+ --crisp-bg-raised: #f7f8f9;
36
38
  --crisp-bg-surface-muted: #f6f7f7;
37
- --crisp-border-default: #e4e4e7;
39
+ --crisp-border-default: #dcdee3;
38
40
  --crisp-border-subtle: #eeeff1;
39
41
  --crisp-border-dropzone: #e6e7ea;
40
42
  --crisp-border-divider: #e6e7ea;
@@ -56,9 +58,9 @@
56
58
  --crisp-shadow-popover3: rgba(24,41,75,0.16);
57
59
  --crisp-fg-primary: #101112;
58
60
  --crisp-fg-muted: #71717a;
59
- --crisp-bg-danger: #e5484d;
60
- --crisp-bg-danger-solid: #ba2525;
61
- --crisp-fg-danger: #eb3b3b;
61
+ --crisp-bg-danger: #fa342c;
62
+ --crisp-bg-danger-solid: #ca1d13;
63
+ --crisp-fg-danger: #fa342c;
62
64
  --crisp-stroke-field-focus: #1a1c20;
63
65
  --crisp-fg-disabled: #d1d3d8;
64
66
  --crisp-bg-neutral-weak: #f3f4f5;
@@ -67,8 +69,9 @@
67
69
  --crisp-fg-neutral-subtle: #868b94;
68
70
  --crisp-fg-neutral-muted: #555d6d;
69
71
  --crisp-stroke-focus-ring: #1e82eb;
70
- --crisp-bg-success: #1f9d57;
71
- --crisp-bg-warning: #b5730f;
72
+ --crisp-bg-success: #079171;
73
+ --crisp-bg-warning: #9b7821;
74
+ --crisp-bg-warning-solid: #fbdc65;
72
75
  --crisp-bg-orange: #f97514;
73
76
  --crisp-bg-cyan: #00b9eb;
74
77
  --crisp-bg-purple: #9b69ff;
@@ -82,11 +85,23 @@
82
85
  --crisp-bg-purple-soft: #f5f0ff;
83
86
  --crisp-fg-purple-soft: #6238b5;
84
87
  --crisp-ring-purple-soft: #e8ddfe;
88
+ --crisp-ring-brand-soft: #d6e5ff;
89
+ --crisp-fg-select-neutral: #1a1c20;
90
+ --crisp-bg-select-listbox: #ffffff;
91
+ --crisp-stroke-select-trigger: #dcdee3;
92
+ --crisp-bg-select-pressed: #00000007;
93
+ --crisp-bg-select-disabled: #f3f4f5;
94
+ --crisp-stroke-select-invalid: #fa342c;
95
+ --crisp-stroke-select-divider: #00000010;
96
+ --crisp-fg-select-placeholder: #b0b3ba;
97
+ --crisp-shadow-select: #0000001f;
85
98
  }
86
99
 
87
100
  [data-theme="dark"] {
88
- --crisp-bg-brand-solid: #266df0;
89
- --crisp-bg-brand-solid-pressed: #1f5fd6;
101
+ --crisp-bg-brand-solid: #0298d9;
102
+ --crisp-bg-brand-solid-pressed: #0283bb;
103
+ --crisp-bg-brand-contrast: #0278ac;
104
+ --crisp-fg-brand-contrast: #0278ac;
90
105
  --crisp-fg-on-brand: #ffffff;
91
106
  --crisp-fg-on-tone: #101112;
92
107
  --crisp-bg-surface: #0a0a0a;
@@ -127,6 +142,7 @@
127
142
  --crisp-stroke-focus-ring: #5e98fe;
128
143
  --crisp-bg-success: #2ea968;
129
144
  --crisp-bg-warning: #e0982a;
145
+ --crisp-bg-warning-solid: #e0982a;
130
146
  --crisp-bg-orange: #f97514;
131
147
  --crisp-bg-cyan: #00b9eb;
132
148
  --crisp-bg-purple: #9b69ff;
@@ -140,6 +156,16 @@
140
156
  --crisp-bg-purple-soft: #2f1e5a;
141
157
  --crisp-fg-purple-soft: #d8c4ff;
142
158
  --crisp-ring-purple-soft: #45297d;
159
+ --crisp-ring-brand-soft: #212224;
160
+ --crisp-fg-select-neutral: #f3f4f5;
161
+ --crisp-bg-select-listbox: #1d2025;
162
+ --crisp-stroke-select-trigger: #393d46;
163
+ --crisp-bg-select-pressed: #ffffff0d;
164
+ --crisp-bg-select-disabled: #2b2e35;
165
+ --crisp-stroke-select-invalid: #ff6e60;
166
+ --crisp-stroke-select-divider: #ffffff17;
167
+ --crisp-fg-select-placeholder: #868b94;
168
+ --crisp-shadow-select: #000000cc;
143
169
  }
144
170
 
145
171
  :root {
@@ -154,12 +180,15 @@
154
180
  --crisp-space-0-5: 2px;
155
181
  --crisp-space-1-5: 6px;
156
182
  --crisp-space-2-5: 10px;
183
+ --crisp-space-3-5: 14px;
184
+ --crisp-radius-xs: 4px;
157
185
  --crisp-radius-chip: 7px;
158
186
  --crisp-radius-sm: 6px;
159
187
  --crisp-radius-md: 8px;
160
188
  --crisp-radius-lg: 9px;
161
189
  --crisp-radius-xl: 12px;
162
190
  --crisp-radius-2xl: 16px;
191
+ --crisp-radius-3xl: 20px;
163
192
  --crisp-radius-full: 999px;
164
193
  --crisp-size-icon: 16px;
165
194
  --crisp-size-chip: 22px;
@@ -170,6 +199,9 @@
170
199
  --crisp-size-header: 48px;
171
200
  --crisp-size-calendarCell: 34px;
172
201
  --crisp-size-calendarPill: 32px;
202
+ --crisp-size-selectTriggerMd: 40px;
203
+ --crisp-size-selectTriggerLg: 52px;
204
+ --crisp-size-selectIconLg: 20px;
173
205
  --crisp-text-xs: 11px;
174
206
  --crisp-text-sm: 12px;
175
207
  --crisp-text-md: 13px;
@@ -182,6 +214,12 @@
182
214
  --crisp-font-sans: "VK Sans Display", "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
183
215
  }
184
216
 
217
+ .crisp-accentpicker {
218
+ display: flex; gap: var(--crisp-space-2);
219
+ & .crisp-accentpicker-swatch { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; margin: 0; border-radius: var(--crisp-radius-full); border: 1px solid transparent; background: none; font-family: inherit; cursor: pointer; }
220
+ & .crisp-accentpicker-swatch:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 2px; }
221
+ }
222
+
185
223
  .crisp-accordion {
186
224
  display: flex; flex-direction: column; font-family: var(--crisp-font-sans);
187
225
  & .crisp-accordion-item { border-bottom: 1px solid var(--crisp-border-subtle); }
@@ -230,7 +268,7 @@
230
268
  background: var(--crisp-bg-raised); color: var(--crisp-fg-neutral-muted); box-shadow: inset 0 0 0 1px var(--crisp-border-default);
231
269
  }
232
270
  .crisp-avatar--tone_brand {
233
- background: var(--crisp-bg-brand-solid); color: #fff;
271
+ background: var(--crisp-bg-brand-contrast); color: #fff;
234
272
  }
235
273
  .crisp-avatar--tone_orange {
236
274
  background: var(--crisp-bg-orange); color: #fff;
@@ -289,13 +327,13 @@
289
327
 
290
328
  }
291
329
  .crisp-badge--compound_0 {
292
- background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); box-shadow: none;
330
+ background: var(--crisp-bg-brand-contrast); color: var(--crisp-fg-on-brand); box-shadow: none;
293
331
  }
294
332
  .crisp-badge--compound_1 {
295
333
  background: var(--crisp-bg-success); color: var(--crisp-fg-on-tone); box-shadow: none;
296
334
  }
297
335
  .crisp-badge--compound_2 {
298
- background: var(--crisp-bg-warning); color: var(--crisp-fg-on-tone); box-shadow: none;
336
+ background: var(--crisp-bg-warning-solid); color: var(--crisp-fg-on-tone); box-shadow: none;
299
337
  }
300
338
  .crisp-badge--compound_3 {
301
339
  background: var(--crisp-bg-danger); color: var(--crisp-fg-on-tone); box-shadow: none;
@@ -370,9 +408,9 @@
370
408
  &:disabled { opacity: 0.5; cursor: not-allowed; }
371
409
  }
372
410
  .crisp-button--intent_primary {
373
- background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06), 0 2px 4px -2px rgba(38,109,240,0.12), 0 3px 6px -2px rgba(38,109,240,0.08);
374
- &:hover { background: var(--crisp-bg-brand-solid-pressed); }
375
- &:active { background: var(--crisp-bg-brand-solid-pressed); }
411
+ background: var(--crisp-bg-brand-contrast); color: var(--crisp-fg-on-brand); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06), 0 2px 4px -2px rgba(38,109,240,0.12), 0 3px 6px -2px rgba(38,109,240,0.08);
412
+ &:hover { filter: brightness(0.96); }
413
+ &:active { filter: brightness(0.92); }
376
414
  }
377
415
  .crisp-button--intent_neutral {
378
416
  background: var(--crisp-bg-surface); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04);
@@ -436,6 +474,12 @@
436
474
  &[data-tone="danger"] { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
437
475
  &[data-tone="danger"] .crisp-callout-icon { color: var(--crisp-bg-danger); }
438
476
  }
477
+ .crisp-callout--bordered_true {
478
+ border: 1px solid var(--crisp-ring-brand-soft); border-radius: var(--crisp-radius-xl); padding: var(--crisp-space-2) var(--crisp-space-3); background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent);
479
+ }
480
+ .crisp-callout--bordered_false {
481
+
482
+ }
439
483
 
440
484
  .crisp-card {
441
485
  display: flex; flex-direction: column; box-sizing: border-box; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-family: var(--crisp-font-sans); color: var(--crisp-fg-primary);
@@ -1354,6 +1398,17 @@
1354
1398
  & .crisp-input-value::placeholder { color: var(--crisp-fg-muted); }
1355
1399
  & .crisp-input-value:disabled { opacity: 0.5; cursor: not-allowed; }
1356
1400
  &:has(.crisp-input-value:disabled) { opacity: 1; }
1401
+ /* crisp#634: measured live on Attio's own Settings > Profile read-only
1402
+ primary-email field -- a tinted field, not just muted text, driven off
1403
+ the native `readOnly` attribute. `ringField` (rgba(0,0,0,.06)) is an
1404
+ exact match for the measured ring; the 2%-fgPrimary tint reuses the
1405
+ same color-mix idiom every other soft crisp surface already uses. */
1406
+ &[data-readonly] { background: color-mix(in srgb, var(--crisp-fg-primary) 2%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-ring-field); }
1407
+ & .crisp-input-suffix { flex-shrink: 0; margin-inline-start: var(--crisp-space-1); }
1408
+ }
1409
+ .crisp-input--size_sm {
1410
+ height: var(--crisp-size-row); border-radius: var(--crisp-radius-md);
1411
+ & .crisp-input-value { padding-inline: var(--crisp-space-2-5); }
1357
1412
  }
1358
1413
  .crisp-input--size_medium {
1359
1414
  height: 32px; border-radius: var(--crisp-radius-md);
@@ -1435,6 +1490,14 @@
1435
1490
  .crisp-menu-item--danger svg { color: var(--crisp-bg-danger); }
1436
1491
  .crisp-menu-item--danger:hover, .crisp-menu-item--danger:focus-visible, .crisp-menu-item--danger[data-highlighted] { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
1437
1492
  .crisp-menu-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
1493
+ /* crisp#875: same measured neutral chip TableToolbar's own ToolbarTool
1494
+ count prop uses (re-confirmed on two live Attio surfaces this round:
1495
+ the Sort tool's own "+N" overflow, a Kanban board's stage-column
1496
+ count) -- a small badge, not bare text. */
1497
+ .crisp-menu-item-count { flex-shrink: 0; margin-inline-start: var(--crisp-space-1-5); display: inline-flex; align-items: center; height: 16px; box-sizing: border-box;
1498
+ padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent);
1499
+ box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft);
1500
+ font-variant-numeric: tabular-nums; }
1438
1501
  .crisp-menu-item-shortcut { flex-shrink: 0; margin-inline-start: var(--crisp-space-3); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); letter-spacing: 0.02em; }
1439
1502
  .crisp-menu-item-check { flex-shrink: 0; color: var(--crisp-bg-brand-solid); }
1440
1503
  .crisp-menu-item-check--placeholder { width: 15px; }
@@ -1455,38 +1518,42 @@
1455
1518
  }
1456
1519
 
1457
1520
 
1458
- /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
1459
- on document.body while open (Zag re-enables it only on layers IT
1460
- tracks), and the portaled listbox is outside Zag's knowledge -- it
1461
- inherited the lock, so every option was unclickable, hit-testing
1462
- right through to whatever real element sat behind it. */
1521
+ /* pointer-events: auto (#375) -- see Select's matching comment. */
1463
1522
  .crisp-multiselect-listbox {
1464
1523
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1465
- position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1466
- max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1);
1467
- border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
1468
- box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
1469
- transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease;
1524
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-2);
1525
+ max-height: 480px; overflow-y: auto; padding: var(--crisp-space-2);
1526
+ border-radius: var(--crisp-radius-3xl); background: var(--crisp-bg-select-listbox);
1527
+ box-shadow: 0 4px 16px var(--crisp-shadow-select);
1528
+ transform-origin: top left; opacity: 1; transform: none;
1529
+ transition: opacity .15s cubic-bezier(0,0,.15,1), transform .15s cubic-bezier(0,0,.15,1);
1470
1530
  }
1471
1531
  .crisp-multiselect-listbox[data-up] { transform-origin: bottom left; }
1472
- .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1473
- .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: 36px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: var(--crisp-space-2) var(--crisp-space-3); color: var(--crisp-fg-muted); }
1532
+ .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.95); } }
1533
+ /* LOCKED geometry (#481, guarded by build/spec-check.mjs): height 36px,
1534
+ gap space["1.5"] (6px), no border-bottom -- an Attio measurement, not
1535
+ part of this seed-parity pass. Only colours below follow Select. */
1536
+ .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: 36px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-2)) calc(-1 * var(--crisp-space-2)) var(--crisp-space-2); padding: var(--crisp-space-2) var(--crisp-space-3); color: var(--crisp-fg-neutral-muted); }
1474
1537
  .crisp-multiselect-search svg { flex-shrink: 0; }
1475
- .crisp-multiselect-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
1476
- .crisp-multiselect-search input::placeholder { color: var(--crisp-fg-muted); }
1477
- /* #343: same measured values as Menu's own group heading
1478
- (crisp-menu-label) -- reused rather than re-measured, since it's the
1479
- same "small muted heading above a run of rows" treatment. */
1480
- .crisp-multiselect-label { padding: var(--crisp-space-1-5) var(--crisp-space-2) var(--crisp-space-0-5); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
1538
+ .crisp-multiselect-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-select-neutral); }
1539
+ .crisp-multiselect-search input::placeholder { color: var(--crisp-fg-select-placeholder); }
1540
+ /* Same groupLabel treatment as Select's (13px/regular/neutral-subtle). */
1541
+ .crisp-multiselect-label { padding: var(--crisp-space-2) var(--crisp-space-4) 0; font-size: var(--crisp-text-md); line-height: 18px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-neutral-subtle); }
1481
1542
  .crisp-multiselect-option {
1482
- box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-menuRow); flex-shrink: 0;
1483
- padding: 0 var(--crisp-space-2); margin: 0; border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; cursor: pointer; text-align: start;
1543
+ box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0;
1544
+ padding: var(--crisp-space-2-5) var(--crisp-space-4); margin: 0; border: none; background: none; border-radius: var(--crisp-radius-xl);
1545
+ font-family: inherit; text-align: start; cursor: pointer;
1546
+ transition: background-color .15s cubic-bezier(.35,0,.35,1);
1484
1547
  }
1548
+ /* Keyboard/hover highlight keeps crisp's own visible neutral fill, same
1549
+ reasoning as Select's matching rule (seed's own pressed tint is too
1550
+ faint for a keyboard-navigation indicator). */
1485
1551
  .crisp-multiselect-option[data-highlighted] { background: var(--crisp-bg-raised); }
1552
+ .crisp-multiselect-option:active { background: var(--crisp-bg-select-pressed); }
1486
1553
  .crisp-multiselect-option-chip { flex: 0 1 auto; min-width: 0; overflow: hidden; }
1487
1554
  .crisp-multiselect-check { flex-shrink: 0; margin-inline-start: auto; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: var(--crisp-radius-sm); box-shadow: inset 0 0 0 1.5px var(--crisp-border-default); color: transparent; }
1488
1555
  .crisp-multiselect-option[aria-selected="true"] .crisp-multiselect-check { background: var(--crisp-bg-brand-solid); box-shadow: none; color: #fff; }
1489
- .crisp-multiselect-empty { padding: var(--crisp-space-3) var(--crisp-space-2); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
1556
+ .crisp-multiselect-empty { padding: var(--crisp-space-3) var(--crisp-space-4); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-neutral-subtle); }
1490
1557
 
1491
1558
  .crisp-recordstable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
1492
1559
  .crisp-recordstable-tag[data-tone="brand"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent); }
@@ -1499,21 +1566,45 @@
1499
1566
 
1500
1567
  .crisp-multiselect {
1501
1568
  position: relative; display: inline-flex; width: 100%; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1502
- & .crisp-multiselect-trigger { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; min-width: 0; min-height: var(--crisp-size-menuRow); margin: 0; padding: var(--crisp-space-0-5) var(--crisp-space-1-5) var(--crisp-space-0-5) var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; text-align: start; transition: background-color .12s ease, box-shadow .12s ease; }
1503
- & .crisp-multiselect-trigger:hover { background: var(--crisp-bg-raised); }
1504
- & .crisp-multiselect-trigger[data-open], & .crisp-multiselect-trigger:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); background: var(--crisp-bg-surface); }
1505
- & .crisp-multiselect-trigger:disabled { opacity: 0.5; cursor: not-allowed; }
1569
+ & .crisp-multiselect-trigger { box-sizing: border-box; display: flex; align-items: center; width: 100%; min-width: 0; margin: 0; border: 1px solid var(--crisp-stroke-select-trigger); background: transparent; cursor: pointer; text-align: start; font-family: inherit; color: var(--crisp-fg-select-neutral); transition: background-color .15s cubic-bezier(.35,0,.35,1), border-color .1s cubic-bezier(.35,0,.35,1), border-width .1s cubic-bezier(.35,0,.35,1); }
1570
+ /* Same pressed/disabled/readonly/focus model as Select's trigger -- see
1571
+ that recipe's comment for why hover and an open/focus ring are gone. */
1572
+ & .crisp-multiselect-trigger:active:not(:disabled):not([aria-readonly="true"]) { background: var(--crisp-bg-select-pressed); }
1573
+ & .crisp-multiselect-trigger:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: -2px; }
1574
+ & .crisp-multiselect-trigger:disabled { background: var(--crisp-bg-select-disabled); cursor: not-allowed; }
1575
+ & .crisp-multiselect-trigger:disabled .crisp-multiselect-placeholder, & .crisp-multiselect-trigger:disabled .crisp-multiselect-chevron { color: var(--crisp-fg-disabled); }
1576
+ & .crisp-multiselect-trigger[aria-readonly="true"] { background: var(--crisp-bg-select-disabled); cursor: default; }
1506
1577
  & .crisp-multiselect-chips { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); }
1507
- & .crisp-multiselect-placeholder { color: var(--crisp-fg-muted); }
1508
- & .crisp-multiselect-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
1509
- & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); }
1578
+ & .crisp-multiselect-placeholder { color: var(--crisp-fg-select-placeholder); }
1579
+ /* closeRotateDuration/openRotateDuration, same asymmetric timing as Select's own chevron (see that recipe's comment). */
1580
+ & .crisp-multiselect-chevron { flex-shrink: 0; color: var(--crisp-fg-neutral-muted); transition: transform .1s cubic-bezier(.35,0,.35,1); }
1581
+ & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); transition-duration: .15s; }
1582
+ }
1583
+ .crisp-multiselect--size_small {
1584
+ & .crisp-multiselect-trigger { min-height: var(--crisp-size-menuRow); border-radius: var(--crisp-radius-md); gap: var(--crisp-space-1); padding: var(--crisp-space-0-5) var(--crisp-space-1-5) var(--crisp-space-0-5) var(--crisp-space-2); }
1585
+ & .crisp-multiselect-chevron { width: var(--crisp-size-icon); height: var(--crisp-size-icon); }
1586
+ }
1587
+ .crisp-multiselect--size_medium {
1588
+ & .crisp-multiselect-trigger { min-height: var(--crisp-size-selectTriggerMd); border-radius: var(--crisp-radius-md); gap: var(--crisp-space-2); padding: var(--crisp-space-1) var(--crisp-space-3-5); }
1589
+ & .crisp-multiselect-chevron { width: var(--crisp-size-icon); height: var(--crisp-size-icon); }
1590
+ }
1591
+ .crisp-multiselect--size_large {
1592
+ & .crisp-multiselect-trigger { min-height: var(--crisp-size-selectTriggerLg); border-radius: var(--crisp-radius-xl); gap: var(--crisp-space-2-5); padding: var(--crisp-space-1-5) var(--crisp-space-4); }
1593
+ & .crisp-multiselect-chevron { width: var(--crisp-size-selectIconLg); height: var(--crisp-size-selectIconLg); }
1510
1594
  }
1511
1595
  .crisp-multiselect--invalid_true {
1512
- & .crisp-multiselect-trigger, & .crisp-multiselect-trigger:hover, & .crisp-multiselect-trigger[data-open], & .crisp-multiselect-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
1596
+ & .crisp-multiselect-trigger { border-width: 2px; border-color: var(--crisp-stroke-select-invalid); }
1513
1597
  }
1514
1598
  .crisp-multiselect--invalid_false {
1515
1599
 
1516
1600
  }
1601
+ .crisp-multiselect--variant_default {
1602
+
1603
+ }
1604
+ .crisp-multiselect--variant_ghost {
1605
+ & .crisp-multiselect-trigger { min-height: 0; height: 100%; border-color: transparent; }
1606
+ & .crisp-multiselect-trigger:hover:not(:disabled) { background: var(--crisp-bg-select-pressed); }
1607
+ }
1517
1608
 
1518
1609
  @media (prefers-reduced-motion: reduce) {
1519
1610
  .crisp-multiselect, .crisp-multiselect * {
@@ -1551,6 +1642,9 @@
1551
1642
  &[data-segmented] { display: flex; gap: var(--crisp-space-1); background: transparent; overflow: visible; }
1552
1643
  &[data-segmented] .crisp-progress-seg { flex: 1; height: 100%; border-radius: var(--crisp-radius-full); background: color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); transition: background 0.2s; }
1553
1644
  &[data-segmented] .crisp-progress-seg[data-filled] { background: var(--crisp-bg-brand-solid); }
1645
+ &[data-variant="circular"] { display: inline-flex; height: auto; border-radius: 0; background: transparent; overflow: visible; }
1646
+ & .crisp-progress-circle-track { stroke: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); }
1647
+ & .crisp-progress-circle-fill { stroke: var(--crisp-bg-brand-solid); transition: stroke-dashoffset 0.25s ease; }
1554
1648
  }
1555
1649
 
1556
1650
  @media (prefers-reduced-motion: reduce) {
@@ -1696,58 +1790,79 @@
1696
1790
 
1697
1791
 
1698
1792
  /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
1699
- on document.body while open (Zag re-enables it only on layers IT
1700
- tracks), and the portaled listbox is outside Zag's knowledge -- it
1701
- inherited the lock, so every option was unclickable, hit-testing
1702
- right through to whatever real element sat behind it. */
1793
+ on document.body while open, and the portaled listbox is outside its
1794
+ knowledge -- it inherited the lock without this. */
1703
1795
  .crisp-select-listbox {
1704
1796
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1705
- position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
1706
- max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1);
1707
- border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
1708
- box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
1709
- transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease;
1797
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-2);
1798
+ max-height: 480px; overflow-y: auto; padding: var(--crisp-space-2);
1799
+ border-radius: var(--crisp-radius-3xl); background: var(--crisp-bg-select-listbox);
1800
+ box-shadow: 0 4px 16px var(--crisp-shadow-select);
1801
+ transform-origin: top left; opacity: 1; transform: none;
1802
+ transition: opacity .15s cubic-bezier(0,0,.15,1), transform .15s cubic-bezier(0,0,.15,1);
1710
1803
  }
1711
- .crisp-select-listbox[data-up] { transform-origin: bottom; }
1712
- .crisp-select-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1713
- .crisp-select-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
1804
+ .crisp-select-listbox[data-up] { transform-origin: bottom left; }
1805
+ .crisp-select-listbox { @starting-style { opacity: 0; transform: scale(0.95); } }
1806
+ /* Composed from @seed-design/rootage's text-input.yaml
1807
+ (variant=outline,size=medium) -- seed's Select has no search field of
1808
+ its own to resolve this from (see the file header), so this reuses
1809
+ the SAME tokens #867 already resolved for the trigger at this size:
1810
+ minHeight x10 (var(--crisp-size-selectTriggerMd)), paddingX x3_5
1811
+ (var(--crisp-space-3-5)), gap x2 (var(--crisp-space-2)), cornerRadius r2
1812
+ (var(--crisp-radius-md)), strokeColor stroke.neutral-weak
1813
+ (var(--crisp-stroke-select-trigger)) -- a real bordered field sitting flush
1814
+ inside the listbox's own 8px padding, replacing the old bare
1815
+ 34px/no-border/bleeds-to-the-edge strip (crisp/#904). */
1816
+ .crisp-select-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-selectTriggerMd); flex-shrink: 0; padding: 0 var(--crisp-space-3-5); border: 1px solid var(--crisp-stroke-select-trigger); border-radius: var(--crisp-radius-md); color: var(--crisp-fg-neutral-muted); }
1714
1817
  .crisp-select-search svg { flex-shrink: 0; }
1715
- .crisp-select-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
1716
- .crisp-select-search input::placeholder { color: var(--crisp-fg-muted); }
1717
- .crisp-select-empty { padding: var(--crisp-space-3) var(--crisp-space-2); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
1718
- /* #343: same measured values as Menu's own group heading
1719
- (crisp-menu-label) -- reused rather than re-measured, since it's the
1720
- same "small muted heading above a run of rows" treatment. */
1721
- .crisp-select-label { padding: var(--crisp-space-1-5) var(--crisp-space-2) var(--crisp-space-0-5); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
1818
+ .crisp-select-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); line-height: 19px; color: var(--crisp-fg-select-neutral); }
1819
+ .crisp-select-search input::placeholder { color: var(--crisp-fg-select-placeholder); }
1820
+ .crisp-select-empty { padding: var(--crisp-space-3) var(--crisp-space-4); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-neutral-subtle); }
1821
+ /* select.yaml's groupLabel -- font-size/line-height/weight are the same
1822
+ across sizes, only paddingY differs (medium 8px, large 10px). */
1823
+ .crisp-select-label { padding: var(--crisp-space-2) var(--crisp-space-4) 0; font-size: var(--crisp-text-md); line-height: 18px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-neutral-subtle); }
1722
1824
  .crisp-select-option {
1723
- box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-menuRow); flex-shrink: 0;
1724
- padding: 0 var(--crisp-space-2); margin: 0; border: none; background: none; border-radius: var(--crisp-radius-md);
1725
- font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: start; cursor: pointer; white-space: nowrap;
1825
+ box-sizing: border-box; display: flex; align-items: center; flex-shrink: 0;
1826
+ padding: var(--crisp-space-2-5) var(--crisp-space-4); margin-inline: 0; border: none; background: none; border-radius: var(--crisp-radius-xl);
1827
+ font-family: inherit; color: var(--crisp-fg-select-neutral); text-align: start; cursor: pointer; white-space: nowrap;
1828
+ transition: background-color .15s cubic-bezier(.35,0,.35,1), margin-inline .15s cubic-bezier(.35,0,.35,1);
1726
1829
  }
1830
+ /* Keyboard/hover highlight keeps crisp's own visible neutral fill --
1831
+ seed's spec has no "highlighted" state at all (only pressed/selected/
1832
+ disabled), and its actual pressed tint (below) is a ~3% black hint,
1833
+ too faint to serve as a keyboard-navigation indicator. */
1727
1834
  .crisp-select-option[data-highlighted] { background: var(--crisp-bg-raised); }
1728
- .crisp-select-option[data-disabled] { opacity: 0.5; cursor: not-allowed; }
1729
- .crisp-select-option-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: var(--crisp-radius-full); }
1835
+ .crisp-select-option:active:not([data-disabled]) { background: var(--crisp-bg-select-pressed); margin-inline: var(--crisp-space-2); }
1836
+ .crisp-select-option[data-disabled] { cursor: not-allowed; }
1837
+ .crisp-select-option[data-disabled] .crisp-select-option-label,
1838
+ .crisp-select-option[data-disabled] .crisp-select-option-description,
1839
+ .crisp-select-option[data-disabled] .crisp-select-option-check { color: var(--crisp-fg-disabled); }
1840
+ .crisp-select-option-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: var(--crisp-radius-full); margin-inline-end: var(--crisp-space-2); }
1841
+ .crisp-select-option-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--crisp-space-0-5); }
1730
1842
  .crisp-select-option-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
1731
- .crisp-select-option-check { flex-shrink: 0; color: var(--crisp-bg-brand-solid); }
1843
+ .crisp-select-option-description { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--crisp-fg-neutral-subtle); }
1844
+ .crisp-select-option-check { flex-shrink: 0; color: var(--crisp-fg-select-neutral); margin-inline-start: var(--crisp-space-2); }
1732
1845
 
1733
1846
  .crisp-select {
1734
1847
  position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
1735
- & .crisp-select-trigger { box-sizing: border-box; display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-menuRow); width: 100%; min-width: 0; margin: 0; padding: 0 var(--crisp-space-1-5) 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; transition: background-color .12s ease, box-shadow .12s ease; }
1736
- & .crisp-select-trigger:hover { background: var(--crisp-bg-raised); }
1737
- & .crisp-select-trigger[data-open], & .crisp-select-trigger:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); background: var(--crisp-bg-surface); }
1738
- & .crisp-select-trigger:disabled { opacity: 0.5; cursor: not-allowed; }
1739
- & .crisp-select-value { flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: start; }
1740
- & .crisp-select-placeholder { color: var(--crisp-fg-muted); }
1741
- & .crisp-select-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
1742
- & .crisp-select-trigger[data-open] .crisp-select-chevron { transform: rotate(180deg); }
1743
- }
1744
- .crisp-select--variant_default {
1745
-
1746
- }
1747
- .crisp-select--variant_ghost {
1748
- & .crisp-select-trigger { background: transparent; box-shadow: none; }
1749
- & .crisp-select-trigger:hover { background: var(--crisp-bg-raised); box-shadow: none; }
1750
- & .crisp-select-trigger[data-open], & .crisp-select-trigger:focus-visible { background: transparent; box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
1848
+ & .crisp-select-trigger { box-sizing: border-box; display: inline-flex; align-items: center; width: 100%; min-width: 0; margin: 0; border: 1px solid var(--crisp-stroke-select-trigger); background: transparent; cursor: pointer; font-family: inherit; color: var(--crisp-fg-select-neutral); transition: background-color .15s cubic-bezier(.35,0,.35,1), border-color .1s cubic-bezier(.35,0,.35,1), border-width .1s cubic-bezier(.35,0,.35,1); }
1849
+ /* seed defines no hover state for this trigger -- only pressed, invalid, disabled and readonly. The scale-down is scoped to the CONTENT (seed's scaleScope: content), not the button itself, so the border
1850
+ never moves. */
1851
+ /* Only the value scales, not the chevron: the chevron's own transform is its open/close rotation, and a scale would fight it for one shared CSS property when both are true at once (pressing while open). */
1852
+ & .crisp-select-trigger:active:not(:disabled):not([aria-readonly="true"]) { background: var(--crisp-bg-select-pressed); }
1853
+ & .crisp-select-trigger:active:not(:disabled):not([aria-readonly="true"]) .crisp-select-value { transform: scale(0.98); }
1854
+ & .crisp-select-trigger:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: -2px; }
1855
+ & .crisp-select-trigger:disabled { background: var(--crisp-bg-select-disabled); cursor: not-allowed; }
1856
+ & .crisp-select-trigger:disabled .crisp-select-value, & .crisp-select-trigger:disabled .crisp-select-placeholder, & .crisp-select-trigger:disabled .crisp-select-chevron { color: var(--crisp-fg-disabled); }
1857
+ /* readonly: same fill as disabled, but the value/placeholder text stays normal ink -- it reads as "answered and locked", not "answered and
1858
+ greyed out" (select-trigger.yaml's readonly state only overrides
1859
+ root.color; value/placeholder keep their enabled colours). */
1860
+ & .crisp-select-trigger[aria-readonly="true"] { background: var(--crisp-bg-select-disabled); cursor: default; }
1861
+ & .crisp-select-value { flex: 1; min-width: 0; display: inline-flex; align-items: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: start; transition: transform .15s cubic-bezier(0,0,.15,1); }
1862
+ & .crisp-select-placeholder { color: var(--crisp-fg-select-placeholder); }
1863
+ /* closeRotateDuration/closeRotateTimingFunction: 100ms, seed's "easing" curve. Overridden to 150ms on open (openRotateDuration) below -- same curve both ways, only the duration differs. */
1864
+ & .crisp-select-chevron { flex-shrink: 0; color: var(--crisp-fg-neutral-muted); transition: transform .1s cubic-bezier(.35,0,.35,1); }
1865
+ & .crisp-select-trigger[data-open] .crisp-select-chevron { transform: rotate(180deg); transition-duration: .15s; }
1751
1866
  }
1752
1867
  .crisp-select--width_full {
1753
1868
  width: 100%;
@@ -1755,12 +1870,49 @@
1755
1870
  .crisp-select--width_auto {
1756
1871
  width: auto;
1757
1872
  }
1873
+ .crisp-select--size_small {
1874
+ & .crisp-select-trigger { height: var(--crisp-size-menuRow); border-radius: var(--crisp-radius-md); gap: var(--crisp-space-1-5); padding-inline: var(--crisp-space-2-5); }
1875
+ & .crisp-select-value, & .crisp-select-placeholder { font-size: var(--crisp-text-lg); line-height: 20px; }
1876
+ & .crisp-select-chevron { width: var(--crisp-size-icon); height: var(--crisp-size-icon); }
1877
+ .crisp-select-option { gap: var(--crisp-space-2); }
1878
+ .crisp-select-option-label { font-size: var(--crisp-text-lg); line-height: 19px; }
1879
+ .crisp-select-option-description { font-size: var(--crisp-text-sm); line-height: 16px; }
1880
+ .crisp-select-option-check { width: var(--crisp-space-3); height: var(--crisp-space-3); }
1881
+ .crisp-select-label { padding-top: var(--crisp-space-2); }
1882
+ }
1883
+ .crisp-select--size_medium {
1884
+ & .crisp-select-trigger { height: var(--crisp-size-selectTriggerMd); border-radius: var(--crisp-radius-md); gap: var(--crisp-space-2); padding-inline: var(--crisp-space-3-5); }
1885
+ & .crisp-select-value, & .crisp-select-placeholder { font-size: var(--crisp-text-lg); line-height: 19px; }
1886
+ & .crisp-select-chevron { width: var(--crisp-size-icon); height: var(--crisp-size-icon); }
1887
+ .crisp-select-option { gap: var(--crisp-space-2); }
1888
+ .crisp-select-option-label { font-size: var(--crisp-text-lg); line-height: 19px; }
1889
+ .crisp-select-option-description { font-size: var(--crisp-text-sm); line-height: 16px; }
1890
+ .crisp-select-option-check { width: var(--crisp-space-3); height: var(--crisp-space-3); }
1891
+ .crisp-select-label { padding-top: var(--crisp-space-2); }
1892
+ }
1893
+ .crisp-select--size_large {
1894
+ & .crisp-select-trigger { height: var(--crisp-size-selectTriggerLg); border-radius: var(--crisp-radius-xl); gap: var(--crisp-space-2-5); padding-inline: var(--crisp-space-4); }
1895
+ & .crisp-select-value, & .crisp-select-placeholder { font-size: var(--crisp-text-xl); line-height: 22px; }
1896
+ & .crisp-select-chevron { width: var(--crisp-size-selectIconLg); height: var(--crisp-size-selectIconLg); }
1897
+ .crisp-select-option { gap: var(--crisp-space-3); }
1898
+ .crisp-select-option-label { font-size: var(--crisp-text-xl); line-height: 22px; }
1899
+ .crisp-select-option-description { font-size: var(--crisp-text-md); line-height: 18px; }
1900
+ .crisp-select-option-check { width: var(--crisp-space-3-5); height: var(--crisp-space-3-5); }
1901
+ .crisp-select-label { padding-top: var(--crisp-space-2-5); }
1902
+ }
1758
1903
  .crisp-select--invalid_true {
1759
- & .crisp-select-trigger, & .crisp-select-trigger:hover, & .crisp-select-trigger[data-open], & .crisp-select-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
1904
+ & .crisp-select-trigger { border-width: 2px; border-color: var(--crisp-stroke-select-invalid); }
1760
1905
  }
1761
1906
  .crisp-select--invalid_false {
1762
1907
 
1763
1908
  }
1909
+ .crisp-select--variant_default {
1910
+
1911
+ }
1912
+ .crisp-select--variant_ghost {
1913
+ & .crisp-select-trigger { height: 100%; border-color: transparent; }
1914
+ & .crisp-select-trigger:hover:not(:disabled) { background: var(--crisp-bg-select-pressed); }
1915
+ }
1764
1916
 
1765
1917
  @media (prefers-reduced-motion: reduce) {
1766
1918
  .crisp-select, .crisp-select * {
@@ -2150,7 +2302,14 @@
2150
2302
  & .crisp-tabletoolbar-tool--raised { border: none; background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); font-family: inherit; cursor: pointer; }
2151
2303
 
2152
2304
  & .crisp-tabletoolbar-sorted-prefix { color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
2153
- & .crisp-tabletoolbar-sorted-count { font-size: var(--crisp-text-sm); color: color-mix(in srgb, var(--crisp-fg-primary) 73%, transparent); }
2305
+ & .crisp-tabletoolbar-sorted-count { display: inline-flex; align-items: center; height: 16px; box-sizing: border-box;
2306
+ padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent);
2307
+ box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
2308
+
2309
+ & .crisp-tabletoolbar-tool-count { display: inline-flex; align-items: center; height: 16px; box-sizing: border-box;
2310
+ padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent);
2311
+ box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft);
2312
+ font-variant-numeric: tabular-nums; }
2154
2313
  [dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
2155
2314
  }
2156
2315
 
@@ -2175,6 +2334,12 @@
2175
2334
  & .crisp-tabs-tab-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 14px; height: 14px; padding: 0 var(--crisp-space-1); border-radius: 4px; background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: 10px; line-height: 14px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
2176
2335
  & .crisp-tabs-tab[data-selected] .crisp-tabs-tab-badge { color: var(--crisp-fg-primary); }
2177
2336
  & .crisp-tabs-indicator { position: absolute; bottom: 0; left: 0; z-index: 1; height: 1px; background: var(--crisp-fg-primary); border-radius: 2px 2px 0 0; transition: transform .2s cubic-bezier(.4,0,.2,1), width .2s cubic-bezier(.4,0,.2,1); pointer-events: none; }
2337
+ /* crisp#863: the "+N more" overflow trigger, measured live -- its computed style is identical to a plain .crisp-tabs-tab (same pill, same 6px icon/label gap the tab class already gives via space["1.5"]), and the dropdown it opens is crisp's own Menu/
2338
+ MenuItem chrome (already matches Attio's popover, nothing new to style there). Only the wrapper needs a rule: an overflowed tab (or the trigger itself, when nothing is hidden) is taken out of the flex row and out of the a11y tree without ever making its own offsetWidth unmeasurable the way display:none would -- that's what
2339
+ lets the tabs.tsx effect recompute the cutoff from cached widths on
2340
+ every resize with no flash of an unclipped row. */
2341
+ & .crisp-tabs-more { display: inline-flex; }
2342
+ & [data-tabs-overflow-hidden] { position: absolute; visibility: hidden; pointer-events: none; }
2178
2343
  & .crisp-tabs-panel { display: flex; flex-direction: column; flex: 1; min-height: 0; padding-top: var(--crisp-space-8); }
2179
2344
  & .crisp-tabs-panel:focus-visible { outline: none; }
2180
2345
  }
@@ -2203,7 +2368,7 @@
2203
2368
  color: var(--crisp-fg-neutral-muted);
2204
2369
  }
2205
2370
  .crisp-text--tone_brand {
2206
- color: var(--crisp-bg-brand-solid);
2371
+ color: var(--crisp-fg-brand-contrast);
2207
2372
  }
2208
2373
  .crisp-text--tone_danger {
2209
2374
  color: var(--crisp-fg-danger);
@@ -2227,8 +2392,9 @@
2227
2392
  &[data-invalid] .crisp-textarea-wrap::after { border-color: var(--crisp-bg-danger); }
2228
2393
  &[data-invalid] .crisp-textarea-wrap:focus-within::after { border-color: var(--crisp-bg-danger); }
2229
2394
  &[data-counted] .crisp-textarea-field { padding-bottom: var(--crisp-space-5); }
2230
- & .crisp-textarea-count { position: absolute; inset-inline-end: 14px; bottom: var(--crisp-space-2-5); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); pointer-events: none; }
2395
+ & .crisp-textarea-count { position: absolute; inset-inline-end: 14px; bottom: var(--crisp-space-2-5); display: flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); pointer-events: none; }
2231
2396
  & .crisp-textarea-count[data-over] { color: var(--crisp-bg-danger); }
2397
+ & .crisp-textarea-progress { flex-shrink: 0; }
2232
2398
  }
2233
2399
 
2234
2400
  @media (prefers-reduced-motion: reduce) {
@@ -2244,11 +2410,20 @@
2244
2410
  &:hover { text-decoration: underline; }
2245
2411
  }
2246
2412
  .crisp-textlink--tone_brand {
2247
- font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-bg-brand-solid);
2413
+ font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-brand-contrast);
2248
2414
  }
2249
2415
  .crisp-textlink--tone_muted {
2250
2416
  font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-muted);
2251
- &:hover { color: var(--crisp-bg-brand-solid); }
2417
+ &:hover { color: var(--crisp-fg-brand-contrast); }
2418
+ }
2419
+ .crisp-textlink--size_sm {
2420
+ font-size: var(--crisp-text-sm);
2421
+ }
2422
+ .crisp-textlink--size_md {
2423
+ font-size: var(--crisp-text-md);
2424
+ }
2425
+ .crisp-textlink--size_lg {
2426
+ font-size: var(--crisp-text-lg);
2252
2427
  }
2253
2428
 
2254
2429
  .crisp-toast {