@crisp-ui-kit/crisp 0.54.1 → 0.54.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 (171) hide show
  1. package/dist/chip.css +7 -1
  2. package/dist/chip.d.ts +2 -1
  3. package/dist/chip.layered.css +7 -1
  4. package/dist/cjs/components/chip/chip.js +3 -2
  5. package/dist/cjs/components/chip/chip.recipe.js +37 -1
  6. package/dist/cjs/components/datatable/datatable.js +490 -111
  7. package/dist/cjs/components/datatable/datatable.recipe.js +4 -0
  8. package/dist/cjs/components/emptystate/emptystate.js +3 -2
  9. package/dist/cjs/components/emptystate/emptystate.recipe.js +26 -1
  10. package/dist/cjs/components/mentionchip/index.js +7 -0
  11. package/dist/cjs/components/mentionchip/mentionchip.js +57 -0
  12. package/dist/cjs/components/mentionchip/mentionchip.recipe.js +38 -0
  13. package/dist/cjs/components/personchip/index.js +17 -0
  14. package/dist/cjs/components/personchip/personchip.js +50 -0
  15. package/dist/cjs/components/table/table.js +2 -2
  16. package/dist/cjs/components/table/table.recipe.js +15 -3
  17. package/dist/cjs/components/tabs/tabs.js +2 -2
  18. package/dist/cjs/components/tabs/tabs.recipe.js +30 -3
  19. package/dist/cjs/components/text/index.js +7 -0
  20. package/dist/cjs/components/text/text.js +55 -0
  21. package/dist/cjs/components/text/text.recipe.js +34 -0
  22. package/dist/cjs/core/floating-stack.js +18 -0
  23. package/dist/cjs/core/index.js +2 -1
  24. package/dist/cjs/index.js +8 -0
  25. package/dist/cjs/product/formdialog/formdialog.js +171 -0
  26. package/dist/cjs/product/formdialog/formdialog.recipe.js +26 -0
  27. package/dist/cjs/product/formdialog/index.js +8 -0
  28. package/dist/cjs/product/headerbar/headerbar.recipe.js +9 -1
  29. package/dist/cjs/product/importdialog/importdialog.js +134 -0
  30. package/dist/cjs/product/importdialog/importdialog.recipe.js +92 -0
  31. package/dist/cjs/product/importdialog/index.js +18 -0
  32. package/dist/cjs/product/recordpage/recordpage.recipe.js +10 -1
  33. package/dist/cjs/product/recordstable/recordstable.js +89 -6
  34. package/dist/cjs/product/richtext/richtext.recipe.js +26 -1
  35. package/dist/cjs/product/savedviews/index.js +7 -0
  36. package/dist/cjs/product/savedviews/savedviews.js +207 -0
  37. package/dist/cjs/product/savedviews/savedviews.recipe.js +103 -0
  38. package/dist/cjs/product/taskstable/index.js +7 -0
  39. package/dist/cjs/product/taskstable/taskstable.js +27 -0
  40. package/dist/cjs/product/taskstable/taskstable.recipe.js +47 -0
  41. package/dist/cjs/product/themepicker/index.js +17 -0
  42. package/dist/cjs/product/themepicker/themepicker.js +32 -0
  43. package/dist/cjs/product/themepicker/themepicker.recipe.js +98 -0
  44. package/dist/cjs/tokens/palette.js +30 -13
  45. package/dist/cjs/tokens/semantic.js +6 -0
  46. package/dist/datatable.css +20 -21
  47. package/dist/datatable.layered.css +20 -21
  48. package/dist/emptystate.css +15 -1
  49. package/dist/emptystate.d.ts +2 -2
  50. package/dist/emptystate.layered.css +15 -1
  51. package/dist/esm/components/chip/chip.js +3 -2
  52. package/dist/esm/components/chip/chip.recipe.js +37 -1
  53. package/dist/esm/components/datatable/datatable.js +489 -111
  54. package/dist/esm/components/datatable/datatable.recipe.js +4 -0
  55. package/dist/esm/components/emptystate/emptystate.js +4 -3
  56. package/dist/esm/components/emptystate/emptystate.recipe.js +26 -1
  57. package/dist/esm/components/emptystate/index.js +1 -1
  58. package/dist/esm/components/mentionchip/index.js +2 -0
  59. package/dist/esm/components/mentionchip/mentionchip.js +21 -0
  60. package/dist/esm/components/mentionchip/mentionchip.recipe.js +35 -0
  61. package/dist/esm/components/personchip/index.js +1 -0
  62. package/dist/esm/components/personchip/personchip.js +47 -0
  63. package/dist/esm/components/table/table.js +2 -2
  64. package/dist/esm/components/table/table.recipe.js +15 -3
  65. package/dist/esm/components/tabs/tabs.js +2 -2
  66. package/dist/esm/components/tabs/tabs.recipe.js +30 -3
  67. package/dist/esm/components/text/index.js +2 -0
  68. package/dist/esm/components/text/text.js +19 -0
  69. package/dist/esm/components/text/text.recipe.js +31 -0
  70. package/dist/esm/core/floating-stack.js +17 -0
  71. package/dist/esm/core/index.js +1 -1
  72. package/dist/esm/index.js +8 -0
  73. package/dist/esm/product/formdialog/formdialog.js +134 -0
  74. package/dist/esm/product/formdialog/formdialog.recipe.js +23 -0
  75. package/dist/esm/product/formdialog/index.js +2 -0
  76. package/dist/esm/product/headerbar/headerbar.recipe.js +9 -1
  77. package/dist/esm/product/importdialog/importdialog.js +97 -0
  78. package/dist/esm/product/importdialog/importdialog.recipe.js +89 -0
  79. package/dist/esm/product/importdialog/index.js +2 -0
  80. package/dist/esm/product/recordpage/recordpage.recipe.js +10 -1
  81. package/dist/esm/product/recordstable/recordstable.js +90 -8
  82. package/dist/esm/product/richtext/richtext.recipe.js +26 -1
  83. package/dist/esm/product/savedviews/index.js +2 -0
  84. package/dist/esm/product/savedviews/savedviews.js +171 -0
  85. package/dist/esm/product/savedviews/savedviews.recipe.js +100 -0
  86. package/dist/esm/product/taskstable/index.js +2 -0
  87. package/dist/esm/product/taskstable/taskstable.js +24 -0
  88. package/dist/esm/product/taskstable/taskstable.recipe.js +44 -0
  89. package/dist/esm/product/themepicker/index.js +1 -0
  90. package/dist/esm/product/themepicker/themepicker.js +29 -0
  91. package/dist/esm/product/themepicker/themepicker.recipe.js +95 -0
  92. package/dist/esm/tokens/palette.js +30 -13
  93. package/dist/esm/tokens/semantic.js +6 -0
  94. package/dist/formdialog.css +6 -0
  95. package/dist/formdialog.d.ts +7 -0
  96. package/dist/formdialog.layered.css +8 -0
  97. package/dist/headerbar.css +1 -1
  98. package/dist/headerbar.layered.css +1 -1
  99. package/dist/importdialog.css +38 -0
  100. package/dist/importdialog.d.ts +7 -0
  101. package/dist/importdialog.layered.css +40 -0
  102. package/dist/mentionchip.css +3 -0
  103. package/dist/mentionchip.d.ts +7 -0
  104. package/dist/mentionchip.layered.css +5 -0
  105. package/dist/native/tokens.d.ts +1 -1
  106. package/dist/native/tokens.js +14 -6
  107. package/dist/recordpage.css +13 -2
  108. package/dist/recordpage.layered.css +13 -2
  109. package/dist/richtext.css +11 -1
  110. package/dist/richtext.layered.css +11 -1
  111. package/dist/savedviews.css +78 -0
  112. package/dist/savedviews.d.ts +7 -0
  113. package/dist/savedviews.layered.css +80 -0
  114. package/dist/styles.css +287 -37
  115. package/dist/styles.layered.css +287 -37
  116. package/dist/table.css +15 -6
  117. package/dist/table.layered.css +15 -6
  118. package/dist/tabs.css +7 -1
  119. package/dist/tabs.d.ts +2 -2
  120. package/dist/tabs.layered.css +7 -1
  121. package/dist/taskstable.css +23 -0
  122. package/dist/taskstable.d.ts +7 -0
  123. package/dist/taskstable.layered.css +25 -0
  124. package/dist/text.css +9 -0
  125. package/dist/text.d.ts +7 -0
  126. package/dist/text.layered.css +11 -0
  127. package/dist/themepicker.css +27 -0
  128. package/dist/themepicker.d.ts +7 -0
  129. package/dist/themepicker.layered.css +29 -0
  130. package/dist/tokens.css +7 -3
  131. package/dist/tokens.json +14 -6
  132. package/dist/types/components/chip/chip.d.ts +32 -0
  133. package/dist/types/components/chip/chip.recipe.d.ts +31 -0
  134. package/dist/types/components/datatable/datatable.d.ts +39 -4
  135. package/dist/types/components/emptystate/emptystate.d.ts +29 -4
  136. package/dist/types/components/emptystate/emptystate.recipe.d.ts +2 -0
  137. package/dist/types/components/emptystate/index.d.ts +1 -1
  138. package/dist/types/components/mentionchip/index.d.ts +2 -0
  139. package/dist/types/components/mentionchip/mentionchip.d.ts +20 -0
  140. package/dist/types/components/mentionchip/mentionchip.recipe.d.ts +18 -0
  141. package/dist/types/components/personchip/index.d.ts +1 -0
  142. package/dist/types/components/personchip/personchip.d.ts +37 -0
  143. package/dist/types/components/table/table.d.ts +36 -0
  144. package/dist/types/components/tabs/tabs.d.ts +4 -2
  145. package/dist/types/components/tabs/tabs.recipe.d.ts +18 -3
  146. package/dist/types/components/text/index.d.ts +2 -0
  147. package/dist/types/components/text/text.d.ts +32 -0
  148. package/dist/types/components/text/text.recipe.d.ts +40 -0
  149. package/dist/types/core/floating-stack.d.ts +14 -0
  150. package/dist/types/core/index.d.ts +1 -1
  151. package/dist/types/index.d.ts +8 -0
  152. package/dist/types/product/formdialog/formdialog.d.ts +57 -0
  153. package/dist/types/product/formdialog/formdialog.recipe.d.ts +3 -0
  154. package/dist/types/product/formdialog/index.d.ts +2 -0
  155. package/dist/types/product/importdialog/importdialog.d.ts +86 -0
  156. package/dist/types/product/importdialog/importdialog.recipe.d.ts +3 -0
  157. package/dist/types/product/importdialog/index.d.ts +2 -0
  158. package/dist/types/product/recordstable/recordstable.d.ts +24 -2
  159. package/dist/types/product/savedviews/index.d.ts +2 -0
  160. package/dist/types/product/savedviews/savedviews.d.ts +55 -0
  161. package/dist/types/product/savedviews/savedviews.recipe.d.ts +3 -0
  162. package/dist/types/product/taskstable/index.d.ts +2 -0
  163. package/dist/types/product/taskstable/taskstable.d.ts +54 -0
  164. package/dist/types/product/taskstable/taskstable.recipe.d.ts +3 -0
  165. package/dist/types/product/themepicker/index.d.ts +1 -0
  166. package/dist/types/product/themepicker/themepicker.d.ts +21 -0
  167. package/dist/types/product/themepicker/themepicker.recipe.d.ts +3 -0
  168. package/dist/types/tokens/contract.d.ts +2 -0
  169. package/dist/types/tokens/palette.d.ts +11 -3
  170. package/dist/types/tokens/semantic.d.ts +6 -0
  171. package/package.json +41 -1
