@crisp-ui-kit/crisp 0.57.1 → 0.57.3

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 (277) hide show
  1. package/dist/authshell.css +9 -4
  2. package/dist/authshell.layered.css +9 -4
  3. package/dist/badge.css +3 -3
  4. package/dist/badge.layered.css +3 -3
  5. package/dist/board.css +28 -8
  6. package/dist/board.layered.css +28 -8
  7. package/dist/bottomsheet.css +26 -0
  8. package/dist/bottomsheet.d.ts +7 -0
  9. package/dist/bottomsheet.layered.css +28 -0
  10. package/dist/button.css +10 -6
  11. package/dist/button.d.ts +2 -2
  12. package/dist/button.layered.css +10 -6
  13. package/dist/checkbox.css +7 -3
  14. package/dist/checkbox.layered.css +7 -3
  15. package/dist/chip.css +16 -1
  16. package/dist/chip.d.ts +3 -1
  17. package/dist/chip.layered.css +16 -1
  18. package/dist/chipgroup.css +5 -0
  19. package/dist/chipgroup.d.ts +7 -0
  20. package/dist/chipgroup.layered.css +7 -0
  21. package/dist/cjs/components/badge/badge.recipe.js +22 -8
  22. package/dist/cjs/components/bottomsheet/bottomsheet.js +90 -0
  23. package/dist/cjs/components/bottomsheet/bottomsheet.recipe.js +77 -0
  24. package/dist/cjs/components/bottomsheet/index.js +9 -0
  25. package/dist/cjs/components/breadcrumb/breadcrumb.js +1 -1
  26. package/dist/cjs/components/button/button.recipe.js +67 -15
  27. package/dist/cjs/components/checkbox/checkbox.recipe.js +61 -9
  28. package/dist/cjs/components/chip/chip.js +14 -2
  29. package/dist/cjs/components/chip/chip.recipe.js +72 -2
  30. package/dist/cjs/components/chipgroup/chipgroup.js +51 -0
  31. package/dist/cjs/components/chipgroup/chipgroup.recipe.js +36 -0
  32. package/dist/cjs/components/chipgroup/index.js +7 -0
  33. package/dist/cjs/components/datatable/datatable.js +5 -1
  34. package/dist/cjs/components/datatable/datatable.recipe.js +21 -6
  35. package/dist/cjs/components/datepickerfield/datepickerfield.js +2 -2
  36. package/dist/cjs/components/datepickerfield/datepickerfield.recipe.js +16 -3
  37. package/dist/cjs/components/dialog/dialog.recipe.js +21 -10
  38. package/dist/cjs/components/emptystate/emptystate.recipe.js +7 -2
  39. package/dist/cjs/components/fileupload/fileupload.js +21 -4
  40. package/dist/cjs/components/input/index.js +2 -1
  41. package/dist/cjs/components/input/input.js +31 -1
  42. package/dist/cjs/components/input/input.recipe.js +16 -9
  43. package/dist/cjs/components/menu/menu.js +18 -2
  44. package/dist/cjs/components/menu/menu.recipe.js +21 -7
  45. package/dist/cjs/components/menusheet/index.js +9 -0
  46. package/dist/cjs/components/menusheet/menusheet.js +133 -0
  47. package/dist/cjs/components/menusheet/menusheet.recipe.js +103 -0
  48. package/dist/cjs/components/multiselect/multiselect.js +1 -1
  49. package/dist/cjs/components/multiselect/multiselect.recipe.js +33 -9
  50. package/dist/cjs/components/select/select.js +1 -1
  51. package/dist/cjs/components/select/select.recipe.js +38 -12
  52. package/dist/cjs/components/snackbar/index.js +8 -0
  53. package/dist/cjs/components/snackbar/snackbar.js +121 -0
  54. package/dist/cjs/components/snackbar/snackbar.recipe.js +71 -0
  55. package/dist/cjs/components/table/table.recipe.js +7 -1
  56. package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
  57. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +37 -12
  58. package/dist/cjs/components/tabs/tabs.js +10 -4
  59. package/dist/cjs/components/tabs/tabs.recipe.js +23 -6
  60. package/dist/cjs/components/textarea/textarea.recipe.js +11 -8
  61. package/dist/cjs/core/floating-portal.js +7 -4
  62. package/dist/cjs/index.js +7 -0
  63. package/dist/cjs/product/authshell/authshell.recipe.js +5 -1
  64. package/dist/cjs/product/command/command.recipe.js +4 -1
  65. package/dist/cjs/product/comments/comments.js +7 -2
  66. package/dist/cjs/product/comments/comments.recipe.js +25 -7
  67. package/dist/cjs/product/inbox/inbox.js +11 -3
  68. package/dist/cjs/product/memberssettings/index.js +6 -0
  69. package/dist/cjs/product/memberssettings/memberssettings.js +99 -0
  70. package/dist/cjs/product/memberssettings/memberssettings.recipe.js +83 -0
  71. package/dist/cjs/product/notificationssettings/index.js +5 -0
  72. package/dist/cjs/product/notificationssettings/notificationssettings.js +19 -0
  73. package/dist/cjs/product/notificationssettings/notificationssettings.recipe.js +44 -0
  74. package/dist/cjs/product/recordpage/index.js +2 -1
  75. package/dist/cjs/product/recordpage/recordpage.js +106 -9
  76. package/dist/cjs/product/recordpage/recordpage.recipe.js +68 -6
  77. package/dist/cjs/product/workspacegeneralsettings/index.js +5 -0
  78. package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.js +21 -0
  79. package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +51 -0
  80. package/dist/cjs/tokens/contract.js +1 -0
  81. package/dist/cjs/tokens/elevation.js +8 -5
  82. package/dist/cjs/tokens/palette.js +28 -8
  83. package/dist/cjs/tokens/scale.js +44 -2
  84. package/dist/cjs/tokens/semantic.js +2 -0
  85. package/dist/columncalc.css +15 -7
  86. package/dist/columncalc.layered.css +15 -7
  87. package/dist/command.css +23 -19
  88. package/dist/command.layered.css +23 -19
  89. package/dist/comments.css +28 -19
  90. package/dist/comments.d.ts +2 -2
  91. package/dist/comments.layered.css +28 -19
  92. package/dist/datatable.css +171 -71
  93. package/dist/datatable.layered.css +171 -71
  94. package/dist/datepicker.css +13 -41
  95. package/dist/datepicker.layered.css +13 -41
  96. package/dist/datepickerfield.css +12 -3
  97. package/dist/datepickerfield.d.ts +2 -2
  98. package/dist/datepickerfield.layered.css +12 -3
  99. package/dist/dialog.css +12 -7
  100. package/dist/dialog.layered.css +12 -7
  101. package/dist/emptystate.css +5 -3
  102. package/dist/emptystate.layered.css +5 -3
  103. package/dist/esm/components/badge/badge.recipe.js +22 -8
  104. package/dist/esm/components/bottomsheet/bottomsheet.js +52 -0
  105. package/dist/esm/components/bottomsheet/bottomsheet.recipe.js +74 -0
  106. package/dist/esm/components/bottomsheet/index.js +2 -0
  107. package/dist/esm/components/breadcrumb/breadcrumb.js +1 -1
  108. package/dist/esm/components/button/button.recipe.js +68 -16
  109. package/dist/esm/components/checkbox/checkbox.recipe.js +61 -9
  110. package/dist/esm/components/chip/chip.js +14 -2
  111. package/dist/esm/components/chip/chip.recipe.js +72 -2
  112. package/dist/esm/components/chipgroup/chipgroup.js +15 -0
  113. package/dist/esm/components/chipgroup/chipgroup.recipe.js +33 -0
  114. package/dist/esm/components/chipgroup/index.js +2 -0
  115. package/dist/esm/components/datatable/datatable.js +5 -1
  116. package/dist/esm/components/datatable/datatable.recipe.js +21 -6
  117. package/dist/esm/components/datepickerfield/datepickerfield.js +2 -2
  118. package/dist/esm/components/datepickerfield/datepickerfield.recipe.js +16 -3
  119. package/dist/esm/components/dialog/dialog.recipe.js +22 -11
  120. package/dist/esm/components/emptystate/emptystate.recipe.js +7 -2
  121. package/dist/esm/components/fileupload/fileupload.js +20 -5
  122. package/dist/esm/components/input/index.js +1 -1
  123. package/dist/esm/components/input/input.js +30 -0
  124. package/dist/esm/components/input/input.recipe.js +17 -10
  125. package/dist/esm/components/menu/menu.js +18 -2
  126. package/dist/esm/components/menu/menu.recipe.js +21 -7
  127. package/dist/esm/components/menusheet/index.js +2 -0
  128. package/dist/esm/components/menusheet/menusheet.js +95 -0
  129. package/dist/esm/components/menusheet/menusheet.recipe.js +100 -0
  130. package/dist/esm/components/multiselect/multiselect.js +1 -1
  131. package/dist/esm/components/multiselect/multiselect.recipe.js +33 -9
  132. package/dist/esm/components/select/select.js +1 -1
  133. package/dist/esm/components/select/select.recipe.js +38 -12
  134. package/dist/esm/components/snackbar/index.js +2 -0
  135. package/dist/esm/components/snackbar/snackbar.js +84 -0
  136. package/dist/esm/components/snackbar/snackbar.recipe.js +68 -0
  137. package/dist/esm/components/table/table.recipe.js +7 -1
  138. package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
  139. package/dist/esm/components/tabletoolbar/tabletoolbar.js +37 -12
  140. package/dist/esm/components/tabs/tabs.js +10 -4
  141. package/dist/esm/components/tabs/tabs.recipe.js +23 -6
  142. package/dist/esm/components/textarea/textarea.recipe.js +12 -9
  143. package/dist/esm/core/floating-portal.js +7 -4
  144. package/dist/esm/index.js +7 -0
  145. package/dist/esm/product/authshell/authshell.recipe.js +5 -1
  146. package/dist/esm/product/command/command.recipe.js +4 -1
  147. package/dist/esm/product/comments/comments.js +7 -2
  148. package/dist/esm/product/comments/comments.recipe.js +25 -7
  149. package/dist/esm/product/inbox/inbox.js +11 -3
  150. package/dist/esm/product/memberssettings/index.js +1 -0
  151. package/dist/esm/product/memberssettings/memberssettings.js +62 -0
  152. package/dist/esm/product/memberssettings/memberssettings.recipe.js +80 -0
  153. package/dist/esm/product/notificationssettings/index.js +1 -0
  154. package/dist/esm/product/notificationssettings/notificationssettings.js +16 -0
  155. package/dist/esm/product/notificationssettings/notificationssettings.recipe.js +41 -0
  156. package/dist/esm/product/recordpage/index.js +1 -1
  157. package/dist/esm/product/recordpage/recordpage.js +106 -10
  158. package/dist/esm/product/recordpage/recordpage.recipe.js +68 -6
  159. package/dist/esm/product/workspacegeneralsettings/index.js +1 -0
  160. package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.js +18 -0
  161. package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +48 -0
  162. package/dist/esm/tokens/contract.js +2 -1
  163. package/dist/esm/tokens/elevation.js +8 -5
  164. package/dist/esm/tokens/palette.js +28 -8
  165. package/dist/esm/tokens/scale.js +43 -1
  166. package/dist/esm/tokens/semantic.js +2 -0
  167. package/dist/fileupload.css +3 -1
  168. package/dist/fileupload.layered.css +3 -1
  169. package/dist/input.css +6 -4
  170. package/dist/input.layered.css +6 -4
  171. package/dist/listpage.css +3 -1
  172. package/dist/listpage.layered.css +3 -1
  173. package/dist/memberssettings.css +67 -0
  174. package/dist/memberssettings.d.ts +7 -0
  175. package/dist/memberssettings.layered.css +69 -0
  176. package/dist/menu.css +2 -2
  177. package/dist/menu.layered.css +2 -2
  178. package/dist/menusheet.css +36 -0
  179. package/dist/menusheet.d.ts +7 -0
  180. package/dist/menusheet.layered.css +38 -0
  181. package/dist/multiselect.css +13 -6
  182. package/dist/multiselect.layered.css +13 -6
  183. package/dist/native/tokens.d.ts +2 -1
  184. package/dist/native/tokens.js +20 -3
  185. package/dist/notificationssettings.css +22 -0
  186. package/dist/notificationssettings.d.ts +7 -0
  187. package/dist/notificationssettings.layered.css +24 -0
  188. package/dist/objectsettings.css +4 -4
  189. package/dist/objectsettings.layered.css +4 -4
  190. package/dist/recordpage.css +90 -23
  191. package/dist/recordpage.layered.css +90 -23
  192. package/dist/recordpanel.css +35 -16
  193. package/dist/recordpanel.layered.css +35 -16
  194. package/dist/resizablepanel.css +8 -5
  195. package/dist/resizablepanel.layered.css +8 -5
  196. package/dist/richtext.css +24 -8
  197. package/dist/richtext.layered.css +24 -8
  198. package/dist/savedviews.css +9 -2
  199. package/dist/savedviews.layered.css +9 -2
  200. package/dist/select.css +25 -5
  201. package/dist/select.layered.css +25 -5
  202. package/dist/settingsshell.css +2 -3
  203. package/dist/settingsshell.layered.css +2 -3
  204. package/dist/slider.css +6 -27
  205. package/dist/slider.layered.css +6 -27
  206. package/dist/snackbar.css +24 -0
  207. package/dist/snackbar.d.ts +7 -0
  208. package/dist/snackbar.layered.css +26 -0
  209. package/dist/statcard.css +3 -1
  210. package/dist/statcard.layered.css +3 -1
  211. package/dist/styles.css +911 -354
  212. package/dist/styles.layered.css +911 -354
  213. package/dist/table.css +35 -12
  214. package/dist/table.layered.css +35 -12
  215. package/dist/tabletoolbar.css +35 -24
  216. package/dist/tabletoolbar.layered.css +35 -24
  217. package/dist/tabs.css +18 -4
  218. package/dist/tabs.layered.css +18 -4
  219. package/dist/textarea.css +2 -6
  220. package/dist/textarea.layered.css +2 -6
  221. package/dist/themepicker.css +2 -1
  222. package/dist/themepicker.layered.css +2 -1
  223. package/dist/tokens.css +13 -2
  224. package/dist/tokens.json +20 -3
  225. package/dist/types/components/bottomsheet/bottomsheet.d.ts +35 -0
  226. package/dist/types/components/bottomsheet/bottomsheet.recipe.d.ts +3 -0
  227. package/dist/types/components/bottomsheet/index.d.ts +2 -0
  228. package/dist/types/components/breadcrumb/breadcrumb.d.ts +9 -1
  229. package/dist/types/components/button/button.d.ts +2 -0
  230. package/dist/types/components/button/button.recipe.d.ts +24 -6
  231. package/dist/types/components/checkbox/checkbox.recipe.d.ts +28 -5
  232. package/dist/types/components/chip/chip.d.ts +22 -0
  233. package/dist/types/components/chip/chip.recipe.d.ts +49 -1
  234. package/dist/types/components/chipgroup/chipgroup.d.ts +14 -0
  235. package/dist/types/components/chipgroup/chipgroup.recipe.d.ts +5 -0
  236. package/dist/types/components/chipgroup/index.d.ts +2 -0
  237. package/dist/types/components/datatable/datatable.d.ts +19 -0
  238. package/dist/types/components/datepickerfield/datepickerfield.d.ts +4 -1
  239. package/dist/types/components/datepickerfield/datepickerfield.recipe.d.ts +18 -3
  240. package/dist/types/components/fileupload/fileupload.d.ts +26 -0
  241. package/dist/types/components/input/index.d.ts +1 -1
  242. package/dist/types/components/input/input.d.ts +72 -0
  243. package/dist/types/components/menusheet/index.d.ts +2 -0
  244. package/dist/types/components/menusheet/menusheet.d.ts +42 -0
  245. package/dist/types/components/menusheet/menusheet.recipe.d.ts +3 -0
  246. package/dist/types/components/snackbar/index.d.ts +2 -0
  247. package/dist/types/components/snackbar/snackbar.d.ts +36 -0
  248. package/dist/types/components/snackbar/snackbar.recipe.d.ts +5 -0
  249. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +28 -1
  250. package/dist/types/components/tabs/tabs.d.ts +11 -1
  251. package/dist/types/core/floating-portal.d.ts +6 -5
  252. package/dist/types/index.d.ts +7 -0
  253. package/dist/types/product/comments/comments.d.ts +9 -3
  254. package/dist/types/product/comments/comments.recipe.d.ts +12 -2
  255. package/dist/types/product/inbox/inbox.d.ts +13 -1
  256. package/dist/types/product/memberssettings/index.d.ts +1 -0
  257. package/dist/types/product/memberssettings/memberssettings.d.ts +85 -0
  258. package/dist/types/product/memberssettings/memberssettings.recipe.d.ts +3 -0
  259. package/dist/types/product/notificationssettings/index.d.ts +1 -0
  260. package/dist/types/product/notificationssettings/notificationssettings.d.ts +37 -0
  261. package/dist/types/product/notificationssettings/notificationssettings.recipe.d.ts +3 -0
  262. package/dist/types/product/recordpage/index.d.ts +1 -1
  263. package/dist/types/product/recordpage/recordpage.d.ts +99 -2
  264. package/dist/types/product/workspacegeneralsettings/index.d.ts +1 -0
  265. package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.d.ts +48 -0
  266. package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.recipe.d.ts +3 -0
  267. package/dist/types/tokens/contract.d.ts +4 -1
  268. package/dist/types/tokens/elevation.d.ts +8 -5
  269. package/dist/types/tokens/palette.d.ts +9 -1
  270. package/dist/types/tokens/scale.d.ts +11 -1
  271. package/dist/types/tokens/semantic.d.ts +2 -0
  272. package/dist/wheelpicker.css +4 -2
  273. package/dist/wheelpicker.layered.css +4 -2
  274. package/dist/workspacegeneralsettings.css +30 -0
  275. package/dist/workspacegeneralsettings.d.ts +7 -0
  276. package/dist/workspacegeneralsettings.layered.css +32 -0
  277. package/package.json +36 -1
