@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
@@ -26,7 +26,9 @@
26
26
  & .crisp-fileupload-remove:hover { color: var(--crisp-fg-primary); }
27
27
  & .crisp-fileupload-remove:focus-visible { outline-color: var(--crisp-stroke-focus-ring); }
28
28
  & .crisp-fileupload-errors { display: flex; flex-direction: column; gap: var(--crisp-space-0-5); margin: 0; padding: 0; list-style: none; }
29
- /* out of flow while empty, so the always-mounted live region costs no layout: display:none would take it out of the accessibility tree, which is the one thing it exists to be in */
29
+ /* out of flow while empty, so the always-mounted live region costs no
30
+ layout: display:none would take it out of the accessibility tree, which
31
+ is the one thing it exists to be in */
30
32
  & .crisp-fileupload-errors:empty { position: absolute; }
31
33
  & .crisp-fileupload-error { color: var(--crisp-bg-danger); font-size: var(--crisp-text-md); line-height: 18px; }
32
34
  }
package/dist/input.css CHANGED
@@ -1,5 +1,5 @@
1
1
  .crisp-input {
2
- position: relative; box-sizing: border-box; display: inline-flex; align-items: center; width: 100%; background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-field); font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); line-height: 20px;
2
+ position: relative; box-sizing: border-box; display: inline-flex; align-items: center; width: 100%; background: var(--crisp-bg-surface); border: 1px solid var(--crisp-border-default); font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); line-height: 20px;
3
3
  &::after { content: ""; position: absolute; inset: 0; border-radius: inherit; border: 2px solid transparent; transition: border-color .1s ease; pointer-events: none; }
4
4
  &:focus-within::after { border-color: var(--crisp-stroke-field-focus); }
5
5
  & .crisp-input-value { box-sizing: border-box; flex: 1 1 auto; min-width: 0; width: 100%; align-self: stretch; margin: 0; border: none; background: none; outline: none; font: inherit; color: var(--crisp-fg-primary); }
@@ -10,8 +10,10 @@
10
10
  primary-email field -- a tinted field, not just muted text, driven off
11
11
  the native `readOnly` attribute. `ringField` (rgba(0,0,0,.06)) is an
12
12
  exact match for the measured ring; the 2%-fgPrimary tint reuses the
13
- same color-mix idiom every other soft crisp surface already uses. */
14
- &[data-readonly] { background: color-mix(in srgb, var(--crisp-fg-primary) 2%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-ring-field); }
13
+ same color-mix idiom every other soft crisp surface already uses.
14
+ `border-color: transparent` neutralises #910's new real rest border
15
+ so this measured ring isn't drawn twice. */
16
+ &[data-readonly] { background: color-mix(in srgb, var(--crisp-fg-primary) 2%, transparent); border-color: transparent; box-shadow: inset 0 0 0 1px var(--crisp-ring-field); }
15
17
  & .crisp-input-suffix { flex-shrink: 0; margin-inline-start: var(--crisp-space-1); }
16
18
  }
17
19
  .crisp-input--size_sm {
@@ -23,7 +25,7 @@
23
25
  & .crisp-input-value { padding-inline: var(--crisp-space-2-5); }
24
26
  }
25
27
  .crisp-input--size_large {
26
- height: 36px; border-radius: 10px;
28
+ height: 36px; border-radius: var(--crisp-radius-xl);
27
29
  & .crisp-input-value { padding-inline: var(--crisp-space-3); }
28
30
  }
29
31
  .crisp-input--invalid_true {
@@ -1,6 +1,6 @@
1
1
  @layer crisp-components {
2
2
  .crisp-input {
3
- position: relative; box-sizing: border-box; display: inline-flex; align-items: center; width: 100%; background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-field); font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); line-height: 20px;
3
+ position: relative; box-sizing: border-box; display: inline-flex; align-items: center; width: 100%; background: var(--crisp-bg-surface); border: 1px solid var(--crisp-border-default); font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); line-height: 20px;
4
4
  &::after { content: ""; position: absolute; inset: 0; border-radius: inherit; border: 2px solid transparent; transition: border-color .1s ease; pointer-events: none; }
5
5
  &:focus-within::after { border-color: var(--crisp-stroke-field-focus); }
6
6
  & .crisp-input-value { box-sizing: border-box; flex: 1 1 auto; min-width: 0; width: 100%; align-self: stretch; margin: 0; border: none; background: none; outline: none; font: inherit; color: var(--crisp-fg-primary); }
@@ -11,8 +11,10 @@
11
11
  primary-email field -- a tinted field, not just muted text, driven off
12
12
  the native `readOnly` attribute. `ringField` (rgba(0,0,0,.06)) is an
13
13
  exact match for the measured ring; the 2%-fgPrimary tint reuses the
14
- same color-mix idiom every other soft crisp surface already uses. */
15
- &[data-readonly] { background: color-mix(in srgb, var(--crisp-fg-primary) 2%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-ring-field); }
14
+ same color-mix idiom every other soft crisp surface already uses.
15
+ `border-color: transparent` neutralises #910's new real rest border
16
+ so this measured ring isn't drawn twice. */
17
+ &[data-readonly] { background: color-mix(in srgb, var(--crisp-fg-primary) 2%, transparent); border-color: transparent; box-shadow: inset 0 0 0 1px var(--crisp-ring-field); }
16
18
  & .crisp-input-suffix { flex-shrink: 0; margin-inline-start: var(--crisp-space-1); }
17
19
  }
18
20
  .crisp-input--size_sm {
@@ -24,7 +26,7 @@
24
26
  & .crisp-input-value { padding-inline: var(--crisp-space-2-5); }
25
27
  }
26
28
  .crisp-input--size_large {
27
- height: 36px; border-radius: 10px;
29
+ height: 36px; border-radius: var(--crisp-radius-xl);
28
30
  & .crisp-input-value { padding-inline: var(--crisp-space-3); }
29
31
  }
30
32
  .crisp-input--invalid_true {
package/dist/listpage.css CHANGED
@@ -5,7 +5,9 @@
5
5
  & .crisp-listpage-count { margin-inline-start: auto; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); white-space: nowrap; }
