@crisp-ui-kit/crisp 0.57.1 → 0.57.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) 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 +7 -6
  11. package/dist/button.layered.css +7 -6
  12. package/dist/checkbox.css +7 -3
  13. package/dist/checkbox.layered.css +7 -3
  14. package/dist/chip.css +15 -0
  15. package/dist/chip.d.ts +3 -1
  16. package/dist/chip.layered.css +15 -0
  17. package/dist/chipgroup.css +5 -0
  18. package/dist/chipgroup.d.ts +7 -0
  19. package/dist/chipgroup.layered.css +7 -0
  20. package/dist/cjs/components/badge/badge.recipe.js +22 -8
  21. package/dist/cjs/components/bottomsheet/bottomsheet.js +90 -0
  22. package/dist/cjs/components/bottomsheet/bottomsheet.recipe.js +77 -0
  23. package/dist/cjs/components/bottomsheet/index.js +9 -0
  24. package/dist/cjs/components/button/button.recipe.js +39 -15
  25. package/dist/cjs/components/checkbox/checkbox.recipe.js +61 -9
  26. package/dist/cjs/components/chip/chip.js +14 -2
  27. package/dist/cjs/components/chip/chip.recipe.js +69 -1
  28. package/dist/cjs/components/chipgroup/chipgroup.js +51 -0
  29. package/dist/cjs/components/chipgroup/chipgroup.recipe.js +36 -0
  30. package/dist/cjs/components/chipgroup/index.js +7 -0
  31. package/dist/cjs/components/datatable/datatable.js +5 -1
  32. package/dist/cjs/components/datatable/datatable.recipe.js +11 -2
  33. package/dist/cjs/components/dialog/dialog.recipe.js +21 -10
  34. package/dist/cjs/components/emptystate/emptystate.recipe.js +7 -2
  35. package/dist/cjs/components/fileupload/fileupload.js +21 -4
  36. package/dist/cjs/components/input/index.js +2 -1
  37. package/dist/cjs/components/input/input.js +31 -1
  38. package/dist/cjs/components/input/input.recipe.js +16 -9
  39. package/dist/cjs/components/menu/menu.recipe.js +21 -7
  40. package/dist/cjs/components/menusheet/index.js +9 -0
  41. package/dist/cjs/components/menusheet/menusheet.js +133 -0
  42. package/dist/cjs/components/menusheet/menusheet.recipe.js +103 -0
  43. package/dist/cjs/components/multiselect/multiselect.js +1 -1
  44. package/dist/cjs/components/multiselect/multiselect.recipe.js +33 -9
  45. package/dist/cjs/components/select/select.js +1 -1
  46. package/dist/cjs/components/select/select.recipe.js +38 -12
  47. package/dist/cjs/components/snackbar/index.js +8 -0
  48. package/dist/cjs/components/snackbar/snackbar.js +121 -0
  49. package/dist/cjs/components/snackbar/snackbar.recipe.js +71 -0
  50. package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
  51. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +37 -12
  52. package/dist/cjs/components/tabs/tabs.js +10 -4
  53. package/dist/cjs/components/tabs/tabs.recipe.js +23 -6
  54. package/dist/cjs/components/textarea/textarea.recipe.js +11 -8
  55. package/dist/cjs/index.js +7 -0
  56. package/dist/cjs/product/authshell/authshell.recipe.js +5 -1
  57. package/dist/cjs/product/command/command.recipe.js +4 -1
  58. package/dist/cjs/product/comments/comments.js +7 -2
  59. package/dist/cjs/product/comments/comments.recipe.js +25 -7
  60. package/dist/cjs/product/memberssettings/index.js +6 -0
  61. package/dist/cjs/product/memberssettings/memberssettings.js +99 -0
  62. package/dist/cjs/product/memberssettings/memberssettings.recipe.js +83 -0
  63. package/dist/cjs/product/notificationssettings/index.js +5 -0
  64. package/dist/cjs/product/notificationssettings/notificationssettings.js +19 -0
  65. package/dist/cjs/product/notificationssettings/notificationssettings.recipe.js +44 -0
  66. package/dist/cjs/product/recordpage/recordpage.js +57 -6
  67. package/dist/cjs/product/recordpage/recordpage.recipe.js +43 -6
  68. package/dist/cjs/product/workspacegeneralsettings/index.js +5 -0
  69. package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.js +21 -0
  70. package/dist/cjs/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +51 -0
  71. package/dist/cjs/tokens/contract.js +1 -0
  72. package/dist/cjs/tokens/elevation.js +8 -5
  73. package/dist/cjs/tokens/palette.js +28 -8
  74. package/dist/cjs/tokens/scale.js +44 -2
  75. package/dist/cjs/tokens/semantic.js +2 -0
  76. package/dist/columncalc.css +15 -7
  77. package/dist/columncalc.layered.css +15 -7
  78. package/dist/command.css +23 -19
  79. package/dist/command.layered.css +23 -19
  80. package/dist/comments.css +28 -19
  81. package/dist/comments.d.ts +2 -2
  82. package/dist/comments.layered.css +28 -19
  83. package/dist/datatable.css +161 -67
  84. package/dist/datatable.layered.css +161 -67
  85. package/dist/datepicker.css +13 -41
  86. package/dist/datepicker.layered.css +13 -41
  87. package/dist/datepickerfield.css +4 -1
  88. package/dist/datepickerfield.layered.css +4 -1
  89. package/dist/dialog.css +12 -7
  90. package/dist/dialog.layered.css +12 -7
  91. package/dist/emptystate.css +5 -3
  92. package/dist/emptystate.layered.css +5 -3
  93. package/dist/esm/components/badge/badge.recipe.js +22 -8
  94. package/dist/esm/components/bottomsheet/bottomsheet.js +52 -0
  95. package/dist/esm/components/bottomsheet/bottomsheet.recipe.js +74 -0
  96. package/dist/esm/components/bottomsheet/index.js +2 -0
  97. package/dist/esm/components/button/button.recipe.js +40 -16
  98. package/dist/esm/components/checkbox/checkbox.recipe.js +61 -9
  99. package/dist/esm/components/chip/chip.js +14 -2
  100. package/dist/esm/components/chip/chip.recipe.js +69 -1
  101. package/dist/esm/components/chipgroup/chipgroup.js +15 -0
  102. package/dist/esm/components/chipgroup/chipgroup.recipe.js +33 -0
  103. package/dist/esm/components/chipgroup/index.js +2 -0
  104. package/dist/esm/components/datatable/datatable.js +5 -1
  105. package/dist/esm/components/datatable/datatable.recipe.js +11 -2
  106. package/dist/esm/components/dialog/dialog.recipe.js +22 -11
  107. package/dist/esm/components/emptystate/emptystate.recipe.js +7 -2
  108. package/dist/esm/components/fileupload/fileupload.js +20 -5
  109. package/dist/esm/components/input/index.js +1 -1
  110. package/dist/esm/components/input/input.js +30 -0
  111. package/dist/esm/components/input/input.recipe.js +17 -10
  112. package/dist/esm/components/menu/menu.recipe.js +21 -7
  113. package/dist/esm/components/menusheet/index.js +2 -0
  114. package/dist/esm/components/menusheet/menusheet.js +95 -0
  115. package/dist/esm/components/menusheet/menusheet.recipe.js +100 -0
  116. package/dist/esm/components/multiselect/multiselect.js +1 -1
  117. package/dist/esm/components/multiselect/multiselect.recipe.js +33 -9
  118. package/dist/esm/components/select/select.js +1 -1
  119. package/dist/esm/components/select/select.recipe.js +38 -12
  120. package/dist/esm/components/snackbar/index.js +2 -0
  121. package/dist/esm/components/snackbar/snackbar.js +84 -0
  122. package/dist/esm/components/snackbar/snackbar.recipe.js +68 -0
  123. package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +7 -2
  124. package/dist/esm/components/tabletoolbar/tabletoolbar.js +37 -12
  125. package/dist/esm/components/tabs/tabs.js +10 -4
  126. package/dist/esm/components/tabs/tabs.recipe.js +23 -6
  127. package/dist/esm/components/textarea/textarea.recipe.js +12 -9
  128. package/dist/esm/index.js +7 -0
  129. package/dist/esm/product/authshell/authshell.recipe.js +5 -1
  130. package/dist/esm/product/command/command.recipe.js +4 -1
  131. package/dist/esm/product/comments/comments.js +7 -2
  132. package/dist/esm/product/comments/comments.recipe.js +25 -7
  133. package/dist/esm/product/memberssettings/index.js +1 -0
  134. package/dist/esm/product/memberssettings/memberssettings.js +62 -0
  135. package/dist/esm/product/memberssettings/memberssettings.recipe.js +80 -0
  136. package/dist/esm/product/notificationssettings/index.js +1 -0
  137. package/dist/esm/product/notificationssettings/notificationssettings.js +16 -0
  138. package/dist/esm/product/notificationssettings/notificationssettings.recipe.js +41 -0
  139. package/dist/esm/product/recordpage/recordpage.js +58 -7
  140. package/dist/esm/product/recordpage/recordpage.recipe.js +43 -6
  141. package/dist/esm/product/workspacegeneralsettings/index.js +1 -0
  142. package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.js +18 -0
  143. package/dist/esm/product/workspacegeneralsettings/workspacegeneralsettings.recipe.js +48 -0
  144. package/dist/esm/tokens/contract.js +2 -1
  145. package/dist/esm/tokens/elevation.js +8 -5
  146. package/dist/esm/tokens/palette.js +28 -8
  147. package/dist/esm/tokens/scale.js +43 -1
  148. package/dist/esm/tokens/semantic.js +2 -0
  149. package/dist/fileupload.css +3 -1
  150. package/dist/fileupload.layered.css +3 -1
  151. package/dist/input.css +6 -4
  152. package/dist/input.layered.css +6 -4
  153. package/dist/listpage.css +3 -1
  154. package/dist/listpage.layered.css +3 -1
  155. package/dist/memberssettings.css +67 -0
  156. package/dist/memberssettings.d.ts +7 -0
  157. package/dist/memberssettings.layered.css +69 -0
  158. package/dist/menu.css +2 -2
  159. package/dist/menu.layered.css +2 -2
  160. package/dist/menusheet.css +36 -0
  161. package/dist/menusheet.d.ts +7 -0
  162. package/dist/menusheet.layered.css +38 -0
  163. package/dist/multiselect.css +13 -6
  164. package/dist/multiselect.layered.css +13 -6
  165. package/dist/native/tokens.d.ts +2 -1
  166. package/dist/native/tokens.js +20 -3
  167. package/dist/notificationssettings.css +22 -0
  168. package/dist/notificationssettings.d.ts +7 -0
  169. package/dist/notificationssettings.layered.css +24 -0
  170. package/dist/objectsettings.css +4 -4
  171. package/dist/objectsettings.layered.css +4 -4
  172. package/dist/recordpage.css +67 -23
  173. package/dist/recordpage.layered.css +67 -23
  174. package/dist/recordpanel.css +35 -16
  175. package/dist/recordpanel.layered.css +35 -16
  176. package/dist/resizablepanel.css +8 -5
  177. package/dist/resizablepanel.layered.css +8 -5
  178. package/dist/richtext.css +24 -8
  179. package/dist/richtext.layered.css +24 -8
  180. package/dist/savedviews.css +9 -2
  181. package/dist/savedviews.layered.css +9 -2
  182. package/dist/select.css +25 -5
  183. package/dist/select.layered.css +25 -5
  184. package/dist/settingsshell.css +2 -3
  185. package/dist/settingsshell.layered.css +2 -3
  186. package/dist/slider.css +6 -27
  187. package/dist/slider.layered.css +6 -27
  188. package/dist/snackbar.css +24 -0
  189. package/dist/snackbar.d.ts +7 -0
  190. package/dist/snackbar.layered.css +26 -0
  191. package/dist/statcard.css +3 -1
  192. package/dist/statcard.layered.css +3 -1
  193. package/dist/styles.css +859 -345
  194. package/dist/styles.layered.css +859 -345
  195. package/dist/table.css +28 -10
  196. package/dist/table.layered.css +28 -10
  197. package/dist/tabletoolbar.css +35 -24
  198. package/dist/tabletoolbar.layered.css +35 -24
  199. package/dist/tabs.css +18 -4
  200. package/dist/tabs.layered.css +18 -4
  201. package/dist/textarea.css +2 -6
  202. package/dist/textarea.layered.css +2 -6
  203. package/dist/themepicker.css +2 -1
  204. package/dist/themepicker.layered.css +2 -1
  205. package/dist/tokens.css +13 -2
  206. package/dist/tokens.json +20 -3
  207. package/dist/types/components/bottomsheet/bottomsheet.d.ts +35 -0
  208. package/dist/types/components/bottomsheet/bottomsheet.recipe.d.ts +3 -0
  209. package/dist/types/components/bottomsheet/index.d.ts +2 -0
  210. package/dist/types/components/button/button.recipe.d.ts +11 -6
  211. package/dist/types/components/checkbox/checkbox.recipe.d.ts +28 -5
  212. package/dist/types/components/chip/chip.d.ts +22 -0
  213. package/dist/types/components/chip/chip.recipe.d.ts +48 -0
  214. package/dist/types/components/chipgroup/chipgroup.d.ts +14 -0
  215. package/dist/types/components/chipgroup/chipgroup.recipe.d.ts +5 -0
  216. package/dist/types/components/chipgroup/index.d.ts +2 -0
  217. package/dist/types/components/datatable/datatable.d.ts +19 -0
  218. package/dist/types/components/fileupload/fileupload.d.ts +26 -0
  219. package/dist/types/components/input/index.d.ts +1 -1
  220. package/dist/types/components/input/input.d.ts +72 -0
  221. package/dist/types/components/menusheet/index.d.ts +2 -0
  222. package/dist/types/components/menusheet/menusheet.d.ts +42 -0
  223. package/dist/types/components/menusheet/menusheet.recipe.d.ts +3 -0
  224. package/dist/types/components/snackbar/index.d.ts +2 -0
  225. package/dist/types/components/snackbar/snackbar.d.ts +36 -0
  226. package/dist/types/components/snackbar/snackbar.recipe.d.ts +5 -0
  227. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +28 -1
  228. package/dist/types/components/tabs/tabs.d.ts +11 -1
  229. package/dist/types/index.d.ts +7 -0
  230. package/dist/types/product/comments/comments.d.ts +9 -3
  231. package/dist/types/product/comments/comments.recipe.d.ts +12 -2
  232. package/dist/types/product/memberssettings/index.d.ts +1 -0
  233. package/dist/types/product/memberssettings/memberssettings.d.ts +85 -0
  234. package/dist/types/product/memberssettings/memberssettings.recipe.d.ts +3 -0
  235. package/dist/types/product/notificationssettings/index.d.ts +1 -0
  236. package/dist/types/product/notificationssettings/notificationssettings.d.ts +37 -0
  237. package/dist/types/product/notificationssettings/notificationssettings.recipe.d.ts +3 -0
  238. package/dist/types/product/recordpage/recordpage.d.ts +53 -2
  239. package/dist/types/product/workspacegeneralsettings/index.d.ts +1 -0
  240. package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.d.ts +48 -0
  241. package/dist/types/product/workspacegeneralsettings/workspacegeneralsettings.recipe.d.ts +3 -0
  242. package/dist/types/tokens/contract.d.ts +4 -1
  243. package/dist/types/tokens/elevation.d.ts +8 -5
  244. package/dist/types/tokens/palette.d.ts +9 -1
  245. package/dist/types/tokens/scale.d.ts +11 -1
  246. package/dist/types/tokens/semantic.d.ts +2 -0
  247. package/dist/wheelpicker.css +4 -2
  248. package/dist/wheelpicker.layered.css +4 -2
  249. package/dist/workspacegeneralsettings.css +30 -0
  250. package/dist/workspacegeneralsettings.d.ts +7 -0
  251. package/dist/workspacegeneralsettings.layered.css +32 -0
  252. package/package.json +36 -1
