@crisp-ui-kit/crisp 0.57.0 → 0.57.2

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 (293) 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/authshell.css +9 -4
  5. package/dist/authshell.layered.css +9 -4
  6. package/dist/avatar.css +1 -1
  7. package/dist/avatar.layered.css +1 -1
  8. package/dist/badge.css +5 -5
  9. package/dist/badge.layered.css +5 -5
  10. package/dist/board.css +28 -8
  11. package/dist/board.layered.css +28 -8
  12. package/dist/bottomsheet.css +26 -0
  13. package/dist/bottomsheet.d.ts +7 -0
  14. package/dist/bottomsheet.layered.css +28 -0
  15. package/dist/button.css +9 -8
  16. package/dist/button.layered.css +9 -8
  17. package/dist/checkbox.css +7 -3
  18. package/dist/checkbox.layered.css +7 -3
  19. package/dist/chip.css +15 -0
  20. package/dist/chip.d.ts +3 -1
  21. package/dist/chip.layered.css +15 -0
  22. package/dist/chipgroup.css +5 -0
  23. package/dist/chipgroup.d.ts +7 -0
  24. package/dist/chipgroup.layered.css +7 -0
  25. package/dist/cjs/components/accentpicker/accentpicker.js +66 -0
  26. package/dist/cjs/components/accentpicker/accentpicker.recipe.js +25 -0
  27. package/dist/cjs/components/accentpicker/index.js +7 -0
  28. package/dist/cjs/components/avatar/avatar.recipe.js +4 -1
  29. package/dist/cjs/components/badge/badge.recipe.js +38 -10
  30. package/dist/cjs/components/bottomsheet/bottomsheet.js +90 -0
  31. package/dist/cjs/components/bottomsheet/bottomsheet.recipe.js +77 -0
  32. package/dist/cjs/components/bottomsheet/index.js +9 -0
  33. package/dist/cjs/components/button/button.recipe.js +55 -21
  34. package/dist/cjs/components/checkbox/checkbox.recipe.js +61 -9
  35. package/dist/cjs/components/chip/chip.js +14 -2
  36. package/dist/cjs/components/chip/chip.recipe.js +69 -1
  37. package/dist/cjs/components/chipgroup/chipgroup.js +51 -0
  38. package/dist/cjs/components/chipgroup/chipgroup.recipe.js +36 -0
  39. package/dist/cjs/components/chipgroup/index.js +7 -0
  40. package/dist/cjs/components/datatable/datatable.js +5 -1
  41. package/dist/cjs/components/datatable/datatable.recipe.js +11 -2
  42. package/dist/cjs/components/dialog/dialog.recipe.js +21 -10
  43. package/dist/cjs/components/emptystate/emptystate.recipe.js +7 -2
  44. package/dist/cjs/components/fileupload/fileupload.js +21 -4
  45. package/dist/cjs/components/input/index.js +2 -1
  46. package/dist/cjs/components/input/input.js +33 -3
  47. package/dist/cjs/components/input/input.recipe.js +22 -7
  48. package/dist/cjs/components/menu/menu.recipe.js +21 -7
  49. package/dist/cjs/components/menusheet/index.js +9 -0
  50. package/dist/cjs/components/menusheet/menusheet.js +133 -0
  51. package/dist/cjs/components/menusheet/menusheet.recipe.js +103 -0
  52. package/dist/cjs/components/multiselect/multiselect.js +2 -2
  53. package/dist/cjs/components/multiselect/multiselect.recipe.js +45 -12
  54. package/dist/cjs/components/progress/progress.js +21 -4
  55. package/dist/cjs/components/progress/progress.recipe.js +30 -0
  56. package/dist/cjs/components/select/select.js +3 -3
  57. package/dist/cjs/components/select/select.recipe.js +63 -10
  58. package/dist/cjs/components/snackbar/index.js +8 -0
  59. package/dist/cjs/components/snackbar/snackbar.js +121 -0
  60. package/dist/cjs/components/snackbar/snackbar.recipe.js +71 -0
  61. package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
  62. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +37 -12
  63. package/dist/cjs/components/tabs/tabs.js +10 -4
  64. package/dist/cjs/components/tabs/tabs.recipe.js +23 -6
  65. package/dist/cjs/components/text/text.recipe.js +8 -7
  66. package/dist/cjs/components/textarea/textarea.js +3 -2
  67. package/dist/cjs/components/textarea/textarea.recipe.js +13 -9
  68. package/dist/cjs/components/textlink/textlink.recipe.js +6 -3
  69. package/dist/cjs/index.js +8 -0
  70. package/dist/cjs/product/authshell/authshell.recipe.js +5 -1
  71. package/dist/cjs/product/command/command.recipe.js +4 -1
  72. package/dist/cjs/product/comments/comments.js +7 -2
  73. package/dist/cjs/product/comments/comments.recipe.js +25 -7
  74. package/dist/cjs/product/memberssettings/index.js +6 -0
  75. package/dist/cjs/product/memberssettings/memberssettings.js +99 -0
  76. package/dist/cjs/product/memberssettings/memberssettings.recipe.js +83 -0
  77. package/dist/cjs/product/notificationssettings/index.js +5 -0
  78. package/dist/cjs/product/notificationssettings/notificationssettings.js +19 -0
  79. package/dist/cjs/product/notificationssettings/notificationssettings.recipe.js +44 -0
  80. package/dist/cjs/product/recordpage/recordpage.js +101 -9
  81. package/dist/cjs/product/recordpage/recordpage.recipe.js +43 -6
  82. package/dist/cjs/product/workspacegeneralsettings/index.js +5 -0
  83. package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.js +21 -0
  84. package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +51 -0
  85. package/dist/cjs/tokens/contract.js +1 -0
  86. package/dist/cjs/tokens/elevation.js +8 -5
  87. package/dist/cjs/tokens/palette.js +107 -33
  88. package/dist/cjs/tokens/scale.js +45 -2
  89. package/dist/cjs/tokens/semantic.js +26 -0
  90. package/dist/columncalc.css +15 -7
  91. package/dist/columncalc.layered.css +15 -7
  92. package/dist/command.css +23 -19
  93. package/dist/command.layered.css +23 -19
  94. package/dist/comments.css +28 -19
  95. package/dist/comments.d.ts +2 -2
  96. package/dist/comments.layered.css +28 -19
  97. package/dist/datatable.css +161 -67
  98. package/dist/datatable.layered.css +161 -67
  99. package/dist/datepicker.css +13 -41
  100. package/dist/datepicker.layered.css +13 -41
  101. package/dist/datepickerfield.css +4 -1
  102. package/dist/datepickerfield.layered.css +4 -1
  103. package/dist/dialog.css +12 -7
  104. package/dist/dialog.layered.css +12 -7
  105. package/dist/emptystate.css +5 -3
  106. package/dist/emptystate.layered.css +5 -3
  107. package/dist/esm/components/accentpicker/accentpicker.js +30 -0
  108. package/dist/esm/components/accentpicker/accentpicker.recipe.js +22 -0
  109. package/dist/esm/components/accentpicker/index.js +2 -0
  110. package/dist/esm/components/avatar/avatar.recipe.js +4 -1
  111. package/dist/esm/components/badge/badge.recipe.js +38 -10
  112. package/dist/esm/components/bottomsheet/bottomsheet.js +52 -0
  113. package/dist/esm/components/bottomsheet/bottomsheet.recipe.js +74 -0
  114. package/dist/esm/components/bottomsheet/index.js +2 -0
  115. package/dist/esm/components/button/button.recipe.js +56 -22
  116. package/dist/esm/components/checkbox/checkbox.recipe.js +61 -9
  117. package/dist/esm/components/chip/chip.js +14 -2
  118. package/dist/esm/components/chip/chip.recipe.js +69 -1
  119. package/dist/esm/components/chipgroup/chipgroup.js +15 -0
  120. package/dist/esm/components/chipgroup/chipgroup.recipe.js +33 -0
  121. package/dist/esm/components/chipgroup/index.js +2 -0
  122. package/dist/esm/components/datatable/datatable.js +5 -1
  123. package/dist/esm/components/datatable/datatable.recipe.js +11 -2
  124. package/dist/esm/components/dialog/dialog.recipe.js +22 -11
  125. package/dist/esm/components/emptystate/emptystate.recipe.js +7 -2
  126. package/dist/esm/components/fileupload/fileupload.js +20 -5
  127. package/dist/esm/components/input/index.js +1 -1
  128. package/dist/esm/components/input/input.js +33 -3
  129. package/dist/esm/components/input/input.recipe.js +23 -8
  130. package/dist/esm/components/menu/menu.recipe.js +21 -7
  131. package/dist/esm/components/menusheet/index.js +2 -0
  132. package/dist/esm/components/menusheet/menusheet.js +95 -0
  133. package/dist/esm/components/menusheet/menusheet.recipe.js +100 -0
  134. package/dist/esm/components/multiselect/multiselect.js +2 -2
  135. package/dist/esm/components/multiselect/multiselect.recipe.js +45 -12
  136. package/dist/esm/components/progress/progress.js +22 -5
  137. package/dist/esm/components/progress/progress.recipe.js +30 -0
  138. package/dist/esm/components/select/select.js +3 -3
  139. package/dist/esm/components/select/select.recipe.js +63 -10
  140. package/dist/esm/components/snackbar/index.js +2 -0
  141. package/dist/esm/components/snackbar/snackbar.js +84 -0
  142. package/dist/esm/components/snackbar/snackbar.recipe.js +68 -0
  143. package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
  144. package/dist/esm/components/tabletoolbar/tabletoolbar.js +37 -12
  145. package/dist/esm/components/tabs/tabs.js +10 -4
  146. package/dist/esm/components/tabs/tabs.recipe.js +23 -6
  147. package/dist/esm/components/text/text.recipe.js +8 -7
  148. package/dist/esm/components/textarea/textarea.js +3 -2
  149. package/dist/esm/components/textarea/textarea.recipe.js +14 -10
  150. package/dist/esm/components/textlink/textlink.recipe.js +6 -3
  151. package/dist/esm/index.js +8 -0
  152. package/dist/esm/product/authshell/authshell.recipe.js +5 -1
  153. package/dist/esm/product/command/command.recipe.js +4 -1
  154. package/dist/esm/product/comments/comments.js +7 -2
  155. package/dist/esm/product/comments/comments.recipe.js +25 -7
  156. package/dist/esm/product/memberssettings/index.js +1 -0
  157. package/dist/esm/product/memberssettings/memberssettings.js +62 -0
  158. package/dist/esm/product/memberssettings/memberssettings.recipe.js +80 -0
  159. package/dist/esm/product/notificationssettings/index.js +1 -0
  160. package/dist/esm/product/notificationssettings/notificationssettings.js +16 -0
  161. package/dist/esm/product/notificationssettings/notificationssettings.recipe.js +41 -0
  162. package/dist/esm/product/recordpage/recordpage.js +102 -10
  163. package/dist/esm/product/recordpage/recordpage.recipe.js +43 -6
  164. package/dist/esm/product/workspacegeneralsettings/index.js +1 -0
  165. package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.js +18 -0
  166. package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +48 -0
  167. package/dist/esm/tokens/contract.js +2 -1
  168. package/dist/esm/tokens/elevation.js +8 -5
  169. package/dist/esm/tokens/palette.js +107 -33
  170. package/dist/esm/tokens/scale.js +44 -1
  171. package/dist/esm/tokens/semantic.js +26 -0
  172. package/dist/fileupload.css +3 -1
  173. package/dist/fileupload.layered.css +3 -1
  174. package/dist/input.css +11 -2
  175. package/dist/input.layered.css +11 -2
  176. package/dist/listpage.css +3 -1
  177. package/dist/listpage.layered.css +3 -1
  178. package/dist/memberssettings.css +67 -0
  179. package/dist/memberssettings.d.ts +7 -0
  180. package/dist/memberssettings.layered.css +69 -0
  181. package/dist/menu.css +2 -2
  182. package/dist/menu.layered.css +2 -2
  183. package/dist/menusheet.css +36 -0
  184. package/dist/menusheet.d.ts +7 -0
  185. package/dist/menusheet.layered.css +38 -0
  186. package/dist/multiselect.css +17 -6
  187. package/dist/multiselect.d.ts +2 -2
  188. package/dist/multiselect.layered.css +17 -6
  189. package/dist/native/tokens.d.ts +2 -1
  190. package/dist/native/tokens.js +53 -25
  191. package/dist/notificationssettings.css +22 -0
  192. package/dist/notificationssettings.d.ts +7 -0
  193. package/dist/notificationssettings.layered.css +24 -0
  194. package/dist/objectsettings.css +4 -4
  195. package/dist/objectsettings.layered.css +4 -4
  196. package/dist/progress.css +3 -0
  197. package/dist/progress.layered.css +3 -0
  198. package/dist/recordpage.css +67 -23
  199. package/dist/recordpage.layered.css +67 -23
  200. package/dist/recordpanel.css +35 -16
  201. package/dist/recordpanel.layered.css +35 -16
  202. package/dist/resizablepanel.css +8 -5
  203. package/dist/resizablepanel.layered.css +8 -5
  204. package/dist/richtext.css +24 -8
  205. package/dist/richtext.layered.css +24 -8
  206. package/dist/savedviews.css +9 -2
  207. package/dist/savedviews.layered.css +9 -2
  208. package/dist/select.css +47 -7
  209. package/dist/select.d.ts +2 -2
  210. package/dist/select.layered.css +47 -7
  211. package/dist/settingsshell.css +2 -3
  212. package/dist/settingsshell.layered.css +2 -3
  213. package/dist/slider.css +6 -27
  214. package/dist/slider.layered.css +6 -27
  215. package/dist/snackbar.css +24 -0
  216. package/dist/snackbar.d.ts +7 -0
  217. package/dist/snackbar.layered.css +26 -0
  218. package/dist/statcard.css +3 -1
  219. package/dist/statcard.layered.css +3 -1
  220. package/dist/styles.css +927 -365
  221. package/dist/styles.layered.css +927 -365
  222. package/dist/table.css +28 -10
  223. package/dist/table.layered.css +28 -10
  224. package/dist/tabletoolbar.css +35 -24
  225. package/dist/tabletoolbar.layered.css +35 -24
  226. package/dist/tabs.css +18 -4
  227. package/dist/tabs.layered.css +18 -4
  228. package/dist/text.css +1 -1
  229. package/dist/text.layered.css +1 -1
  230. package/dist/textarea.css +4 -7
  231. package/dist/textarea.layered.css +4 -7
  232. package/dist/textlink.css +2 -2
  233. package/dist/textlink.layered.css +2 -2
  234. package/dist/themepicker.css +2 -1
  235. package/dist/themepicker.layered.css +2 -1
  236. package/dist/tokens.css +31 -13
  237. package/dist/tokens.json +53 -25
  238. package/dist/types/components/accentpicker/accentpicker.d.ts +23 -0
  239. package/dist/types/components/accentpicker/accentpicker.recipe.d.ts +3 -0
  240. package/dist/types/components/accentpicker/index.d.ts +2 -0
  241. package/dist/types/components/bottomsheet/bottomsheet.d.ts +35 -0
  242. package/dist/types/components/bottomsheet/bottomsheet.recipe.d.ts +3 -0
  243. package/dist/types/components/bottomsheet/index.d.ts +2 -0
  244. package/dist/types/components/button/button.recipe.d.ts +13 -8
  245. package/dist/types/components/checkbox/checkbox.recipe.d.ts +28 -5
  246. package/dist/types/components/chip/chip.d.ts +22 -0
  247. package/dist/types/components/chip/chip.recipe.d.ts +48 -0
  248. package/dist/types/components/chipgroup/chipgroup.d.ts +14 -0
  249. package/dist/types/components/chipgroup/chipgroup.recipe.d.ts +5 -0
  250. package/dist/types/components/chipgroup/index.d.ts +2 -0
  251. package/dist/types/components/datatable/datatable.d.ts +19 -0
  252. package/dist/types/components/fileupload/fileupload.d.ts +26 -0
  253. package/dist/types/components/input/index.d.ts +1 -1
  254. package/dist/types/components/input/input.d.ts +84 -0
  255. package/dist/types/components/menusheet/index.d.ts +2 -0
  256. package/dist/types/components/menusheet/menusheet.d.ts +42 -0
  257. package/dist/types/components/menusheet/menusheet.recipe.d.ts +3 -0
  258. package/dist/types/components/multiselect/multiselect.d.ts +4 -3
  259. package/dist/types/components/multiselect/multiselect.recipe.d.ts +3 -0
  260. package/dist/types/components/progress/progress.d.ts +16 -4
  261. package/dist/types/components/progress/progress.recipe.d.ts +22 -0
  262. package/dist/types/components/select/select.d.ts +6 -5
  263. package/dist/types/components/select/select.recipe.d.ts +3 -0
  264. package/dist/types/components/snackbar/index.d.ts +2 -0
  265. package/dist/types/components/snackbar/snackbar.d.ts +36 -0
  266. package/dist/types/components/snackbar/snackbar.recipe.d.ts +5 -0
  267. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +28 -1
  268. package/dist/types/components/tabs/tabs.d.ts +11 -1
  269. package/dist/types/components/textarea/textarea.d.ts +16 -0
  270. package/dist/types/index.d.ts +8 -0
  271. package/dist/types/product/comments/comments.d.ts +9 -3
  272. package/dist/types/product/comments/comments.recipe.d.ts +12 -2
  273. package/dist/types/product/memberssettings/index.d.ts +1 -0
  274. package/dist/types/product/memberssettings/memberssettings.d.ts +85 -0
  275. package/dist/types/product/memberssettings/memberssettings.recipe.d.ts +3 -0
  276. package/dist/types/product/notificationssettings/index.d.ts +1 -0
  277. package/dist/types/product/notificationssettings/notificationssettings.d.ts +37 -0
  278. package/dist/types/product/notificationssettings/notificationssettings.recipe.d.ts +3 -0
  279. package/dist/types/product/recordpage/recordpage.d.ts +89 -2
  280. package/dist/types/product/workspacegeneralsettings/index.d.ts +1 -0
  281. package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.d.ts +48 -0
  282. package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.recipe.d.ts +3 -0
  283. package/dist/types/tokens/contract.d.ts +7 -1
  284. package/dist/types/tokens/elevation.d.ts +8 -5
  285. package/dist/types/tokens/palette.d.ts +28 -12
  286. package/dist/types/tokens/scale.d.ts +12 -1
  287. package/dist/types/tokens/semantic.d.ts +17 -0
  288. package/dist/wheelpicker.css +4 -2
  289. package/dist/wheelpicker.layered.css +4 -2
  290. package/dist/workspacegeneralsettings.css +30 -0
  291. package/dist/workspacegeneralsettings.d.ts +7 -0
  292. package/dist/workspacegeneralsettings.layered.css +32 -0
  293. package/package.json +41 -1