6
6
  /* #641: trailing (View settings / New) has to reach the toolbar's own
7
7
  inline-end edge on its own -- the only thing pushing it there used
8
- to be .crisp-listpage-count's margin-inline-start: auto, which a consumer with no count badge (TasksTable, measured live: trailing sat right after leading, nowhere near the row's own right edge)
8
+ to be .crisp-listpage-count's margin-inline-start: auto, which a
9
+ consumer with no count badge (TasksTable, measured live: trailing
10
+ sat right after leading, nowhere near the row's own right edge)
9
11
  never renders. A bare margin-inline-start: auto here is safely
10
12
  overridden by the more specific rule right below whenever count IS
11
13
  present, so the two cases don't fight -- count's own auto margin
@@ -6,7 +6,9 @@
6
6
  & .crisp-listpage-count { margin-inline-start: auto; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); white-space: nowrap; }
7
7
  /* #641: trailing (View settings / New) has to reach the toolbar's own
8
8
  inline-end edge on its own -- the only thing pushing it there used
9
- to be .crisp-listpage-count's margin-inline-start: auto, which a consumer with no count badge (TasksTable, measured live: trailing sat right after leading, nowhere near the row's own right edge)
9
+ to be .crisp-listpage-count's margin-inline-start: auto, which a
10
+ consumer with no count badge (TasksTable, measured live: trailing
11
+ sat right after leading, nowhere near the row's own right edge)
10
12
  never renders. A bare margin-inline-start: auto here is safely
11
13
  overridden by the more specific rule right below whenever count IS
12
14
  present, so the two cases don't fight -- count's own auto margin
@@ -0,0 +1,67 @@
1
+ .crisp-memberssettings {
2
+ & .crisp-memberssettings-page { display: flex; flex-direction: column; gap: var(--crisp-space-6); font-family: var(--crisp-font-sans); }
3
+ & .crisp-memberssettings-heading { display: flex; flex-direction: column; gap: var(--crisp-space-0-5); }
4
+ & .crisp-memberssettings-title { font-size: 24px; line-height: 28px; font-weight: var(--crisp-weight-semibold); letter-spacing: -0.48px; color: var(--crisp-fg-primary); margin: 0; }
5
+ & .crisp-memberssettings-desc { font-size: var(--crisp-text-lg); line-height: 20px; color: var(--crisp-fg-muted); margin: 0; }
6
+ /* Segmented Members/Teams switcher -- measured: 28px pills, radius 8,
7
+ 4px gap, 6px icon-label gap, 14/500 label, selected bg bgSubtle +
8
+ inset borderSubtle ring, unselected transparent + a flat 63%-opacity
9
+ fgPrimary mix (measured rgba(0,0,0,.63) on the live page, not the
10
+ solid fgMuted token — same alpha technique this file's table header
11
+ already uses). */
12
+ & .crisp-memberssettings-tabpair { display: inline-flex; align-items: center; gap: 4px; }
13
+ & .crisp-memberssettings-tab { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: 28px; padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: none; box-shadow: inset 0 0 0 1px transparent; 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; white-space: nowrap; transition: color .12s ease, background-color .12s ease, box-shadow .12s ease; }
14
+ & .crisp-memberssettings-tab svg { flex-shrink: 0; }
15
+ & .crisp-memberssettings-tab:hover:not([data-selected]) { color: var(--crisp-fg-primary); }
16
+ & .crisp-memberssettings-tab[data-selected] { color: var(--crisp-fg-primary); background: var(--crisp-bg-subtle); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
17
+ & .crisp-memberssettings-tab:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
18
+ /* Toolbar row: search grows, Filter + Invite sit trailing -- measured
19
+ 32px height on all three, search radius 9 with a 6% ink ring,
20
+ Filter/Invite radius 9 with the button drop-shadow pairing. */
21
+ & .crisp-memberssettings-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); }
22
+ & .crisp-memberssettings-search { display: flex; align-items: center; flex: 1; min-width: 0; gap: var(--crisp-space-1-5); height: 32px; padding: 0 var(--crisp-space-2-5) 0 var(--crisp-space-2); border-radius: 9px; background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-muted); }
23
+ & .crisp-memberssettings-search:focus-within { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
24
+ & .crisp-memberssettings-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
25
+ & .crisp-memberssettings-search input::placeholder { color: var(--crisp-fg-muted); }
26
+ & .crisp-memberssettings-filterbtn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: 32px; padding: 6px 10px 6px 8px; border: none; border-radius: 9px; background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px transparent, 0 0 2px 0 rgba(28,40,64,.18), 0 1px 3px 0 rgba(0,0,0,.04); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); cursor: pointer; white-space: nowrap; }
27
+ & .crisp-memberssettings-filterbtn:hover { background: var(--crisp-bg-raised); }
28
+ /* your-moon/crisp#979: bgBrandContrast, not bgBrandSolid -- the accent
29
+ (#0298d9) only clears 3.23:1 with white; the darker sibling clears
30
+ 4.5:1+, same fix already applied to Button/Badge/Avatar (#897) and
31
+ TableToolbar/Dialog/Command/Comments/AuthShell (#953/#961), which
32
+ explicitly flagged this button as found-not-fixed. */
33
+ & .crisp-memberssettings-invitebtn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: 32px; padding: 6px 10px 6px 8px; border: none; border-radius: 9px; background: var(--crisp-bg-brand-contrast); box-shadow: inset 0 0 0 1px rgba(0,0,0,.06), 0 2px 4px -2px color-mix(in srgb, var(--crisp-bg-brand-contrast) 12%, transparent), 0 3px 6px -2px color-mix(in srgb, var(--crisp-bg-brand-contrast) 8%, transparent); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); cursor: pointer; white-space: nowrap; }
34
+ & .crisp-memberssettings-invitebtn:hover { filter: brightness(0.95); }
35
+ /* Table wrapper -- measured card: radius 12, 1px borderSubtle, 40px
36
+ rows, header label 12/500/63%-opacity fgPrimary. */
37
+ & .crisp-memberssettings-table-wrap { border-radius: 12px; border: 1px solid var(--crisp-border-subtle); overflow: hidden; }
38
+ & .crisp-memberssettings-table { width: 100%; border-collapse: collapse; font-family: inherit; }
39
+ & .crisp-memberssettings-table th { height: 32px; padding: 0 var(--crisp-space-4); text-align: start; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); border-bottom: 1px solid var(--crisp-border-subtle); background: var(--crisp-bg-surface); }
40
+ & .crisp-memberssettings-table td { height: 40px; padding: 0 var(--crisp-space-4); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); border-bottom: 1px solid var(--crisp-border-subtle); }
41
+ & .crisp-memberssettings-table tr:last-child td { border-bottom: none; }
42
+ & .crisp-memberssettings-user { display: flex; align-items: center; gap: var(--crisp-space-2); }
43
+ & .crisp-memberssettings-avatarimg { width: 24px; height: 24px; border-radius: var(--crisp-radius-full); object-fit: cover; }
44
+ /* Name + email sit on ONE line, not stacked -- confirmed live: both spans
45
+ share the same y and the same 14px size, only the email's colour
46
+ differs (a flat 63%-opacity fgPrimary mix, not a smaller muted font). */
47
+ & .crisp-memberssettings-usermeta { display: flex; align-items: baseline; gap: var(--crisp-space-2); min-width: 0; }
48
+ & .crisp-memberssettings-usermeta > span:first-child { flex-shrink: 0; }
49
+ & .crisp-memberssettings-useremail { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-regular); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
50
+ & .crisp-memberssettings-kebab { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-inline-start: auto; border: none; border-radius: var(--crisp-radius-sm); background: none; font-family: inherit; color: var(--crisp-fg-muted); cursor: pointer; }
51
+ & .crisp-memberssettings-kebab:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
52
+ & .crisp-memberssettings-teamspanel { display: flex; align-items: center; justify-content: center; padding: var(--crisp-space-8) 0; color: var(--crisp-fg-muted); font-size: var(--crisp-text-lg); }
53
+ /* Invite dialog fields -- measured 708x386 dialog, radius 16; the
54
+ "Invite as"/"Add to team" selects are 32/34px with a flat 1px
55
+ 6%-ink border and 9/10px radius respectively (Attio's own two
56
+ selects don't share one radius). */
57
+ & .crisp-memberssettings-invitefield { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); }
58
+ & .crisp-memberssettings-invitelabel { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
59
+ }
60
+
61
+ @media (prefers-reduced-motion: reduce) {
62
+ .crisp-memberssettings, .crisp-memberssettings * {
63
+ animation-duration: 0.01ms !important;
64
+ animation-iteration-count: 1 !important;
65
+ transition-duration: 0.01ms !important;
66
+ }
67
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface MemberssettingsVariants {
4
+
5
+ }
6
+
7
+ export declare const memberssettingsRecipe: RecipeFn<{ }>;
@@ -0,0 +1,69 @@
1
+ @layer crisp-components {
2
+ .crisp-memberssettings {
3
+ & .crisp-memberssettings-page { display: flex; flex-direction: column; gap: var(--crisp-space-6); font-family: var(--crisp-font-sans); }
4
+ & .crisp-memberssettings-heading { display: flex; flex-direction: column; gap: var(--crisp-space-0-5); }
5
+ & .crisp-memberssettings-title { font-size: 24px; line-height: 28px; font-weight: var(--crisp-weight-semibold); letter-spacing: -0.48px; color: var(--crisp-fg-primary); margin: 0; }
6
+ & .crisp-memberssettings-desc { font-size: var(--crisp-text-lg); line-height: 20px; color: var(--crisp-fg-muted); margin: 0; }
7
+ /* Segmented Members/Teams switcher -- measured: 28px pills, radius 8,
8
+ 4px gap, 6px icon-label gap, 14/500 label, selected bg bgSubtle +
9
+ inset borderSubtle ring, unselected transparent + a flat 63%-opacity
10
+ fgPrimary mix (measured rgba(0,0,0,.63) on the live page, not the
11
+ solid fgMuted token — same alpha technique this file's table header
12
+ already uses). */
13
+ & .crisp-memberssettings-tabpair { display: inline-flex; align-items: center; gap: 4px; }
14
+ & .crisp-memberssettings-tab { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: 28px; padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: none; box-shadow: inset 0 0 0 1px transparent; 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; white-space: nowrap; transition: color .12s ease, background-color .12s ease, box-shadow .12s ease; }
15
+ & .crisp-memberssettings-tab svg { flex-shrink: 0; }
16
+ & .crisp-memberssettings-tab:hover:not([data-selected]) { color: var(--crisp-fg-primary); }
17
+ & .crisp-memberssettings-tab[data-selected] { color: var(--crisp-fg-primary); background: var(--crisp-bg-subtle); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
18
+ & .crisp-memberssettings-tab:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
19
+ /* Toolbar row: search grows, Filter + Invite sit trailing -- measured
20
+ 32px height on all three, search radius 9 with a 6% ink ring,
21
+ Filter/Invite radius 9 with the button drop-shadow pairing. */
22
+ & .crisp-memberssettings-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); }
23
+ & .crisp-memberssettings-search { display: flex; align-items: center; flex: 1; min-width: 0; gap: var(--crisp-space-1-5); height: 32px; padding: 0 var(--crisp-space-2-5) 0 var(--crisp-space-2); border-radius: 9px; background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-muted); }
24
+ & .crisp-memberssettings-search:focus-within { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
25
+ & .crisp-memberssettings-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
26
+ & .crisp-memberssettings-search input::placeholder { color: var(--crisp-fg-muted); }
27
+ & .crisp-memberssettings-filterbtn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: 32px; padding: 6px 10px 6px 8px; border: none; border-radius: 9px; background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px transparent, 0 0 2px 0 rgba(28,40,64,.18), 0 1px 3px 0 rgba(0,0,0,.04); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); cursor: pointer; white-space: nowrap; }
28
+ & .crisp-memberssettings-filterbtn:hover { background: var(--crisp-bg-raised); }
29
+ /* your-moon/crisp#979: bgBrandContrast, not bgBrandSolid -- the accent
30
+ (#0298d9) only clears 3.23:1 with white; the darker sibling clears
31
+ 4.5:1+, same fix already applied to Button/Badge/Avatar (#897) and
32
+ TableToolbar/Dialog/Command/Comments/AuthShell (#953/#961), which
33
+ explicitly flagged this button as found-not-fixed. */
34
+ & .crisp-memberssettings-invitebtn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: 32px; padding: 6px 10px 6px 8px; border: none; border-radius: 9px; background: var(--crisp-bg-brand-contrast); box-shadow: inset 0 0 0 1px rgba(0,0,0,.06), 0 2px 4px -2px color-mix(in srgb, var(--crisp-bg-brand-contrast) 12%, transparent), 0 3px 6px -2px color-mix(in srgb, var(--crisp-bg-brand-contrast) 8%, transparent); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); cursor: pointer; white-space: nowrap; }
35
+ & .crisp-memberssettings-invitebtn:hover { filter: brightness(0.95); }
36
+ /* Table wrapper -- measured card: radius 12, 1px borderSubtle, 40px
37
+ rows, header label 12/500/63%-opacity fgPrimary. */
38
+ & .crisp-memberssettings-table-wrap { border-radius: 12px; border: 1px solid var(--crisp-border-subtle); overflow: hidden; }
39
+ & .crisp-memberssettings-table { width: 100%; border-collapse: collapse; font-family: inherit; }
40
+ & .crisp-memberssettings-table th { height: 32px; padding: 0 var(--crisp-space-4); text-align: start; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); border-bottom: 1px solid var(--crisp-border-subtle); background: var(--crisp-bg-surface); }
41
+ & .crisp-memberssettings-table td { height: 40px; padding: 0 var(--crisp-space-4); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); border-bottom: 1px solid var(--crisp-border-subtle); }
42
+ & .crisp-memberssettings-table tr:last-child td { border-bottom: none; }
43
+ & .crisp-memberssettings-user { display: flex; align-items: center; gap: var(--crisp-space-2); }
44
+ & .crisp-memberssettings-avatarimg { width: 24px; height: 24px; border-radius: var(--crisp-radius-full); object-fit: cover; }
45
+ /* Name + email sit on ONE line, not stacked -- confirmed live: both spans
46
+ share the same y and the same 14px size, only the email's colour
47
+ differs (a flat 63%-opacity fgPrimary mix, not a smaller muted font). */
48
+ & .crisp-memberssettings-usermeta { display: flex; align-items: baseline; gap: var(--crisp-space-2); min-width: 0; }
49
+ & .crisp-memberssettings-usermeta > span:first-child { flex-shrink: 0; }
50
+ & .crisp-memberssettings-useremail { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-regular); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
51
+ & .crisp-memberssettings-kebab { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-inline-start: auto; border: none; border-radius: var(--crisp-radius-sm); background: none; font-family: inherit; color: var(--crisp-fg-muted); cursor: pointer; }
52
+ & .crisp-memberssettings-kebab:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
53
+ & .crisp-memberssettings-teamspanel { display: flex; align-items: center; justify-content: center; padding: var(--crisp-space-8) 0; color: var(--crisp-fg-muted); font-size: var(--crisp-text-lg); }
54
+ /* Invite dialog fields -- measured 708x386 dialog, radius 16; the
55
+ "Invite as"/"Add to team" selects are 32/34px with a flat 1px
56
+ 6%-ink border and 9/10px radius respectively (Attio's own two
57
+ selects don't share one radius). */
58
+ & .crisp-memberssettings-invitefield { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); }
59
+ & .crisp-memberssettings-invitelabel { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
60
+ }
61
+
62
+ @media (prefers-reduced-motion: reduce) {
63
+ .crisp-memberssettings, .crisp-memberssettings * {
64
+ animation-duration: 0.01ms !important;
65
+ animation-iteration-count: 1 !important;
66
+ transition-duration: 0.01ms !important;
67
+ }
68
+ }
69
+ }
package/dist/menu.css CHANGED
@@ -8,8 +8,8 @@
8
8
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
9
9
  position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