@@ -4,7 +4,11 @@
4
4
  & .crisp-authshell-progress { position: absolute; top: 0; left: 0; width: 100%; height: 2px; background: var(--crisp-border-default); }
5
5
  & .crisp-authshell-progress-fill { height: 2px; background: var(--crisp-fg-primary); border-radius: 4px; transition: width .2s; }
6
6
  & .crisp-authshell-logo { margin-top: var(--crisp-space-8); min-height: 24px; display: flex; align-items: center; gap: var(--crisp-space-2-5); }
7
- & .crisp-authshell-logo-badge { flex-shrink: 0; box-sizing: border-box; width: 32px; height: 32px; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: #fff; display: flex; align-items: center; justify-content: center; }
7
+ /* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
8
+ the accent (#0298d9) only clears 3.23:1 with white; the darker
9
+ sibling clears 4.5:1+, same fix already applied to Button/Badge/
10
+ Avatar (#897). */
11
+ & .crisp-authshell-logo-badge { flex-shrink: 0; box-sizing: border-box; width: 32px; height: 32px; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-contrast); color: #fff; display: flex; align-items: center; justify-content: center; }
8
12
  & .crisp-authshell-logo-text { display: flex; flex-direction: column; line-height: 1.2; }
9
13
  & .crisp-authshell-logo-title { font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-bold); letter-spacing: -0.2px; color: var(--crisp-fg-primary); }