@@ -2,6 +2,21 @@
2
2
  display: flex; flex-direction: column; height: 100%; min-height: 0; background: var(--crisp-bg-surface); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: var(--crisp-fg-primary);
3
3
  & * { box-sizing: border-box; }
4
4
  & .crisp-recordpage-topbar { display: flex; align-items: center; gap: var(--crisp-space-2); height: 44px; flex-shrink: 0; padding: 0 var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); }
5
+ /* #624: expanding a peek to its full record keeps a hybrid header
6
+ (Close/Previous/Next/counter) instead of reverting to the plain
7
+ breadcrumb above -- measured live on a real expanded record: 49px
8
+ tall (not 44px), 8px/10px padding, same borderSubtle hairline. Same
9
+ tokens as product/recordpanel's own already-shipped toolbar, not
10
+ new values -- this is the same row, reused in a second component. */
11
+ & .crisp-recordpage-topbar[data-peek] { height: 49px; padding: var(--crisp-space-2) var(--crisp-space-2-5); }
12
+ & .crisp-recordpage-peekbar { display: flex; align-items: center; }
13
+ & .crisp-recordpage-peek-iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex-shrink: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s; }
14
+ & .crisp-recordpage-peek-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
15
+ & .crisp-recordpage-peek-pager { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-inline-start: var(--crisp-space-3); }
16
+ & .crisp-recordpage-peek-navbtn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex-shrink: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
17
+ & .crisp-recordpage-peek-navbtn:hover:not(:disabled) { background: var(--crisp-bg-raised); }
18
+ & .crisp-recordpage-peek-navbtn:disabled { opacity: 0.4; cursor: not-allowed; }
19
+ & .crisp-recordpage-peek-counter { margin-inline-start: var(--crisp-space-3); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
5
20
  & .crisp-recordpage-crumbs { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; }
6
21
  & .crisp-recordpage-crumb { display: inline-flex; align-items: center; height: 26px; padding: 0 var(--crisp-space-1-5); margin: 0 calc(-1 * var(--crisp-space-1-5)) 0 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: var(--crisp-fg-muted); cursor: pointer; }
7
22
  & .crisp-recordpage-crumb:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
@@ -19,6 +34,17 @@
19
34
  & .crisp-recordpage-resizer::before { content: ""; position: absolute; top: 0; bottom: 0; inset-inline-start: -4px; width: 9px; }
20
35
  & .crisp-recordpage-resizer::after { content: ""; position: absolute; top: 0; bottom: 0; inset-inline-start: -1px; width: 2px; background: transparent; transition: background-color .12s ease; }
21
36
  & .crisp-recordpage-resizer:hover::after, & .crisp-recordpage-resizer[data-active]::after { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 55%, transparent); }