10
10
  min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1);
11
- border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
12
- box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
11
+ border-radius: var(--crisp-radius-3xl); background: var(--crisp-bg-popover);
12
+ box-shadow: 0 4px 16px var(--crisp-shadow-select);
13
13
  transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease;
14
14
  }
15
15
  .crisp-menu-content[data-align="end"] { transform-origin: top right; }
@@ -9,8 +9,8 @@
9
9
  font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
10
10
  position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
11
11
  min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1);
12
- border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
13
- box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
12
+ border-radius: var(--crisp-radius-3xl); background: var(--crisp-bg-popover);
13
+ box-shadow: 0 4px 16px var(--crisp-shadow-select);
14
14
  transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease;
15
15
  }
16
16
  .crisp-menu-content[data-align="end"] { transform-origin: top right; }
@@ -0,0 +1,36 @@
1
+ .crisp-menusheet {
2
+ display: contents; font-family: var(--crisp-font-sans);
3
+ & .crisp-menusheet-backdrop { position: fixed; inset: 0; z-index: 60; background: var(--crisp-bg-overlay-strong); /* menu-sheet.yaml:95 backdrop.color = $color.bg.overlay */ opacity: 1; transition: opacity 100ms cubic-bezier(0,0,.15,1); /* menu-sheet.yaml:96-98 enterDuration/enterTimingFunction = $duration.d2/$timing-function.enter */ @starting-style { opacity: 0; } }
4
+ & .crisp-menusheet-positioner { position: fixed; inset: 0; z-index: 61; display: flex; align-items: flex-end; justify-content: center; }
5
+ & .crisp-menusheet-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; /* menu-sheet.yaml:104 content.maxWidth */ max-height: 85vh; background: var(--crisp-bg-surface); /* menu-sheet.yaml:103 content.color = $color.bg.layer-floating */ padding: var(--crisp-space-6) var(--crisp-space-4) var(--crisp-space-4); /* menu-sheet.yaml:105-107 content.paddingX/paddingTop/paddingBottom = global-gutter/x6/x4 (16px/24px/16px) */ border-radius: var(--crisp-radius-3xl) var(--crisp-radius-3xl) 0 0; /* menu-sheet.yaml:108 content.topCornerRadius = $radius.r5 (20px) */ transform: translateY(0); transition: transform 300ms cubic-bezier(.03,.4,.1,1); /* menu-sheet.yaml:109-110 content.enterDuration/enterTimingFunction (enter-expressive) */ @starting-style { transform: translateY(100%); } }
6
+ & .crisp-menusheet-header { display: flex; flex-direction: column; gap: var(--crisp-space-1); /* menu-sheet.yaml:115 header.gap = $dimension.x1 (4px) */ padding-bottom: var(--crisp-space-4); /* menu-sheet.yaml:116 header.paddingBottom = $dimension.x4 (16px) */ flex-shrink: 0; }
7
+ & .crisp-menusheet-title { color: var(--crisp-fg-primary); /* menu-sheet.yaml:121 title.color = $color.fg.neutral */ font-size: 18px; line-height: 24px; font-weight: var(--crisp-weight-bold); /* menu-sheet.yaml:118-120 title.fontSize/lineHeight/fontWeight = $font-size.t6/$line-height.t6/bold */ }
8
+ & .crisp-menusheet-description { color: var(--crisp-fg-muted); /* menu-sheet.yaml:126 description.color = $color.fg.neutral-muted */ font-size: var(--crisp-text-lg); line-height: 19px; font-weight: var(--crisp-weight-regular); /* menu-sheet.yaml:123-125 description.fontSize/lineHeight/fontWeight = $font-size.t4/$line-height.t4/regular */ }
9
+ & .crisp-menusheet-list { display: flex; flex-direction: column; gap: var(--crisp-space-2-5); /* menu-sheet.yaml:129 list.gap = $dimension.x2_5 (10px) */ overflow-y: auto; min-height: 0; }
10
+ & .crisp-menusheet-group { display: flex; flex-direction: column; border-radius: var(--crisp-radius-2xl); overflow: hidden; /* menu-sheet.yaml:131 group.cornerRadius = $radius.r4 (16px) */ }
11
+ & .crisp-menusheet-group > * + * { border-top: 1px solid var(--crisp-stroke-group-divider); }
12
+ /* menu-sheet.yaml:132-134 divider.strokeBottomWidth/strokeColor = 1px/$color.stroke.neutral-muted */
13
+ & .crisp-menusheet-footer { flex-shrink: 0; padding-top: var(--crisp-space-2-5); /* menu-sheet.yaml:136 footer.paddingTop = $dimension.x2_5 (10px) */ }
14
+ & .crisp-menusheet-item { position: relative; box-sizing: border-box; display: flex; align-items: center; width: 100%; min-height: 52px; /* menu-sheet-item.yaml:72 root.minHeight */ padding: var(--crisp-space-3-5) var(--crisp-space-4); gap: var(--crisp-space-3-5); /* menu-sheet-item.yaml:73-75 root.paddingX/paddingY/gap = x4/x3_5/x3_5 (16px/14px/14px) */ border: none; margin: 0; cursor: pointer; text-align: start; background: var(--crisp-bg-neutral-weak); /* menu-sheet-item.yaml:71 root.color = $color.bg.neutral-weak */ font-family: inherit; }
15
+ & .crisp-menusheet-item:hover, & .crisp-menusheet-item:active { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, var(--crisp-bg-neutral-weak)); }
16
+ /* menu-sheet-item.yaml:90-91 pressed.root.color = $color.bg.neutral-weak-pressed, approximated as a tint over the base fill */
17
+ & .crisp-menusheet-item:active .crisp-menusheet-item-content { transform: scale(0.98); }
18
+ /* menu-sheet-item.yaml:92 pressed.root.scaleScope = content */
19
+ & .crisp-menusheet-item-icon { flex-shrink: 0; display: inline-flex; width: 22px; height: 22px; }
20
+ /* menu-sheet-item.yaml:77 prefixIcon.size */
21
+ & .crisp-menusheet-item-content { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--crisp-space-0-5); /* menu-sheet-item.yaml:79 content.gap = $dimension.x0_5 (2px) */ transition: transform 150ms cubic-bezier(0,0,.15,1); }
22
+ & .crisp-menusheet-item-label { font-size: var(--crisp-text-xl); line-height: 22px; font-weight: var(--crisp-weight-regular); /* menu-sheet-item.yaml:81-83 label.fontSize/lineHeight/fontWeight = $font-size.t5/$line-height.t5/regular */ }
23
+ & .crisp-menusheet-item-description { color: var(--crisp-fg-neutral-subtle); /* menu-sheet-item.yaml:88 description.color = $color.fg.neutral-subtle */ font-size: var(--crisp-text-md); line-height: 18px; font-weight: var(--crisp-weight-medium); /* menu-sheet-item.yaml:85-87 description.fontSize/lineHeight/fontWeight = $font-size.t3/$line-height.t3/medium */ }
24
+ & .crisp-menusheet-item[data-tone="neutral"] .crisp-menusheet-item-icon, & .crisp-menusheet-item[data-tone="neutral"] .crisp-menusheet-item-label { color: var(--crisp-fg-primary); }
25
+ /* menu-sheet-item.yaml:93-98 tone=neutral */
26
+ & .crisp-menusheet-item[data-tone="critical"] .crisp-menusheet-item-icon, & .crisp-menusheet-item[data-tone="critical"] .crisp-menusheet-item-label { color: var(--crisp-fg-danger); }
27
+ /* menu-sheet-item.yaml:99-104 tone=critical */
28
+ }
29
+
30
+ @media (prefers-reduced-motion: reduce) {
31
+ .crisp-menusheet, .crisp-menusheet * {
32
+ animation-duration: 0.01ms !important;
33
+ animation-iteration-count: 1 !important;
34
+ transition-duration: 0.01ms !important;
35
+ }
36
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface MenusheetVariants {
4
+
5
+ }
6
+
7
+ export declare const menusheetRecipe: RecipeFn<{ }>;
@@ -0,0 +1,38 @@
1
+ @layer crisp-components {
2
+ .crisp-menusheet {
3
+ display: contents; font-family: var(--crisp-font-sans);
4
+ & .crisp-menusheet-backdrop { position: fixed; inset: 0; z-index: 60; background: var(--crisp-bg-overlay-strong); /* menu-sheet.yaml:95 backdrop.color = $color.bg.overlay */ opacity: 1; transition: opacity 100ms cubic-bezier(0,0,.15,1); /* menu-sheet.yaml:96-98 enterDuration/enterTimingFunction = $duration.d2/$timing-function.enter */ @starting-style { opacity: 0; } }
5
+ & .crisp-menusheet-positioner { position: fixed; inset: 0; z-index: 61; display: flex; align-items: flex-end; justify-content: center; }
6
+ & .crisp-menusheet-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; /* menu-sheet.yaml:104 content.maxWidth */ max-height: 85vh; background: var(--crisp-bg-surface); /* menu-sheet.yaml:103 content.color = $color.bg.layer-floating */ padding: var(--crisp-space-6) var(--crisp-space-4) var(--crisp-space-4); /* menu-sheet.yaml:105-107 content.paddingX/paddingTop/paddingBottom = global-gutter/x6/x4 (16px/24px/16px) */ border-radius: var(--crisp-radius-3xl) var(--crisp-radius-3xl) 0 0; /* menu-sheet.yaml:108 content.topCornerRadius = $radius.r5 (20px) */ transform: translateY(0); transition: transform 300ms cubic-bezier(.03,.4,.1,1); /* menu-sheet.yaml:109-110 content.enterDuration/enterTimingFunction (enter-expressive) */ @starting-style { transform: translateY(100%); } }
7
+ & .crisp-menusheet-header { display: flex; flex-direction: column; gap: var(--crisp-space-1); /* menu-sheet.yaml:115 header.gap = $dimension.x1 (4px) */ padding-bottom: var(--crisp-space-4); /* menu-sheet.yaml:116 header.paddingBottom = $dimension.x4 (16px) */ flex-shrink: 0; }
8
+ & .crisp-menusheet-title { color: var(--crisp-fg-primary); /* menu-sheet.yaml:121 title.color = $color.fg.neutral */ font-size: 18px; line-height: 24px; font-weight: var(--crisp-weight-bold); /* menu-sheet.yaml:118-120 title.fontSize/lineHeight/fontWeight = $font-size.t6/$line-height.t6/bold */ }
9
+ & .crisp-menusheet-description { color: var(--crisp-fg-muted); /* menu-sheet.yaml:126 description.color = $color.fg.neutral-muted */ font-size: var(--crisp-text-lg); line-height: 19px; font-weight: var(--crisp-weight-regular); /* menu-sheet.yaml:123-125 description.fontSize/lineHeight/fontWeight = $font-size.t4/$line-height.t4/regular */ }
10
+ & .crisp-menusheet-list { display: flex; flex-direction: column; gap: var(--crisp-space-2-5); /* menu-sheet.yaml:129 list.gap = $dimension.x2_5 (10px) */ overflow-y: auto; min-height: 0; }
11
+ & .crisp-menusheet-group { display: flex; flex-direction: column; border-radius: var(--crisp-radius-2xl); overflow: hidden; /* menu-sheet.yaml:131 group.cornerRadius = $radius.r4 (16px) */ }
12
+ & .crisp-menusheet-group > * + * { border-top: 1px solid var(--crisp-stroke-group-divider); }
13
+ /* menu-sheet.yaml:132-134 divider.strokeBottomWidth/strokeColor = 1px/$color.stroke.neutral-muted */
14
+ & .crisp-menusheet-footer { flex-shrink: 0; padding-top: var(--crisp-space-2-5); /* menu-sheet.yaml:136 footer.paddingTop = $dimension.x2_5 (10px) */ }
15
+ & .crisp-menusheet-item { position: relative; box-sizing: border-box; display: flex; align-items: center; width: 100%; min-height: 52px; /* menu-sheet-item.yaml:72 root.minHeight */ padding: var(--crisp-space-3-5) var(--crisp-space-4); gap: var(--crisp-space-3-5); /* menu-sheet-item.yaml:73-75 root.paddingX/paddingY/gap = x4/x3_5/x3_5 (16px/14px/14px) */ border: none; margin: 0; cursor: pointer; text-align: start; background: var(--crisp-bg-neutral-weak); /* menu-sheet-item.yaml:71 root.color = $color.bg.neutral-weak */ font-family: inherit; }
16
+ & .crisp-menusheet-item:hover, & .crisp-menusheet-item:active { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, var(--crisp-bg-neutral-weak)); }
17
+ /* menu-sheet-item.yaml:90-91 pressed.root.color = $color.bg.neutral-weak-pressed, approximated as a tint over the base fill */
18
+ & .crisp-menusheet-item:active .crisp-menusheet-item-content { transform: scale(0.98); }
19
+ /* menu-sheet-item.yaml:92 pressed.root.scaleScope = content */
20
+ & .crisp-menusheet-item-icon { flex-shrink: 0; display: inline-flex; width: 22px; height: 22px; }
21
+ /* menu-sheet-item.yaml:77 prefixIcon.size */
22
+ & .crisp-menusheet-item-content { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--crisp-space-0-5); /* menu-sheet-item.yaml:79 content.gap = $dimension.x0_5 (2px) */ transition: transform 150ms cubic-bezier(0,0,.15,1); }
23
+ & .crisp-menusheet-item-label { font-size: var(--crisp-text-xl); line-height: 22px; font-weight: var(--crisp-weight-regular); /* menu-sheet-item.yaml:81-83 label.fontSize/lineHeight/fontWeight = $font-size.t5/$line-height.t5/regular */ }
24
+ & .crisp-menusheet-item-description { color: var(--crisp-fg-neutral-subtle); /* menu-sheet-item.yaml:88 description.color = $color.fg.neutral-subtle */ font-size: var(--crisp-text-md); line-height: 18px; font-weight: var(--crisp-weight-medium); /* menu-sheet-item.yaml:85-87 description.fontSize/lineHeight/fontWeight = $font-size.t3/$line-height.t3/medium */ }
25
+ & .crisp-menusheet-item[data-tone="neutral"] .crisp-menusheet-item-icon, & .crisp-menusheet-item[data-tone="neutral"] .crisp-menusheet-item-label { color: var(--crisp-fg-primary); }
26
+ /* menu-sheet-item.yaml:93-98 tone=neutral */
27
+ & .crisp-menusheet-item[data-tone="critical"] .crisp-menusheet-item-icon, & .crisp-menusheet-item[data-tone="critical"] .crisp-menusheet-item-label { color: var(--crisp-fg-danger); }
28
+ /* menu-sheet-item.yaml:99-104 tone=critical */
29
+ }
30
+
31
+ @media (prefers-reduced-motion: reduce) {
32
+ .crisp-menusheet, .crisp-menusheet * {
33
+ animation-duration: 0.01ms !important;
34
+ animation-iteration-count: 1 !important;
35
+ transition-duration: 0.01ms !important;
36
+ }
37
+ }
38
+ }
@@ -11,13 +11,19 @@
11
11
  }