@@ -0,0 +1,38 @@
1
+ .crisp-importdialog {
2
+ display: contents; font-family: var(--crisp-font-sans);
3
+ & .crisp-importdialog-backdrop { position: fixed; inset: 0; z-index: 60; background: transparent; }
4
+ & .crisp-importdialog-positioner { position: fixed; inset: 0; z-index: 61; display: flex; }
5
+ & .crisp-importdialog-content { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; display: flex; flex-direction: column; box-sizing: border-box; width: 100%; height: 100%; border-radius: 0; background: var(--crisp-bg-surface); box-shadow: none; transform: none; opacity: 1; transition: opacity 0.2s ease; @starting-style { opacity: 0; } }
6
+ & .crisp-importdialog-header { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; height: 52px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-6); border-bottom: 1px solid var(--crisp-border-subtle); }
7
+ & .crisp-importdialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); margin: 0; }
8
+ & .crisp-importdialog-close { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
9
+ & .crisp-importdialog-close:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
10
+ & .crisp-importdialog-steps { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; padding: var(--crisp-space-4) var(--crisp-space-6) 0; }
11
+ & .crisp-importdialog-step { display: inline-flex; align-items: center; height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: transparent; color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: default; transition: background-color .12s, color .12s; }
12
+ & button.crisp-importdialog-step { cursor: pointer; }
13
+ & .crisp-importdialog-step[data-active] { 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)); }
14
+ & .crisp-importdialog-step:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: 1px; }
15
+ & .crisp-importdialog-body { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; padding: var(--crisp-space-6); }
16
+ & .crisp-importdialog-footer { display: flex; align-items: center; justify-content: flex-end; gap: var(--crisp-space-3); flex-shrink: 0; min-height: 56px; padding: 0 var(--crisp-space-6); border-top: 1px solid var(--crisp-border-subtle); }
17
+ & .crisp-importdialog-dropzone { box-sizing: border-box; position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--crisp-space-1); width: 100%; border: 1px dashed var(--crisp-border-dropzone); border-radius: 20px; background: var(--crisp-bg-subtle); text-align: center; transition: background-color .12s, border-color .12s; }
18
+ & .crisp-importdialog-dropzone[data-dragging-over] { border-color: var(--crisp-bg-brand-solid); background: color-mix(in srgb, var(--crisp-bg-brand-solid) 6%, transparent); }
19
+ & .crisp-importdialog-dropzone[data-invalid] { border-color: var(--crisp-bg-danger); }
20
+ & .crisp-importdialog-dropzone-title { color: var(--crisp-fg-primary); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); }
21
+ & .crisp-importdialog-dropzone-or { color: var(--crisp-fg-muted); font-size: var(--crisp-text-md); line-height: 18px; }
22
+ & .crisp-importdialog-dropzone-choose { border: none; background: none; padding: 0; margin: 0; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-bg-brand-solid); cursor: pointer; }
23
+ & .crisp-importdialog-dropzone-choose:hover { color: var(--crisp-bg-brand-solid-pressed); }
24
+ & .crisp-importdialog-dropzone-choose:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: 2px; border-radius: var(--crisp-radius-sm); }
25
+ & .crisp-importdialog-dropzone-learnmore { color: var(--crisp-fg-muted); font-size: var(--crisp-text-md); text-decoration: underline; }
26
+ & .crisp-importdialog-dropzone-input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
27
+ & .crisp-importdialog-dropzone-errors { margin: 0; padding: 0; list-style: none; }
28
+ & .crisp-importdialog-dropzone-errors:empty { position: absolute; }
29
+ & .crisp-importdialog-dropzone-error { color: var(--crisp-bg-danger); font-size: var(--crisp-text-md); line-height: 18px; }
30
+ }
31
+
32
+ @media (prefers-reduced-motion: reduce) {
33
+ .crisp-importdialog, .crisp-importdialog * {
34
+ animation-duration: 0.01ms !important;
35
+ animation-iteration-count: 1 !important;
36
+ transition-duration: 0.01ms !important;
37
+ }
38
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface ImportdialogVariants {
4
+
5
+ }
6
+
7
+ export declare const importdialogRecipe: RecipeFn<{ }>;
@@ -0,0 +1,40 @@
1
+ @layer crisp-components {
2
+ .crisp-importdialog {
3
+ display: contents; font-family: var(--crisp-font-sans);
4
+ & .crisp-importdialog-backdrop { position: fixed; inset: 0; z-index: 60; background: transparent; }
5
+ & .crisp-importdialog-positioner { position: fixed; inset: 0; z-index: 61; display: flex; }
6
+ & .crisp-importdialog-content { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; display: flex; flex-direction: column; box-sizing: border-box; width: 100%; height: 100%; border-radius: 0; background: var(--crisp-bg-surface); box-shadow: none; transform: none; opacity: 1; transition: opacity 0.2s ease; @starting-style { opacity: 0; } }
7
+ & .crisp-importdialog-header { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; height: 52px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-6); border-bottom: 1px solid var(--crisp-border-subtle); }
8
+ & .crisp-importdialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); margin: 0; }
9
+ & .crisp-importdialog-close { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
10
+ & .crisp-importdialog-close:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
11
+ & .crisp-importdialog-steps { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; padding: var(--crisp-space-4) var(--crisp-space-6) 0; }
12
+ & .crisp-importdialog-step { display: inline-flex; align-items: center; height: var(--crisp-size-row); padding: 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: transparent; color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: default; transition: background-color .12s, color .12s; }
13
+ & button.crisp-importdialog-step { cursor: pointer; }
14
+ & .crisp-importdialog-step[data-active] { 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)); }
15
+ & .crisp-importdialog-step:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: 1px; }
16
+ & .crisp-importdialog-body { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; padding: var(--crisp-space-6); }
17
+ & .crisp-importdialog-footer { display: flex; align-items: center; justify-content: flex-end; gap: var(--crisp-space-3); flex-shrink: 0; min-height: 56px; padding: 0 var(--crisp-space-6); border-top: 1px solid var(--crisp-border-subtle); }
18
+ & .crisp-importdialog-dropzone { box-sizing: border-box; position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--crisp-space-1); width: 100%; border: 1px dashed var(--crisp-border-dropzone); border-radius: 20px; background: var(--crisp-bg-subtle); text-align: center; transition: background-color .12s, border-color .12s; }
19
+ & .crisp-importdialog-dropzone[data-dragging-over] { border-color: var(--crisp-bg-brand-solid); background: color-mix(in srgb, var(--crisp-bg-brand-solid) 6%, transparent); }
20
+ & .crisp-importdialog-dropzone[data-invalid] { border-color: var(--crisp-bg-danger); }
21
+ & .crisp-importdialog-dropzone-title { color: var(--crisp-fg-primary); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); }
22
+ & .crisp-importdialog-dropzone-or { color: var(--crisp-fg-muted); font-size: var(--crisp-text-md); line-height: 18px; }
23
+ & .crisp-importdialog-dropzone-choose { border: none; background: none; padding: 0; margin: 0; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-bg-brand-solid); cursor: pointer; }
24
+ & .crisp-importdialog-dropzone-choose:hover { color: var(--crisp-bg-brand-solid-pressed); }
25
+ & .crisp-importdialog-dropzone-choose:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: 2px; border-radius: var(--crisp-radius-sm); }
26
+ & .crisp-importdialog-dropzone-learnmore { color: var(--crisp-fg-muted); font-size: var(--crisp-text-md); text-decoration: underline; }
27
+ & .crisp-importdialog-dropzone-input { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
28
+ & .crisp-importdialog-dropzone-errors { margin: 0; padding: 0; list-style: none; }
29
+ & .crisp-importdialog-dropzone-errors:empty { position: absolute; }
30
+ & .crisp-importdialog-dropzone-error { color: var(--crisp-bg-danger); font-size: var(--crisp-text-md); line-height: 18px; }
31
+ }
32
+
33
+ @media (prefers-reduced-motion: reduce) {
34
+ .crisp-importdialog, .crisp-importdialog * {
35
+ animation-duration: 0.01ms !important;
36
+ animation-iteration-count: 1 !important;
37
+ transition-duration: 0.01ms !important;
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,3 @@
1
+ .crisp-mention-chip {
2
+ display: inline; border-radius: var(--crisp-radius-chip); padding-inline: var(--crisp-space-1); 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)); font-weight: var(--crisp-weight-medium); cursor: default;
3
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface Mention-chipVariants {
4
+
5
+ }
6
+
7
+ export declare const mention-chipRecipe: RecipeFn<{ }>;
@@ -0,0 +1,5 @@
1
+ @layer crisp-components {
2
+ .crisp-mention-chip {
3
+ display: inline; border-radius: var(--crisp-radius-chip); padding-inline: var(--crisp-space-1); 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)); font-weight: var(--crisp-weight-medium); cursor: default;
4
+ }
5
+ }
@@ -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" | "fgOnBrand" | "fgOnTone" | "bgSurface" | "bgRaised" | "borderDefault" | "borderSubtle" | "ringNeutral" | "ringField" | "ringSwitch" | "bgTileActive" | "shadowTileActive" | "bgOverlayFrost" | "shadowOverlay1" | "shadowOverlay2" | "shadowOverlay3" | "bgPopover" | "ringPopover" | "shadowPopover1" | "shadowPopover2" | "shadowPopover3" | "fgPrimary" | "fgMuted" | "bgDanger" | "bgDangerSolid" | "strokeFieldFocus" | "fgDisabled" | "bgNeutralWeak" | "bgNeutralInverted" | "fgOnNeutralInverted" | "fgNeutralSubtle" | "fgNeutralMuted" | "strokeFocusRing" | "bgSuccess" | "bgWarning" | "bgOrange" | "bgCyan" | "bgPurple" | "bgSidebar" | "bgSubtle" | "fgBrandSoft" | "fgSuccessSoft" | "fgWarningSoft" | "fgDangerSoft" | "fgNeutralSoft" | "bgPurpleSoft" | "fgPurpleSoft" | "ringPurpleSoft", string>;
5
+ export type ColorTokens = Record<"bgBrandSolid" | "bgBrandSolidPressed" | "fgOnBrand" | "fgOnTone" | "bgSurface" | "bgRaised" | "borderDefault" | "borderSubtle" | "borderDropzone" | "ringNeutral" | "ringField" | "ringSwitch" | "bgTileActive" | "shadowTileActive" | "bgOverlayFrost" | "shadowOverlay1" | "shadowOverlay2" | "shadowOverlay3" | "bgPopover" | "ringPopover" | "shadowPopover1" | "shadowPopover2" | "shadowPopover3" | "fgPrimary" | "fgMuted" | "bgDanger" | "bgDangerSolid" | "fgDanger" | "strokeFieldFocus" | "fgDisabled" | "bgNeutralWeak" | "bgNeutralInverted" | "fgOnNeutralInverted" | "fgNeutralSubtle" | "fgNeutralMuted" | "strokeFocusRing" | "bgSuccess" | "bgWarning" | "bgOrange" | "bgCyan" | "bgPurple" | "bgSidebar" | "bgSubtle" | "fgBrandSoft" | "fgSuccessSoft" | "fgWarningSoft" | "fgDangerSoft" | "fgNeutralSoft" | "bgPurpleSoft" | "fgPurpleSoft" | "ringPurpleSoft", string>;
6
6
  export declare const tokens: {
7
7
  color: Record<Theme, ColorTokens>;
8
8
  palette: Record<Theme, Record<string, string>>;
@@ -12,6 +12,7 @@ export const tokens = {
12
12
  "bgRaised": "#f4f4f5",
13
13
  "borderDefault": "#e4e4e7",
14
14
  "borderSubtle": "#eeeff1",
15
+ "borderDropzone": "#e6e7ea",
15
16
  "ringNeutral": "transparent",
16
17
  "ringField": "rgba(0,0,0,0.06)",
17
18
  "ringSwitch": "#d9dade",
@@ -30,6 +31,7 @@ export const tokens = {
30
31
  "fgMuted": "#71717a",
31
32
  "bgDanger": "#e5484d",
32
33
  "bgDangerSolid": "#ba2525",
34
+ "fgDanger": "#eb3b3b",
33
35
  "strokeFieldFocus": "#1a1c20",
34
36
  "fgDisabled": "#d1d3d8",
35
37
  "bgNeutralWeak": "#f3f4f5",
@@ -63,6 +65,7 @@ export const tokens = {
63
65
  "bgRaised": "#101112",
64
66
  "borderDefault": "#212224",
65
67
  "borderSubtle": "#1c1d1f",
68
+ "borderDropzone": "#212224",
66
69
  "ringNeutral": "#212224",
67
70
  "ringField": "#212224",
68
71
  "ringSwitch": "#212224",
@@ -81,6 +84,7 @@ export const tokens = {
81
84
  "fgMuted": "#9a9aa2",
82
85
  "bgDanger": "#ff5a5f",
83
86
  "bgDangerSolid": "#ba2525",
87
+ "fgDanger": "#ff5a5f",
84
88
  "strokeFieldFocus": "#f3f4f5",
85
89
  "fgDisabled": "#5b606a",
86
90
  "bgNeutralWeak": "#1d2025",
@@ -101,9 +105,9 @@ export const tokens = {
101
105
  "fgWarningSoft": "#e0982a",
102
106
  "fgDangerSoft": "#ff5a5f",
103
107
  "fgNeutralSoft": "#9a9aa2",
104
- "bgPurpleSoft": "#f5f0ff",
105
- "fgPurpleSoft": "#6238b5",
106
- "ringPurpleSoft": "#e8ddfe"
108
+ "bgPurpleSoft": "#2f1e5a",
109
+ "fgPurpleSoft": "#d8c4ff",
110
+ "ringPurpleSoft": "#45297d"
107
111
  }
108
112
  },
109
113
  "palette": {
@@ -115,6 +119,7 @@ export const tokens = {
115
119
  "gray900": "#101112",
116
120
  "line200": "#e4e4e7",
117
121
  "line100": "#eeeff1",
122
+ "line150": "#e6e7ea",
118
123
  "ringNeutral": "transparent",
119
124
  "ringField": "rgba(0,0,0,0.06)",
120
125
  "ringSwitch": "#d9dade",
@@ -134,6 +139,7 @@ export const tokens = {
134
139
  "brand700": "#1f5fd6",
135
140
  "red600": "#e5484d",
136
141
  "red700": "#ba2525",
142
+ "red500": "#eb3b3b",
137
143
  "fieldFocus": "#1a1c20",
138
144
  "disabledFg": "#d1d3d8",
139
145
  "neutralWeak": "#f3f4f5",
@@ -165,6 +171,7 @@ export const tokens = {
165
171
  "gray900": "#f5f5f5",
166
172
  "line200": "#212224",
167
173
  "line100": "#1c1d1f",
174
+ "line150": "#212224",
168
175
  "ringNeutral": "#212224",
169
176
  "ringField": "#212224",
170
177
  "ringSwitch": "#212224",
@@ -184,6 +191,7 @@ export const tokens = {
184
191
  "brand700": "#1f5fd6",
185
192
  "red600": "#ff5a5f",
186
193
  "red700": "#ba2525",
194
+ "red500": "#ff5a5f",
187
195
  "fieldFocus": "#f3f4f5",
188
196
  "disabledFg": "#5b606a",
189
197
  "neutralWeak": "#1d2025",
@@ -203,9 +211,9 @@ export const tokens = {
203
211
  "softWarningText": "#e0982a",
204
212
  "softDangerText": "#ff5a5f",
205
213
  "softNeutralText": "#9a9aa2",
206
- "purpleTint": "#f5f0ff",
207
- "softPurpleText": "#6238b5",
208
- "purpleRing": "#e8ddfe"
214
+ "purpleTint": "#2f1e5a",
215
+ "softPurpleText": "#d8c4ff",
216
+ "purpleRing": "#45297d"
209
217
  }
210
218
  },
211
219
  "space": {
@@ -92,17 +92,21 @@
92
92
  & .crisp-recordpage-link:hover { text-decoration: underline; }
93
93
  & .crisp-recordpage-emptystate { padding: var(--crisp-space-2) var(--crisp-space-1); font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
94
94
  & .crisp-recordpage-main { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 0; overflow-y: auto; padding: var(--crisp-space-3) var(--crisp-space-5); }
95
- & .crisp-recordpage-panel { padding-top: var(--crisp-space-4); display: flex; flex-direction: column; gap: var(--crisp-space-4); }
95
+ /* no padding-top: Tabs' own panel supplies it now (#588) */
96
+ & .crisp-recordpage-panel { display: flex; flex-direction: column; gap: var(--crisp-space-4); }
96
97
  & .crisp-recordpage-card { border: 1px solid var(--crisp-border-subtle); border-radius: var(--crisp-radius-2xl); background: var(--crisp-bg-surface); overflow: hidden; }
97
98
  & .crisp-recordpage-card-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); letter-spacing: -0.14px; color: var(--crisp-fg-primary); padding: var(--crisp-space-3) var(--crisp-space-3) var(--crisp-space-2); }
98
99
  & .crisp-recordpage-hl-card { border: 1px solid var(--crisp-border-subtle); border-radius: var(--crisp-radius-2xl); overflow: hidden; }
99
- /* gap-as-gridlines: a 1px gap over the border colour draws dividers at any column count, so the grid stays responsive (auto-fit) without per-cell nth-child border hacks that break when the column count changes. */
100
+ /* gap-as-gridlines: a 1px gap over the border colour draws dividers at any
101
+ column count, so the grid stays responsive (auto-fit) without per-cell
102
+ nth-child border hacks that break when the column count changes. */
100
103
  & .crisp-recordpage-hl-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1px; background: var(--crisp-border-subtle); }
101
104
  & .crisp-recordpage-hl-cell { position: relative; min-height: 84px; padding: var(--crisp-space-2-5) var(--crisp-space-3); background: var(--crisp-bg-surface); }
102
105
  & .crisp-recordpage-hl-icon { position: absolute; top: var(--crisp-space-2-5); inset-inline-end: var(--crisp-space-3); color: var(--crisp-fg-muted); }
103
106
  & .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); }
104
107
  & .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); }
105
108
  & .crisp-recordpage-hl-value--empty { color: var(--crisp-fg-muted); font-weight: var(--crisp-weight-regular); }
109
+
106
110
  & .crisp-recordpage-feed { display: flex; flex-direction: column; }
107
111
  & .crisp-recordpage-feed-item { display: flex; align-items: flex-start; gap: var(--crisp-space-2-5); padding: var(--crisp-space-2) 0; }
108
112
  & .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); }
@@ -111,6 +115,7 @@
111
115
  & .crisp-recordpage-feed-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); margin-top: 2px; }