10
14
  & .crisp-authshell-logo-subtitle { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
@@ -20,7 +24,8 @@
20
24
  & .crisp-authshell-form { align-self: stretch; display: flex; flex-direction: column; gap: 28px; }
21
25
  & .crisp-authshell-footer { margin-top: var(--crisp-space-6); display: flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
22
26
  & .crisp-authshell-footer a { color: inherit; font-weight: var(--crisp-weight-medium); text-decoration: underline; }
23
- /* Auth-surface control treatment: flatter than the in-app chrome — a plain hairline ring instead of elevation.field's soft glow, and a 36px (not
27
+ /* Auth-surface control treatment: flatter than the in-app chrome — a plain
28
+ hairline ring instead of elevation.field's soft glow, and a 36px (not
24
29
  40px) submit. Scoped to .crisp-authshell-body so a consumer keeps using
25
30
  crisp's Input / FormField / Button and gets the auth treatment for free. */
26
31
  & .crisp-authshell-body .crisp-formfield-label { font-size: var(--crisp-text-sm); line-height: 16px; font-weight: var(--crisp-weight-medium); letter-spacing: -0.12px; color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); padding-inline-start: var(--crisp-space-1); }
@@ -28,10 +33,10 @@
28
33
  & .crisp-authshell-body .crisp-input { height: 34px; padding-inline: var(--crisp-space-2-5); border-radius: 10px; background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); letter-spacing: -0.14px; transition: box-shadow .14s, background-color .14s; }
29
34
  & .crisp-authshell-body .crisp-input:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
30
35
  /* Same three-layer brand shadow as Button's primary intent, but the auth
31
- button's inset ring is measured at rgba(0,0,0,0.06) — a hairline, not the in-app button's rgba(255,255,255,0.07) highlight. */
36
+ button's inset ring is measured at rgba(0,0,0,0.06) — a hairline, not
37
+ the in-app button's rgba(255,255,255,0.07) highlight. */
32
38
  & .crisp-authshell-body .crisp-button { height: 36px; padding-inline: var(--crisp-space-3); border-radius: 10px; }
33
39
  & .crisp-authshell-body .crisp-button--intent_primary { 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); }
34
-
35
40
  /* The preview pane drops out in JS on narrow viewports (measured: two
36
41
  panes at 1393px, one at 954px), so 1200px is a chosen threshold inside
37
42
  that bracket, not a measured value. A CONTAINER query, not a media
@@ -5,7 +5,11 @@
5
5
  & .crisp-authshell-progress { position: absolute; top: 0; left: 0; width: 100%; height: 2px; background: var(--crisp-border-default); }
6
6
  & .crisp-authshell-progress-fill { height: 2px; background: var(--crisp-fg-primary); border-radius: 4px; transition: width .2s; }
7
7
  & .crisp-authshell-logo { margin-top: var(--crisp-space-8); min-height: 24px; display: flex; align-items: center; gap: var(--crisp-space-2-5); }
8
- & .crisp-authshell-logo-badge { flex-shrink: 0; box-sizing: border-box; width: 32px; height: 32px; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: #fff; display: flex; align-items: center; justify-content: center; }
8
+ /* your-moon/crisp#953: bgBrandContrast, not bgBrandSolid --
9
+ the accent (#0298d9) only clears 3.23:1 with white; the darker
10
+ sibling clears 4.5:1+, same fix already applied to Button/Badge/
11
+ Avatar (#897). */
12
+ & .crisp-authshell-logo-badge { flex-shrink: 0; box-sizing: border-box; width: 32px; height: 32px; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-contrast); color: #fff; display: flex; align-items: center; justify-content: center; }
9
13
  & .crisp-authshell-logo-text { display: flex; flex-direction: column; line-height: 1.2; }
10
14
  & .crisp-authshell-logo-title { font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-bold); letter-spacing: -0.2px; color: var(--crisp-fg-primary); }
11
15
  & .crisp-authshell-logo-subtitle { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
@@ -21,7 +25,8 @@
21
25
  & .crisp-authshell-form { align-self: stretch; display: flex; flex-direction: column; gap: 28px; }
22
26
  & .crisp-authshell-footer { margin-top: var(--crisp-space-6); display: flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
23
27
  & .crisp-authshell-footer a { color: inherit; font-weight: var(--crisp-weight-medium); text-decoration: underline; }
24
- /* Auth-surface control treatment: flatter than the in-app chrome — a plain hairline ring instead of elevation.field's soft glow, and a 36px (not
28
+ /* Auth-surface control treatment: flatter than the in-app chrome — a plain
29
+ hairline ring instead of elevation.field's soft glow, and a 36px (not
25
30
  40px) submit. Scoped to .crisp-authshell-body so a consumer keeps using
26
31
  crisp's Input / FormField / Button and gets the auth treatment for free. */
27
32
  & .crisp-authshell-body .crisp-formfield-label { font-size: var(--crisp-text-sm); line-height: 16px; font-weight: var(--crisp-weight-medium); letter-spacing: -0.12px; color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); padding-inline-start: var(--crisp-space-1); }
@@ -29,10 +34,10 @@
29
34
  & .crisp-authshell-body .crisp-input { height: 34px; padding-inline: var(--crisp-space-2-5); border-radius: 10px; background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); letter-spacing: -0.14px; transition: box-shadow .14s, background-color .14s; }
30
35
  & .crisp-authshell-body .crisp-input:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
31
36
  /* Same three-layer brand shadow as Button's primary intent, but the auth
32
- button's inset ring is measured at rgba(0,0,0,0.06) — a hairline, not the in-app button's rgba(255,255,255,0.07) highlight. */
37
+ button's inset ring is measured at rgba(0,0,0,0.06) — a hairline, not
38
+ the in-app button's rgba(255,255,255,0.07) highlight. */
33
39
  & .crisp-authshell-body .crisp-button { height: 36px; padding-inline: var(--crisp-space-3); border-radius: 10px; }
34
40
  & .crisp-authshell-body .crisp-button--intent_primary { 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); }