12
12
  .crisp-multiselect-listbox[data-up] { transform-origin: bottom left; }
13
13
  .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.95); } }
14
- /* LOCKED geometry (#481, guarded by build/spec-check.mjs): height 36px,
15
- gap space["1.5"] (6px), no border-bottom -- an Attio measurement, not
16
- part of this seed-parity pass. Only colours below follow Select. */
17
- .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: 36px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-2)) calc(-1 * var(--crisp-space-2)) var(--crisp-space-2); padding: var(--crisp-space-2) var(--crisp-space-3); color: var(--crisp-fg-neutral-muted); }
14
+ /* Seed geometry (build/spec-check.mjs guards these four properties
15
+ directly), superseding #481's old Attio lock -- see this file's
16
+ header comment and Select's matching .crisp-select-search comment
17
+ for the full citation. An ordinary flex child of the listbox, so its
18
+ own 8px gap provides the inset/seam on every side, same as Select. */
19
+ .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-selectTriggerMd); flex-shrink: 0; padding: 0 var(--crisp-space-3-5); border: 1px solid var(--crisp-stroke-select-trigger); border-radius: var(--crisp-radius-md); color: var(--crisp-fg-neutral-muted); }
18
20
  .crisp-multiselect-search svg { flex-shrink: 0; }