112
116
  & .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; }
113
117
  & .crisp-recordpage-feed-more:hover { text-decoration: underline; }
118
+
114
119
  & .crisp-recordpage-section-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-1); }
115
120
  & .crisp-recordpage-section-head .crisp-recordpage-section-title { padding: 0; }
116
121
  & .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); }
@@ -118,6 +123,7 @@
118
123
  & .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; }
119
124
  & .crisp-recordpage-addbtn:hover { background: var(--crisp-bg-raised); }
120
125
  & .crisp-recordpage-addbtn svg { flex-shrink: 0; }
126
+
121
127
  & .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); }
122
128
  & .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); }
123
129
  & .crisp-recordpage-composer textarea:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); border-radius: var(--crisp-radius-md); }
@@ -127,18 +133,23 @@
127
133
  & .crisp-recordpage-btn:hover { background: var(--crisp-bg-raised); }
128
134
  & .crisp-recordpage-btn--primary { box-shadow: none; background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); }
129
135
  & .crisp-recordpage-btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }
136
+
130
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); }
131
138
  & .crisp-recordpage-note-body { flex: 1; min-width: 0; }
132
139
  & .crisp-recordpage-note-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-bottom: var(--crisp-space-0-5); }
133
140
  & .crisp-recordpage-note-author { font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
134
141
  & .crisp-recordpage-note-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
135
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
+
136
144
  & .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); }