@@ -8,9 +8,14 @@ exports.palette = {
8
8
  // on a bright tone fill. Same value as gray900's light side (the measured
9
9
  // near-black), named separately because its job is not "primary foreground".
10
10
  ink: { light: "#101112", dark: "#101112" },
11
- gray50: { light: "#f4f4f5", dark: "#101112" },
11
+ // seed-identity migration (your-moon/crisp#890): seed's bg.layer-default-
12
+ // pressed / gray-100. Light side only — dark is untouched, unmeasured
13
+ // Attio territory this migration doesn't scope into.
14
+ gray50: { light: "#f7f8f9", dark: "#101112" },
12
15
  gray900: { light: "#101112", dark: "#f5f5f5" },
13
- line200: { light: "#e4e4e7", dark: "#212224" },
16
+ // seed-identity migration (your-moon/crisp#890): seed's stroke.neutral-
17
+ // weak / gray-400. Light side only, same scoping as `gray50` above.
18
+ line200: { light: "#dcdee3", dark: "#212224" },
14
19
  line100: { light: "#eeeff1", dark: "#1c1d1f" },
15
20
  // ImportDialog's dropzone border — measured live from Attio's Import CSV
16
21
  // flow (`rgb(230,231,234)`), distinct from `line200`/`line100` (#e4e4e7 /
@@ -22,8 +27,11 @@ exports.palette = {
22
27
  line150: { light: "#e6e7ea", dark: "#212224" },
23
28
  // The filter chip's field/value segments while the condition is
24
29
  // incomplete (no value typed yet) — measured live on Attio's own filter
25
- // chip (`rgb(246,247,247)`), lighter than `gray50` (#f4f4f5, close but not
26
- // equal). The chip's operator/kebab segments stay `gray00` in the same
30
+ // chip (`rgb(246,247,247)`), close to but not equal to `gray50`
31
+ // (`#f7f8f9` since the seed-identity migration, your-moon/crisp#890 — the
32
+ // two used to differ the other direction, gray25 lighter; the relative
33
+ // order isn't the point, staying off `gray50` while remaining a
34
+ // near-neighbour is). The chip's operator/kebab segments stay `gray00` in the same
27
35
  // state; only the two text-content segments carry this muted fill. Dark
28
36
  // value not independently re-measured (Attio's dark theme is off-limits to
29
37
  // toggle) — reuses `gray50`'s dark value, the nearest existing "muted
@@ -58,14 +66,34 @@ exports.palette = {
58
66
  ringBrandSoft: { light: "#d6e5ff", dark: "#212224" },
59
67
  tileActive: { light: "#ffffff", dark: "#101112" },
60
68
  tileActiveShadow: { light: "rgba(0,0,0,0.04)", dark: "rgba(0,0,0,0)" },
61
- // Dialog's page-dimming backdrop (crisp#677) — measured live behind the
62
- // Create-attribute FormDialog, both themes: `rgba(0,0,0,.25)` light,
63
- // `rgba(0,0,0,.55)` dark. `Dialog`'s own backdrop had shipped fully
64
- // `transparent` (AUTHORING's Lesson 14 measured the command palette has
65
- // NO dark backdrop and that got generalized to every `Dialog`, which this
66
- // corrects — the palette is a different surface from a plain content
67
- // dialog and really does dim the page).
68
- bgScrim: { light: "rgba(0,0,0,0.25)", dark: "rgba(0,0,0,0.55)" },
69
+ // Dialog's page-dimming backdrop (crisp#677, Attio's own measured value:
70
+ // `rgba(0,0,0,.25)` light, `rgba(0,0,0,.55)` dark — `Dialog`'s own backdrop
71
+ // had shipped fully `transparent`, AUTHORING's Lesson 14 measured the
72
+ // command palette has NO dark backdrop and that got generalized to every
73
+ // `Dialog`, which this corrected).
74
+ //
75
+ // your-moon/crisp#934: light theme moved to seed-design's own scrim
76
+ // (`#00000074` ≈ 45% black, `bg.overlay`) — the owner's flat-dialog
77
+ // directive names "seed's own scrim" specifically, now that elevation is
78
+ // conveyed by the scrim alone (no more frosted-glass shadow/blur). Dark
79
+ // theme's `.55` is UNCHANGED: seed's own token system has no separate
80
+ // dark-theme scrim value to adopt, and `.55` wasn't found wrong -- only
81
+ // light had a sourced replacement value to move to.
82
+ bgScrim: { light: "rgba(0,0,0,0.45)", dark: "rgba(0,0,0,0.55)" },
83
+ // seed-design's `$color.bg.overlay` (BottomSheet/MenuSheet's own backdrop,
84
+ // crisp#911) — kept as its OWN token rather than folded into `bgScrim`
85
+ // above, even though #934 (landed after this one was added) moved
86
+ // `bgScrim`'s LIGHT value to the same `#00000074`: `bgOverlayStrong` is
87
+ // seed's literally theme-CONSTANT value (`color.yaml` gives the same hex
88
+ // for both `theme-light` and `theme-dark`), while `bgScrim` still differs
89
+ // by theme (`.45`/`.55`) -- the two tokens express different design
90
+ // decisions that currently coincide in one theme only.
91
+ bgOverlayStrong: { light: "#00000074", dark: "#00000074" },
92
+ // seed-design's `$color.stroke.neutral-muted` (MenuSheet group divider,
93
+ // crisp#911) -- a faint alpha hairline between grouped rows, theme-flipping
94
+ // (`color.yaml`: `static-black-alpha-300` light / `static-white-alpha-100`
95
+ // dark).
96
+ strokeGroupDivider: { light: "#00000010", dark: "#ffffff17" },
69
97
  // The discard-confirm's description line (crisp#677, `Dialog`'s new
70
98
  // `variant="alert"`) — measured live, both themes, over `popoverBg`: a
71
99
  // theme-relative alpha rather than a flat gray, so it stays legible if
@@ -84,25 +112,54 @@ exports.palette = {
84
112
  shadowPopover2: { light: "rgba(28,40,64,0.12)", dark: "rgba(0,0,0,0.24)" },
85
113
  shadowPopover3: { light: "rgba(24,41,75,0.16)", dark: "rgba(0,0,0,0.32)" },
86
114
  gray400: { light: "#71717a", dark: "#9a9aa2" },
87
- brand600: { light: "#266df0", dark: "#266df0" },
88
- brand700: { light: "#1f5fd6", dark: "#1f5fd6" },
89
- red600: { light: "#e5484d", dark: "#ff5a5f" },
90
- // A red dark enough to carry white text. red600 cannot: white on it is
91
- // 3.91:1 light / 3.05:1 dark, and the solid button's hover DARKENS the fill
92
- // (filter: brightness), so dark ink fails there instead (4.49 at hover).
93
- // Measured from the reference stylesheet, which ships this red alongside the
94
- // #EB3B3B it uses for destructive menu TEXT. Does not flip: a filled
95
- // destructive control needs the same white-bearing fill in both themes.
96
- red700: { light: "#ba2525", dark: "#ba2525" },
97
- // The #EB3B3B named in red700's own comment above (destructive menu text) —
98
- // it had never actually been given a token. Independently re-measured live
99
- // on `app.attio.com/.../tasks`, `rgb(235,59,59)`, as the overdue due-date
100
- // text colour on the Tasks page (crisp#462) — same hex, second surface.
101
- // Dark not independently re-measured (Attio's theme toggle is off-limits,
102
- // same restriction noted throughout this file); reuses red600's dark value,
103
- // the same "brightens for legibility on a dark surface" tone this red
104
- // already sits next to, rather than inventing a third red.
105
- red500: { light: "#eb3b3b", dark: "#ff5a5f" },
115
+ // seed-identity migration (your-moon/crisp#890, "Attio structure, seed
116
+ // look"): the owner's TechPartners primary (#0298D9, sourced from the
117
+ // official logo SVG + the live site's own compiled CSS — see
118
+ // ~/grc-parity/seed-identity-spec.md §1) replaces the old measured-from-
119
+ // Attio brand blue, built as seed's own carrot-scale RELATIVE lightness
120
+ // shape around that exact hex at step 600 ("Method A" in the spec — the
121
+ // verified logo hex stays literally in the scale, at the step that's
122
+ // actually rendered, rather than a mathematically tidier neighbour).
123
+ // Does not flip with theme, matching this token's own prior precedent.
124
+ brand600: { light: "#0298d9", dark: "#0298d9" },
125
+ // Method A's raw carrot-shape output (L 37.1%) — the hover/pressed-darken
126
+ // step of the ACCENT colour above, same role brand700 has always had.
127
+ // Not tuned for any particular contrast target; see `brandContrast` below
128
+ // for the token that carries that job.
129
+ brand700: { light: "#0283bb", dark: "#0283bb" },
130
+ // your-moon/crisp#897: #0298d9 (the verified brand hex, kept exactly as
131
+ // the ACCENT everywhere else — focus rings, selected states, icons,
132
+ // tints) only clears 3.23:1 against white, short of the 4.5:1 a SOLID
133
+ // fill carrying white text needs (Button primary, Badge solid+brand,
134
+ // Avatar's brand tone), or brand-coloured TEXT sitting directly on a white
135
+ // page (TextLink/Text's brand tone). This is that darker, AA-safe step —
136
+ // same hue (198°), L dropped to 34% — clearing 4.88:1 with white. An
137
+ // earlier round of this fix used dark ink text instead of finding this
138
+ // value; that read off-brand (seed's own solid buttons use white) and got
139
+ // reverted in favour of this.
140
+ brandContrast: { light: "#0278ac", dark: "#0278ac" },
141
+ // seed's red-700 (fg.critical) — the accent used for plain danger TEXT
142
+ // (an overdue due-date, a destructive menu label) and for tinting
143
+ // (Chip/Badge's soft-danger `color-mix()` inputs). NOT used for a solid
144
+ // fill paired with white text — see `red700` below for why that split
145
+ // matters here specifically.
146
+ red600: { light: "#fa342c", dark: "#ff5a5f" },
147
+ // seed's red-800 (bg.critical-solid-**pressed**), not red-700
148
+ // (bg.critical-solid-enabled, `red600` above) — deliberately the darker
149
+ // of the two. `red700` is crisp's SOLID destructive fill (Button danger,
150
+ // Badge solid+danger), which pairs with white text and, on Button,
151
+ // DARKENS further on hover/active via a brightness filter (not a second
152
+ // token, per this token's own original comment below this migration note
153
+ // — that invariant is why a dark-enough red matters at all). Seed's own
154
+ // red-700 only clears 3.76:1 with white (measured) — short of AA even
155
+ // before any hover darkening — so reusing crisp's existing "needs to
156
+ // survive getting darker" role means red-800 (5.68:1 at rest, improving
157
+ // through hover/active) is the correct step, not seed's literal
158
+ // "enabled" one. `red500` below is pure text again (no fill/contrast
159
+ // constraint), so it stays on the
160
+ // lighter red-700, matching seed exactly.
161
+ red700: { light: "#ca1d13", dark: "#ba2525" },
162
+ red500: { light: "#fa342c", dark: "#ff5a5f" },
106
163
  // seed-design's field focus ring (stroke-neutral-contrast = gray-1000),
107
164
  // measured from @seed-design/css. A high-contrast neutral rather than a brand
108
165
  // hue: the ring reads as "this field has focus", not as a state colour.
@@ -122,8 +179,25 @@ exports.palette = {
122
179
  neutralSubtle: { light: "#868b94", dark: "#b0b3ba" },
123
180
  neutralMuted: { light: "#555d6d", dark: "#dcdee3" },
124
181
  focusRing: { light: "#1e82eb", dark: "#5e98fe" },
125
- green600: { light: "#1f9d57", dark: "#2ea968" },
126
- amber600: { light: "#b5730f", dark: "#e0982a" },
182
+ // seed's fg.positive / bg.positive-solid (green-700).
183
+ green600: { light: "#079171", dark: "#2ea968" },
184
+ // seed's fg.warning / stroke.warning-solid (yellow-700) — the ACCENT used
185
+ // for tinting (Badge/Chip's `soft()`/`ring()` colour-mix formulas), not
186
+ // seed's actual solid-fill colour, which is a much paler yellow at a
187
+ // different scale step — see `amberSolid` below for why the two need to
188
+ // stay separate tokens.
189
+ amber600: { light: "#9b7821", dark: "#e0982a" },
190
+ // seed's bg.warning-solid (yellow-300) — genuinely NOT amber600 tinted
191
+ // lighter: seed's warning-solid is its own pale scale step, distinct from
192
+ // the darker accent every other tone's solid fill derives from (see the
193
+ // spec's Badge section). Badge's `variant="solid" tone="warning"` uses
194
+ // this directly, unmixed, the same way `red700`'s solid destructive fill
195
+ // is used directly rather than computed from a tint. Dark side is NOT
196
+ // independently sourced (this is a new token; no prior Attio measurement
197
+ // exists to preserve) — reuses amber600's own dark value as the nearest
198
+ // existing "warning, dark theme" tone, same convention this file uses
199
+ // throughout for an unmeasured dark side (ringSwitch, line150, gray25).
200
+ amberSolid: { light: "#fbdc65", dark: "#e0982a" },
127
201
  orange600: { light: "#f97514", dark: "#f97514" },
128
202
  cyan600: { light: "#00b9eb", dark: "#00b9eb" },
129
203
  purple600: { light: "#9b69ff", dark: "#9b69ff" },
@@ -9,7 +9,7 @@
9
9
  // Recipes MUST reference these through the contract (`c.space[...]`), never a
10
10
  // literal px — this file is the only exception.
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.weight = exports.text = exports.font = exports.size = exports.radius = exports.space = void 0;
12
+ exports.tracking = exports.weight = exports.text = exports.font = exports.size = exports.radius = exports.space = void 0;
13
13
  // Spacing: gaps, padding, margins. Keys follow the Tailwind step convention
14
14
  // (0.5 = half a 4px step = 2px) so the numbers stay legible to consumers.
15
15
  exports.space = {
@@ -29,13 +29,23 @@ exports.space = {
29
29
  // Corner radius. sm/md/lg are the three used on stacked surfaces
30
30
  // (inputs, rows, tiles); full is the pill.
31
31
  exports.radius = {
32
- chip: "7px", // tag / chip corner — the single most used radius
32
+ xs: "4px", // seed-design's $radius.r1 — small badge / checkbox box corner
33
+ // your-moon/crisp#919: was `7px` (Attio's own most-measured
34
+ // radius, 70 occurrences) -- now a pill, matching seed-design's own
35
+ // `chip.yaml` (`$radius.full` at every size, no size-based radius step at
36
+ // all, unlike Button/Badge). Same numeric value as `full` below, kept as
37
+ // its own named token because every one of this token's ~9 consumers
38
+ // (Chip, DataTable/RecordPage/RecordsTable/MultiSelect's own tag/mention
39
+ // rules, TableToolbar/DatePickerField's date-preset chips) reasons about
40
+ // "the chip corner" as its own concept, not literally "a generic pill".
41
+ chip: "999px",
33
42
  sm: "6px", // chips, badges
34
43
  md: "8px", // inputs, search box
35
44
  lg: "9px", // rows, tiles, list items
36
45
  xl: "12px", // overlay items (command rows)
37
46
  "2xl": "16px", // overlay panels (command surface)
38
47
  "3xl": "20px", // seed-design's $radius.r5 — Select's listbox corner (crisp/#867)
48
+ "4xl": "24px", // seed-design's $radius.r6 — BottomSheet's top corner radius (crisp/#911)
39
49
  full: "999px", // pills
40
50
  };
41
51
  // Component sizing — recurring measured dimensions that are neither spacing nor
@@ -87,3 +97,36 @@ exports.weight = {
87
97
  semibold: "600",
88
98
  bold: "700", // seed-design's font-weight-bold, for the seed-styled calendar
89
99
  };
100
+ // Size-based letter-spacing ramp for DISPLAY/HEADING type (18px and up —
101
+ // `text.*` above tops out at 16px and stays untracked). crisp's five
102
+ // already-shipped headings tighten as they grow — authshell 20px/-0.4px (2%
103
+ // of size), objectsettings 24px/-0.48px (2%), richtext 32px/-0.6px (1.875%)
104
+ // — all Attio-measured (Inter) and left exactly as they are; this token
105
+ // never touches them, or the button (-0.07px) / table-cell (-0.14px)
106
+ // tracking, which are body sizes, not display type. (statcard's 28px/-0.4px,
107
+ // 1.43%, is a looser outlier — it sets tabular numerals, not prose — and is
108
+ // also left alone.)
109
+ //
110
+ // crisp#909: the study at docs/study/korean/ observed that Naver and Kakao
111
+ // both tighten tracking as type gets bigger, and crisp's OWN large type
112
+ // (EmptyState's 20px title, Dialog's 18px alert title, and any future
113
+ // heading) had no tracking at all — it read as default, not set. The study
114
+ // supplied the PATTERN only, never a number: Naver/Kakao's own values are
115
+ // Korean-specific and were not copied. The numbers below come from rendering
116
+ // real Mongolian Cyrillic ("Эрсдэлийн бүртгэл", "Хяналтын самбар") in VK Sans
117
+ // Display — crisp's own font override, see `font.sans` above — at every
118
+ // display size crisp uses today (18/20/24/26/28/32px), screenshotting six
119
+ // candidates per size (0%, 1%, 1.5%, 2%, 2.5%, 3% of the font-size) and
120
+ // checking for glyph collision. None collided even at 3%, so the pre-existing
121
+ // 2%-of-size rule the five Attio headings already happen to follow was kept
122
+ // as the ramp, rounded to the nearest 0.01px — it reads as deliberately set
123
+ // with headroom to spare, and keeps new display type visually consistent
124
+ // with the Attio-measured headings already shipped.
125
+ exports.tracking = {
126
+ "18": "-0.36px",
127
+ "20": "-0.4px",
128
+ "24": "-0.48px",
129
+ "26": "-0.52px",
130
+ "28": "-0.56px",
131
+ "32": "-0.64px",
132
+ };
@@ -4,6 +4,17 @@ exports.semantic = void 0;
4
4
  exports.semantic = {
5
5
  bgBrandSolid: "brand600",
6
6
  bgBrandSolidPressed: "brand700",
7
+ /** your-moon/crisp#897: the AA-safe darker sibling of `bgBrandSolid` — a
8
+ * SOLID fill carrying white text (Button primary, Badge solid+brand,
9
+ * Avatar's brand tone). `bgBrandSolid` itself stays the exact brand
10
+ * accent (focus rings, selected states, icons, tints), unpaired with
11
+ * white text anywhere that matters for contrast. */
12
+ bgBrandContrast: "brandContrast",
13
+ /** your-moon/crisp#897: brand-coloured TEXT sitting on a white page
14
+ * (TextLink/Text's `brand` tone) — same value as `bgBrandContrast`,
15
+ * named separately because one's a background and one's a foreground,
16
+ * matching every other fg/bg pair in this file. */
17
+ fgBrandContrast: "brandContrast",
7
18
  fgOnBrand: "white",
8
19
  // text on a solid success/warning/danger fill. Those tone tokens BRIGHTEN in
9
20
  // dark (they are tuned for tinted backgrounds and coloured text), so white on
@@ -30,6 +41,8 @@ exports.semantic = {
30
41
  bgTileActive: "tileActive",
31
42
  shadowTileActive: "tileActiveShadow",
32
43
  bgScrim: "bgScrim",
44
+ bgOverlayStrong: "bgOverlayStrong",
45
+ strokeGroupDivider: "strokeGroupDivider",
33
46
  fgAlertDescription: "fgAlertDescription",
34
47
  bgOverlayFrost: "overlayFrost",
35
48
  shadowOverlay1: "shadowOverlay1",
@@ -41,6 +54,15 @@ exports.semantic = {
41
54
  shadowPopover2: "shadowPopover2",
42
55
  shadowPopover3: "shadowPopover3",
43
56
  fgPrimary: "gray900",
57
+ // seed-identity migration (your-moon/crisp#890): NOT touched here, on
58
+ // purpose. seed's closest analog (fg.neutral-subtle, #868b94) is lighter
59
+ // than crisp's current #71717a, and Badge's neutral-SOLID variant reuses
60
+ // this exact token as a BACKGROUND paired with white text
61
+ // (`badge.recipe.ts`'s compound variant) — #868b94 drops that pairing to
62
+ // 3.42:1, below AA. Retargeting `fgMuted` and fixing that one background
63
+ // choice belong together in Badge's own upcoming look PR, not split
64
+ // across two PRs where the token change alone would ship a known
65
+ // contrast regression.
44
66
  fgMuted: "gray400",
45
67
  bgDanger: "red600",
46
68
  /** Fill for a SOLID destructive control that carries white text. */
@@ -66,6 +88,10 @@ exports.semantic = {
66
88
  strokeFocusRing: "focusRing",
67
89
  bgSuccess: "green600",
68
90
  bgWarning: "amber600",
91
+ /** A SOLID warning fill (Badge's `variant="solid" tone="warning"`) — seed's
92
+ * own warning-solid is a distinct, paler yellow, not `bgWarning` tinted
93
+ * lighter. See `amberSolid` in palette.ts. */
94
+ bgWarningSolid: "amberSolid",
69
95
  bgOrange: "orange600",
70
96
  bgCyan: "cyan600",
71
97
  bgPurple: "purple600",
@@ -1,30 +1,38 @@
1
1
  .crisp-columncalc {
2
- display: flex; align-items: stretch; width: 100%; height: 100%; font-family: var(--crisp-font-sans); /* Menu wraps its trigger in a flex div that sizes to content, which would shrink the button back to its text. Make the wrapper fill too, so the whole cell stays clickable. */
2
+ display: flex; align-items: stretch; width: 100%; height: 100%; font-family: var(--crisp-font-sans); /* Menu wraps its trigger in a flex div that sizes to content, which would
3
+ shrink the button back to its text. Make the wrapper fill too, so the
4
+ whole cell stays clickable. */
3
5
  & .crisp-menu { width: 100%; height: 100%; }
4
- /* No radius: the trigger fills the cell, so rounding its own corners leaves the cell's background showing through at the four corners as
6
+ /* No radius: the trigger fills the cell, so rounding its own corners
7
+ leaves the cell's background showing through at the four corners as
5
8
  soon as the hover tint paints. Everything else that fills a grid cell
6
9
  agrees -- recordstable-sum-btn, the same summary trigger, declares no
7
10
  radius, and datatable-grip and the embedded pickers zero theirs. An 8px
8
11
  radius survived the chip-to-full-cell conversion and shipped rounded
9
- until #282, so the spec check now guards it. */
10
- /* The hit target is the WHOLE summary cell -- measured 246x36 with
12
+ until #282, so the spec check now guards it. */ /* The hit target is the WHOLE summary cell -- measured 246x36 with
11
13
  padding 0 12px, not a content-sized chip. Clicking anywhere in the cell
12
14
  opens the aggregation menu.
13
15
  No `min-height` (crisp#834, found reproducing the footer-row-38px-
14
- not-36px bug in an isolated browser test, not table.recipe.ts's own border/box-sizing, the hypothesis the issue itself flagged as unconfirmed): the table cell's OWN `height: tableRow` (36px,
16
+ not-36px bug in an isolated browser test, not table.recipe.ts's own
17
+ border/box-sizing, the hypothesis the issue itself flagged as
18
+ unconfirmed): the table cell's OWN `height: tableRow` (36px,
15
19
  border-box) leaves 34px of content box once its 2px of top+bottom
16
20
  border are counted, and `min-height: tableRow` here demanded 36px
17
21
  of CONTENT height regardless -- overflowing the cell by 2px, which
18
22
  auto-height table layout resolves by growing the whole row to fit,
19
23
  landing at exactly the reported 38. `height: 100%` alone already
20
- fills whatever the cell's real content box is (the doc comment above this rule's own stated intent), with nothing left demanding more. */
24
+ fills whatever the cell's real content box is (the doc comment above
25
+ this rule's own stated intent), with nothing left demanding more. */
21
26
  & .crisp-columncalc-trigger { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; height: 100%; margin: 0; padding: 0 var(--crisp-space-3); border: none; background: transparent; color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); white-space: nowrap; cursor: pointer; transition: background-color .12s, color .12s; }
22
27
  & .crisp-columncalc-trigger:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-primary); }
23
28
  & .crisp-columncalc-trigger svg { flex-shrink: 0; opacity: 0.7; }
24
29
  & .crisp-columncalc-trigger[data-align="right"] { justify-content: flex-end; }
25
30
  & .crisp-columncalc-placeholder { overflow: hidden; text-overflow: ellipsis; }
26
31
  & .crisp-columncalc-value { color: var(--crisp-fg-primary); font-variant-numeric: tabular-nums; }
27
- /* crisp#837: re-measured live against Attio's real footer calc label -- 14px (was 13px, `c.text.md`, fixed on the shared trigger rule above) and rgba(0,0,0,.63), the same color-mix(fgPrimary, 63%) figure this file's own -op label already should have used instead of the flatter
32
+ /* crisp#837: re-measured live against Attio's real footer calc label --
33
+ 14px (was 13px, `c.text.md`, fixed on the shared trigger rule above)
34
+ and rgba(0,0,0,.63), the same color-mix(fgPrimary, 63%) figure this
35
+ file's own -op label already should have used instead of the flatter
28
36
  `fgMuted` token (a close but not measured match). */
29
37
  & .crisp-columncalc-op { color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
30
38
  & .crisp-columncalc-section { padding: var(--crisp-space-1-5) var(--crisp-space-2) var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
@@ -1,31 +1,39 @@
1
1
  @layer crisp-components {
2
2
  .crisp-columncalc {
3
- display: flex; align-items: stretch; width: 100%; height: 100%; font-family: var(--crisp-font-sans); /* Menu wraps its trigger in a flex div that sizes to content, which would shrink the button back to its text. Make the wrapper fill too, so the whole cell stays clickable. */
3
+ display: flex; align-items: stretch; width: 100%; height: 100%; font-family: var(--crisp-font-sans); /* Menu wraps its trigger in a flex div that sizes to content, which would
4
+ shrink the button back to its text. Make the wrapper fill too, so the
5
+ whole cell stays clickable. */
4
6
  & .crisp-menu { width: 100%; height: 100%; }
5
- /* No radius: the trigger fills the cell, so rounding its own corners leaves the cell's background showing through at the four corners as
7
+ /* No radius: the trigger fills the cell, so rounding its own corners
8
+ leaves the cell's background showing through at the four corners as
6
9
  soon as the hover tint paints. Everything else that fills a grid cell
7
10
  agrees -- recordstable-sum-btn, the same summary trigger, declares no
8
11
  radius, and datatable-grip and the embedded pickers zero theirs. An 8px
9
12
  radius survived the chip-to-full-cell conversion and shipped rounded
10
- until #282, so the spec check now guards it. */
11
- /* The hit target is the WHOLE summary cell -- measured 246x36 with
13
+ until #282, so the spec check now guards it. */ /* The hit target is the WHOLE summary cell -- measured 246x36 with
12
14
  padding 0 12px, not a content-sized chip. Clicking anywhere in the cell
13
15
  opens the aggregation menu.
14
16
  No `min-height` (crisp#834, found reproducing the footer-row-38px-
15
- not-36px bug in an isolated browser test, not table.recipe.ts's own border/box-sizing, the hypothesis the issue itself flagged as unconfirmed): the table cell's OWN `height: tableRow` (36px,
17
+ not-36px bug in an isolated browser test, not table.recipe.ts's own
18
+ border/box-sizing, the hypothesis the issue itself flagged as
19
+ unconfirmed): the table cell's OWN `height: tableRow` (36px,
16
20
  border-box) leaves 34px of content box once its 2px of top+bottom
17
21
  border are counted, and `min-height: tableRow` here demanded 36px
18
22
  of CONTENT height regardless -- overflowing the cell by 2px, which
19
23
  auto-height table layout resolves by growing the whole row to fit,
20
24
  landing at exactly the reported 38. `height: 100%` alone already
21
- fills whatever the cell's real content box is (the doc comment above this rule's own stated intent), with nothing left demanding more. */
25
+ fills whatever the cell's real content box is (the doc comment above
26
+ this rule's own stated intent), with nothing left demanding more. */
22
27
  & .crisp-columncalc-trigger { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; height: 100%; margin: 0; padding: 0 var(--crisp-space-3); border: none; background: transparent; color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); white-space: nowrap; cursor: pointer; transition: background-color .12s, color .12s; }
23
28
  & .crisp-columncalc-trigger:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-primary); }
24
29
  & .crisp-columncalc-trigger svg { flex-shrink: 0; opacity: 0.7; }
25
30
  & .crisp-columncalc-trigger[data-align="right"] { justify-content: flex-end; }
26
31
  & .crisp-columncalc-placeholder { overflow: hidden; text-overflow: ellipsis; }
27
32
  & .crisp-columncalc-value { color: var(--crisp-fg-primary); font-variant-numeric: tabular-nums; }
28
- /* crisp#837: re-measured live against Attio's real footer calc label -- 14px (was 13px, `c.text.md`, fixed on the shared trigger rule above) and rgba(0,0,0,.63), the same color-mix(fgPrimary, 63%) figure this file's own -op label already should have used instead of the flatter
33
+ /* crisp#837: re-measured live against Attio's real footer calc label --
34
+ 14px (was 13px, `c.text.md`, fixed on the shared trigger rule above)
35
+ and rgba(0,0,0,.63), the same color-mix(fgPrimary, 63%) figure this
36
+ file's own -op label already should have used instead of the flatter
29
37
  `fgMuted` token (a close but not measured match). */
30
38
  & .crisp-columncalc-op { color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
31
39
  & .crisp-columncalc-section { padding: var(--crisp-space-1-5) var(--crisp-space-2) var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
package/dist/command.css CHANGED
@@ -7,28 +7,32 @@
7
7
  & .crisp-command-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); overflow: hidden; }
8
8
  & .crisp-command-control { display: flex; align-items: center; gap: var(--crisp-space-2-5); height: 52px; flex-shrink: 0; padding: 0 var(--crisp-space-4); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
9
9
  & .crisp-command-control svg { flex-shrink: 0; }
10
- /* The palette's label element. It exists for the assistive tree only: zag's combobox names the input through it and points the listbox's
10
+ /* The palette's label element. It exists for the assistive tree only: zag's
11
+ combobox names the input through it and points the listbox's
11
12
  aria-labelledby at it, and without it both were unnamed and the reference
12
13
  resolved to nothing (#225). Clipped rather than display:none, which would
13
14
  take it out of the tree it exists for. */
14
- & .crisp-command-srlabel { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
15
- & .crisp-command-input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-xl); color: var(--crisp-fg-primary); }
16
- & .crisp-command-input::placeholder { color: var(--crisp-fg-muted); }
17
- & .crisp-command-list { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-1) var(--crisp-space-2-5); display: flex; flex-direction: column; gap: var(--crisp-space-px); }
18
- & .crisp-command-empty { padding: var(--crisp-space-8) var(--crisp-space-3); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
19
- & .crisp-command-item { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: 36px; padding-inline: var(--crisp-space-2-5); border-radius: var(--crisp-radius-xl); font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; }
20
- & .crisp-command-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
21
- & .crisp-command-item[data-highlighted] { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
22
- & .crisp-command-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
23
- & .crisp-command-item-shortcut { margin-inline-start: auto; flex-shrink: 0; display: flex; align-items: center; gap: var(--crisp-space-0-5); }
24
- & .crisp-command-group-label { padding: var(--crisp-space-2) var(--crisp-space-2-5) var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
25
- & .crisp-command-list > .crisp-command-group-label:first-child { padding-top: var(--crisp-space-1); }
26
- & .crisp-command-footer { display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; height: 44px; padding: 0 var(--crisp-space-2-5); border-top: 1px solid var(--crisp-border-subtle); }
27
- & .crisp-command-footer-nav { display: flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
28
- & .crisp-command-footer-action { display: flex; align-items: center; gap: var(--crisp-space-2); height: 28px; max-width: 60%; padding: 0 var(--crisp-space-1) 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
29
- & .crisp-command-footer-action:disabled { opacity: 0.5; cursor: default; }
30
- & .crisp-command-footer-action-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
31
- & .crisp-command-footer-key { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: rgba(255,255,255,0.22); font-size: var(--crisp-text-xs); }
15
+ & .crisp-command-srlabel { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
16
+ & .crisp-command-input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-xl); color: var(--crisp-fg-primary); }
17
+ & .crisp-command-input::placeholder { color: var(--crisp-fg-muted); }
18
+ & .crisp-command-list { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-1) var(--crisp-space-2-5); display: flex; flex-direction: column; gap: var(--crisp-space-px); }
19
+ & .crisp-command-empty { padding: var(--crisp-space-8) var(--crisp-space-3); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
20
+ & .crisp-command-item { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: 36px; padding-inline: var(--crisp-space-2-5); border-radius: var(--crisp-radius-xl); font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; }
21
+ & .crisp-command-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
22
+ & .crisp-command-item[data-highlighted] { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
23
+ & .crisp-command-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
24
+ & .crisp-command-item-shortcut { margin-inline-start: auto; flex-shrink: 0; display: flex; align-items: center; gap: var(--crisp-space-0-5); }
25
+ & .crisp-command-group-label { padding: var(--crisp-space-2) var(--crisp-space-2-5) var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
26
+ & .crisp-command-list > .crisp-command-group-label:first-child { padding-top: var(--crisp-space-1); }
27
+ & .crisp-command-footer { display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; height: 44px; padding: 0 var(--crisp-space-2-5); border-top: 1px solid var(--crisp-border-subtle); }
28
+ & .crisp-command-footer-nav { display: flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
29
+ /* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
30
+ the accent (#0298d9) only clears 3.23:1 with white; the darker sibling
31
+ clears 4.5:1+, same fix already applied to Button/Badge/Avatar (#897). */
32
+ & .crisp-command-footer-action { display: flex; align-items: center; gap: var(--crisp-space-2); height: 28px; max-width: 60%; padding: 0 var(--crisp-space-1) 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-contrast); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
33
+ & .crisp-command-footer-action:disabled { opacity: 0.5; cursor: default; }
34
+ & .crisp-command-footer-action-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
35
+ & .crisp-command-footer-key { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: rgba(255,255,255,0.22); font-size: var(--crisp-text-xs); }
32
36
  }
33
37
 
34
38
  @media (prefers-reduced-motion: reduce) {
@@ -8,28 +8,32 @@
8
8
  & .crisp-command-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); overflow: hidden; }
9
9
  & .crisp-command-control { display: flex; align-items: center; gap: var(--crisp-space-2-5); height: 52px; flex-shrink: 0; padding: 0 var(--crisp-space-4); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
10
10
  & .crisp-command-control svg { flex-shrink: 0; }
11
- /* The palette's label element. It exists for the assistive tree only: zag's combobox names the input through it and points the listbox's
11
+ /* The palette's label element. It exists for the assistive tree only: zag's
12
+ combobox names the input through it and points the listbox's
12
13
  aria-labelledby at it, and without it both were unnamed and the reference
13
14
  resolved to nothing (#225). Clipped rather than display:none, which would
14
15
  take it out of the tree it exists for. */
15
- & .crisp-command-srlabel { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
16
- & .crisp-command-input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-xl); color: var(--crisp-fg-primary); }
17
- & .crisp-command-input::placeholder { color: var(--crisp-fg-muted); }
18
- & .crisp-command-list { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-1) var(--crisp-space-2-5); display: flex; flex-direction: column; gap: var(--crisp-space-px); }
19
- & .crisp-command-empty { padding: var(--crisp-space-8) var(--crisp-space-3); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
20
- & .crisp-command-item { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: 36px; padding-inline: var(--crisp-space-2-5); border-radius: var(--crisp-radius-xl); font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; }
21
- & .crisp-command-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
22
- & .crisp-command-item[data-highlighted] { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
23
- & .crisp-command-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
24
- & .crisp-command-item-shortcut { margin-inline-start: auto; flex-shrink: 0; display: flex; align-items: center; gap: var(--crisp-space-0-5); }
25
- & .crisp-command-group-label { padding: var(--crisp-space-2) var(--crisp-space-2-5) var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
26
- & .crisp-command-list > .crisp-command-group-label:first-child { padding-top: var(--crisp-space-1); }
27
- & .crisp-command-footer { display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; height: 44px; padding: 0 var(--crisp-space-2-5); border-top: 1px solid var(--crisp-border-subtle); }
28
- & .crisp-command-footer-nav { display: flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
29
- & .crisp-command-footer-action { display: flex; align-items: center; gap: var(--crisp-space-2); height: 28px; max-width: 60%; padding: 0 var(--crisp-space-1) 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
30
- & .crisp-command-footer-action:disabled { opacity: 0.5; cursor: default; }
31
- & .crisp-command-footer-action-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
32
- & .crisp-command-footer-key { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: rgba(255,255,255,0.22); font-size: var(--crisp-text-xs); }
16
+ & .crisp-command-srlabel { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
17
+ & .crisp-command-input { flex: 1; min-width: 0; border: none; outline: none; background: transparent; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-xl); color: var(--crisp-fg-primary); }
18
+ & .crisp-command-input::placeholder { color: var(--crisp-fg-muted); }
19
+ & .crisp-command-list { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-1) var(--crisp-space-2-5); display: flex; flex-direction: column; gap: var(--crisp-space-px); }
20
+ & .crisp-command-empty { padding: var(--crisp-space-8) var(--crisp-space-3); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
21
+ & .crisp-command-item { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); height: 36px; padding-inline: var(--crisp-space-2-5); border-radius: var(--crisp-radius-xl); font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; }
22
+ & .crisp-command-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
23
+ & .crisp-command-item[data-highlighted] { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
24
+ & .crisp-command-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
25
+ & .crisp-command-item-shortcut { margin-inline-start: auto; flex-shrink: 0; display: flex; align-items: center; gap: var(--crisp-space-0-5); }
26
+ & .crisp-command-group-label { padding: var(--crisp-space-2) var(--crisp-space-2-5) var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
27
+ & .crisp-command-list > .crisp-command-group-label:first-child { padding-top: var(--crisp-space-1); }
28
+ & .crisp-command-footer { display: flex; align-items: center; justify-content: space-between; flex-shrink: 0; height: 44px; padding: 0 var(--crisp-space-2-5); border-top: 1px solid var(--crisp-border-subtle); }
29
+ & .crisp-command-footer-nav { display: flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
30
+ /* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
31
+ the accent (#0298d9) only clears 3.23:1 with white; the darker sibling
32
+ clears 4.5:1+, same fix already applied to Button/Badge/Avatar (#897). */
33
+ & .crisp-command-footer-action { display: flex; align-items: center; gap: var(--crisp-space-2); height: 28px; max-width: 60%; padding: 0 var(--crisp-space-1) 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-contrast); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
34
+ & .crisp-command-footer-action:disabled { opacity: 0.5; cursor: default; }
35
+ & .crisp-command-footer-action-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
36
+ & .crisp-command-footer-key { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: rgba(255,255,255,0.22); font-size: var(--crisp-text-xs); }
33
37
  }
34
38
 
35
39
  @media (prefers-reduced-motion: reduce) {