19
- .crisp-multiselect-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-select-neutral); }
21
+ .crisp-multiselect-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); line-height: 19px; color: var(--crisp-fg-select-neutral); }
20
22
  .crisp-multiselect-search input::placeholder { color: var(--crisp-fg-select-placeholder); }
23
+ /* Same header/body seam as Select's own .crisp-select-divider -- see
24
+ that recipe's comment for the seed source (select.yaml's divider
25
+ slot, stroke.neutral-muted). */
26
+ .crisp-multiselect-divider { flex-shrink: 0; height: 1px; margin-inline: var(--crisp-space-4); background: var(--crisp-stroke-select-divider); }
21
27
  /* Same groupLabel treatment as Select's (13px/regular/neutral-subtle). */
22
28
  .crisp-multiselect-label { padding: var(--crisp-space-2) var(--crisp-space-4) 0; font-size: var(--crisp-text-md); line-height: 18px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-neutral-subtle); }
23
29
  .crisp-multiselect-option {
@@ -57,7 +63,8 @@
57
63
  & .crisp-multiselect-trigger[aria-readonly="true"] { background: var(--crisp-bg-select-disabled); cursor: default; }
58
64
  & .crisp-multiselect-chips { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); }
59
65
  & .crisp-multiselect-placeholder { color: var(--crisp-fg-select-placeholder); }