137
145
  & .crisp-recordpage-task-text { flex: 1; min-width: 0; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); padding-top: 1px; }
138
146
  & .crisp-recordpage-task[data-done] .crisp-recordpage-task-text { text-decoration: line-through; color: var(--crisp-fg-muted); }
147
+
139
148
  & .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; }
140
149
  & .crisp-recordpage-emptycard svg { color: var(--crisp-fg-muted); opacity: 0.7; }
150
+
141
151
  & .crisp-recordpage-action[data-active] svg { color: #f5b83d; fill: #f5b83d; }
152
+
142
153
  & .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); }
143
154
  & .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)); }
144
155
  & .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)); }
@@ -93,17 +93,21 @@
93
93
  & .crisp-recordpage-link:hover { text-decoration: underline; }
94
94
  & .crisp-recordpage-emptystate { padding: var(--crisp-space-2) var(--crisp-space-1); font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
95
95
  & .crisp-recordpage-main { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 0; overflow-y: auto; padding: var(--crisp-space-3) var(--crisp-space-5); }
96
- & .crisp-recordpage-panel { padding-top: var(--crisp-space-4); display: flex; flex-direction: column; gap: var(--crisp-space-4); }
96
+ /* no padding-top: Tabs' own panel supplies it now (#588) */
97
+ & .crisp-recordpage-panel { display: flex; flex-direction: column; gap: var(--crisp-space-4); }
97
98
  & .crisp-recordpage-card { border: 1px solid var(--crisp-border-subtle); border-radius: var(--crisp-radius-2xl); background: var(--crisp-bg-surface); overflow: hidden; }
98
99
  & .crisp-recordpage-card-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); letter-spacing: -0.14px; color: var(--crisp-fg-primary); padding: var(--crisp-space-3) var(--crisp-space-3) var(--crisp-space-2); }