35
-
36
41
  /* The preview pane drops out in JS on narrow viewports (measured: two
37
42
  panes at 1393px, one at 954px), so 1200px is a chosen threshold inside
38
43
  that bracket, not a measured value. A CONTAINER query, not a media
package/dist/badge.css CHANGED
@@ -21,13 +21,13 @@
21
21
  background: var(--crisp-bg-purple-soft); color: var(--crisp-fg-purple-soft); box-shadow: inset 0 0 0 1px var(--crisp-ring-purple-soft);
22
22
  }
23
23
  .crisp-badge--size_small {
24
- height: 16px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; border-radius: var(--crisp-radius-sm);
24
+ height: 16px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; border-radius: var(--crisp-radius-xs);
25
25
  }
26
26
  .crisp-badge--size_medium {
27
- height: 20px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; gap: 3px; border-radius: var(--crisp-radius-sm);
27
+ height: 20px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; gap: 3px; border-radius: var(--crisp-radius-xs);
28
28
  }
29
29
  .crisp-badge--size_large {
30
- height: var(--crisp-size-chip); padding-block: var(--crisp-space-px); padding-inline-start: var(--crisp-space-1); padding-inline-end: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); letter-spacing: -0.1px; border-radius: var(--crisp-radius-lg);
30
+ height: var(--crisp-size-chip); padding-block: var(--crisp-space-px); padding-inline-start: var(--crisp-space-1); padding-inline-end: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); letter-spacing: -0.1px; border-radius: var(--crisp-radius-sm);
31
31
  }
32
32
  .crisp-badge--variant_soft {
33
33
 
@@ -22,13 +22,13 @@
22
22
  background: var(--crisp-bg-purple-soft); color: var(--crisp-fg-purple-soft); box-shadow: inset 0 0 0 1px var(--crisp-ring-purple-soft);
23
23
  }
24
24
  .crisp-badge--size_small {
25
- height: 16px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; border-radius: var(--crisp-radius-sm);
25
+ height: 16px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; border-radius: var(--crisp-radius-xs);
26
26
  }
27
27
  .crisp-badge--size_medium {
28
- height: 20px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; gap: 3px; border-radius: var(--crisp-radius-sm);
28
+ height: 20px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; gap: 3px; border-radius: var(--crisp-radius-xs);
29
29
  }
30
30
  .crisp-badge--size_large {
31
- height: var(--crisp-size-chip); padding-block: var(--crisp-space-px); padding-inline-start: var(--crisp-space-1); padding-inline-end: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); letter-spacing: -0.1px; border-radius: var(--crisp-radius-lg);
31
+ height: var(--crisp-size-chip); padding-block: var(--crisp-space-px); padding-inline-start: var(--crisp-space-1); padding-inline-end: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); letter-spacing: -0.1px; border-radius: var(--crisp-radius-sm);
32
32
  }
33
33
  .crisp-badge--variant_soft {
34
34
 
package/dist/board.css CHANGED
@@ -11,19 +11,29 @@
11
11
  & .crisp-board-density button[data-state="on"] { background: var(--crisp-bg-surface); color: var(--crisp-fg-primary); }
12
12
  & .crisp-board-row { display: flex; gap: var(--crisp-space-2); flex: 1; min-height: 0; box-sizing: border-box; padding: var(--crisp-space-3); overflow-x: auto; align-items: flex-start; }
13
13
  & .crisp-board-col { display: flex; flex-direction: column; width: 268px; flex-shrink: 0; max-height: 100%; box-sizing: border-box; transition: width 0.15s; }
14
- /* #718: a collapsed column is a 52px vertical rail -- header only (dot + count stacked above a vertical-rl title), body/footer hidden entirely. Measured live: 52px width, 8px 0 padding on the header, 14px/600 title text. */
14
+ /* #718: a collapsed column is a 52px vertical rail -- header only (dot
15
+ + count stacked above a vertical-rl title), body/footer hidden
16
+ entirely. Measured live: 52px width, 8px 0 padding on the header,
17
+ 14px/600 title text. */
15
18
  & .crisp-board-col[data-density="collapse"] { width: 52px; }
16
19
  & .crisp-board-col[data-density="collapse"] .crisp-board-col-header { flex-direction: column; align-items: center; height: auto; padding: var(--crisp-space-2) 0; gap: var(--crisp-space-1); }
17
- /* Measured stacking order (top to bottom): dot, count, THEN the vertical title -- reordered visually via `order`, not by changing the JSX/DOM order, which stays dot/title/count (reading order, unaffected by density). */
20
+ /* Measured stacking order (top to bottom): dot, count, THEN the vertical
21
+ title -- reordered visually via `order`, not by changing the JSX/DOM
22
+ order, which stays dot/title/count (reading order, unaffected by
23
+ density). */
18
24
  & .crisp-board-col[data-density="collapse"] .crisp-board-col-title { order: 1; writing-mode: vertical-rl; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); }
19
25
  & .crisp-board-col[data-density="collapse"] .crisp-board-col-count { order: 0; }
20
26
  & .crisp-board-col[data-density="collapse"] .crisp-board-col-body, & .crisp-board-col[data-density="collapse"] .crisp-board-col-footer { display: none; }
21
27
  & .crisp-board-col-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 36px; padding: 0 var(--crisp-space-1); flex-shrink: 0; }
22
28
  & .crisp-board-col-dot { width: 12px; height: 12px; border-radius: var(--crisp-radius-full); flex-shrink: 0; }
23
29
  & .crisp-board-col-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
24
- /* crisp#697: HANDOFF's #472 note claimed the count pill's color-mix(fgPrimary, 63%, transparent) reproduced the measured rgb(80,81,85) -- it doesn't; 63% of fgPrimary composited on white
30
+ /* crisp#697: HANDOFF's #472 note claimed the count pill's
31
+ color-mix(fgPrimary, 63%, transparent) reproduced the measured
32
+ rgb(80,81,85) -- it doesn't; 63% of fgPrimary composited on white
25
33
  paints rgb(104,105,105), visibly lighter. Text now reads
26
- fgNeutralSoft directly (the same rgb(80,81,85) token Badge's neutral tone uses, #696), and the ring the pill was also missing (inset 0 0 0 1px borderSubtle, measured rgb(238,239,241)) is added. */
34
+ fgNeutralSoft directly (the same rgb(80,81,85) token Badge's neutral
35
+ tone uses, #696), and the ring the pill was also missing
36
+ (inset 0 0 0 1px borderSubtle, measured rgb(238,239,241)) is added. */
27
37
  & .crisp-board-col-count { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: var(--crisp-text-sm); line-height: 16px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
28
38
  & .crisp-board-col-add { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin-inline-start: auto; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
29
39
  & .crisp-board-col-add:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
@@ -32,7 +42,11 @@
32
42
  & .crisp-board-newcard { display: flex; align-items: center; justify-content: center; gap: var(--crisp-space-1-5); height: 32px; flex-shrink: 0; border: none; border-radius: var(--crisp-radius-md); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
33
43
  & .crisp-board-newcard:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); }
34
44
  & .crisp-board-card { display: flex; flex-direction: column; gap: var(--crisp-space-2); box-sizing: border-box; padding: var(--crisp-space-2-5) var(--crisp-space-3); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); cursor: grab; touch-action: none; }
35
- /* #718: a collapsed card is a single 40px row -- measured live and independent of `c.size.tableRow`/`tableHeader` (36/40px) even though it happens to match the latter; a plain literal, not a cross-reference to a token measured for a different surface. `renderCard`'s own second argument is what actually decides what a
45
+ /* #718: a collapsed card is a single 40px row -- measured live and
46
+ independent of `c.size.tableRow`/`tableHeader` (36/40px) even
47
+ though it happens to match the latter; a plain literal, not a
48
+ cross-reference to a token measured for a different surface.
49
+ `renderCard`'s own second argument is what actually decides what a
36
50
  collapsed card SHOWS (Board never sees inside its opaque output);
37
51
  this only supplies the row-shaped box that content sits in. */
38
52
  & .crisp-board-card[data-density="collapse"] { flex-direction: row; align-items: center; height: 40px; padding: 0 var(--crisp-space-3); }
@@ -40,11 +54,15 @@
40
54
  & .crisp-board-card[data-dragging] { opacity: 0.4; }
41
55
  & .crisp-board-card:focus { outline: none; }
42
56
  & .crisp-board-card:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
43
- /* #674: the pointer-events drag's own drag image -- the same card surface above, just pinned to the pointer instead of the flex flow. No shadow lift or scale: neither was measured against Attio, and this is the same card, momentarily somewhere else, not a new look. */
57
+ /* #674: the pointer-events drag's own drag image -- the same card
58
+ surface above, just pinned to the pointer instead of the flex flow.
59
+ No shadow lift or scale: neither was measured against Attio, and this
60
+ is the same card, momentarily somewhere else, not a new look. */
44
61
  & .crisp-board-ghost { position: fixed; z-index: 1; pointer-events: none; cursor: grabbing; }
45
62
  /* #604: a per-column calc footer, mirroring the table's own (measured
46
63
  live, Deals pipeline). Sits below the scrollable card body, not
47
- inside it or pinned to it -- Attio's own is position: static, not sticky, so it's a plain flex-shrink:0 sibling here too. */
64
+ inside it or pinned to it -- Attio's own is position: static, not
65
+ sticky, so it's a plain flex-shrink:0 sibling here too. */
48
66
  & .crisp-board-col-footer { flex-shrink: 0; padding: var(--crisp-space-1) 0; }
49
67
  & .crisp-board-col-calc { display: flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); width: 100%; height: 28px; padding: var(--crisp-space-1) var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); cursor: pointer; }