60
- /* closeRotateDuration/openRotateDuration, same asymmetric timing as Select's own chevron (see that recipe's comment). */
66
+ /* closeRotateDuration/openRotateDuration, same asymmetric timing as
67
+ Select's own chevron (see that recipe's comment). */
61
68
  & .crisp-multiselect-chevron { flex-shrink: 0; color: var(--crisp-fg-neutral-muted); transition: transform .1s cubic-bezier(.35,0,.35,1); }
62
69
  & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); transition-duration: .15s; }
63
70
  }
@@ -12,13 +12,19 @@
12
12
  }
13
13
  .crisp-multiselect-listbox[data-up] { transform-origin: bottom left; }
14
14
  .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.95); } }
15
- /* LOCKED geometry (#481, guarded by build/spec-check.mjs): height 36px,
16
- gap space["1.5"] (6px), no border-bottom -- an Attio measurement, not
17
- part of this seed-parity pass. Only colours below follow Select. */
18
- .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: 36px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-2)) calc(-1 * var(--crisp-space-2)) var(--crisp-space-2); padding: var(--crisp-space-2) var(--crisp-space-3); color: var(--crisp-fg-neutral-muted); }
15
+ /* Seed geometry (build/spec-check.mjs guards these four properties
16
+ directly), superseding #481's old Attio lock -- see this file's
17
+ header comment and Select's matching .crisp-select-search comment
18
+ for the full citation. An ordinary flex child of the listbox, so its
19
+ own 8px gap provides the inset/seam on every side, same as Select. */
20
+ .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-selectTriggerMd); flex-shrink: 0; padding: 0 var(--crisp-space-3-5); border: 1px solid var(--crisp-stroke-select-trigger); border-radius: var(--crisp-radius-md); color: var(--crisp-fg-neutral-muted); }
19
21
  .crisp-multiselect-search svg { flex-shrink: 0; }