99
100
  & .crisp-recordpage-hl-card { border: 1px solid var(--crisp-border-subtle); border-radius: var(--crisp-radius-2xl); overflow: hidden; }
100
- /* gap-as-gridlines: a 1px gap over the border colour draws dividers at any column count, so the grid stays responsive (auto-fit) without per-cell nth-child border hacks that break when the column count changes. */
101
+ /* gap-as-gridlines: a 1px gap over the border colour draws dividers at any
102
+ column count, so the grid stays responsive (auto-fit) without per-cell
103
+ nth-child border hacks that break when the column count changes. */
101
104
  & .crisp-recordpage-hl-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1px; background: var(--crisp-border-subtle); }
102
105
  & .crisp-recordpage-hl-cell { position: relative; min-height: 84px; padding: var(--crisp-space-2-5) var(--crisp-space-3); background: var(--crisp-bg-surface); }
103
106
  & .crisp-recordpage-hl-icon { position: absolute; top: var(--crisp-space-2-5); inset-inline-end: var(--crisp-space-3); color: var(--crisp-fg-muted); }
104
107
  & .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); }
105
108
  & .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); }
106
109
  & .crisp-recordpage-hl-value--empty { color: var(--crisp-fg-muted); font-weight: var(--crisp-weight-regular); }