50
68
  & .crisp-board-col-calc:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
@@ -53,7 +71,9 @@
53
71
  & .crisp-board-col-calc-value { color: var(--crisp-fg-primary); font-variant-numeric: tabular-nums; }
54
72
  /* #718: "Add stage" -- measured live: 52×52px, transparent, a 1px
55
73
  dashed border (rgb(230,231,234), exactly `borderDropzone`/`line150`
56
- -- the same dashed-border colour ImportDialog's own dropzone already uses, not borderSubtle/line100, a close but different value), radius.xl (16px), a centered 16px "+". */
74
+ -- the same dashed-border colour ImportDialog's own dropzone already
75
+ uses, not borderSubtle/line100, a close but different value), radius.xl
76
+ (16px), a centered 16px "+". */
57
77
  & .crisp-board-addstage { display: inline-flex; align-items: center; justify-content: center; width: 52px; height: 52px; flex-shrink: 0; border: 1px dashed var(--crisp-border-dropzone); border-radius: var(--crisp-radius-xl); background: none; color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
58
78
  & .crisp-board-addstage:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
59
79
  /* announced, never drawn */
@@ -12,19 +12,29 @@
12
12
  & .crisp-board-density button[data-state="on"] { background: var(--crisp-bg-surface); color: var(--crisp-fg-primary); }
13
13
  & .crisp-board-row { display: flex; gap: var(--crisp-space-2); flex: 1; min-height: 0; box-sizing: border-box; padding: var(--crisp-space-3); overflow-x: auto; align-items: flex-start; }
14
14
  & .crisp-board-col { display: flex; flex-direction: column; width: 268px; flex-shrink: 0; max-height: 100%; box-sizing: border-box; transition: width 0.15s; }
15
- /* #718: a collapsed column is a 52px vertical rail -- header only (dot + count stacked above a vertical-rl title), body/footer hidden entirely. Measured live: 52px width, 8px 0 padding on the header, 14px/600 title text. */
15
+ /* #718: a collapsed column is a 52px vertical rail -- header only (dot
16
+ + count stacked above a vertical-rl title), body/footer hidden
17
+ entirely. Measured live: 52px width, 8px 0 padding on the header,
18
+ 14px/600 title text. */
16
19
  & .crisp-board-col[data-density="collapse"] { width: 52px; }
17
20
  & .crisp-board-col[data-density="collapse"] .crisp-board-col-header { flex-direction: column; align-items: center; height: auto; padding: var(--crisp-space-2) 0; gap: var(--crisp-space-1); }
18
- /* Measured stacking order (top to bottom): dot, count, THEN the vertical title -- reordered visually via `order`, not by changing the JSX/DOM order, which stays dot/title/count (reading order, unaffected by density). */
21
+ /* Measured stacking order (top to bottom): dot, count, THEN the vertical
22
+ title -- reordered visually via `order`, not by changing the JSX/DOM
23
+ order, which stays dot/title/count (reading order, unaffected by
24
+ density). */
19
25
  & .crisp-board-col[data-density="collapse"] .crisp-board-col-title { order: 1; writing-mode: vertical-rl; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); }
20
26
  & .crisp-board-col[data-density="collapse"] .crisp-board-col-count { order: 0; }
21
27
  & .crisp-board-col[data-density="collapse"] .crisp-board-col-body, & .crisp-board-col[data-density="collapse"] .crisp-board-col-footer { display: none; }
22
28
  & .crisp-board-col-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 36px; padding: 0 var(--crisp-space-1); flex-shrink: 0; }
23
29
  & .crisp-board-col-dot { width: 12px; height: 12px; border-radius: var(--crisp-radius-full); flex-shrink: 0; }
24
30
  & .crisp-board-col-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
25
- /* crisp#697: HANDOFF's #472 note claimed the count pill's color-mix(fgPrimary, 63%, transparent) reproduced the measured rgb(80,81,85) -- it doesn't; 63% of fgPrimary composited on white
31
+ /* crisp#697: HANDOFF's #472 note claimed the count pill's
32
+ color-mix(fgPrimary, 63%, transparent) reproduced the measured
33
+ rgb(80,81,85) -- it doesn't; 63% of fgPrimary composited on white
26
34
  paints rgb(104,105,105), visibly lighter. Text now reads
27
- fgNeutralSoft directly (the same rgb(80,81,85) token Badge's neutral tone uses, #696), and the ring the pill was also missing (inset 0 0 0 1px borderSubtle, measured rgb(238,239,241)) is added. */
35
+ fgNeutralSoft directly (the same rgb(80,81,85) token Badge's neutral
36
+ tone uses, #696), and the ring the pill was also missing
37
+ (inset 0 0 0 1px borderSubtle, measured rgb(238,239,241)) is added. */
28
38
  & .crisp-board-col-count { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: var(--crisp-text-sm); line-height: 16px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
29
39
  & .crisp-board-col-add { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin-inline-start: auto; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
30
40
  & .crisp-board-col-add:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
@@ -33,7 +43,11 @@
33
43
  & .crisp-board-newcard { display: flex; align-items: center; justify-content: center; gap: var(--crisp-space-1-5); height: 32px; flex-shrink: 0; border: none; border-radius: var(--crisp-radius-md); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
34
44
  & .crisp-board-newcard:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); }
35
45
  & .crisp-board-card { display: flex; flex-direction: column; gap: var(--crisp-space-2); box-sizing: border-box; padding: var(--crisp-space-2-5) var(--crisp-space-3); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); cursor: grab; touch-action: none; }
36
- /* #718: a collapsed card is a single 40px row -- measured live and independent of `c.size.tableRow`/`tableHeader` (36/40px) even though it happens to match the latter; a plain literal, not a cross-reference to a token measured for a different surface. `renderCard`'s own second argument is what actually decides what a
46
+ /* #718: a collapsed card is a single 40px row -- measured live and
47
+ independent of `c.size.tableRow`/`tableHeader` (36/40px) even
48
+ though it happens to match the latter; a plain literal, not a
49
+ cross-reference to a token measured for a different surface.
50
+ `renderCard`'s own second argument is what actually decides what a
37
51
  collapsed card SHOWS (Board never sees inside its opaque output);
38
52
  this only supplies the row-shaped box that content sits in. */
39
53
  & .crisp-board-card[data-density="collapse"] { flex-direction: row; align-items: center; height: 40px; padding: 0 var(--crisp-space-3); }
@@ -41,11 +55,15 @@
41
55
  & .crisp-board-card[data-dragging] { opacity: 0.4; }
42
56
  & .crisp-board-card:focus { outline: none; }
43
57
  & .crisp-board-card:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
44
- /* #674: the pointer-events drag's own drag image -- the same card surface above, just pinned to the pointer instead of the flex flow. No shadow lift or scale: neither was measured against Attio, and this is the same card, momentarily somewhere else, not a new look. */
58
+ /* #674: the pointer-events drag's own drag image -- the same card
59
+ surface above, just pinned to the pointer instead of the flex flow.
60
+ No shadow lift or scale: neither was measured against Attio, and this
61
+ is the same card, momentarily somewhere else, not a new look. */
45
62
  & .crisp-board-ghost { position: fixed; z-index: 1; pointer-events: none; cursor: grabbing; }
46
63
  /* #604: a per-column calc footer, mirroring the table's own (measured
47
64
  live, Deals pipeline). Sits below the scrollable card body, not
48
- inside it or pinned to it -- Attio's own is position: static, not sticky, so it's a plain flex-shrink:0 sibling here too. */
65
+ inside it or pinned to it -- Attio's own is position: static, not
66
+ sticky, so it's a plain flex-shrink:0 sibling here too. */
49
67
  & .crisp-board-col-footer { flex-shrink: 0; padding: var(--crisp-space-1) 0; }
50
68
  & .crisp-board-col-calc { display: flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); width: 100%; height: 28px; padding: var(--crisp-space-1) var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); cursor: pointer; }
51
69
  & .crisp-board-col-calc:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
@@ -54,7 +72,9 @@
54
72
  & .crisp-board-col-calc-value { color: var(--crisp-fg-primary); font-variant-numeric: tabular-nums; }