20
- .crisp-multiselect-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-select-neutral); }
22
+ .crisp-multiselect-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); line-height: 19px; color: var(--crisp-fg-select-neutral); }
21
23
  .crisp-multiselect-search input::placeholder { color: var(--crisp-fg-select-placeholder); }
24
+ /* Same header/body seam as Select's own .crisp-select-divider -- see
25
+ that recipe's comment for the seed source (select.yaml's divider
26
+ slot, stroke.neutral-muted). */
27
+ .crisp-multiselect-divider { flex-shrink: 0; height: 1px; margin-inline: var(--crisp-space-4); background: var(--crisp-stroke-select-divider); }
22
28
  /* Same groupLabel treatment as Select's (13px/regular/neutral-subtle). */
23
29
  .crisp-multiselect-label { padding: var(--crisp-space-2) var(--crisp-space-4) 0; font-size: var(--crisp-text-md); line-height: 18px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-neutral-subtle); }
24
30
  .crisp-multiselect-option {
@@ -58,7 +64,8 @@
58
64
  & .crisp-multiselect-trigger[aria-readonly="true"] { background: var(--crisp-bg-select-disabled); cursor: default; }
59
65
  & .crisp-multiselect-chips { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); }
60
66
  & .crisp-multiselect-placeholder { color: var(--crisp-fg-select-placeholder); }
61
- /* closeRotateDuration/openRotateDuration, same asymmetric timing as Select's own chevron (see that recipe's comment). */
67
+ /* closeRotateDuration/openRotateDuration, same asymmetric timing as
68
+ Select's own chevron (see that recipe's comment). */
62
69
  & .crisp-multiselect-chevron { flex-shrink: 0; color: var(--crisp-fg-neutral-muted); transition: transform .1s cubic-bezier(.35,0,.35,1); }
63
70
  & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); transition-duration: .15s; }
64
71
  }
@@ -2,7 +2,7 @@
2
2
  // The same tokens the CSS custom properties carry, resolved per theme, with
3
3
  // dimensions as numbers for React Native and Lynx style objects.
4
4
  export type Theme = "light" | "dark";