37
+ /* #930: RecordDetails' own standalone resize handle -- same visible
38
+ hit-slop/line-highlight shape as .crisp-recordpage-resizer just above,
39
+ just absolutely positioned at the trailing edge instead of a 0-width
40
+ flex sibling, since RecordDetails always returns a single root (the
41
+ same internal-strip placement RecordPanel's own resize handle uses,
42
+ mirrored to the opposite edge -- this column is leading, RecordPanel
43
+ is trailing). */
44
+ & .crisp-recordpage-section[data-resizable] { position: relative; }
45
+ & .crisp-recordpage-detailresize { position: absolute; top: 0; bottom: 0; inset-inline-end: -4px; width: 9px; cursor: col-resize; z-index: 5; touch-action: none; }
46
+ & .crisp-recordpage-detailresize::after { content: ""; position: absolute; top: 0; bottom: 0; inset-inline-end: 3px; width: 2px; background: transparent; transition: background-color .12s ease; }
47
+ & .crisp-recordpage-detailresize:hover::after, & .crisp-recordpage-detailresize[data-active]::after { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 55%, transparent); }
22
48
  & .crisp-recordpage-entity { display: flex; align-items: center; gap: var(--crisp-space-2); padding: var(--crisp-space-1) var(--crisp-space-1) var(--crisp-space-2); }
23
49
  & .crisp-recordpage-entity-logo { width: 32px; height: 32px; border-radius: 30%; flex-shrink: 0; object-fit: cover; background: var(--crisp-bg-raised); }
24
50
  & .crisp-recordpage-entity-name { flex: 0 1 auto; min-width: 0; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); letter-spacing: -0.3px; color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -34,7 +60,8 @@
34
60
  & .crisp-recordpage-quickbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
35
61
  & .crisp-recordpage-section { padding-top: var(--crisp-space-2); }
36
62
  & .crisp-recordpage-section-title { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); letter-spacing: -0.12px; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); padding: var(--crisp-space-1); }
37
- /* main-area section headers (Highlights / Activity / Emails / Notes / Tasks) are 14px; the left column's (Record Details / Lists) stay 12px. */
63
+ /* main-area section headers (Highlights / Activity / Emails / Notes / Tasks)
64
+ are 14px; the left column's (Record Details / Lists) stay 12px. */
38
65
  & .crisp-recordpage-main .crisp-recordpage-section-title { font-size: var(--crisp-text-lg); }
39
66
  & .crisp-recordpage-detailhead { display: flex; align-items: center; gap: var(--crisp-space-0-5); margin-bottom: var(--crisp-space-3); padding-inline-end: var(--crisp-space-0-5); }
40
67
  & .crisp-recordpage-collapse { display: inline-flex; align-items: center; gap: 2px; flex: 1; min-width: 0; margin: 0; border: none; background: none; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); letter-spacing: -0.12px; color: var(--crisp-fg-muted); cursor: pointer; text-align: start; }
@@ -49,7 +76,8 @@
49
76
  & .crisp-recordpage-noresults { padding: var(--crisp-space-1-5) var(--crisp-space-1); font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
50
77
  /* A caller-supplied `sections` grouping (#528) is not an Attio-measured
51
78
  shape (its own Details column is flat) -- this heading reuses
52
- .crisp-recordpage-section-title's own type treatment verbatim, just spaced from the group above it. */
79
+ .crisp-recordpage-section-title's own type treatment verbatim, just
80
+ spaced from the group above it. */
53
81
  & .crisp-recordpage-fieldsection-title { margin-top: var(--crisp-space-3); }
54
82
  & .crisp-recordpage-morevalues { display: inline-flex; align-items: center; padding: 0; margin: 0; border: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-muted); cursor: pointer; }
55
83
  & .crisp-recordpage-morevalues:hover { color: var(--crisp-fg-primary); }
@@ -65,25 +93,38 @@
65
93
  & .crisp-recordpage-field-label-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
66
94
  & .crisp-recordpage-field-value { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); padding-top: 2px; line-height: 20px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
67
95
  & .crisp-recordpage-field-value[data-editable] { cursor: pointer; }
68
- /* the click-to-edit trigger is a real <button> (keyboard-operable), reset back to plain inline text and made a flex-wrap container of its own -- FieldValue can render several chips (tags), which still need to wrap the way they did before this had a button around them at all. It wraps only FieldValue, never the error slot beside it (see the component's own comment) -- NOT `display: contents`, which
96
+ /* the click-to-edit trigger is a real <button> (keyboard-operable),
97
+ reset back to plain inline text and made a flex-wrap container of its
98
+ own -- FieldValue can render several chips (tags), which still need
99
+ to wrap the way they did before this had a button around them at
100
+ all. It wraps only FieldValue, never the error slot beside it (see
101
+ the component's own comment) -- NOT `display: contents`, which
69
102
  drops a button's accessible semantics in some engines. */
70
103
  & .crisp-recordpage-edit-trigger { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); margin: 0; padding: 0; border: none; background: none; text-align: start; font: inherit; color: inherit; cursor: pointer; }
71
104
  & .crisp-recordpage-empty { color: var(--crisp-fg-muted); }