55
73
  /* #718: "Add stage" -- measured live: 52×52px, transparent, a 1px
56
74
  dashed border (rgb(230,231,234), exactly `borderDropzone`/`line150`
57
- -- the same dashed-border colour ImportDialog's own dropzone already uses, not borderSubtle/line100, a close but different value), radius.xl (16px), a centered 16px "+". */
75
+ -- the same dashed-border colour ImportDialog's own dropzone already
76
+ uses, not borderSubtle/line100, a close but different value), radius.xl
77
+ (16px), a centered 16px "+". */
58
78
  & .crisp-board-addstage { display: inline-flex; align-items: center; justify-content: center; width: 52px; height: 52px; flex-shrink: 0; border: 1px dashed var(--crisp-border-dropzone); border-radius: var(--crisp-radius-xl); background: none; color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
59
79
  & .crisp-board-addstage:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
60
80
  /* announced, never drawn */
@@ -0,0 +1,26 @@
1
+ .crisp-bottomsheet {
2
+ display: contents; font-family: var(--crisp-font-sans);
3
+ & .crisp-bottomsheet-backdrop { position: fixed; inset: 0; z-index: 60; background: var(--crisp-bg-overlay-strong); /* bottom-sheet.yaml:99 backdrop.color = $color.bg.overlay -- a different, darker, theme-constant scrim than the Dialog bgScrim token, see its own comment */ opacity: 1; transition: opacity 300ms cubic-bezier(0,0,.15,1); /* bottom-sheet.yaml:100-102 enterDuration/enterTimingFunction */ @starting-style { opacity: 0; } }
4
+ & .crisp-bottomsheet-positioner { position: fixed; inset: 0; z-index: 61; display: flex; align-items: flex-end; justify-content: center; }
5
+ & .crisp-bottomsheet-content { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; box-sizing: border-box; display: flex; flex-direction: column; overflow: hidden; width: 100%; max-width: 480px; /* bottom-sheet.yaml:110 content.maxWidth */ max-height: 85vh; background: var(--crisp-bg-surface); /* bottom-sheet.yaml:109 content.color = $color.bg.layer-floating */ border-radius: var(--crisp-radius-4xl) var(--crisp-radius-4xl) 0 0; /* bottom-sheet.yaml:111 content.topCornerRadius = $radius.r6 (24px), bottom flush with the viewport */ transform: translateY(0); transition: transform 300ms cubic-bezier(.03,.4,.1,1); /* bottom-sheet.yaml:112-113 content.enterDuration/enterTimingFunction (enter-expressive) */ @starting-style { transform: translateY(100%); } }
6
+ & .crisp-bottomsheet-header { position: relative; display: flex; flex-direction: column; gap: var(--crisp-space-2); /* bottom-sheet.yaml:120 header.gap = $dimension.x2 (8px) */ padding-top: var(--crisp-space-6); padding-bottom: var(--crisp-space-4); /* bottom-sheet.yaml:121-122 header.paddingTop/paddingBottom = $dimension.x6/x4 (24px/16px) */ flex-shrink: 0; }
7
+ & .crisp-bottomsheet-title { color: var(--crisp-fg-primary); /* bottom-sheet.yaml:130 title.color = $color.fg.neutral */ font-size: 22px; line-height: 30px; font-weight: var(--crisp-weight-bold); /* bottom-sheet.yaml:131-133 title.fontSize/lineHeight/fontWeight = $font-size.t8/$line-height.t8/bold */ padding-inline: var(--crisp-space-4); /* default (headerAlignment=left, no close button): bottom-sheet.yaml:150-152 */ }
8
+ &[data-header-align="left"][data-has-close] .crisp-bottomsheet-title { padding-inline-start: var(--crisp-space-4); padding-inline-end: 56px; }
9
+ /* bottom-sheet.yaml:141-144 */
10
+ &[data-header-align="center"] .crisp-bottomsheet-title { text-align: center; }
11
+ &[data-header-align="center"][data-has-close] .crisp-bottomsheet-title { padding-inline: 56px; }
12
+ /* bottom-sheet.yaml:154-157 */
13
+ & .crisp-bottomsheet-description { color: var(--crisp-fg-muted); /* bottom-sheet.yaml:138 description.color = $color.fg.neutral-muted */ font-size: var(--crisp-text-xl); line-height: 22px; font-weight: var(--crisp-weight-regular); /* bottom-sheet.yaml:139-141 description.fontSize/lineHeight/fontWeight = $font-size.t5/$line-height.t5/regular */ padding-inline: var(--crisp-space-4); /* bottom-sheet.yaml:142 description.paddingX = global-gutter (16px) */ }
14
+ & .crisp-bottomsheet-close { position: absolute; top: var(--crisp-space-6); inset-inline-end: var(--crisp-space-4); /* bottom-sheet.yaml:145-146 closeButton.fromTop/fromRight = $dimension.x6/x4 (24px/16px) */ display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
15
+ & .crisp-bottomsheet-close:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
16
+ & .crisp-bottomsheet-body { flex: 1; min-height: 0; overflow-y: auto; padding-inline: var(--crisp-space-4); /* bottom-sheet.yaml:126 body.paddingX = global-gutter (16px) -- no vertical padding in the spec */ }
17
+ & .crisp-bottomsheet-footer { display: flex; align-items: center; justify-content: flex-end; gap: var(--crisp-space-3); flex-shrink: 0; padding-inline: var(--crisp-space-4); padding-top: var(--crisp-space-3); padding-bottom: var(--crisp-space-4); /* bottom-sheet.yaml:127-129 footer.paddingX/paddingTop/paddingBottom = global-gutter/x3/x4 (16px/12px/16px) */ }
18
+ }
19
+
20
+ @media (prefers-reduced-motion: reduce) {
21
+ .crisp-bottomsheet, .crisp-bottomsheet * {
22
+ animation-duration: 0.01ms !important;
23
+ animation-iteration-count: 1 !important;
24
+ transition-duration: 0.01ms !important;
25
+ }
26
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface BottomsheetVariants {
4
+
5
+ }
6
+
7
+ export declare const bottomsheetRecipe: RecipeFn<{ }>;
@@ -0,0 +1,28 @@
1
+ @layer crisp-components {
2
+ .crisp-bottomsheet {
3
+ display: contents; font-family: var(--crisp-font-sans);
4
+ & .crisp-bottomsheet-backdrop { position: fixed; inset: 0; z-index: 60; background: var(--crisp-bg-overlay-strong); /* bottom-sheet.yaml:99 backdrop.color = $color.bg.overlay -- a different, darker, theme-constant scrim than the Dialog bgScrim token, see its own comment */ opacity: 1; transition: opacity 300ms cubic-bezier(0,0,.15,1); /* bottom-sheet.yaml:100-102 enterDuration/enterTimingFunction */ @starting-style { opacity: 0; } }
5
+ & .crisp-bottomsheet-positioner { position: fixed; inset: 0; z-index: 61; display: flex; align-items: flex-end; justify-content: center; }
6
+ & .crisp-bottomsheet-content { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; box-sizing: border-box; display: flex; flex-direction: column; overflow: hidden; width: 100%; max-width: 480px; /* bottom-sheet.yaml:110 content.maxWidth */ max-height: 85vh; background: var(--crisp-bg-surface); /* bottom-sheet.yaml:109 content.color = $color.bg.layer-floating */ border-radius: var(--crisp-radius-4xl) var(--crisp-radius-4xl) 0 0; /* bottom-sheet.yaml:111 content.topCornerRadius = $radius.r6 (24px), bottom flush with the viewport */ transform: translateY(0); transition: transform 300ms cubic-bezier(.03,.4,.1,1); /* bottom-sheet.yaml:112-113 content.enterDuration/enterTimingFunction (enter-expressive) */ @starting-style { transform: translateY(100%); } }
7
+ & .crisp-bottomsheet-header { position: relative; display: flex; flex-direction: column; gap: var(--crisp-space-2); /* bottom-sheet.yaml:120 header.gap = $dimension.x2 (8px) */ padding-top: var(--crisp-space-6); padding-bottom: var(--crisp-space-4); /* bottom-sheet.yaml:121-122 header.paddingTop/paddingBottom = $dimension.x6/x4 (24px/16px) */ flex-shrink: 0; }
8
+ & .crisp-bottomsheet-title { color: var(--crisp-fg-primary); /* bottom-sheet.yaml:130 title.color = $color.fg.neutral */ font-size: 22px; line-height: 30px; font-weight: var(--crisp-weight-bold); /* bottom-sheet.yaml:131-133 title.fontSize/lineHeight/fontWeight = $font-size.t8/$line-height.t8/bold */ padding-inline: var(--crisp-space-4); /* default (headerAlignment=left, no close button): bottom-sheet.yaml:150-152 */ }
9
+ &[data-header-align="left"][data-has-close] .crisp-bottomsheet-title { padding-inline-start: var(--crisp-space-4); padding-inline-end: 56px; }
10
+ /* bottom-sheet.yaml:141-144 */
11
+ &[data-header-align="center"] .crisp-bottomsheet-title { text-align: center; }
12
+ &[data-header-align="center"][data-has-close] .crisp-bottomsheet-title { padding-inline: 56px; }
13
+ /* bottom-sheet.yaml:154-157 */
14
+ & .crisp-bottomsheet-description { color: var(--crisp-fg-muted); /* bottom-sheet.yaml:138 description.color = $color.fg.neutral-muted */ font-size: var(--crisp-text-xl); line-height: 22px; font-weight: var(--crisp-weight-regular); /* bottom-sheet.yaml:139-141 description.fontSize/lineHeight/fontWeight = $font-size.t5/$line-height.t5/regular */ padding-inline: var(--crisp-space-4); /* bottom-sheet.yaml:142 description.paddingX = global-gutter (16px) */ }
15
+ & .crisp-bottomsheet-close { position: absolute; top: var(--crisp-space-6); inset-inline-end: var(--crisp-space-4); /* bottom-sheet.yaml:145-146 closeButton.fromTop/fromRight = $dimension.x6/x4 (24px/16px) */ display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
16
+ & .crisp-bottomsheet-close:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
17
+ & .crisp-bottomsheet-body { flex: 1; min-height: 0; overflow-y: auto; padding-inline: var(--crisp-space-4); /* bottom-sheet.yaml:126 body.paddingX = global-gutter (16px) -- no vertical padding in the spec */ }
18
+ & .crisp-bottomsheet-footer { display: flex; align-items: center; justify-content: flex-end; gap: var(--crisp-space-3); flex-shrink: 0; padding-inline: var(--crisp-space-4); padding-top: var(--crisp-space-3); padding-bottom: var(--crisp-space-4); /* bottom-sheet.yaml:127-129 footer.paddingX/paddingTop/paddingBottom = global-gutter/x3/x4 (16px/12px/16px) */ }
19
+ }
20
+
21
+ @media (prefers-reduced-motion: reduce) {
22
+ .crisp-bottomsheet, .crisp-bottomsheet * {
23
+ animation-duration: 0.01ms !important;
24
+ animation-iteration-count: 1 !important;
25
+ transition-duration: 0.01ms !important;
26
+ }
27
+ }
28
+ }
package/dist/button.css CHANGED
@@ -1,35 +1,39 @@
1
1
  .crisp-button {
2
2
  display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1-5); font-family: var(--crisp-font-sans); font-weight: var(--crisp-weight-medium); letter-spacing: -0.07px; line-height: 20px; white-space: nowrap; border: none; cursor: pointer; transition: background-color .2s, box-shadow .2s, color .2s;
3
3
  &:disabled { opacity: 0.5; cursor: not-allowed; }
4
+ &:active { transform: scale(0.98); }
4
5
  }
5
6
  .crisp-button--intent_primary {
6
- 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);
7
+ background: var(--crisp-bg-brand-contrast); color: var(--crisp-fg-on-brand); box-shadow: none;
7
8
  &:hover { filter: brightness(0.96); }
8
9
  &:active { filter: brightness(0.92); }
9
10
  }
10
11
  .crisp-button--intent_neutral {
11
- 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);
12
- &:hover { background: var(--crisp-bg-raised); }
12
+ background: var(--crisp-bg-neutral-weak); color: var(--crisp-fg-primary); box-shadow: none;
13
+ &:hover { background: var(--crisp-border-subtle); }
13
14
  }
14
15
  .crisp-button--intent_danger {
15
- background: var(--crisp-bg-danger-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(186,37,37,0.20), 0 3px 6px -2px rgba(186,37,37,0.12);
16
+ background: var(--crisp-bg-danger-solid); color: var(--crisp-fg-on-brand); box-shadow: none;
16
17
  &:hover { filter: brightness(0.96); }
17
18
  &:active { filter: brightness(0.92); }
18
19
  }
19
20
  .crisp-button--intent_ghost {
20
- background: transparent; color: var(--crisp-fg-muted); box-shadow: none;
21
+ background: transparent; color: var(--crisp-fg-primary); box-shadow: none;
21
22
  &:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
22
23
  }
23
24
  .crisp-button--size_sm {
24
25
  height: 24px; padding-inline: var(--crisp-space-1-5); font-size: var(--crisp-text-md); border-radius: var(--crisp-radius-md);
25
26
  }
27
+ .crisp-button--size_xs {
28
+ height: 20px; padding-inline: var(--crisp-space-1-5); font-size: 10px; font-weight: var(--crisp-weight-regular); line-height: 15px; letter-spacing: normal; border-radius: var(--crisp-radius-sm); gap: var(--crisp-space-1);
29
+ }
26
30
  .crisp-button--size_md {
27
31
  height: 28px; padding-inline: var(--crisp-space-2); font-size: var(--crisp-text-lg); border-radius: var(--crisp-radius-md);
28
32
  &[data-icon-start] { padding-inline-start: var(--crisp-space-1-5); }
29
33
  &[data-icon-end] { padding-inline-end: var(--crisp-space-1-5); }
30
34
  }
31
35
  .crisp-button--size_lg {
32
- height: 40px; padding-inline: 14px; font-size: var(--crisp-text-lg); border-radius: 10px;
36
+ height: 40px; padding-inline: 14px; font-size: var(--crisp-text-lg); border-radius: var(--crisp-radius-xl);
33
37
  }
34
38
  .crisp-button--shape_text {
35
39
 
package/dist/button.d.ts CHANGED
@@ -2,9 +2,9 @@ import type { RecipeFn } from "../core/types";
2
2
 
3
3
  export interface ButtonVariants {
4
4
  intent?: "primary" | "neutral" | "danger" | "ghost";
5
- size?: "sm" | "md" | "lg";
5
+ size?: "sm" | "xs" | "md" | "lg";
6
6
  shape?: "text" | "icon";
7
7
  touchTarget?: boolean;
8
8
  }
9
9
 
10
- export declare const buttonRecipe: RecipeFn<{ intent: { primary: string; neutral: string; danger: string; ghost: string }; size: { sm: string; md: string; lg: string }; shape: { text: string; icon: string }; touchTarget: { true: string; false: string } }>;
10
+ export declare const buttonRecipe: RecipeFn<{ intent: { primary: string; neutral: string; danger: string; ghost: string }; size: { sm: string; xs: string; md: string; lg: string }; shape: { text: string; icon: string }; touchTarget: { true: string; false: string } }>;
@@ -2,35 +2,39 @@
2
2
  .crisp-button {
3
3
  display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1-5); font-family: var(--crisp-font-sans); font-weight: var(--crisp-weight-medium); letter-spacing: -0.07px; line-height: 20px; white-space: nowrap; border: none; cursor: pointer; transition: background-color .2s, box-shadow .2s, color .2s;
4
4
  &:disabled { opacity: 0.5; cursor: not-allowed; }
5
+ &:active { transform: scale(0.98); }
5
6
  }
6
7
  .crisp-button--intent_primary {
7
- 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);
8
+ background: var(--crisp-bg-brand-contrast); color: var(--crisp-fg-on-brand); box-shadow: none;
8
9
  &:hover { filter: brightness(0.96); }
9
10
  &:active { filter: brightness(0.92); }
10
11
  }
11
12
  .crisp-button--intent_neutral {
12
- 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);
13
- &:hover { background: var(--crisp-bg-raised); }
13
+ background: var(--crisp-bg-neutral-weak); color: var(--crisp-fg-primary); box-shadow: none;
14
+ &:hover { background: var(--crisp-border-subtle); }
14
15
  }