5
- export type ColorTokens = Record<"bgBrandSolid" | "bgBrandSolidPressed" | "bgBrandContrast" | "fgBrandContrast" | "fgOnBrand" | "fgOnTone" | "bgSurface" | "bgRaised" | "bgSurfaceMuted" | "borderDefault" | "borderSubtle" | "borderDropzone" | "borderDivider" | "ringNeutral" | "ringField" | "ringSwitch" | "bgTileActive" | "shadowTileActive" | "bgScrim" | "fgAlertDescription" | "bgOverlayFrost" | "shadowOverlay1" | "shadowOverlay2" | "shadowOverlay3" | "bgPopover" | "ringPopover" | "shadowPopover1" | "shadowPopover2" | "shadowPopover3" | "fgPrimary" | "fgMuted" | "bgDanger" | "bgDangerSolid" | "fgDanger" | "strokeFieldFocus" | "fgDisabled" | "bgNeutralWeak" | "bgNeutralInverted" | "fgOnNeutralInverted" | "fgNeutralSubtle" | "fgNeutralMuted" | "strokeFocusRing" | "bgSuccess" | "bgWarning" | "bgWarningSolid" | "bgOrange" | "bgCyan" | "bgPurple" | "bgSidebar" | "bgSubtle" | "fgBrandSoft" | "fgSuccessSoft" | "fgWarningSoft" | "fgDangerSoft" | "fgNeutralSoft" | "bgPurpleSoft" | "fgPurpleSoft" | "ringPurpleSoft" | "ringBrandSoft" | "fgSelectNeutral" | "bgSelectListbox" | "strokeSelectTrigger" | "bgSelectPressed" | "bgSelectDisabled" | "strokeSelectInvalid" | "strokeSelectDivider" | "fgSelectPlaceholder" | "shadowSelect", string>;
5
+ export type ColorTokens = Record<"bgBrandSolid" | "bgBrandSolidPressed" | "bgBrandContrast" | "fgBrandContrast" | "fgOnBrand" | "fgOnTone" | "bgSurface" | "bgRaised" | "bgSurfaceMuted" | "borderDefault" | "borderSubtle" | "borderDropzone" | "borderDivider" | "ringNeutral" | "ringField" | "ringSwitch" | "bgTileActive" | "shadowTileActive" | "bgScrim" | "bgOverlayStrong" | "strokeGroupDivider" | "fgAlertDescription" | "bgOverlayFrost" | "shadowOverlay1" | "shadowOverlay2" | "shadowOverlay3" | "bgPopover" | "ringPopover" | "shadowPopover1" | "shadowPopover2" | "shadowPopover3" | "fgPrimary" | "fgMuted" | "bgDanger" | "bgDangerSolid" | "fgDanger" | "strokeFieldFocus" | "fgDisabled" | "bgNeutralWeak" | "bgNeutralInverted" | "fgOnNeutralInverted" | "fgNeutralSubtle" | "fgNeutralMuted" | "strokeFocusRing" | "bgSuccess" | "bgWarning" | "bgWarningSolid" | "bgOrange" | "bgCyan" | "bgPurple" | "bgSidebar" | "bgSubtle" | "fgBrandSoft" | "fgSuccessSoft" | "fgWarningSoft" | "fgDangerSoft" | "fgNeutralSoft" | "bgPurpleSoft" | "fgPurpleSoft" | "ringPurpleSoft" | "ringBrandSoft" | "fgSelectNeutral" | "bgSelectListbox" | "strokeSelectTrigger" | "bgSelectPressed" | "bgSelectDisabled" | "strokeSelectInvalid" | "strokeSelectDivider" | "fgSelectPlaceholder" | "shadowSelect", string>;
6
6
  export declare const tokens: {
7
7
  color: Record<Theme, ColorTokens>;
8
8
  palette: Record<Theme, Record<string, string>>;
@@ -10,6 +10,7 @@ export declare const tokens: {
10
10
  radius: Record<string, number>;
11
11
  size: Record<string, number>;
12
12
  text: Record<string, number>;
13
+ tracking: Record<string, number>;
13
14
  font: Record<string, string>;
14
15
  weight: Record<string, string>;
15
16
  };
@@ -22,7 +22,9 @@ export const tokens = {
22
22
  "ringSwitch": "#d9dade",
23
23
  "bgTileActive": "#ffffff",
24
24
  "shadowTileActive": "rgba(0,0,0,0.04)",
25
- "bgScrim": "rgba(0,0,0,0.25)",
25
+ "bgScrim": "rgba(0,0,0,0.45)",
26
+ "bgOverlayStrong": "#00000074",
27
+ "strokeGroupDivider": "#00000010",
26
28
  "fgAlertDescription": "rgba(0,0,0,0.63)",
27
29
  "bgOverlayFrost": "#ffffff",
28
30
  "shadowOverlay1": "rgba(28,40,64,0.12)",
@@ -93,6 +95,8 @@ export const tokens = {
93
95
  "bgTileActive": "#101112",
94
96
  "shadowTileActive": "rgba(0,0,0,0)",
95
97
  "bgScrim": "rgba(0,0,0,0.55)",
98
+ "bgOverlayStrong": "#00000074",
99
+ "strokeGroupDivider": "#ffffff17",
96
100
  "fgAlertDescription": "rgba(255,255,255,0.6)",
97
101
  "bgOverlayFrost": "#1c1d1f",
98
102
  "shadowOverlay1": "rgba(0,0,0,0.48)",
@@ -161,7 +165,9 @@ export const tokens = {
161
165
  "ringBrandSoft": "#d6e5ff",
162
166
  "tileActive": "#ffffff",
163
167
  "tileActiveShadow": "rgba(0,0,0,0.04)",
164
- "bgScrim": "rgba(0,0,0,0.25)",
168
+ "bgScrim": "rgba(0,0,0,0.45)",
169
+ "bgOverlayStrong": "#00000074",
170
+ "strokeGroupDivider": "#00000010",
165
171
  "fgAlertDescription": "rgba(0,0,0,0.63)",
166
172
  "overlayFrost": "#ffffff",
167
173
  "shadowOverlay1": "rgba(28,40,64,0.12)",
@@ -228,6 +234,8 @@ export const tokens = {
228
234
  "tileActive": "#101112",
229
235
  "tileActiveShadow": "rgba(0,0,0,0)",
230
236
  "bgScrim": "rgba(0,0,0,0.55)",
237
+ "bgOverlayStrong": "#00000074",
238
+ "strokeGroupDivider": "#ffffff17",
231
239
  "fgAlertDescription": "rgba(255,255,255,0.6)",
232
240
  "overlayFrost": "#1c1d1f",
233
241
  "shadowOverlay1": "rgba(0,0,0,0.48)",
@@ -294,13 +302,14 @@ export const tokens = {
294
302
  },
295
303
  "radius": {
296
304
  "xs": 4,
297
- "chip": 7,
305
+ "chip": 999,
298
306
  "sm": 6,
299
307
  "md": 8,
300
308
  "lg": 9,
301
309
  "xl": 12,
302
310
  "2xl": 16,
303
311
  "3xl": 20,
312
+ "4xl": 24,
304
313
  "full": 999
305
314
  },
306
315
  "size": {
@@ -324,6 +333,14 @@ export const tokens = {
324
333
  "lg": 14,
325
334
  "xl": 16
326
335
  },
336
+ "tracking": {
337
+ "18": -0.36,
338
+ "20": -0.4,
339
+ "24": -0.48,
340
+ "26": -0.52,
341
+ "28": -0.56,
342
+ "32": -0.64
343
+ },
327
344
  "font": {
328
345
  "sans": "\"VK Sans Display\", \"Inter\", system-ui, -apple-system, \"Segoe UI\", sans-serif"
329
346
  },
@@ -0,0 +1,22 @@
1
+ .crisp-notificationssettings {
2
+ & .crisp-notificationssettings-page { display: flex; flex-direction: column; gap: var(--crisp-space-6); font-family: var(--crisp-font-sans); }
3
+ & .crisp-notificationssettings-heading { display: flex; flex-direction: column; gap: var(--crisp-space-0-5); }
4
+ & .crisp-notificationssettings-title { font-size: 24px; line-height: 28px; font-weight: var(--crisp-weight-semibold); letter-spacing: -0.48px; color: var(--crisp-fg-primary); margin: 0; }
5
+ & .crisp-notificationssettings-desc { font-size: var(--crisp-text-lg); line-height: 20px; color: var(--crisp-fg-muted); margin: 0; }
6
+ & .crisp-notificationssettings-section { display: flex; flex-direction: column; gap: var(--crisp-space-4); }
7
+ & .crisp-notificationssettings-sectiontitle { font-size: 16px; line-height: 20px; font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); margin: 0; }
8
+ /* Daily digest card: one bordered 12px-radius row. */
9
+ & .crisp-notificationssettings-digestcard { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-6); padding: var(--crisp-space-2) var(--crisp-space-3); border: 1px solid var(--crisp-border-subtle); border-radius: 12px; background: var(--crisp-bg-surface); }
10
+ & .crisp-notificationssettings-digesttext { display: flex; flex-direction: column; gap: var(--crisp-space-1); }
11
+ & .crisp-notificationssettings-rowtitle { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
12
+ & .crisp-notificationssettings-rowdesc { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
13
+ /* Collaboration matrix: a bordered card, header row + N body rows. */
14
+ & .crisp-notificationssettings-matrix { border: 1px solid var(--crisp-border-subtle); border-radius: 12px; overflow: hidden; background: var(--crisp-bg-surface); }
15
+ & .crisp-notificationssettings-matrixhead { display: flex; align-items: center; gap: var(--crisp-space-3); padding: 0 var(--crisp-space-4); height: 40px; border-bottom: 1px solid var(--crisp-border-subtle); }
16
+ & .crisp-notificationssettings-matrixhead-about { display: flex; align-items: center; gap: var(--crisp-space-1-5); flex: 1; min-width: 0; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
17
+ & .crisp-notificationssettings-matrixhead-col { display: flex; align-items: center; justify-content: center; gap: var(--crisp-space-1-5); width: 64px; flex-shrink: 0; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
18
+ & .crisp-notificationssettings-matrixrow { display: flex; align-items: center; gap: var(--crisp-space-3); padding: var(--crisp-space-2) var(--crisp-space-4); min-height: 52px; }
19
+ & .crisp-notificationssettings-matrixrow + .crisp-notificationssettings-matrixrow { border-top: 1px solid var(--crisp-border-subtle); }
20
+ & .crisp-notificationssettings-matrixrow-about { display: flex; flex-direction: column; gap: var(--crisp-space-1); flex: 1; min-width: 0; }
21
+ & .crisp-notificationssettings-matrixrow-col { display: flex; align-items: center; justify-content: center; width: 64px; flex-shrink: 0; }
22
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface NotificationssettingsVariants {
4
+
5
+ }
6
+
7
+ export declare const notificationssettingsRecipe: RecipeFn<{ }>;