72
105
  /* #431: measured live on app.attio.com's record page Details column --
73
- clicking a field's value opens a plain, borderless field exactly filling the value's own box (no border, no background, no
106
+ clicking a field's value opens a plain, borderless field exactly
107
+ filling the value's own box (no border, no background, no
74
108
  box-shadow), same font as the value it replaces (hence `font:
75
- inherit`, not a restated size/weight). A field row's own hover tint above already carries the "this is interactive" affordance; the pending/error treatment isn't Attio-measured -- it reuses the same
76
- tokens DataTable's identical states already use (opacity 0.5, `bgDanger`), per #385/#430. */
109
+ inherit`, not a restated size/weight). A field row's own hover tint
110
+ above already carries the "this is interactive" affordance; the
111
+ pending/error treatment isn't Attio-measured -- it reuses the same
112
+ tokens DataTable's identical states already use (opacity 0.5,
113
+ `bgDanger`), per #385/#430. */
77
114
  & .crisp-recordpage-edit { display: block; width: 100%; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; box-shadow: none; outline: none; font: inherit; color: inherit; }
78
- /* not Attio-measured (its own field shows no focus ring either, caret only) -- kept for real keyboard users, the same brand ring every other crisp field already shows on focus (DataTable's identical
115
+ /* not Attio-measured (its own field shows no focus ring either, caret
116
+ only) -- kept for real keyboard users, the same brand ring every
117
+ other crisp field already shows on focus (DataTable's identical
79
118
  .crisp-datatable-edit:focus, e.g.). */
80
119
  & .crisp-recordpage-edit:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
81
120
  & .crisp-recordpage-edit:disabled { opacity: 0.5; cursor: not-allowed; }
82
121
  & .crisp-recordpage-edit-pending { flex-shrink: 0; color: var(--crisp-fg-muted); }
83
122
  & .crisp-recordpage-edit-error { flex-basis: 100%; margin-top: var(--crisp-space-0-5); font-size: var(--crisp-text-sm); color: var(--crisp-bg-danger); }
84
- /* #457: an `editor: "select"` field's at-rest chip -- same shape as RecordsTable's own `.crisp-recordstable-status[-dot]` (already
123
+ /* #457: an `editor: "select"` field's at-rest chip -- same shape as
124
+ RecordsTable's own `.crisp-recordstable-status[-dot]` (already
85
125
  measured against Attio there), but its own classes: that pair is
86
- scoped under `.crisp-recordstable`'s own recipe root, so reusing the classnames verbatim here would resolve to nothing. */
126
+ scoped under `.crisp-recordstable`'s own recipe root, so reusing the
127
+ classnames verbatim here would resolve to nothing. */
87
128
  & .crisp-recordpage-status { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; }
88
129
  & .crisp-recordpage-status-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: var(--crisp-radius-full); }
89
130
  & .crisp-recordpage-edit-picker { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; }
@@ -106,7 +147,6 @@
106
147
  & .crisp-recordpage-hl-label { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); margin-bottom: var(--crisp-space-2-5); padding-inline-end: var(--crisp-space-4); }
107
148
  & .crisp-recordpage-hl-value { display: flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
108
149
  & .crisp-recordpage-hl-value--empty { color: var(--crisp-fg-muted); font-weight: var(--crisp-weight-regular); }
109
-
110
150
  & .crisp-recordpage-feed { display: flex; flex-direction: column; }
111
151
  & .crisp-recordpage-feed-item { display: flex; align-items: flex-start; gap: var(--crisp-space-2-5); padding: var(--crisp-space-2) 0; }
112
152
  & .crisp-recordpage-feed-dot { position: relative; display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; flex-shrink: 0; border-radius: var(--crisp-radius-full); background: var(--crisp-bg-raised); color: var(--crisp-fg-muted); }
@@ -115,7 +155,6 @@
115
155
  & .crisp-recordpage-feed-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); margin-top: 2px; }
116
156
  & .crisp-recordpage-feed-more { align-self: flex-start; margin-top: var(--crisp-space-1); border: none; background: none; padding: var(--crisp-space-1) 0; color: var(--crisp-bg-brand-solid); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
117
157
  & .crisp-recordpage-feed-more:hover { text-decoration: underline; }
118
-
119
158
  & .crisp-recordpage-section-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-1); }
120
159
  & .crisp-recordpage-section-head .crisp-recordpage-section-title { padding: 0; }
121
160
  & .crisp-recordpage-section-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) 6%, transparent); font-size: var(--crisp-text-xs); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
@@ -123,7 +162,6 @@
123
162
  & .crisp-recordpage-addbtn { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: 26px; padding: 0 var(--crisp-space-1-5); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
124
163
  & .crisp-recordpage-addbtn:hover { background: var(--crisp-bg-raised); }
125
164
  & .crisp-recordpage-addbtn svg { flex-shrink: 0; }
126
-
127
165
  & .crisp-recordpage-composer { display: flex; flex-direction: column; gap: var(--crisp-space-2); padding: var(--crisp-space-2); border: 1px solid var(--crisp-border-default); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); margin-bottom: var(--crisp-space-2); }
128
166
  & .crisp-recordpage-composer textarea { width: 100%; min-height: 56px; resize: vertical; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
129
167
  & .crisp-recordpage-composer textarea:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); border-radius: var(--crisp-radius-md); }
@@ -133,23 +171,29 @@
133
171
  & .crisp-recordpage-btn:hover { background: var(--crisp-bg-raised); }
134
172
  & .crisp-recordpage-btn--primary { box-shadow: none; background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); }
135
173
  & .crisp-recordpage-btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }
136
-
137
- & .crisp-recordpage-note { display: flex; gap: var(--crisp-space-2-5); padding: var(--crisp-space-2-5) 0; border-top: 1px solid var(--crisp-border-subtle); }
138
- & .crisp-recordpage-note-body { flex: 1; min-width: 0; }
139
- & .crisp-recordpage-note-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-bottom: var(--crisp-space-0-5); }
140
- & .crisp-recordpage-note-author { font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
141
- & .crisp-recordpage-note-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
142
- & .crisp-recordpage-note-text { font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); white-space: pre-wrap; word-break: break-word; }
143
-
174
+ /* #871: one bordered card per note (border-radius.xl, borderSubtle),
175
+ not a flush divider-list row -- measured live on a real populated
176
+ note: the whole row is flex space-between, avatar+title+body on the
177
+ left (its own flex, gap.2), the relative time alone on the right.
178
+ The real DOM nests an inner clickable button (padding 6/8, radius.md)
179
+ inside an outer card (padding 4px, radius.xl) -- collapsed into this
180
+ one non-interactive div's own combined padding (2.5/3) since crisp's
181
+ NotesSection has no click-to-open behaviour to justify the extra
182
+ layer. The 6px gap between stacked cards is NOT independently
183
+ measured (this workspace only ever had one real note to check) --
184
+ a judgement call off the existing space scale, not a live value. */
185
+ & .crisp-recordpage-note { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-3); padding: var(--crisp-space-2-5) var(--crisp-space-3); border: 1px solid var(--crisp-border-subtle); border-radius: var(--crisp-radius-xl); }
186
+ & .crisp-recordpage-note + .crisp-recordpage-note { margin-top: var(--crisp-space-1-5); }
187
+ & .crisp-recordpage-note-left { display: flex; align-items: center; gap: var(--crisp-space-2); min-width: 0; overflow: hidden; }
188
+ & .crisp-recordpage-note-title { flex-shrink: 0; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
189
+ & .crisp-recordpage-note-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
190
+ & .crisp-recordpage-note-time { flex-shrink: 0; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
144
191
  & .crisp-recordpage-task { display: flex; align-items: flex-start; gap: var(--crisp-space-2); padding: var(--crisp-space-1-5) 0; border-top: 1px solid var(--crisp-border-subtle); }
145
192
  & .crisp-recordpage-task-text { flex: 1; min-width: 0; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); padding-top: 1px; }
146
193
  & .crisp-recordpage-task[data-done] .crisp-recordpage-task-text { text-decoration: line-through; color: var(--crisp-fg-muted); }
147
-
148
194
  & .crisp-recordpage-emptycard { display: flex; flex-direction: column; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-6) var(--crisp-space-3); border: 1px dashed var(--crisp-border-default); border-radius: var(--crisp-radius-xl); color: var(--crisp-fg-muted); font-size: var(--crisp-text-md); text-align: center; }
149
195
  & .crisp-recordpage-emptycard svg { color: var(--crisp-fg-muted); opacity: 0.7; }
150
-
151
196
  & .crisp-recordpage-action[data-active] svg { color: #f5b83d; fill: #f5b83d; }
152
-
153
197
  & .crisp-recordstable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); }
154
198
  & .crisp-recordstable-tag[data-tone="brand"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); }
155
199
  & .crisp-recordstable-tag[data-tone="success"] { background: color-mix(in srgb, var(--crisp-bg-success) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-success) 78%, var(--crisp-fg-primary)); }
@@ -3,6 +3,21 @@
3
3
  display: flex; flex-direction: column; height: 100%; min-height: 0; background: var(--crisp-bg-surface); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: var(--crisp-fg-primary);
4
4
  & * { box-sizing: border-box; }
5
5
  & .crisp-recordpage-topbar { display: flex; align-items: center; gap: var(--crisp-space-2); height: 44px; flex-shrink: 0; padding: 0 var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); }
6
+ /* #624: expanding a peek to its full record keeps a hybrid header
7
+ (Close/Previous/Next/counter) instead of reverting to the plain
8
+ breadcrumb above -- measured live on a real expanded record: 49px
9
+ tall (not 44px), 8px/10px padding, same borderSubtle hairline. Same
10
+ tokens as product/recordpanel's own already-shipped toolbar, not
11
+ new values -- this is the same row, reused in a second component. */
12
+ & .crisp-recordpage-topbar[data-peek] { height: 49px; padding: var(--crisp-space-2) var(--crisp-space-2-5); }
13
+ & .crisp-recordpage-peekbar { display: flex; align-items: center; }
14
+ & .crisp-recordpage-peek-iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex-shrink: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s; }
15
+ & .crisp-recordpage-peek-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
16
+ & .crisp-recordpage-peek-pager { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-inline-start: var(--crisp-space-3); }
17
+ & .crisp-recordpage-peek-navbtn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex-shrink: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
18
+ & .crisp-recordpage-peek-navbtn:hover:not(:disabled) { background: var(--crisp-bg-raised); }
19
+ & .crisp-recordpage-peek-navbtn:disabled { opacity: 0.4; cursor: not-allowed; }
20
+ & .crisp-recordpage-peek-counter { margin-inline-start: var(--crisp-space-3); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
6
21
  & .crisp-recordpage-crumbs { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; }
7
22
  & .crisp-recordpage-crumb { display: inline-flex; align-items: center; height: 26px; padding: 0 var(--crisp-space-1-5); margin: 0 calc(-1 * var(--crisp-space-1-5)) 0 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: var(--crisp-fg-muted); cursor: pointer; }
8
23
  & .crisp-recordpage-crumb:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
@@ -20,6 +35,17 @@
20
35
  & .crisp-recordpage-resizer::before { content: ""; position: absolute; top: 0; bottom: 0; inset-inline-start: -4px; width: 9px; }
21
36
  & .crisp-recordpage-resizer::after { content: ""; position: absolute; top: 0; bottom: 0; inset-inline-start: -1px; width: 2px; background: transparent; transition: background-color .12s ease; }
22
37
  & .crisp-recordpage-resizer:hover::after, & .crisp-recordpage-resizer[data-active]::after { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 55%, transparent); }
38
+ /* #930: RecordDetails' own standalone resize handle -- same visible
39
+ hit-slop/line-highlight shape as .crisp-recordpage-resizer just above,
40
+ just absolutely positioned at the trailing edge instead of a 0-width
41
+ flex sibling, since RecordDetails always returns a single root (the
42
+ same internal-strip placement RecordPanel's own resize handle uses,
43
+ mirrored to the opposite edge -- this column is leading, RecordPanel
44
+ is trailing). */
45
+ & .crisp-recordpage-section[data-resizable] { position: relative; }
46
+ & .crisp-recordpage-detailresize { position: absolute; top: 0; bottom: 0; inset-inline-end: -4px; width: 9px; cursor: col-resize; z-index: 5; touch-action: none; }
47
+ & .crisp-recordpage-detailresize::after { content: ""; position: absolute; top: 0; bottom: 0; inset-inline-end: 3px; width: 2px; background: transparent; transition: background-color .12s ease; }
48
+ & .crisp-recordpage-detailresize:hover::after, & .crisp-recordpage-detailresize[data-active]::after { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 55%, transparent); }
23
49
  & .crisp-recordpage-entity { display: flex; align-items: center; gap: var(--crisp-space-2); padding: var(--crisp-space-1) var(--crisp-space-1) var(--crisp-space-2); }
24
50
  & .crisp-recordpage-entity-logo { width: 32px; height: 32px; border-radius: 30%; flex-shrink: 0; object-fit: cover; background: var(--crisp-bg-raised); }
25
51
  & .crisp-recordpage-entity-name { flex: 0 1 auto; min-width: 0; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); letter-spacing: -0.3px; color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -35,7 +61,8 @@
35
61
  & .crisp-recordpage-quickbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
36
62
  & .crisp-recordpage-section { padding-top: var(--crisp-space-2); }
37
63
  & .crisp-recordpage-section-title { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); letter-spacing: -0.12px; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); padding: var(--crisp-space-1); }
38
- /* main-area section headers (Highlights / Activity / Emails / Notes / Tasks) are 14px; the left column's (Record Details / Lists) stay 12px. */
64
+ /* main-area section headers (Highlights / Activity / Emails / Notes / Tasks)
65
+ are 14px; the left column's (Record Details / Lists) stay 12px. */
39
66
  & .crisp-recordpage-main .crisp-recordpage-section-title { font-size: var(--crisp-text-lg); }
40
67
  & .crisp-recordpage-detailhead { display: flex; align-items: center; gap: var(--crisp-space-0-5); margin-bottom: var(--crisp-space-3); padding-inline-end: var(--crisp-space-0-5); }
41
68
  & .crisp-recordpage-collapse { display: inline-flex; align-items: center; gap: 2px; flex: 1; min-width: 0; margin: 0; border: none; background: none; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); letter-spacing: -0.12px; color: var(--crisp-fg-muted); cursor: pointer; text-align: start; }
@@ -50,7 +77,8 @@
50
77
  & .crisp-recordpage-noresults { padding: var(--crisp-space-1-5) var(--crisp-space-1); font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
51
78
  /* A caller-supplied `sections` grouping (#528) is not an Attio-measured
52
79
  shape (its own Details column is flat) -- this heading reuses
53
- .crisp-recordpage-section-title's own type treatment verbatim, just spaced from the group above it. */
80
+ .crisp-recordpage-section-title's own type treatment verbatim, just
81
+ spaced from the group above it. */
54
82
  & .crisp-recordpage-fieldsection-title { margin-top: var(--crisp-space-3); }
55
83
  & .crisp-recordpage-morevalues { display: inline-flex; align-items: center; padding: 0; margin: 0; border: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-muted); cursor: pointer; }
56
84
  & .crisp-recordpage-morevalues:hover { color: var(--crisp-fg-primary); }
@@ -66,25 +94,38 @@
66
94
  & .crisp-recordpage-field-label-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
67
95
  & .crisp-recordpage-field-value { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); padding-top: 2px; line-height: 20px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
68
96
  & .crisp-recordpage-field-value[data-editable] { cursor: pointer; }
69
- /* the click-to-edit trigger is a real <button> (keyboard-operable), reset back to plain inline text and made a flex-wrap container of its own -- FieldValue can render several chips (tags), which still need to wrap the way they did before this had a button around them at all. It wraps only FieldValue, never the error slot beside it (see the component's own comment) -- NOT `display: contents`, which
97
+ /* the click-to-edit trigger is a real <button> (keyboard-operable),
98
+ reset back to plain inline text and made a flex-wrap container of its
99
+ own -- FieldValue can render several chips (tags), which still need
100
+ to wrap the way they did before this had a button around them at
101
+ all. It wraps only FieldValue, never the error slot beside it (see
102
+ the component's own comment) -- NOT `display: contents`, which
70
103
  drops a button's accessible semantics in some engines. */
71
104
  & .crisp-recordpage-edit-trigger { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); margin: 0; padding: 0; border: none; background: none; text-align: start; font: inherit; color: inherit; cursor: pointer; }
72
105
  & .crisp-recordpage-empty { color: var(--crisp-fg-muted); }
73
106
  /* #431: measured live on app.attio.com's record page Details column --
74
- clicking a field's value opens a plain, borderless field exactly filling the value's own box (no border, no background, no
107
+ clicking a field's value opens a plain, borderless field exactly
108
+ filling the value's own box (no border, no background, no
75
109
  box-shadow), same font as the value it replaces (hence `font:
76
- inherit`, not a restated size/weight). A field row's own hover tint above already carries the "this is interactive" affordance; the pending/error treatment isn't Attio-measured -- it reuses the same
77
- tokens DataTable's identical states already use (opacity 0.5, `bgDanger`), per #385/#430. */
110
+ inherit`, not a restated size/weight). A field row's own hover tint
111
+ above already carries the "this is interactive" affordance; the
112
+ pending/error treatment isn't Attio-measured -- it reuses the same
113
+ tokens DataTable's identical states already use (opacity 0.5,
114
+ `bgDanger`), per #385/#430. */
78
115
  & .crisp-recordpage-edit { display: block; width: 100%; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; box-shadow: none; outline: none; font: inherit; color: inherit; }
79
- /* not Attio-measured (its own field shows no focus ring either, caret only) -- kept for real keyboard users, the same brand ring every other crisp field already shows on focus (DataTable's identical
116
+ /* not Attio-measured (its own field shows no focus ring either, caret
117
+ only) -- kept for real keyboard users, the same brand ring every
118
+ other crisp field already shows on focus (DataTable's identical
80
119
  .crisp-datatable-edit:focus, e.g.). */
81
120
  & .crisp-recordpage-edit:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
82
121
  & .crisp-recordpage-edit:disabled { opacity: 0.5; cursor: not-allowed; }
83
122
  & .crisp-recordpage-edit-pending { flex-shrink: 0; color: var(--crisp-fg-muted); }
84
123
  & .crisp-recordpage-edit-error { flex-basis: 100%; margin-top: var(--crisp-space-0-5); font-size: var(--crisp-text-sm); color: var(--crisp-bg-danger); }