15
16
  .crisp-button--intent_danger {
16
- background: var(--crisp-bg-danger-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(186,37,37,0.20), 0 3px 6px -2px rgba(186,37,37,0.12);
17
+ background: var(--crisp-bg-danger-solid); color: var(--crisp-fg-on-brand); box-shadow: none;
17
18
  &:hover { filter: brightness(0.96); }
18
19
  &:active { filter: brightness(0.92); }
19
20
  }
20
21
  .crisp-button--intent_ghost {
21
- background: transparent; color: var(--crisp-fg-muted); box-shadow: none;
22
+ background: transparent; color: var(--crisp-fg-primary); box-shadow: none;
22
23
  &:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
23
24
  }
24
25
  .crisp-button--size_sm {
25
26
  height: 24px; padding-inline: var(--crisp-space-1-5); font-size: var(--crisp-text-md); border-radius: var(--crisp-radius-md);
26
27
  }
28
+ .crisp-button--size_xs {
29
+ height: 20px; padding-inline: var(--crisp-space-1-5); font-size: 10px; font-weight: var(--crisp-weight-regular); line-height: 15px; letter-spacing: normal; border-radius: var(--crisp-radius-sm); gap: var(--crisp-space-1);
30
+ }
27
31
  .crisp-button--size_md {
28
32
  height: 28px; padding-inline: var(--crisp-space-2); font-size: var(--crisp-text-lg); border-radius: var(--crisp-radius-md);
29
33
  &[data-icon-start] { padding-inline-start: var(--crisp-space-1-5); }
30
34
  &[data-icon-end] { padding-inline-end: var(--crisp-space-1-5); }
31
35
  }
32
36
  .crisp-button--size_lg {
33
- height: 40px; padding-inline: 14px; font-size: var(--crisp-text-lg); border-radius: 10px;
37
+ height: 40px; padding-inline: 14px; font-size: var(--crisp-text-lg); border-radius: var(--crisp-radius-xl);
34
38
  }
35
39
  .crisp-button--shape_text {
36
40
 
package/dist/checkbox.css CHANGED
@@ -1,10 +1,14 @@
1
1
  .crisp-checkbox {
2
- appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: none; border-radius: var(--crisp-radius-sm); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 9%, transparent); cursor: pointer; transition: background-color .12s, box-shadow .12s;
3
- &:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
4
- &:checked, &:indeterminate { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; box-shadow: none; }
2
+ appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: 1px solid var(--crisp-border-default); border-radius: var(--crisp-radius-xs); background: var(--crisp-bg-surface); cursor: pointer; transition: background-color .12s, border-color .12s;
3
+ &:hover { border-color: color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
4
+ &:checked, &:indeterminate { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; border-color: transparent; }
5
5
  &:checked { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
6
6
  &:indeterminate { background-image: linear-gradient(var(--crisp-fg-on-brand), var(--crisp-fg-on-brand)); background-size: 8px 2px; }
7
7
  &:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
8
+ &:disabled { background: var(--crisp-bg-neutral-weak); border-color: var(--crisp-border-subtle); cursor: not-allowed; }
9
+ &:checked:disabled, &:indeterminate:disabled { background: var(--crisp-bg-neutral-weak) center / 10px no-repeat; border-color: var(--crisp-border-subtle); }
10
+ &:checked:disabled { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
11
+ &:indeterminate:disabled { background-image: linear-gradient(var(--crisp-fg-on-brand), var(--crisp-fg-on-brand)); background-size: 8px 2px; }
8
12
  }
9
13
 
10
14
  @media (prefers-reduced-motion: reduce) {
@@ -1,11 +1,15 @@
1
1
  @layer crisp-components {
2
2
  .crisp-checkbox {
3
- appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: none; border-radius: var(--crisp-radius-sm); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 9%, transparent); cursor: pointer; transition: background-color .12s, box-shadow .12s;
4
- &:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
5
- &:checked, &:indeterminate { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; box-shadow: none; }
3
+ appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: 1px solid var(--crisp-border-default); border-radius: var(--crisp-radius-xs); background: var(--crisp-bg-surface); cursor: pointer; transition: background-color .12s, border-color .12s;
4
+ &:hover { border-color: color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
5
+ &:checked, &:indeterminate { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; border-color: transparent; }
6
6
  &:checked { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
7
7
  &:indeterminate { background-image: linear-gradient(var(--crisp-fg-on-brand), var(--crisp-fg-on-brand)); background-size: 8px 2px; }
8
8
  &:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
9
+ &:disabled { background: var(--crisp-bg-neutral-weak); border-color: var(--crisp-border-subtle); cursor: not-allowed; }
10
+ &:checked:disabled, &:indeterminate:disabled { background: var(--crisp-bg-neutral-weak) center / 10px no-repeat; border-color: var(--crisp-border-subtle); }
11
+ &:checked:disabled { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
12
+ &:indeterminate:disabled { background-image: linear-gradient(var(--crisp-fg-on-brand), var(--crisp-fg-on-brand)); background-size: 8px 2px; }
9
13
  }
10
14
 
11
15
  @media (prefers-reduced-motion: reduce) {
package/dist/chip.css CHANGED
@@ -2,7 +2,7 @@
2
2
  display: inline-flex; align-items: center; gap: 3px; height: var(--crisp-size-chip); min-width: 0; max-width: 100%; padding-inline: 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;
3
3
  }
4
4
  .crisp-chip--truncate_true {
5
- & .crisp-chip-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
5
+ & .crisp-chip-label { min-width: 0; overflow: clip; text-overflow: ellipsis; white-space: nowrap; display: block; }
6
6
  }
7
7
  .crisp-chip--truncate_false {
8
8
 
@@ -31,3 +31,18 @@
31
31
  .crisp-chip--tone_orange {
32
32
  background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-orange) 30%, transparent);
33
33
  }
34
+ .crisp-chip--appearance_filled {
35
+
36
+ }
37
+ .crisp-chip--appearance_outline {
38
+ background: transparent;
39
+ }
40
+ .crisp-chip--selected_true {
41
+ background: var(--crisp-bg-neutral-inverted); color: var(--crisp-fg-on-neutral-inverted); box-shadow: none;
42
+ }
43
+ .crisp-chip--selected_false {
44
+
45
+ }
46
+ .crisp-chip--compound_0 {
47
+ box-shadow: inset 0 0 0 1px var(--crisp-border-default);
48
+ }
package/dist/chip.d.ts CHANGED
@@ -3,6 +3,8 @@ import type { RecipeFn } from "../core/types";
3
3
  export interface ChipVariants {
4
4
  truncate?: boolean;
5
5
  tone?: "neutral" | "brand" | "success" | "warning" | "danger" | "purple" | "cyan" | "orange";
6
+ appearance?: "filled" | "outline";
7
+ selected?: boolean;
6
8
  }
7
9
 
8
- export declare const chipRecipe: RecipeFn<{ truncate: { true: string; false: string }; tone: { neutral: string; brand: string; success: string; warning: string; danger: string; purple: string; cyan: string; orange: string } }>;
10
+ export declare const chipRecipe: RecipeFn<{ truncate: { true: string; false: string }; tone: { neutral: string; brand: string; success: string; warning: string; danger: string; purple: string; cyan: string; orange: string }; appearance: { filled: string; outline: string }; selected: { true: string; false: string } }>;
@@ -3,7 +3,7 @@
3
3
  display: inline-flex; align-items: center; gap: 3px; height: var(--crisp-size-chip); min-width: 0; max-width: 100%; padding-inline: 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;
4
4
  }
5
5
  .crisp-chip--truncate_true {
6
- & .crisp-chip-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
6
+ & .crisp-chip-label { min-width: 0; overflow: clip; text-overflow: ellipsis; white-space: nowrap; display: block; }
7
7
  }
8
8
  .crisp-chip--truncate_false {
9
9
 
@@ -32,4 +32,19 @@
32
32
  .crisp-chip--tone_orange {
33
33
  background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-orange) 30%, transparent);
34
34
  }
35
+ .crisp-chip--appearance_filled {
36
+
37
+ }
38
+ .crisp-chip--appearance_outline {
39
+ background: transparent;
40
+ }
41
+ .crisp-chip--selected_true {
42
+ background: var(--crisp-bg-neutral-inverted); color: var(--crisp-fg-on-neutral-inverted); box-shadow: none;
43
+ }
44
+ .crisp-chip--selected_false {
45
+
46
+ }
47
+ .crisp-chip--compound_0 {
48
+ box-shadow: inset 0 0 0 1px var(--crisp-border-default);
49
+ }
35
50
  }
@@ -0,0 +1,5 @@
1
+ .crisp-chipgroup {
2
+ display: flex; flex-wrap: nowrap; align-items: center; gap: var(--crisp-space-1-5); overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none; -ms-overflow-style: none;
3
+ &::-webkit-scrollbar { display: none; }
4
+ & > * { flex-shrink: 0; scroll-snap-align: start; }
5
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface ChipgroupVariants {
4
+
5
+ }
6
+
7
+ export declare const chipgroupRecipe: RecipeFn<{ }>;
@@ -0,0 +1,7 @@
1
+ @layer crisp-components {
2
+ .crisp-chipgroup {
3
+ display: flex; flex-wrap: nowrap; align-items: center; gap: var(--crisp-space-1-5); overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none; -ms-overflow-style: none;
4
+ &::-webkit-scrollbar { display: none; }
5
+ & > * { flex-shrink: 0; scroll-snap-align: start; }
6
+ }
7
+ }