110
+
107
111
  & .crisp-recordpage-feed { display: flex; flex-direction: column; }
108
112
  & .crisp-recordpage-feed-item { display: flex; align-items: flex-start; gap: var(--crisp-space-2-5); padding: var(--crisp-space-2) 0; }
109
113
  & .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); }
@@ -112,6 +116,7 @@
112
116
  & .crisp-recordpage-feed-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); margin-top: 2px; }
113
117
  & .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; }
114
118
  & .crisp-recordpage-feed-more:hover { text-decoration: underline; }
119
+
115
120
  & .crisp-recordpage-section-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-1); }
116
121
  & .crisp-recordpage-section-head .crisp-recordpage-section-title { padding: 0; }
117
122
  & .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); }
@@ -119,6 +124,7 @@
119
124
  & .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; }
120
125
  & .crisp-recordpage-addbtn:hover { background: var(--crisp-bg-raised); }
121
126
  & .crisp-recordpage-addbtn svg { flex-shrink: 0; }
127
+
122
128
  & .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); }
123
129
  & .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); }
124
130
  & .crisp-recordpage-composer textarea:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); border-radius: var(--crisp-radius-md); }
@@ -128,18 +134,23 @@
128
134
  & .crisp-recordpage-btn:hover { background: var(--crisp-bg-raised); }
129
135
  & .crisp-recordpage-btn--primary { box-shadow: none; background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); }
130
136
  & .crisp-recordpage-btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }
137
+
131
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); }
132
139
  & .crisp-recordpage-note-body { flex: 1; min-width: 0; }
133
140
  & .crisp-recordpage-note-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-bottom: var(--crisp-space-0-5); }
134
141
  & .crisp-recordpage-note-author { font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
135
142
  & .crisp-recordpage-note-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
136
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
+
137
145
  & .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); }
138
146
  & .crisp-recordpage-task-text { flex: 1; min-width: 0; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); padding-top: 1px; }
139
147
  & .crisp-recordpage-task[data-done] .crisp-recordpage-task-text { text-decoration: line-through; color: var(--crisp-fg-muted); }
148
+
140
149
  & .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; }
141
150
  & .crisp-recordpage-emptycard svg { color: var(--crisp-fg-muted); opacity: 0.7; }
151
+
142
152
  & .crisp-recordpage-action[data-active] svg { color: #f5b83d; fill: #f5b83d; }
153
+
143
154
  & .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); }
144
155
  & .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)); }
145
156
  & .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)); }
package/dist/richtext.css CHANGED
@@ -9,7 +9,17 @@
9
9
  & .crisp-rte-body h1 { font-size: var(--crisp-text-xl); line-height: 28px; font-weight: var(--crisp-weight-semibold); letter-spacing: -0.3px; margin-top: var(--crisp-space-4); }
10
10
  & .crisp-rte-body h2 { font-size: 17px; line-height: 24px; font-weight: var(--crisp-weight-semibold); letter-spacing: -0.2px; margin-top: var(--crisp-space-3); }
11
11
  & .crisp-rte-body h3 { font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-semibold); margin-top: var(--crisp-space-2-5); }
12
- & .crisp-rte-body ul, & .crisp-rte-body ol { padding-inline-start: var(--crisp-space-5); }
12
+ /* #575: a consumer's CSS reset (e.g. Tailwind preflight's un-scoped ul, ol { list-style: none }
13
+ , specificity 0,0,1) was winning every list marker outright -- this rule set padding but never declared list-style-type, so there was no higher-specificity value (this selector is 0,1,1) to beat the reset with. Split into two single-selector rules, each declaring its own marker type, rather than the old single comma-joined rule ( .crisp-rte-body ul, & .crisp-rte-body ol ) the issue flagged as malformed. #611: padding-inline-start re-measured live once CRUD on the measurement workspace was allowed (a "zz-parity" note with a bulleted list, a nested bulleted list, and a numbered list) -- Attio's own <ul>/<ol> measures 36px (getComputedStyle,
14
+ ~36.1353px), not the 20px placeholder #575 shipped with no real
15
+ content to check against. 36px isn't in tokens/scale.ts (steps stop at 24px, jump to 32px) and is a single component-intrinsic value, so it stays a raw px per AUTHORING.md's golden rule 4b
16
+ rather than being rounded to an existing token or added to the
17
+ shared scale. Marker colour (currentColor via the already-measured
18
+ fgPrimary, confirmed to equal Attio's measured rgb(16,17,18) == #101112 exactly) and the ~4px li-to-li gap (the existing li margin-top rule below) were re-checked at the same time and already matched -- only the padding was wrong. Attio doesn't vary
19
+ marker type for a nested list either (nested <ul> is disc too,
20
+ not circle), which this already doesn't attempt. */
21
+ & .crisp-rte-body ul { list-style-type: disc; padding-inline-start: 36px; }
22
+ & .crisp-rte-body ol { list-style-type: decimal; padding-inline-start: 36px; }
13
23
  & .crisp-rte-body li { margin-top: var(--crisp-space-1); }
14
24
  & .crisp-rte-body blockquote { padding-inline-start: var(--crisp-space-3); border-inline-start: 2px solid var(--crisp-border-default); color: var(--crisp-fg-muted); }