85
- /* #457: an `editor: "select"` field's at-rest chip -- same shape as RecordsTable's own `.crisp-recordstable-status[-dot]` (already
124
+ /* #457: an `editor: "select"` field's at-rest chip -- same shape as
125
+ RecordsTable's own `.crisp-recordstable-status[-dot]` (already
86
126
  measured against Attio there), but its own classes: that pair is
87
- scoped under `.crisp-recordstable`'s own recipe root, so reusing the classnames verbatim here would resolve to nothing. */
127
+ scoped under `.crisp-recordstable`'s own recipe root, so reusing the
128
+ classnames verbatim here would resolve to nothing. */
88
129
  & .crisp-recordpage-status { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; }
89
130
  & .crisp-recordpage-status-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: var(--crisp-radius-full); }
90
131
  & .crisp-recordpage-edit-picker { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; }
@@ -107,7 +148,6 @@
107
148
  & .crisp-recordpage-hl-label { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); margin-bottom: var(--crisp-space-2-5); padding-inline-end: var(--crisp-space-4); }
108
149
  & .crisp-recordpage-hl-value { display: flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
109
150
  & .crisp-recordpage-hl-value--empty { color: var(--crisp-fg-muted); font-weight: var(--crisp-weight-regular); }
110
-
111
151
  & .crisp-recordpage-feed { display: flex; flex-direction: column; }
112
152
  & .crisp-recordpage-feed-item { display: flex; align-items: flex-start; gap: var(--crisp-space-2-5); padding: var(--crisp-space-2) 0; }
113
153
  & .crisp-recordpage-feed-dot { position: relative; display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; flex-shrink: 0; border-radius: var(--crisp-radius-full); background: var(--crisp-bg-raised); color: var(--crisp-fg-muted); }
@@ -116,7 +156,6 @@
116
156
  & .crisp-recordpage-feed-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); margin-top: 2px; }
117
157
  & .crisp-recordpage-feed-more { align-self: flex-start; margin-top: var(--crisp-space-1); border: none; background: none; padding: var(--crisp-space-1) 0; color: var(--crisp-bg-brand-solid); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
118
158
  & .crisp-recordpage-feed-more:hover { text-decoration: underline; }
119
-
120
159
  & .crisp-recordpage-section-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-1); }
121
160
  & .crisp-recordpage-section-head .crisp-recordpage-section-title { padding: 0; }
122
161
  & .crisp-recordpage-section-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) 6%, transparent); font-size: var(--crisp-text-xs); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
@@ -124,7 +163,6 @@
124
163
  & .crisp-recordpage-addbtn { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: 26px; padding: 0 var(--crisp-space-1-5); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-neutral), 0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
125
164
  & .crisp-recordpage-addbtn:hover { background: var(--crisp-bg-raised); }
126
165
  & .crisp-recordpage-addbtn svg { flex-shrink: 0; }
127
-
128
166
  & .crisp-recordpage-composer { display: flex; flex-direction: column; gap: var(--crisp-space-2); padding: var(--crisp-space-2); border: 1px solid var(--crisp-border-default); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); margin-bottom: var(--crisp-space-2); }
129
167
  & .crisp-recordpage-composer textarea { width: 100%; min-height: 56px; resize: vertical; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
130
168
  & .crisp-recordpage-composer textarea:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); border-radius: var(--crisp-radius-md); }
@@ -134,23 +172,29 @@
134
172
  & .crisp-recordpage-btn:hover { background: var(--crisp-bg-raised); }
135
173
  & .crisp-recordpage-btn--primary { box-shadow: none; background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); }
136
174
  & .crisp-recordpage-btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }
137
-
138
- & .crisp-recordpage-note { display: flex; gap: var(--crisp-space-2-5); padding: var(--crisp-space-2-5) 0; border-top: 1px solid var(--crisp-border-subtle); }
139
- & .crisp-recordpage-note-body { flex: 1; min-width: 0; }
140
- & .crisp-recordpage-note-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-bottom: var(--crisp-space-0-5); }
141
- & .crisp-recordpage-note-author { font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
142
- & .crisp-recordpage-note-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
143
- & .crisp-recordpage-note-text { font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); white-space: pre-wrap; word-break: break-word; }
144
-
175
+ /* #871: one bordered card per note (border-radius.xl, borderSubtle),
176
+ not a flush divider-list row -- measured live on a real populated
177
+ note: the whole row is flex space-between, avatar+title+body on the
178
+ left (its own flex, gap.2), the relative time alone on the right.
179
+ The real DOM nests an inner clickable button (padding 6/8, radius.md)
180
+ inside an outer card (padding 4px, radius.xl) -- collapsed into this
181
+ one non-interactive div's own combined padding (2.5/3) since crisp's
182
+ NotesSection has no click-to-open behaviour to justify the extra
183
+ layer. The 6px gap between stacked cards is NOT independently
184
+ measured (this workspace only ever had one real note to check) --
185
+ a judgement call off the existing space scale, not a live value. */
186
+ & .crisp-recordpage-note { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-3); padding: var(--crisp-space-2-5) var(--crisp-space-3); border: 1px solid var(--crisp-border-subtle); border-radius: var(--crisp-radius-xl); }
187
+ & .crisp-recordpage-note + .crisp-recordpage-note { margin-top: var(--crisp-space-1-5); }
188
+ & .crisp-recordpage-note-left { display: flex; align-items: center; gap: var(--crisp-space-2); min-width: 0; overflow: hidden; }
189
+ & .crisp-recordpage-note-title { flex-shrink: 0; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
190
+ & .crisp-recordpage-note-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
191
+ & .crisp-recordpage-note-time { flex-shrink: 0; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
145
192
  & .crisp-recordpage-task { display: flex; align-items: flex-start; gap: var(--crisp-space-2); padding: var(--crisp-space-1-5) 0; border-top: 1px solid var(--crisp-border-subtle); }
146
193
  & .crisp-recordpage-task-text { flex: 1; min-width: 0; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); padding-top: 1px; }
147
194
  & .crisp-recordpage-task[data-done] .crisp-recordpage-task-text { text-decoration: line-through; color: var(--crisp-fg-muted); }
148
-
149
195
  & .crisp-recordpage-emptycard { display: flex; flex-direction: column; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-6) var(--crisp-space-3); border: 1px dashed var(--crisp-border-default); border-radius: var(--crisp-radius-xl); color: var(--crisp-fg-muted); font-size: var(--crisp-text-md); text-align: center; }
150
196
  & .crisp-recordpage-emptycard svg { color: var(--crisp-fg-muted); opacity: 0.7; }
151
-
152
197
  & .crisp-recordpage-action[data-active] svg { color: #f5b83d; fill: #f5b83d; }
153
-
154
198
  & .crisp-recordstable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); }
155
199
  & .crisp-recordstable-tag[data-tone="brand"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); }
156
200
  & .crisp-recordstable-tag[data-tone="success"] { background: color-mix(in srgb, var(--crisp-bg-success) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-success) 78%, var(--crisp-fg-primary)); }
@@ -8,11 +8,14 @@
8
8
  beneath (the same borderSubtle every other panel/row edge here
9
9
  already uses). Close keeps the existing transparent ghost button;
10
10
  Previous/Next/Open record are a distinct field-elevation style