15
25
  & .crisp-rte-body code { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; font-size: var(--crisp-text-md); padding: 1px var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
@@ -10,7 +10,17 @@
10
10
  & .crisp-rte-body h1 { font-size: var(--crisp-text-xl); line-height: 28px; font-weight: var(--crisp-weight-semibold); letter-spacing: -0.3px; margin-top: var(--crisp-space-4); }
11
11
  & .crisp-rte-body h2 { font-size: 17px; line-height: 24px; font-weight: var(--crisp-weight-semibold); letter-spacing: -0.2px; margin-top: var(--crisp-space-3); }
12
12
  & .crisp-rte-body h3 { font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-semibold); margin-top: var(--crisp-space-2-5); }
13
- & .crisp-rte-body ul, & .crisp-rte-body ol { padding-inline-start: var(--crisp-space-5); }
13
+ /* #575: a consumer's CSS reset (e.g. Tailwind preflight's un-scoped ul, ol { list-style: none }
14
+ , specificity 0,0,1) was winning every list marker outright -- this rule set padding but never declared list-style-type, so there was no higher-specificity value (this selector is 0,1,1) to beat the reset with. Split into two single-selector rules, each declaring its own marker type, rather than the old single comma-joined rule ( .crisp-rte-body ul, & .crisp-rte-body ol ) the issue flagged as malformed. #611: padding-inline-start re-measured live once CRUD on the measurement workspace was allowed (a "zz-parity" note with a bulleted list, a nested bulleted list, and a numbered list) -- Attio's own <ul>/<ol> measures 36px (getComputedStyle,
15
+ ~36.1353px), not the 20px placeholder #575 shipped with no real
16
+ content to check against. 36px isn't in tokens/scale.ts (steps stop at 24px, jump to 32px) and is a single component-intrinsic value, so it stays a raw px per AUTHORING.md's golden rule 4b
17
+ rather than being rounded to an existing token or added to the
18
+ shared scale. Marker colour (currentColor via the already-measured
19
+ fgPrimary, confirmed to equal Attio's measured rgb(16,17,18) == #101112 exactly) and the ~4px li-to-li gap (the existing li margin-top rule below) were re-checked at the same time and already matched -- only the padding was wrong. Attio doesn't vary
20
+ marker type for a nested list either (nested <ul> is disc too,
21
+ not circle), which this already doesn't attempt. */
22
+ & .crisp-rte-body ul { list-style-type: disc; padding-inline-start: 36px; }
23
+ & .crisp-rte-body ol { list-style-type: decimal; padding-inline-start: 36px; }
14
24
  & .crisp-rte-body li { margin-top: var(--crisp-space-1); }
15
25
  & .crisp-rte-body blockquote { padding-inline-start: var(--crisp-space-3); border-inline-start: 2px solid var(--crisp-border-default); color: var(--crisp-fg-muted); }
16
26
  & .crisp-rte-body code { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; font-size: var(--crisp-text-md); padding: 1px var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
@@ -0,0 +1,78 @@
1
+
2
+ /* pointer-events: auto (#375) — see Menu/MultiSelect's matching comment:
3
+ a modal Dialog sets pointer-events: none on document.body, and a
4
+ portaled layer outside Zag's knowledge inherits that lock. */
5
+ .crisp-savedviews-panel {
6
+ font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
7
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
8
+ min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1);
9
+ border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
10
+ 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
+ transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease;
12
+ }
13
+ .crisp-savedviews-panel[data-up] { transform-origin: bottom left; }
14
+ .crisp-savedviews-panel { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
15
+
16
+ .crisp-savedviews-row {
17
+ box-sizing: border-box; position: relative; display: flex; align-items: center; gap: var(--crisp-space-1-5);
18
+ height: var(--crisp-size-menuRow); flex-shrink: 0; padding: var(--crisp-space-1-5) var(--crisp-space-2);
19
+ border-radius: var(--crisp-radius-md); cursor: pointer; -webkit-user-select: none; user-select: none;
20
+ }
21
+ .crisp-savedviews-row:hover, .crisp-savedviews-row[data-highlighted] { background: var(--crisp-bg-raised); }
22
+ .crisp-savedviews-row-icon { flex-shrink: 0; display: inline-flex; width: var(--crisp-size-icon); height: var(--crisp-size-icon); color: var(--crisp-fg-muted); }
23
+ .crisp-savedviews-row-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
24
+ .crisp-savedviews-row[aria-selected="true"] .crisp-savedviews-row-label { font-weight: var(--crisp-weight-semibold); }
25
+ .crisp-savedviews-row-shared { flex-shrink: 0; display: inline-flex; color: var(--crisp-fg-muted); }
26
+
27
+ /* The kebab's own <Menu> is wrapped in a slot div (savedviews.tsx) that
28
+ stops a click from bubbling — through the REACT tree, which a portal
29
+ does not leave, even though the Menu's content is a DOM sibling under
30
+ document.body — into the row's own onClick. The slot, not the kebab
31
+ button itself, is what the row's flex layout pushes to the trailing
32
+ edge. */
33
+ .crisp-savedviews-kebab-slot { flex-shrink: 0; margin-inline-start: auto; }
34
+ /* 20px / 4px padding is a component-intrinsic size (AUTHORING.md §4b —
35
+ "a badge's 20px" is the named example), used once here: raw, not a
36
+ scale step. */
37
+ .crisp-savedviews-kebab {
38
+ box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center;
39
+ width: 20px; height: 20px; padding: var(--crisp-space-1); margin: 0;
40
+ border: none; border-radius: var(--crisp-radius-sm); background: none; color: var(--crisp-fg-muted); cursor: pointer;
41
+ opacity: 0; transition: opacity .1s ease, background-color .12s ease, color .12s ease;
42
+ }
43
+ .crisp-savedviews-row:hover .crisp-savedviews-kebab,
44
+ .crisp-savedviews-row:focus-within .crisp-savedviews-kebab,
45
+ .crisp-savedviews-kebab[data-open] { opacity: 1; }
46
+ .crisp-savedviews-kebab:hover, .crisp-savedviews-kebab[data-open] { background: var(--crisp-bg-surface); color: var(--crisp-fg-primary); }
47
+
48
+ .crisp-savedviews {
49
+ position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; /* Trigger fill measured rgb(246,247,247); bgRaised's light value is
50
+ #f4f4f5 (244,244,245) — a 2-unit-per-channel difference, inside
51
+ screenshot/anti-aliasing noise, not a second real colour. Reusing the
52
+ token (Lesson 3 — tokens, not raw px/hex) gets a correct,
53
+ already-established dark-mode fill for free instead of a light-only
54
+ literal; AUTHORING.md Lesson 29 is the case where that shortcut went
55
+ wrong (a flat colour that stayed visible where the reference had
56
+ none) — this is the opposite risk (a token that already flips per
57
+ theme, applied to the closest measured match). */
58
+ & .crisp-savedviews-trigger {
59
+ box-sizing: border-box; display: inline-flex; align-items: center; gap: var(--crisp-space-1-5);
60
+ height: var(--crisp-size-row); margin: 0; padding: var(--crisp-space-1) var(--crisp-space-1-5);
61
+ border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-raised);
62
+ font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary);
63
+ cursor: pointer; white-space: nowrap; transition: background-color .12s ease;
64
+ }
65
+ & .crisp-savedviews-trigger:hover,
66
+ & .crisp-savedviews-trigger[data-open] { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, var(--crisp-bg-raised)); }
67
+ & .crisp-savedviews-trigger-icon { flex-shrink: 0; display: inline-flex; width: var(--crisp-size-icon); height: var(--crisp-size-icon); }
68
+ & .crisp-savedviews-trigger-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
69
+ & .crisp-savedviews-trigger-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); }
70
+ }
71
+
72
+ @media (prefers-reduced-motion: reduce) {
73
+ .crisp-savedviews, .crisp-savedviews * {
74
+ animation-duration: 0.01ms !important;
75
+ animation-iteration-count: 1 !important;
76
+ transition-duration: 0.01ms !important;
77
+ }
78
+ }
@@ -0,0 +1,7 @@
1
+ import type { RecipeFn } from "../core/types";
2
+
3
+ export interface SavedviewsVariants {
4
+
5
+ }
6
+
7
+ export declare const savedviewsRecipe: RecipeFn<{ }>;
@@ -0,0 +1,80 @@
1
+ @layer crisp-components {
2
+
3
+ /* pointer-events: auto (#375) — see Menu/MultiSelect's matching comment:
4
+ a modal Dialog sets pointer-events: none on document.body, and a
5
+ portaled layer outside Zag's knowledge inherits that lock. */
6
+ .crisp-savedviews-panel {
7
+ font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
8
+ position: fixed; z-index: 70; pointer-events: auto; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px);
9
+ min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1);
10
+ border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover);
11
+ 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
+ transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease;
13
+ }
14
+ .crisp-savedviews-panel[data-up] { transform-origin: bottom left; }
15
+ .crisp-savedviews-panel { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
16
+
17
+ .crisp-savedviews-row {
18
+ box-sizing: border-box; position: relative; display: flex; align-items: center; gap: var(--crisp-space-1-5);
19
+ height: var(--crisp-size-menuRow); flex-shrink: 0; padding: var(--crisp-space-1-5) var(--crisp-space-2);
20
+ border-radius: var(--crisp-radius-md); cursor: pointer; -webkit-user-select: none; user-select: none;
21
+ }
22
+ .crisp-savedviews-row:hover, .crisp-savedviews-row[data-highlighted] { background: var(--crisp-bg-raised); }
23
+ .crisp-savedviews-row-icon { flex-shrink: 0; display: inline-flex; width: var(--crisp-size-icon); height: var(--crisp-size-icon); color: var(--crisp-fg-muted); }
24
+ .crisp-savedviews-row-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
25
+ .crisp-savedviews-row[aria-selected="true"] .crisp-savedviews-row-label { font-weight: var(--crisp-weight-semibold); }
26
+ .crisp-savedviews-row-shared { flex-shrink: 0; display: inline-flex; color: var(--crisp-fg-muted); }
27
+
28
+ /* The kebab's own <Menu> is wrapped in a slot div (savedviews.tsx) that
29
+ stops a click from bubbling — through the REACT tree, which a portal
30
+ does not leave, even though the Menu's content is a DOM sibling under
31
+ document.body — into the row's own onClick. The slot, not the kebab
32
+ button itself, is what the row's flex layout pushes to the trailing
33
+ edge. */
34
+ .crisp-savedviews-kebab-slot { flex-shrink: 0; margin-inline-start: auto; }
35
+ /* 20px / 4px padding is a component-intrinsic size (AUTHORING.md §4b —
36
+ "a badge's 20px" is the named example), used once here: raw, not a
37
+ scale step. */
38
+ .crisp-savedviews-kebab {
39
+ box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center;
40
+ width: 20px; height: 20px; padding: var(--crisp-space-1); margin: 0;
41
+ border: none; border-radius: var(--crisp-radius-sm); background: none; color: var(--crisp-fg-muted); cursor: pointer;
42
+ opacity: 0; transition: opacity .1s ease, background-color .12s ease, color .12s ease;
43
+ }
44
+ .crisp-savedviews-row:hover .crisp-savedviews-kebab,
45
+ .crisp-savedviews-row:focus-within .crisp-savedviews-kebab,
46
+ .crisp-savedviews-kebab[data-open] { opacity: 1; }
47
+ .crisp-savedviews-kebab:hover, .crisp-savedviews-kebab[data-open] { background: var(--crisp-bg-surface); color: var(--crisp-fg-primary); }
48
+
49
+ .crisp-savedviews {
50
+ position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; /* Trigger fill measured rgb(246,247,247); bgRaised's light value is
51
+ #f4f4f5 (244,244,245) — a 2-unit-per-channel difference, inside
52
+ screenshot/anti-aliasing noise, not a second real colour. Reusing the
53
+ token (Lesson 3 — tokens, not raw px/hex) gets a correct,
54
+ already-established dark-mode fill for free instead of a light-only
55
+ literal; AUTHORING.md Lesson 29 is the case where that shortcut went
56
+ wrong (a flat colour that stayed visible where the reference had
57
+ none) — this is the opposite risk (a token that already flips per
58
+ theme, applied to the closest measured match). */
59
+ & .crisp-savedviews-trigger {
60
+ box-sizing: border-box; display: inline-flex; align-items: center; gap: var(--crisp-space-1-5);
61
+ height: var(--crisp-size-row); margin: 0; padding: var(--crisp-space-1) var(--crisp-space-1-5);
62
+ border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-raised);
63
+ font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary);
64
+ cursor: pointer; white-space: nowrap; transition: background-color .12s ease;
65
+ }
66
+ & .crisp-savedviews-trigger:hover,
67
+ & .crisp-savedviews-trigger[data-open] { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, var(--crisp-bg-raised)); }
68
+ & .crisp-savedviews-trigger-icon { flex-shrink: 0; display: inline-flex; width: var(--crisp-size-icon); height: var(--crisp-size-icon); }
69
+ & .crisp-savedviews-trigger-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
70
+ & .crisp-savedviews-trigger-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); }
71
+ }
72
+
73
+ @media (prefers-reduced-motion: reduce) {
74
+ .crisp-savedviews, .crisp-savedviews * {
75
+ animation-duration: 0.01ms !important;
76
+ animation-iteration-count: 1 !important;
77
+ transition-duration: 0.01ms !important;
78
+ }
79
+ }
80
+ }