11
- (white fill, e.field's own ring+shadow, solid icon) -- measured as genuinely different chrome from Close, not a reuse. */
11
+ (white fill, e.field's own ring+shadow, solid icon) -- measured as
12
+ genuinely different chrome from Close, not a reuse. */
12
13
  & .crisp-recordpanel-toolbar { display: flex; align-items: center; height: 49px; flex-shrink: 0; padding: var(--crisp-space-2) var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); }
13
14
  & .crisp-recordpanel-toolbar-spacer { flex: 1; }
14
15
  & .crisp-recordpanel-pager { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-inline-start: var(--crisp-space-3); }
15
- /* #413: "2 of 37 in All Companies" -- measured live, same toolbar row, right after Prev/Next. 12px/500, the same 63%-of-fgPrimary mix every other muted heading in this panel already uses. */
16
+ /* #413: "2 of 37 in All Companies" -- measured live, same toolbar row,
17
+ right after Prev/Next. 12px/500, the same 63%-of-fgPrimary mix every
18
+ other muted heading in this panel already uses. */
16
19
  & .crisp-recordpanel-counter { margin-inline-start: var(--crisp-space-3); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
17
20
  & .crisp-recordpanel-iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex-shrink: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s; }
18
21
  & .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
@@ -20,26 +23,36 @@
20
23
  & .crisp-recordpanel-navbtn:hover:not(:disabled) { background: var(--crisp-bg-raised); }
21
24
  & .crisp-recordpanel-navbtn:disabled { opacity: 0.4; cursor: not-allowed; }
22
25
  /* #413: measured live -- a 10px strip at the panel's own left edge,
23
- cursor: col-resize (the issue's own repro calls it "ew-resize"; the actual computed value read off the live DOM is col-resize, the same cursor family under a different keyword). Kept fully inside the panel's own box, not extending past inset-inline-start: 0, so the
24
- panel's own overflow: hidden (there for its rounded corners) never clips it. touch-action: none stops a touchscreen's own pan gesture
26
+ cursor: col-resize (the issue's own repro calls it "ew-resize";
27
+ the actual computed value read off the live DOM is col-resize, the
28
+ same cursor family under a different keyword). Kept fully inside the
29
+ panel's own box, not extending past inset-inline-start: 0, so the
30
+ panel's own overflow: hidden (there for its rounded corners) never
31
+ clips it. touch-action: none stops a touchscreen's own pan gesture
25
32
  from fighting the drag. */
26
33
  & .crisp-recordpanel-resize-handle { position: absolute; top: 0; bottom: 0; inset-inline-start: 0; width: 10px; cursor: col-resize; z-index: 1; touch-action: none; }
27
34
  & .crisp-recordpanel-resize-handle:hover, & .crisp-recordpanel-resize-handle:active { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
28
-
29
35
  & .crisp-recordpanel-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 52px; flex-shrink: 0; padding: 0 var(--crisp-space-3); }
30
36
  & .crisp-recordpanel-fav { width: 22px; height: var(--crisp-size-chip); border-radius: var(--crisp-radius-sm); flex-shrink: 0; object-fit: cover; background: var(--crisp-bg-raised); }
31
37
  & .crisp-recordpanel-title { flex: 1; min-width: 0; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); letter-spacing: -0.2px; color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
32
-
33
38
  & .crisp-recordpanel-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-2) var(--crisp-space-3); }
34
-
35
- /* #448: measured live on app.attio.com's peek (hover a Companies row, click "Open preview"). Section label reads identically for both Highlights and Activity: 14px/500, the same 63%-of-fgPrimary mix RecordPage's own field-label already uses (product/recordpage's .crisp-recordpage-field-label) -- one more surface landing on the same measured "muted section heading" colour. */
39
+ /* #448: measured live on app.attio.com's peek (hover a Companies row,
40
+ click "Open preview"). Section label reads identically for both
41
+ Highlights and Activity: 14px/500, the same 63%-of-fgPrimary mix
42
+ RecordPage's own field-label already uses (product/recordpage's
43
+ .crisp-recordpage-field-label) -- one more surface landing on the
44
+ same measured "muted section heading" colour. */
36
45
  & .crisp-recordpanel-section { padding: var(--crisp-space-2) var(--crisp-space-1) 0; }
37
46
  & .crisp-recordpanel-section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); height: 20px; margin-bottom: var(--crisp-space-2); }
38
47
  & .crisp-recordpanel-section-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
39
- /* "View all" -- measured 10px/400, a lighter mix than the section label (55%, not 63%) -- its own distinct, honestly-measured value, not a reuse of a nearby one that happened to be close. */
48
+ /* "View all" -- measured 10px/400, a lighter mix than the section label
49
+ (55%, not 63%) -- its own distinct, honestly-measured value, not a
50
+ reuse of a nearby one that happened to be close. */
40
51
  & .crisp-recordpanel-section-action { border: none; background: none; padding: 0; font-family: inherit; font-size: 10px; font-weight: var(--crisp-weight-regular); color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; }
41
52
  & .crisp-recordpanel-section-action:hover { color: var(--crisp-fg-primary); }
42
- /* Highlights: a 2-column grid of label+icon+value cards, no card chrome at all (no border/background/radius/shadow -- confirmed on the live DOM: every highlight's computed style is fully transparent).
53
+ /* Highlights: a 2-column grid of label+icon+value cards, no card
54
+ chrome at all (no border/background/radius/shadow -- confirmed on
55
+ the live DOM: every highlight's computed style is fully transparent).
43
56
  8px row/column gap; two rows measured "233x86" inside 473px content
44
57
  width is exactly (473 - 8) / 2. */
45
58
  & .crisp-recordpanel-highlights { display: grid; grid-template-columns: 1fr 1fr; gap: var(--crisp-space-2); }
@@ -48,27 +61,33 @@
48
61
  & .crisp-recordpanel-highlight-label span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
49
62
  & .crisp-recordpanel-highlight-label svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
50
63
  & .crisp-recordpanel-highlight-value { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; }
51
-
52
64
  /* Activity is a consumer-supplied slot (crisp has no activity-feed
53
65
  model of its own to render) -- this only wraps it with the measured
54
66
  section heading above. */
55
67
  & .crisp-recordpanel-activity { font-size: var(--crisp-text-lg); }
56
-
57
68
  /* #413: collapsed Emails/Notes/Tasks below Activity -- measured live: a
58
- 473px-wide row (the panel's own content width, 497 minus its 12px/8px side insets), 20px tall, 14px/500 solid fgPrimary label (NOT the 63% mix Highlights/Activity headings use -- this is body text, not a muted heading), a trailing count. padding "0 8px 0 12px" measured on the row itself; reproduced here as the trigger's own padding, since
59
- the trigger IS the row (a plain div, not a button, when there's no content to expand into -- matches the empty ("Emails 0") row measured live, which has no expand affordance at all). */
69
+ 473px-wide row (the panel's own content width, 497 minus its 12px/8px
70
+ side insets), 20px tall, 14px/500 solid fgPrimary label (NOT the 63%
71
+ mix Highlights/Activity headings use -- this is body text, not a
72
+ muted heading), a trailing count. padding "0 8px 0 12px" measured on
73
+ the row itself; reproduced here as the trigger's own padding, since
74
+ the trigger IS the row (a plain div, not a button, when there's no
75
+ content to expand into -- matches the empty ("Emails 0") row
76
+ measured live, which has no expand affordance at all). */
60
77
  & .crisp-recordpanel-sections { display: flex; flex-direction: column; padding-top: var(--crisp-space-2); }
61
78
  & .crisp-recordpanel-section-trigger { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; height: 20px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-3); border: none; background: none; font-family: inherit; text-align: start; cursor: pointer; }
62
79
  & .crisp-recordpanel-section-trigger-inert { cursor: default; }
63
80
  & .crisp-recordpanel-section-row-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
64
81
  /* The count wasn't captured with its own background/pill chrome in the
65
82
  live measurement (only its text: 14px, a "tertiary" internal variant
66
- name that doesn't map to anything crisp defines) -- muted text next to the label, not an invented badge shape. */
83
+ name that doesn't map to anything crisp defines) -- muted text next
84
+ to the label, not an invented badge shape. */
67
85
  & .crisp-recordpanel-section-row-count { font-size: var(--crisp-text-lg); color: var(--crisp-fg-muted); }
68
86
  & .crisp-recordpanel-section-chevron { margin-inline-start: auto; flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
69
87
  & .crisp-recordpanel-section-chevron[data-open] { transform: rotate(180deg); }
70
88
  & .crisp-recordpanel-section-content { padding: var(--crisp-space-2) var(--crisp-space-2) var(--crisp-space-2) var(--crisp-space-3); }
71
- /* #329: an optional slot for record actions (e.g. Edit). Reuses the header's own measured values rather than inventing new ones -- the
89
+ /* #329: an optional slot for record actions (e.g. Edit). Reuses the
90
+ header's own measured values rather than inventing new ones -- the
72
91
  same horizontal inset (space.3), the same hairline border token
73
92
  (borderSubtle, flipped to border-top since this sits at the opposite
74
93
  edge), and the header/body gap (space.2) for its own vertical padding
@@ -9,11 +9,14 @@
9
9
  beneath (the same borderSubtle every other panel/row edge here
10
10
  already uses). Close keeps the existing transparent ghost button;
11
11
  Previous/Next/Open record are a distinct field-elevation style
12
- (white fill, e.field's own ring+shadow, solid icon) -- measured as genuinely different chrome from Close, not a reuse. */
12
+ (white fill, e.field's own ring+shadow, solid icon) -- measured as
13
+ genuinely different chrome from Close, not a reuse. */
13
14
  & .crisp-recordpanel-toolbar { display: flex; align-items: center; height: 49px; flex-shrink: 0; padding: var(--crisp-space-2) var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); }
14
15
  & .crisp-recordpanel-toolbar-spacer { flex: 1; }
15
16
  & .crisp-recordpanel-pager { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-inline-start: var(--crisp-space-3); }
16
- /* #413: "2 of 37 in All Companies" -- measured live, same toolbar row, right after Prev/Next. 12px/500, the same 63%-of-fgPrimary mix every other muted heading in this panel already uses. */
17
+ /* #413: "2 of 37 in All Companies" -- measured live, same toolbar row,
18
+ right after Prev/Next. 12px/500, the same 63%-of-fgPrimary mix every
19
+ other muted heading in this panel already uses. */
17
20
  & .crisp-recordpanel-counter { margin-inline-start: var(--crisp-space-3); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
18
21
  & .crisp-recordpanel-iconbtn { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex-shrink: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s; }
19
22
  & .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
@@ -21,26 +24,36 @@
21
24
  & .crisp-recordpanel-navbtn:hover:not(:disabled) { background: var(--crisp-bg-raised); }
22
25
  & .crisp-recordpanel-navbtn:disabled { opacity: 0.4; cursor: not-allowed; }
23
26
  /* #413: measured live -- a 10px strip at the panel's own left edge,
24
- cursor: col-resize (the issue's own repro calls it "ew-resize"; the actual computed value read off the live DOM is col-resize, the same cursor family under a different keyword). Kept fully inside the panel's own box, not extending past inset-inline-start: 0, so the
25
- panel's own overflow: hidden (there for its rounded corners) never clips it. touch-action: none stops a touchscreen's own pan gesture
27
+ cursor: col-resize (the issue's own repro calls it "ew-resize";
28
+ the actual computed value read off the live DOM is col-resize, the
29
+ same cursor family under a different keyword). Kept fully inside the
30
+ panel's own box, not extending past inset-inline-start: 0, so the
31
+ panel's own overflow: hidden (there for its rounded corners) never
32
+ clips it. touch-action: none stops a touchscreen's own pan gesture
26
33
  from fighting the drag. */
27
34
  & .crisp-recordpanel-resize-handle { position: absolute; top: 0; bottom: 0; inset-inline-start: 0; width: 10px; cursor: col-resize; z-index: 1; touch-action: none; }
28
35
  & .crisp-recordpanel-resize-handle:hover, & .crisp-recordpanel-resize-handle:active { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
29
-
30
36
  & .crisp-recordpanel-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 52px; flex-shrink: 0; padding: 0 var(--crisp-space-3); }
31
37
  & .crisp-recordpanel-fav { width: 22px; height: var(--crisp-size-chip); border-radius: var(--crisp-radius-sm); flex-shrink: 0; object-fit: cover; background: var(--crisp-bg-raised); }
32
38
  & .crisp-recordpanel-title { flex: 1; min-width: 0; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); letter-spacing: -0.2px; color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
33
-
34
39
  & .crisp-recordpanel-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-2) var(--crisp-space-3); }
35
-
36
- /* #448: measured live on app.attio.com's peek (hover a Companies row, click "Open preview"). Section label reads identically for both Highlights and Activity: 14px/500, the same 63%-of-fgPrimary mix RecordPage's own field-label already uses (product/recordpage's .crisp-recordpage-field-label) -- one more surface landing on the same measured "muted section heading" colour. */
40
+ /* #448: measured live on app.attio.com's peek (hover a Companies row,
41
+ click "Open preview"). Section label reads identically for both
42
+ Highlights and Activity: 14px/500, the same 63%-of-fgPrimary mix
43
+ RecordPage's own field-label already uses (product/recordpage's
44
+ .crisp-recordpage-field-label) -- one more surface landing on the
45
+ same measured "muted section heading" colour. */
37
46
  & .crisp-recordpanel-section { padding: var(--crisp-space-2) var(--crisp-space-1) 0; }
38
47
  & .crisp-recordpanel-section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); height: 20px; margin-bottom: var(--crisp-space-2); }
39
48
  & .crisp-recordpanel-section-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
40
- /* "View all" -- measured 10px/400, a lighter mix than the section label (55%, not 63%) -- its own distinct, honestly-measured value, not a reuse of a nearby one that happened to be close. */
49
+ /* "View all" -- measured 10px/400, a lighter mix than the section label
50
+ (55%, not 63%) -- its own distinct, honestly-measured value, not a
51
+ reuse of a nearby one that happened to be close. */
41
52
  & .crisp-recordpanel-section-action { border: none; background: none; padding: 0; font-family: inherit; font-size: 10px; font-weight: var(--crisp-weight-regular); color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; }
42
53
  & .crisp-recordpanel-section-action:hover { color: var(--crisp-fg-primary); }
43
- /* Highlights: a 2-column grid of label+icon+value cards, no card chrome at all (no border/background/radius/shadow -- confirmed on the live DOM: every highlight's computed style is fully transparent).
54
+ /* Highlights: a 2-column grid of label+icon+value cards, no card
55
+ chrome at all (no border/background/radius/shadow -- confirmed on
56
+ the live DOM: every highlight's computed style is fully transparent).
44
57
  8px row/column gap; two rows measured "233x86" inside 473px content
45
58
  width is exactly (473 - 8) / 2. */
46
59
  & .crisp-recordpanel-highlights { display: grid; grid-template-columns: 1fr 1fr; gap: var(--crisp-space-2); }
@@ -49,27 +62,33 @@
49
62
  & .crisp-recordpanel-highlight-label span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
50
63
  & .crisp-recordpanel-highlight-label svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
51
64
  & .crisp-recordpanel-highlight-value { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; }
52
-
53
65
  /* Activity is a consumer-supplied slot (crisp has no activity-feed
54
66
  model of its own to render) -- this only wraps it with the measured
55
67
  section heading above. */
56
68
  & .crisp-recordpanel-activity { font-size: var(--crisp-text-lg); }
57
-
58
69
  /* #413: collapsed Emails/Notes/Tasks below Activity -- measured live: a
59
- 473px-wide row (the panel's own content width, 497 minus its 12px/8px side insets), 20px tall, 14px/500 solid fgPrimary label (NOT the 63% mix Highlights/Activity headings use -- this is body text, not a muted heading), a trailing count. padding "0 8px 0 12px" measured on the row itself; reproduced here as the trigger's own padding, since
60
- the trigger IS the row (a plain div, not a button, when there's no content to expand into -- matches the empty ("Emails 0") row measured live, which has no expand affordance at all). */
70
+ 473px-wide row (the panel's own content width, 497 minus its 12px/8px
71
+ side insets), 20px tall, 14px/500 solid fgPrimary label (NOT the 63%
72
+ mix Highlights/Activity headings use -- this is body text, not a
73
+ muted heading), a trailing count. padding "0 8px 0 12px" measured on
74
+ the row itself; reproduced here as the trigger's own padding, since
75
+ the trigger IS the row (a plain div, not a button, when there's no
76
+ content to expand into -- matches the empty ("Emails 0") row
77
+ measured live, which has no expand affordance at all). */
61
78
  & .crisp-recordpanel-sections { display: flex; flex-direction: column; padding-top: var(--crisp-space-2); }
62
79
  & .crisp-recordpanel-section-trigger { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; height: 20px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-3); border: none; background: none; font-family: inherit; text-align: start; cursor: pointer; }
63
80
  & .crisp-recordpanel-section-trigger-inert { cursor: default; }
64
81
  & .crisp-recordpanel-section-row-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
65
82
  /* The count wasn't captured with its own background/pill chrome in the
66
83
  live measurement (only its text: 14px, a "tertiary" internal variant
67
- name that doesn't map to anything crisp defines) -- muted text next to the label, not an invented badge shape. */
84
+ name that doesn't map to anything crisp defines) -- muted text next
85
+ to the label, not an invented badge shape. */
68
86
  & .crisp-recordpanel-section-row-count { font-size: var(--crisp-text-lg); color: var(--crisp-fg-muted); }
69
87
  & .crisp-recordpanel-section-chevron { margin-inline-start: auto; flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
70
88
  & .crisp-recordpanel-section-chevron[data-open] { transform: rotate(180deg); }
71
89
  & .crisp-recordpanel-section-content { padding: var(--crisp-space-2) var(--crisp-space-2) var(--crisp-space-2) var(--crisp-space-3); }
72
- /* #329: an optional slot for record actions (e.g. Edit). Reuses the header's own measured values rather than inventing new ones -- the
90
+ /* #329: an optional slot for record actions (e.g. Edit). Reuses the
91
+ header's own measured values rather than inventing new ones -- the
73
92
  same horizontal inset (space.3), the same hairline border token
74
93
  (borderSubtle, flipped to border-top since this sits at the opposite
75
94
  edge), and the header/body gap (space.2) for its own vertical padding