@crisp-ui-kit/crisp 0.50.0 → 0.52.0

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 (128) hide show
  1. package/dist/cjs/components/composewindow/composewindow.js +144 -0
  2. package/dist/cjs/components/composewindow/composewindow.recipe.js +45 -0
  3. package/dist/cjs/components/composewindow/index.js +8 -0
  4. package/dist/cjs/components/datatable/datatable.js +224 -43
  5. package/dist/cjs/components/datatable/datatable.recipe.js +37 -3
  6. package/dist/cjs/components/datatable/index.js +6 -0
  7. package/dist/cjs/components/datepickerfield/datepickerfield.js +25 -15
  8. package/dist/cjs/components/datepickerfield/datepickerfield.recipe.js +25 -8
  9. package/dist/cjs/components/dialog/dialog.recipe.js +9 -1
  10. package/dist/cjs/components/menu/menu.js +4 -2
  11. package/dist/cjs/components/multiselect/multiselect.recipe.js +14 -8
  12. package/dist/cjs/components/select/select.js +2 -1
  13. package/dist/cjs/components/table/table.recipe.js +12 -3
  14. package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +1 -1
  15. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +18 -7
  16. package/dist/cjs/core/caret-rect.js +73 -0
  17. package/dist/cjs/core/cell-date.js +11 -0
  18. package/dist/cjs/core/index.js +8 -1
  19. package/dist/cjs/core/mention.js +32 -0
  20. package/dist/cjs/core/use-mention-trigger.js +124 -0
  21. package/dist/cjs/index.js +1 -0
  22. package/dist/cjs/product/recordpage/recordpage.js +88 -10
  23. package/dist/cjs/product/recordpage/recordpage.recipe.js +30 -0
  24. package/dist/cjs/product/recordpanel/recordpanel.js +11 -29
  25. package/dist/cjs/product/recordpanel/recordpanel.recipe.js +55 -17
  26. package/dist/cjs/product/recordstable/editable-field.js +113 -0
  27. package/dist/cjs/product/recordstable/index.js +4 -1
  28. package/dist/cjs/product/recordstable/recordstable.js +67 -11
  29. package/dist/cjs/product/recordstable/recordstable.recipe.js +9 -1
  30. package/dist/cjs/product/recordstable/recordstable.tag.js +8 -3
  31. package/dist/cjs/product/richtext/index.js +2 -1
  32. package/dist/cjs/product/richtext/richtext.js +440 -23
  33. package/dist/cjs/product/richtext/richtext.recipe.js +59 -9
  34. package/dist/cjs/product/settingsshell/settingsshell.recipe.js +13 -4
  35. package/dist/cjs/product/sidebar/sidebar.js +15 -3
  36. package/dist/cjs/product/sidebar/sidebar.recipe.js +21 -2
  37. package/dist/composewindow.css +24 -0
  38. package/dist/composewindow.d.ts +7 -0
  39. package/dist/composewindow.layered.css +26 -0
  40. package/dist/datatable.css +33 -14
  41. package/dist/datatable.layered.css +33 -14
  42. package/dist/datepickerfield.css +9 -4
  43. package/dist/datepickerfield.layered.css +9 -4
  44. package/dist/dialog.css +2 -1
  45. package/dist/dialog.layered.css +2 -1
  46. package/dist/esm/components/composewindow/composewindow.js +107 -0
  47. package/dist/esm/components/composewindow/composewindow.recipe.js +42 -0
  48. package/dist/esm/components/composewindow/index.js +2 -0
  49. package/dist/esm/components/datatable/datatable.js +226 -45
  50. package/dist/esm/components/datatable/datatable.recipe.js +37 -3
  51. package/dist/esm/components/datatable/index.js +6 -0
  52. package/dist/esm/components/datepickerfield/datepickerfield.js +26 -16
  53. package/dist/esm/components/datepickerfield/datepickerfield.recipe.js +25 -8
  54. package/dist/esm/components/dialog/dialog.recipe.js +9 -1
  55. package/dist/esm/components/menu/menu.js +4 -2
  56. package/dist/esm/components/multiselect/multiselect.recipe.js +14 -8
  57. package/dist/esm/components/select/select.js +2 -1
  58. package/dist/esm/components/table/table.recipe.js +12 -3
  59. package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +1 -1
  60. package/dist/esm/components/tabletoolbar/tabletoolbar.js +18 -7
  61. package/dist/esm/core/caret-rect.js +70 -0
  62. package/dist/esm/core/cell-date.js +10 -0
  63. package/dist/esm/core/index.js +4 -1
  64. package/dist/esm/core/mention.js +29 -0
  65. package/dist/esm/core/use-mention-trigger.js +88 -0
  66. package/dist/esm/index.js +1 -0
  67. package/dist/esm/product/recordpage/recordpage.js +89 -11
  68. package/dist/esm/product/recordpage/recordpage.recipe.js +30 -0
  69. package/dist/esm/product/recordpanel/index.js +1 -1
  70. package/dist/esm/product/recordpanel/recordpanel.js +13 -31
  71. package/dist/esm/product/recordpanel/recordpanel.recipe.js +56 -18
  72. package/dist/esm/product/recordstable/editable-field.js +76 -0
  73. package/dist/esm/product/recordstable/index.js +1 -0
  74. package/dist/esm/product/recordstable/recordstable.js +69 -13
  75. package/dist/esm/product/recordstable/recordstable.recipe.js +9 -1
  76. package/dist/esm/product/recordstable/recordstable.tag.js +8 -3
  77. package/dist/esm/product/richtext/index.js +1 -1
  78. package/dist/esm/product/richtext/richtext.js +439 -22
  79. package/dist/esm/product/richtext/richtext.recipe.js +60 -10
  80. package/dist/esm/product/settingsshell/settingsshell.recipe.js +13 -4
  81. package/dist/esm/product/sidebar/sidebar.js +15 -3
  82. package/dist/esm/product/sidebar/sidebar.recipe.js +21 -2
  83. package/dist/multiselect.css +8 -8
  84. package/dist/multiselect.layered.css +8 -8
  85. package/dist/recordpage.css +25 -13
  86. package/dist/recordpage.layered.css +25 -13
  87. package/dist/recordpanel.css +43 -20
  88. package/dist/recordpanel.layered.css +43 -20
  89. package/dist/recordstable.css +9 -2
  90. package/dist/recordstable.layered.css +9 -2
  91. package/dist/richtext.css +31 -5
  92. package/dist/richtext.layered.css +31 -5
  93. package/dist/settingsshell.css +2 -2
  94. package/dist/settingsshell.layered.css +2 -2
  95. package/dist/sidebar.css +7 -2
  96. package/dist/sidebar.layered.css +7 -2
  97. package/dist/styles.css +199 -74
  98. package/dist/styles.layered.css +199 -74
  99. package/dist/table.css +4 -2
  100. package/dist/table.layered.css +4 -2
  101. package/dist/tabletoolbar.css +1 -1
  102. package/dist/tabletoolbar.layered.css +1 -1
  103. package/dist/types/components/composewindow/composewindow.d.ts +80 -0
  104. package/dist/types/components/composewindow/composewindow.recipe.d.ts +3 -0
  105. package/dist/types/components/composewindow/index.d.ts +2 -0
  106. package/dist/types/components/datatable/datatable.d.ts +58 -4
  107. package/dist/types/components/datatable/index.d.ts +1 -1
  108. package/dist/types/components/datepickerfield/datepickerfield.d.ts +18 -4
  109. package/dist/types/components/menu/menu.d.ts +10 -1
  110. package/dist/types/components/select/select.d.ts +6 -1
  111. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +29 -5
  112. package/dist/types/core/caret-rect.d.ts +16 -0
  113. package/dist/types/core/cell-date.d.ts +17 -0
  114. package/dist/types/core/index.d.ts +4 -1
  115. package/dist/types/core/mention.d.ts +27 -0
  116. package/dist/types/core/use-mention-trigger.d.ts +41 -0
  117. package/dist/types/index.d.ts +1 -0
  118. package/dist/types/product/recordpage/recordpage.d.ts +59 -1
  119. package/dist/types/product/recordpanel/index.d.ts +1 -1
  120. package/dist/types/product/recordpanel/recordpanel.d.ts +81 -17
  121. package/dist/types/product/recordstable/editable-field.d.ts +48 -0
  122. package/dist/types/product/recordstable/index.d.ts +1 -0
  123. package/dist/types/product/recordstable/recordstable.d.ts +29 -0
  124. package/dist/types/product/recordstable/recordstable.tag.d.ts +8 -3
  125. package/dist/types/product/richtext/index.d.ts +1 -1
  126. package/dist/types/product/richtext/richtext.d.ts +168 -7
  127. package/dist/types/product/sidebar/sidebar.d.ts +60 -4
  128. package/package.json +6 -1
package/dist/styles.css CHANGED
@@ -486,6 +486,31 @@
486
486
  }
487
487
  }
488
488
 
489
+ .crisp-composewindow {
490
+ display: contents; font-family: var(--crisp-font-sans);
491
+ & .crisp-composewindow-backdrop { position: fixed; inset: 0; z-index: 60; background: transparent; pointer-events: none; }
492
+ & .crisp-composewindow-positioner { position: fixed; inset: 0; z-index: 61; display: flex; align-items: flex-start; justify-content: center; padding: 15vh var(--crisp-space-4) var(--crisp-space-4); pointer-events: none; }
493
+ & .crisp-composewindow-content { pointer-events: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; position: relative; display: flex; flex-direction: column; box-sizing: border-box; width: 90vw; max-height: 74vh; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-2xl); background: color-mix(in srgb, var(--crisp-bg-overlay-frost) 60%, transparent); backdrop-filter: blur(15px); -webkit-backdrop-filter: blur(15px); box-shadow: 0 8px 28px -6px var(--crisp-shadow-overlay1), 0 18px 88px -4px var(--crisp-shadow-overlay2), 0 0 1px var(--crisp-shadow-overlay3); opacity: 1; transform: scale(1); transition: opacity 0.2s ease, transform 0.2s ease; @starting-style { opacity: 0; transform: scale(0.97); } }
494
+ & .crisp-composewindow-content[data-minimized] { visibility: hidden; opacity: 0; }
495
+ & .crisp-composewindow-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); overflow: hidden; }
496
+ & .crisp-composewindow-header { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); flex-shrink: 0; height: 52px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-4); border-bottom: 1px solid var(--crisp-border-subtle); }
497
+ & .crisp-composewindow-breadcrumb { display: flex; align-items: center; gap: var(--crisp-space-1); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
498
+ & .crisp-composewindow-actions { display: flex; align-items: center; gap: var(--crisp-space-0-5); flex-shrink: 0; }
499
+ & .crisp-composewindow-action-btn { 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; }
500
+ & .crisp-composewindow-action-btn:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
501
+ & .crisp-composewindow-action-btn[data-state="on"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: var(--crisp-bg-brand-solid); }
502
+ & .crisp-composewindow-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; padding: var(--crisp-space-5) var(--crisp-space-4); }
503
+ & .crisp-composewindow-content-body { display: flex; flex-direction: column; gap: var(--crisp-space-4); }
504
+ }
505
+
506
+ @media (prefers-reduced-motion: reduce) {
507
+ .crisp-composewindow, .crisp-composewindow * {
508
+ animation-duration: 0.01ms !important;
509
+ animation-iteration-count: 1 !important;
510
+ transition-duration: 0.01ms !important;
511
+ }
512
+ }
513
+
489
514
 
490
515
  /* pointer-events: auto (#375): a modal Dialog sets pointer-events: none
491
516
  on document.body while open (Zag re-enables it only on layers IT
@@ -548,10 +573,13 @@
548
573
  & .crisp-datatable-th-rename:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
549
574
  & .crisp-datatable-th-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
550
575
  & .crisp-datatable-sort { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; font: inherit; letter-spacing: inherit; color: inherit; text-align: start; cursor: pointer; }
551
- & th[data-align="right"] .crisp-datatable-sort { justify-content: flex-end; padding-inline-end: 0; }
552
- & th[data-align="right"] .crisp-datatable-th-inner { justify-content: flex-end; }
576
+ /* A right-aligned column's header keeps its field-icon + label packed at
577
+ the START, matching its own values only in that the VALUES right-align
578
+ -- Attio's own right-aligned header (measured live: "Twitter follower
579
+ count") keeps the icon+label left and only the trailing column-menu icon sits pinned to the right edge, independent of the label's width
580
+ (#406, reversing #393's own justify-content: flex-end here). The chevron's own margin-inline-start: auto below already pins IT to the
581
+ end of a flex-start row with no override needed -- that's what pins the trailing icon on Attio too. */
553
582
  & .crisp-datatable-chevron { margin-inline-start: auto; flex-shrink: 0; color: var(--crisp-fg-muted); opacity: 0; transition: opacity .12s; }
554
- & th[data-align="right"] .crisp-datatable-chevron { margin-inline-start: 0; order: -1; }
555
583
  & .crisp-datatable-sort:hover .crisp-datatable-chevron { opacity: 0.6; }
556
584
  & .crisp-datatable-sort[data-sorted] .crisp-datatable-chevron { opacity: 1; color: var(--crisp-fg-primary); }
557
585
  /* sticky first column(s) + horizontal scroll shadow — RecordsTable's feel */
@@ -574,6 +602,28 @@
574
602
  & .crisp-datatable-editable:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, var(--crisp-bg-surface)); cursor: text; }
575
603
  & .crisp-datatable-edit { width: 100%; height: 28px; margin: 0; padding: 0 var(--crisp-space-1-5); border: none; border-radius: var(--crisp-radius-sm); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); outline: none; vertical-align: middle; }
576
604
  & .crisp-datatable-edit:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
605
+ /* An async onEdit's in-flight state (#385) -- the field/picker dims and
606
+ stops accepting input rather than disappearing, so the just-typed or
607
+ just-chosen value stays visible while its commit is pending. Same
608
+ treatment Input already gives its own disabled state. */
609
+ & .crisp-datatable-edit:disabled { opacity: 0.5; cursor: not-allowed; }
610
+ & .crisp-datatable-edit-pending { flex-shrink: 0; margin-inline-start: var(--crisp-space-1); color: var(--crisp-fg-muted); vertical-align: middle; }
611
+ /* The rejection's message, beside the cell's own content -- a sibling in
612
+ the TableCell, never nested inside a column's own render output, so a hover-only wrapper (a Tooltip, say) around a custom render can't hide
613
+ it. Block-level: the row grows to fit it rather than floating over
614
+ the row below, so it can never end up clipped by the scroll
615
+ container's overflow the way a position:fixed escape would need guarding against. */
616
+ & .crisp-datatable-edit-error { display: block; padding: var(--crisp-space-0-5) 0 0; font-size: var(--crisp-text-sm); color: var(--crisp-bg-danger); }
617
+ /* editor: "select"/"switch" -- always live, no separate edit mode, so the cell IS the picker: same chromeless-fill treatment as RecordsTable's own --picker cells (measured there already; DataTable
618
+ shares RecordsTable's grid, Golden Rule 0). */
619
+ & .crisp-datatable-td--picker { padding: 0; }
620
+ & .crisp-datatable-edit-picker { display: flex; align-items: center; gap: var(--crisp-space-1); height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-2); }
621
+ & .crisp-datatable-edit-picker .crisp-select-trigger { flex: 1; min-width: 0; height: 100%; min-height: 0; border-radius: 0; box-shadow: none; padding: 0; }
622
+ & .crisp-datatable-td--picker .crisp-datatable-edit-error { padding-inline-start: var(--crisp-space-2); }
623
+ /* reference picker: a leading 16px avatar per option, plus a trailing "Create X" row when the consumer supplies one (#449) -- same measured values as RecordsTable's own .crisp-recordstable-refoption*. */
624
+ & .crisp-datatable-refoption { display: flex; align-items: center; gap: var(--crisp-space-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
625
+ & .crisp-datatable-refoption-avatar { flex-shrink: 0; }
626
+ & .crisp-datatable-refoption--create { color: var(--crisp-fg-muted); }
577
627
  & .crisp-datatable-empty { padding: var(--crisp-space-8) var(--crisp-space-3); text-align: center; color: var(--crisp-fg-muted); font-size: var(--crisp-text-lg); }
578
628
  /* fixed layout so column widths (and resize) are exact — like RecordsTable */
579
629
  & table { table-layout: fixed; }
@@ -585,12 +635,7 @@
585
635
  & .crisp-datatable-entity { display: flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; color: var(--crisp-fg-primary); font-weight: var(--crisp-weight-medium); }
586
636
  & .crisp-datatable-entity-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
587
637
  & .crisp-datatable-avatar { width: var(--crisp-size-icon); height: var(--crisp-size-icon); border-radius: var(--crisp-radius-sm); flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; line-height: 1; font-weight: var(--crisp-weight-semibold); text-transform: uppercase; color: var(--crisp-fg-on-brand); background: var(--crisp-bg-brand-solid); }
588
- & .crisp-datatable-avatar[data-tone="success"] { background: var(--crisp-bg-success); }
589
- & .crisp-datatable-avatar[data-tone="warning"] { background: var(--crisp-bg-warning); }
590
- & .crisp-datatable-avatar[data-tone="danger"] { background: var(--crisp-bg-danger); }
591
- & .crisp-datatable-avatar[data-tone="purple"] { background: var(--crisp-bg-purple); }
592
- & .crisp-datatable-avatar[data-tone="cyan"] { background: var(--crisp-bg-cyan); }
593
- & .crisp-datatable-avatar[data-tone="orange"] { background: var(--crisp-bg-orange); }
638
+ & .crisp-datatable-avatar[data-tone="success"] { background: var(--crisp-bg-success); } & .crisp-datatable-avatar[data-tone="warning"] { background: var(--crisp-bg-warning); } & .crisp-datatable-avatar[data-tone="danger"] { background: var(--crisp-bg-danger); } & .crisp-datatable-avatar[data-tone="purple"] { background: var(--crisp-bg-purple); } & .crisp-datatable-avatar[data-tone="cyan"] { background: var(--crisp-bg-cyan); } & .crisp-datatable-avatar[data-tone="orange"] { background: var(--crisp-bg-orange); }
594
639
  & .crisp-datatable-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
595
640
  & .crisp-datatable-tags { display: flex; align-items: center; gap: var(--crisp-space-1); overflow: hidden; }
596
641
  & .crisp-datatable-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); }
@@ -603,11 +648,10 @@
603
648
  & .crisp-datatable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
604
649
  & .crisp-datatable-num { font-variant-numeric: tabular-nums; }
605
650
  & .crisp-datatable-muted { color: var(--crisp-fg-muted); }
606
- /* row drag-to-reorder -- a Settings > Objects > Attributes screen measures a leading 20px grip column, a 16px grip icon, and the row's own
607
- hairline doubling as the drop indicator (it tints toward the brand
608
- colour as the active drop target). The affordance + geometry are
609
- measured; the drag MECHANISM is crisp's existing house idiom -- HTML5 draggable + dataTransfer, the same one column reorder already uses (RecordsTable's reorderColumn) -- not a proprietary
610
- pointer-events implementation. */
651
+ /* row drag-to-reorder -- a Settings > Objects > Attributes screen measures
652
+ a leading 20px grip column, a 16px grip icon, and the row's own hairline doubling as the drop indicator (it tints toward the brand colour as the active drop target). The affordance + geometry are measured; the drag MECHANISM is crisp's existing house idiom -- HTML5
653
+ draggable + dataTransfer, the same one column reorder already uses
654
+ (RecordsTable's reorderColumn) -- not a proprietary pointer-events implementation. */
611
655
  & .crisp-datatable-col-grip { width: 20px; padding: 0; text-align: center; }
612
656
  & .crisp-datatable-grip { display: inline-flex; align-items: center; justify-content: center; width: 100%; height: 100%; margin: 0; border: none; border-radius: 0; background: none; font-family: inherit; color: var(--crisp-fg-muted); cursor: grab; }
613
657
  & .crisp-datatable-grip:active { cursor: grabbing; }
@@ -738,11 +782,16 @@
738
782
 
739
783
  .crisp-datepickerfield {
740
784
  display: inline-flex; font-family: var(--crisp-font-sans);
741
- & .crisp-datepickerfield-trigger { display: inline-flex; align-items: center; gap: var(--crisp-space-2); box-sizing: border-box; height: 32px; padding: 0 var(--crisp-space-2-5); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); white-space: nowrap; cursor: pointer; }
742
- & .crisp-datepickerfield-trigger[data-ghost] { background: transparent; box-shadow: none; }
743
- & .crisp-datepickerfield-trigger[data-ghost]:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
744
- & .crisp-datepickerfield-trigger[data-placeholder] { color: var(--crisp-fg-muted); }
785
+ & .crisp-datepickerfield-box { display: inline-flex; align-items: center; box-sizing: border-box; height: 32px; margin: 0; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); }
786
+ & .crisp-datepickerfield-box[data-ghost] { background: transparent; box-shadow: none; }
787
+ & .crisp-datepickerfield-box[data-ghost]:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
788
+ & .crisp-datepickerfield-trigger { display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 100%; padding: 0 var(--crisp-space-2-5); margin: 0; border: none; background: none; color: inherit; font-family: inherit; font-size: inherit; white-space: nowrap; cursor: pointer; }
789
+ & .crisp-datepickerfield-box[data-placeholder] .crisp-datepickerfield-trigger { color: var(--crisp-fg-muted); }
745
790
  & .crisp-datepickerfield-trigger svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
791
+ /* Reuses TableToolbar's measured filter-chip remove button
792
+ (tabletoolbar.chrome.ts's .crisp-tabletoolbar-fchip-x) -- the same small inline "clear this value" affordance, not a freshly-measured one: no live Attio composition for a DatePickerField-equivalent clear was reachable this round (#394). */
793
+ & .crisp-datepickerfield-clear { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin-inline-end: var(--crisp-space-1); padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
794
+ & .crisp-datepickerfield-clear:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 10%, transparent); color: var(--crisp-fg-primary); }
746
795
  & .crisp-datepickerfield-panel { padding: var(--crisp-space-2); width: 300px; }
747
796
  & .crisp-datepickerfield-presets { display: flex; flex-wrap: wrap; gap: var(--crisp-space-1); margin-top: var(--crisp-space-2); }
748
797
  & .crisp-datepickerfield-preset { height: var(--crisp-size-chip); padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-chip); background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-sm); cursor: pointer; }
@@ -766,7 +815,8 @@
766
815
  & .crisp-dialog-field-label { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
767
816
  & .crisp-dialog-more { display: inline-flex; align-items: center; gap: var(--crisp-space-2); margin-inline-end: auto; border: none; background: none; padding: 0; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); cursor: pointer; }
768
817
  & .crisp-dialog-submit { display: inline-flex; align-items: center; gap: var(--crisp-space-2); height: 28px; padding: 0 var(--crisp-space-1) 0 var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
769
- & .crisp-dialog-submit-key { display: inline-flex; align-items: center; justify-content: center; height: 18px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: rgba(255,255,255,0.22); font-size: var(--crisp-text-xs); }
818
+ & .crisp-dialog-submit-key { display: inline-flex; align-items: center; gap: var(--crisp-space-1); }
819
+ & .crisp-dialog-submit-key kbd { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0 3px; border-radius: 4px; background: transparent; color: var(--crisp-fg-on-brand); font-family: inherit; font-style: normal; font-size: 10px; }
770
820
  }
771
821
 
772
822
  @media (prefers-reduced-motion: reduce) {
@@ -1103,14 +1153,14 @@
1103
1153
  .crisp-multiselect-option[aria-selected="true"] .crisp-multiselect-check { background: var(--crisp-bg-brand-solid); box-shadow: none; color: #fff; }
1104
1154
  .crisp-multiselect-empty { padding: var(--crisp-space-3) var(--crisp-space-2); text-align: center; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
1105
1155
 
1106
- .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; overflow: hidden; text-overflow: ellipsis; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); }
1107
- .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)); }
1108
- .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)); }
1109
- .crisp-recordstable-tag[data-tone="warning"] { background: color-mix(in srgb, var(--crisp-bg-warning) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-warning) 82%, var(--crisp-fg-primary)); }
1110
- .crisp-recordstable-tag[data-tone="danger"] { background: color-mix(in srgb, var(--crisp-bg-danger) 15%, transparent); color: color-mix(in srgb, var(--crisp-bg-danger) 80%, var(--crisp-fg-primary)); }
1111
- .crisp-recordstable-tag[data-tone="purple"] { background: color-mix(in srgb, var(--crisp-bg-purple) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-purple) 80%, var(--crisp-fg-primary)); }
1112
- .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); }
1113
- .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
1156
+ .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; overflow: hidden; text-overflow: ellipsis; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
1157
+ .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)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent); }
1158
+ .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)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-success) 30%, transparent); }
1159
+ .crisp-recordstable-tag[data-tone="warning"] { background: color-mix(in srgb, var(--crisp-bg-warning) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-warning) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-warning) 30%, transparent); }
1160
+ .crisp-recordstable-tag[data-tone="danger"] { background: color-mix(in srgb, var(--crisp-bg-danger) 15%, transparent); color: color-mix(in srgb, var(--crisp-bg-danger) 80%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-danger) 30%, transparent); }
1161
+ .crisp-recordstable-tag[data-tone="purple"] { background: color-mix(in srgb, var(--crisp-bg-purple) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-purple) 80%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-purple) 30%, transparent); }
1162
+ .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-cyan) 30%, transparent); }
1163
+ .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-orange) 30%, transparent); }
1114
1164
 
1115
1165
  .crisp-multiselect {
1116
1166
  position: relative; display: inline-flex; width: 100%; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
@@ -1516,11 +1566,11 @@
1516
1566
  & .crisp-table-scroll { overflow-x: auto; }
1517
1567
  & table { width: 100%; border-collapse: separate; border-spacing: 0; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
1518
1568
  & th, & td { position: relative; height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-2); border-bottom: 1px solid var(--crisp-border-subtle); border-inline-end: 1px solid var(--crisp-border-subtle); text-align: start; vertical-align: middle; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
1519
- & th { height: var(--crisp-size-tableHeader); background: var(--crisp-bg-surface); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); letter-spacing: -0.14px; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); user-select: none; }
1569
+ & th { height: var(--crisp-size-tableHeader); background: var(--crisp-bg-surface); border-top: 1px solid var(--crisp-border-subtle); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); letter-spacing: -0.14px; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); user-select: none; }
1520
1570
  & td { color: var(--crisp-fg-primary); background: var(--crisp-bg-surface); }
1521
1571
  & th:last-child, & td:last-child { border-inline-end: none; }
1522
1572
  & tbody tr:last-child td { border-bottom: none; }
1523
- & tfoot td { border-top: 1px solid var(--crisp-border-subtle); border-bottom: none; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
1573
+ & tfoot td { border-top: 1px solid var(--crisp-border-subtle); border-bottom: 1px solid var(--crisp-border-subtle); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
1524
1574
  & caption { padding: var(--crisp-space-2) var(--crisp-space-2); text-align: start; font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); caption-side: bottom; }
1525
1575
  & td[data-align="right"], & th[data-align="right"] { text-align: end; }
1526
1576
  & td[data-align="center"], & th[data-align="center"] { text-align: center; }
@@ -1534,6 +1584,8 @@
1534
1584
  }
1535
1585
  .crisp-table--surface_card {
1536
1586
  border: 1px solid var(--crisp-border-subtle); border-radius: var(--crisp-radius-xl); overflow: hidden;
1587
+ & th { border-top: none; }
1588
+ & tfoot td { border-bottom: none; }
1537
1589
  }
1538
1590
  .crisp-table--surface_bleed {
1539
1591
  border: none; border-radius: 0;
@@ -1556,7 +1608,7 @@
1556
1608
  & .crisp-tabletoolbar-search svg { flex-shrink: 0; }
1557
1609
  & .crisp-tabletoolbar-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
1558
1610
  & .crisp-tabletoolbar-search input::placeholder { color: var(--crisp-fg-muted); }
1559
- & .crisp-tabletoolbar-tool { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: var(--crisp-size-row); margin: 0; padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px var(--crisp-border-default); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; transition: background-color .12s; }
1611
+ & .crisp-tabletoolbar-tool { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: var(--crisp-size-row); margin: 0; padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px var(--crisp-border-default); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); white-space: nowrap; cursor: pointer; transition: background-color .12s; }
1560
1612
  & .crisp-tabletoolbar-tool:hover { background: var(--crisp-bg-raised); }
1561
1613
  & .crisp-tabletoolbar-tool svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
1562
1614
  & .crisp-tabletoolbar-tool--active { background: var(--crisp-bg-raised); }
@@ -2088,27 +2140,46 @@
2088
2140
  & .crisp-recordpage-field-label svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
2089
2141
  & .crisp-recordpage-field-label-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2090
2142
  & .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); }
2143
+ & .crisp-recordpage-field-value[data-editable] { cursor: pointer; }
2144
+ /* the click-to-edit trigger is a real <button> (keyboard-operable),
2145
+ reset back to plain inline text and made a flex-wrap container of its
2146
+ own -- FieldValue can render several chips (tags), which still need
2147
+ to wrap the way they did before this had a button around them at
2148
+ all. It wraps only FieldValue, never the error slot beside it (see
2149
+ the component's own comment) -- NOT `display: contents`, which drops a button's accessible semantics in some engines. */
2150
+ & .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; }
2091
2151
  & .crisp-recordpage-empty { color: var(--crisp-fg-muted); }
2152
+
2153
+ /* #431: measured live on app.attio.com's record page Details column -- clicking a field's value opens a plain, borderless field exactly
2154
+ filling the value's own box (no border, no background, no box-shadow), same font as the value it replaces (hence `font: inherit`, not a restated size/weight). A field row's own hover tint
2155
+ above already carries the "this is interactive" affordance; the
2156
+ pending/error treatment isn't Attio-measured -- it reuses the same tokens DataTable's identical states already use (opacity 0.5,
2157
+ `bgDanger`), per #385/#430. */
2158
+ & .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; }
2159
+ /* not Attio-measured (its own field shows no focus ring either, caret
2160
+ only) -- kept for real keyboard users, the same brand ring every
2161
+ other crisp field already shows on focus (DataTable's identical .crisp-datatable-edit:focus, e.g.). */
2162
+ & .crisp-recordpage-edit:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
2163
+ & .crisp-recordpage-edit:disabled { opacity: 0.5; cursor: not-allowed; }
2164
+ & .crisp-recordpage-edit-pending { flex-shrink: 0; color: var(--crisp-fg-muted); }
2165
+ & .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); }
2166
+ & .crisp-recordpage-edit-picker { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; }
2167
+ & .crisp-recordpage-edit-picker .crisp-select-trigger { flex: 1; min-width: 0; }
2092
2168
  & .crisp-recordpage-link { color: var(--crisp-fg-primary); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
2093
2169
  & .crisp-recordpage-link:hover { text-decoration: underline; }
2094
2170
  & .crisp-recordpage-emptystate { padding: var(--crisp-space-2) var(--crisp-space-1); font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
2095
-
2096
2171
  & .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); }
2097
-
2098
2172
  & .crisp-recordpage-panel { padding-top: var(--crisp-space-4); display: flex; flex-direction: column; gap: var(--crisp-space-4); }
2099
2173
  & .crisp-recordpage-card { border: 1px solid var(--crisp-border-subtle); border-radius: var(--crisp-radius-2xl); background: var(--crisp-bg-surface); overflow: hidden; }
2100
2174
  & .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); }
2101
2175
  & .crisp-recordpage-hl-card { border: 1px solid var(--crisp-border-subtle); border-radius: var(--crisp-radius-2xl); overflow: hidden; }
2102
- /* gap-as-gridlines: a 1px gap over the border colour draws dividers at any
2103
- column count, so the grid stays responsive (auto-fit) without per-cell
2104
- nth-child border hacks that break when the column count changes. */
2176
+ /* 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. */
2105
2177
  & .crisp-recordpage-hl-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1px; background: var(--crisp-border-subtle); }
2106
2178
  & .crisp-recordpage-hl-cell { position: relative; min-height: 84px; padding: var(--crisp-space-2-5) var(--crisp-space-3); background: var(--crisp-bg-surface); }
2107
2179
  & .crisp-recordpage-hl-icon { position: absolute; top: var(--crisp-space-2-5); inset-inline-end: var(--crisp-space-3); color: var(--crisp-fg-muted); }
2108
2180
  & .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); }
2109
2181
  & .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); }
2110
2182
  & .crisp-recordpage-hl-value--empty { color: var(--crisp-fg-muted); font-weight: var(--crisp-weight-regular); }
2111
-
2112
2183
  & .crisp-recordpage-feed { display: flex; flex-direction: column; }
2113
2184
  & .crisp-recordpage-feed-item { display: flex; align-items: flex-start; gap: var(--crisp-space-2-5); padding: var(--crisp-space-2) 0; }
2114
2185
  & .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); }
@@ -2117,7 +2188,6 @@
2117
2188
  & .crisp-recordpage-feed-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); margin-top: 2px; }
2118
2189
  & .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; }
2119
2190
  & .crisp-recordpage-feed-more:hover { text-decoration: underline; }
2120
-
2121
2191
  & .crisp-recordpage-section-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-1); }
2122
2192
  & .crisp-recordpage-section-head .crisp-recordpage-section-title { padding: 0; }
2123
2193
  & .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); }
@@ -2125,7 +2195,6 @@
2125
2195
  & .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; }
2126
2196
  & .crisp-recordpage-addbtn:hover { background: var(--crisp-bg-raised); }
2127
2197
  & .crisp-recordpage-addbtn svg { flex-shrink: 0; }
2128
-
2129
2198
  & .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); }
2130
2199
  & .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); }
2131
2200
  & .crisp-recordpage-composer textarea:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); border-radius: var(--crisp-radius-md); }
@@ -2135,23 +2204,18 @@
2135
2204
  & .crisp-recordpage-btn:hover { background: var(--crisp-bg-raised); }
2136
2205
  & .crisp-recordpage-btn--primary { box-shadow: none; background: var(--crisp-bg-brand-solid); color: var(--crisp-fg-on-brand); }
2137
2206
  & .crisp-recordpage-btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }
2138
-
2139
2207
  & .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); }
2140
2208
  & .crisp-recordpage-note-body { flex: 1; min-width: 0; }
2141
2209
  & .crisp-recordpage-note-head { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-bottom: var(--crisp-space-0-5); }
2142
2210
  & .crisp-recordpage-note-author { font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
2143
2211
  & .crisp-recordpage-note-time { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
2144
2212
  & .crisp-recordpage-note-text { font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); white-space: pre-wrap; word-break: break-word; }
2145
-
2146
2213
  & .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); }
2147
2214
  & .crisp-recordpage-task-text { flex: 1; min-width: 0; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); padding-top: 1px; }
2148
2215
  & .crisp-recordpage-task[data-done] .crisp-recordpage-task-text { text-decoration: line-through; color: var(--crisp-fg-muted); }
2149
-
2150
2216
  & .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; }
2151
2217
  & .crisp-recordpage-emptycard svg { color: var(--crisp-fg-muted); opacity: 0.7; }
2152
-
2153
2218
  & .crisp-recordpage-action[data-active] svg { color: #f5b83d; fill: #f5b83d; }
2154
-
2155
2219
  & .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); }
2156
2220
  & .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)); }
2157
2221
  & .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)); }
@@ -2174,35 +2238,58 @@
2174
2238
  position: absolute; top: var(--crisp-space-2); inset-inline-end: var(--crisp-space-2); bottom: var(--crisp-space-2); z-index: 20; display: flex; flex-direction: column; overflow: hidden; width: 420px; max-width: calc(92% - var(--crisp-space-2)); background: var(--crisp-bg-surface); border-radius: var(--crisp-radius-xl); 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); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; transform: translateX(0); transition: transform .2s ease;
2175
2239
  @starting-style { transform: translateX(calc(100% + var(--crisp-space-2))); }
2176
2240
  & * { box-sizing: border-box; }
2177
- & .crisp-recordpanel-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 52px; flex-shrink: 0; padding: 0 var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); }
2241
+ /* #448: measured live on app.attio.com's peek -- a toolbar row above
2242
+ the identity header: Close, then Previous/Next, on the left; "Open
2243
+ record" on the right. 49px tall, 8px/10px padding, a hairline border
2244
+ beneath (the same borderSubtle every other panel/row edge here
2245
+ already uses). Close keeps the existing transparent ghost button;
2246
+ Previous/Next/Open record are a distinct field-elevation style
2247
+ (white fill, e.field's own ring+shadow, solid icon) -- measured as genuinely different chrome from Close, not a reuse. */
2248
+ & .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); }
2249
+ & .crisp-recordpanel-toolbar-spacer { flex: 1; }
2250
+ & .crisp-recordpanel-pager { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-inline-start: var(--crisp-space-3); }
2251
+ & .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; }
2252
+ & .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
2253
+ & .crisp-recordpanel-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; }
2254
+ & .crisp-recordpanel-navbtn:hover:not(:disabled) { background: var(--crisp-bg-raised); }
2255
+ & .crisp-recordpanel-navbtn:disabled { opacity: 0.4; cursor: not-allowed; }
2256
+ & .crisp-recordpanel-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 52px; flex-shrink: 0; padding: 0 var(--crisp-space-3); }
2178
2257
  & .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); }
2179
2258
  & .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; }
2180
- & .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: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; transition: background-color .12s; }
2181
- & .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
2182
2259
  & .crisp-recordpanel-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-2) var(--crisp-space-3); }
2183
- & .crisp-recordpanel-sectionlabel { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); padding: var(--crisp-space-2) var(--crisp-space-1) var(--crisp-space-1); }
2184
- & .crisp-recordpanel-field { display: flex; align-items: flex-start; gap: var(--crisp-space-2); min-height: 32px; padding: var(--crisp-space-1) var(--crisp-space-1); border-radius: var(--crisp-radius-md); }
2185
- & .crisp-recordpanel-field:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 3%, transparent); }
2186
- & .crisp-recordpanel-field-label { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 132px; flex-shrink: 0; padding-top: 3px; color: var(--crisp-fg-muted); font-size: var(--crisp-text-md); }
2187
- & .crisp-recordpanel-field-label svg { flex-shrink: 0; }
2188
- & .crisp-recordpanel-field-value { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--crisp-space-1); padding-top: 3px; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
2189
- & .crisp-recordpanel-empty { color: var(--crisp-fg-muted); }
2190
- & .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); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
2191
- & .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)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent); }
2192
- & .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)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-success) 30%, transparent); }
2193
- & .crisp-recordstable-tag[data-tone="warning"] { background: color-mix(in srgb, var(--crisp-bg-warning) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-warning) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-warning) 30%, transparent); }
2194
- & .crisp-recordstable-tag[data-tone="danger"] { background: color-mix(in srgb, var(--crisp-bg-danger) 15%, transparent); color: color-mix(in srgb, var(--crisp-bg-danger) 80%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-danger) 30%, transparent); }
2195
- & .crisp-recordstable-tag[data-tone="purple"] { background: color-mix(in srgb, var(--crisp-bg-purple) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-purple) 80%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-purple) 30%, transparent); }
2196
- & .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-cyan) 30%, transparent); }
2197
- & .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-orange) 30%, transparent); }
2198
- & .crisp-recordpanel-link { color: var(--crisp-bg-brand-solid); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
2199
- & .crisp-recordpanel-link:hover { text-decoration: underline; }
2260
+ /* #448: measured live on app.attio.com's peek (hover a Companies row,
2261
+ click "Open preview"). Section label reads identically for both
2262
+ Highlights and Activity: 14px/500, the same 63%-of-fgPrimary mix
2263
+ RecordPage's own field-label already uses (product/recordpage's
2264
+ .crisp-recordpage-field-label) -- one more surface landing on the
2265
+ same measured "muted section heading" colour. */
2266
+ & .crisp-recordpanel-section { padding: var(--crisp-space-2) var(--crisp-space-1) 0; }
2267
+ & .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); }
2268
+ & .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); }
2269
+ /* "View all" -- measured 10px/400, a lighter mix than the section label
2270
+ (55%, not 63%) -- its own distinct, honestly-measured value, not a
2271
+ reuse of a nearby one that happened to be close. */
2272
+ & .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; }
2273
+ & .crisp-recordpanel-section-action:hover { color: var(--crisp-fg-primary); }
2274
+
2275
+ /* Highlights: a 2-column grid of label+icon+value cards, no card
2276
+ chrome at all (no border/background/radius/shadow -- confirmed on
2277
+ the live DOM: every highlight's computed style is fully transparent). 8px row/column gap; two rows measured "233x86" inside 473px content width is exactly (473 - 8) / 2. */
2278
+ & .crisp-recordpanel-highlights { display: grid; grid-template-columns: 1fr 1fr; gap: var(--crisp-space-2); }
2279
+ & .crisp-recordpanel-highlight { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); min-width: 0; }
2280
+ & .crisp-recordpanel-highlight-label { display: flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
2281
+ & .crisp-recordpanel-highlight-label span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2282
+ & .crisp-recordpanel-highlight-label svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
2283
+ & .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; }
2284
+ /* Activity is a consumer-supplied slot (crisp has no activity-feed model of its own to render) -- this only wraps it with the measured section heading above. */
2285
+ & .crisp-recordpanel-activity { font-size: var(--crisp-text-lg); }
2200
2286
  /* #329: an optional slot for record actions (e.g. Edit). Reuses the header's own measured values rather than inventing new ones -- the
2201
2287
  same horizontal inset (space.3), the same hairline border token
2202
2288
  (borderSubtle, flipped to border-top since this sits at the opposite
2203
2289
  edge), and the header/body gap (space.2) for its own vertical padding
2204
2290
  and for spacing between whatever it's given. */
2205
2291
  & .crisp-recordpanel-footer { flex-shrink: 0; display: flex; align-items: center; gap: var(--crisp-space-2); padding: var(--crisp-space-2) var(--crisp-space-3); border-top: 1px solid var(--crisp-border-subtle); }
2292
+ [dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
2206
2293
  }
2207
2294
 
2208
2295
  @media (prefers-reduced-motion: reduce) {
@@ -2223,7 +2310,7 @@
2223
2310
  & .crisp-recordstable-search svg { flex-shrink: 0; }
2224
2311
  & .crisp-recordstable-search input { border: none; outline: none; background: transparent; font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); width: 180px; }
2225
2312
  & .crisp-recordstable-search input::placeholder { color: var(--crisp-fg-muted); }
2226
- & .crisp-recordstable-tool { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: var(--crisp-size-row); margin: 0; padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px var(--crisp-border-default); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; transition: background-color .12s; }
2313
+ & .crisp-recordstable-tool { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: var(--crisp-size-row); margin: 0; padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: transparent; box-shadow: inset 0 0 0 1px var(--crisp-border-default); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); white-space: nowrap; cursor: pointer; transition: background-color .12s; }
2227
2314
  & .crisp-recordstable-tool:hover { background: var(--crisp-bg-raised); }
2228
2315
  & .crisp-recordstable-tool svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
2229
2316
  & .crisp-recordstable-tool--active { background: var(--crisp-bg-raised); }
@@ -2327,6 +2414,13 @@
2327
2414
  & .crisp-recordstable-td--picker .crisp-multiselect-chips .crisp-recordstable-tag { flex-shrink: 0; max-width: none; }
2328
2415
  & .crisp-recordstable-td--picker .crisp-multiselect-chevron { display: none; }
2329
2416
  & .crisp-recordstable-td--picker .crisp-multiselect-placeholder { color: var(--crisp-fg-muted); }
2417
+ /* reference picker: a leading 16px avatar per option, plus a trailing
2418
+ "Create X" row when the consumer supplies one (#449) -- measured live
2419
+ against Attio's own picker (16px circular avatar, 16px plain icon for the create row, both sitting in the option's existing 8px gap, no new
2420
+ gap value invented). */
2421
+ & .crisp-recordstable-refoption { display: flex; align-items: center; gap: var(--crisp-space-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
2422
+ & .crisp-recordstable-refoption-avatar { flex-shrink: 0; }
2423
+ & .crisp-recordstable-refoption--create { color: var(--crisp-fg-muted); }
2330
2424
  & .crisp-recordstable-status { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; }
2331
2425
  & .crisp-recordstable-status-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: var(--crisp-radius-full); }
2332
2426
  & .crisp-recordstable-cell { display: flex; align-items: center; gap: var(--crisp-space-2); height: 100%; min-width: 0; }
@@ -2392,7 +2486,7 @@
2392
2486
  & .crisp-recordstable-empty { display: flex; align-items: center; justify-content: center; min-height: 320px; padding: var(--crisp-space-8) var(--crisp-space-4); }
2393
2487
 
2394
2488
  /* summary footer — per-column aggregation, sticky to the bottom */
2395
- & .crisp-recordstable-sum { position: sticky; bottom: 0; z-index: 2; height: var(--crisp-size-tableRow); padding: 0; border-top: 1px solid var(--crisp-border-subtle); border-inline-end: 1px solid var(--crisp-border-subtle); background: var(--crisp-bg-surface); }
2489
+ & .crisp-recordstable-sum { position: sticky; bottom: 0; z-index: 2; height: var(--crisp-size-tableRow); padding: 0; border-top: 1px solid var(--crisp-border-subtle); border-bottom: 1px solid var(--crisp-border-subtle); border-inline-end: 1px solid var(--crisp-border-subtle); background: var(--crisp-bg-surface); }
2396
2490
  & tfoot .crisp-recordstable-col-check, & tfoot .crisp-recordstable-col-entity { position: sticky; bottom: 0; z-index: 3; }
2397
2491
  & .crisp-recordstable-sum:last-child { border-inline-end: none; }
2398
2492
  & .crisp-recordstable-sum-btn { display: flex; align-items: center; justify-content: flex-end; gap: var(--crisp-space-1-5); width: 100%; height: 100%; margin: 0; padding: 0 var(--crisp-space-3); border: none; background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); cursor: pointer; white-space: nowrap; overflow: hidden; }
@@ -2443,12 +2537,38 @@
2443
2537
  & .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); }
2444
2538
  & .crisp-rte-body a { color: var(--crisp-bg-brand-solid); text-decoration: underline; text-underline-offset: 2px; }
2445
2539
  & .crisp-rte-body strong { font-weight: var(--crisp-weight-semibold); }
2446
- & .crisp-rte-toolbar { position: fixed; z-index: 70; display: inline-flex; align-items: center; gap: 2px; padding: var(--crisp-space-0-5); border-radius: var(--crisp-radius-md); background: #20242c; box-shadow: 0 8px 28px -6px rgba(0,0,0,0.36), 0 2px 6px -2px rgba(0,0,0,0.24); transform: translate(-50%, -100%); opacity: 1; transition: opacity 0.1s ease; }
2540
+ & .crisp-rte-body img { display: block; max-width: 100%; border-radius: var(--crisp-radius-md); }
2541
+ /* Not measured against Attio (#428) — nothing in a read-only pass over app.attio.com had a live @mention rendered to read computed styles from, and typing one to create one is off-limits there. Reused verbatim from the one measured "brand" tag/chip this repo already has (RecordsTable/MultiSelect's [data-tone="brand"]) rather than
2542
+ inventing a new color or shape. */
2543
+ & .crisp-rte-mention { display: inline; border-radius: var(--crisp-radius-chip); padding: 0 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; }
2544
+
2545
+ & .crisp-rte-toolbar { position: fixed; z-index: 70; display: inline-flex; align-items: center; gap: 2px; padding: 2px; border-radius: 10px; background: var(--crisp-bg-surface); 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); transform: translate(-50%, -100%); opacity: 1; transition: opacity 0.1s ease; }
2447
2546
  & .crisp-rte-toolbar { @starting-style { opacity: 0; } }
2448
- & .crisp-rte-tool { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; margin: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; color: rgba(255,255,255,0.86); font-family: inherit; cursor: pointer; transition: background-color .1s; }
2449
- & .crisp-rte-tool:hover { background: rgba(255,255,255,0.12); color: #fff; }
2450
- & .crisp-rte-tool[data-active] { color: var(--crisp-bg-brand-solid); }
2451
- & .crisp-rte-tool-sep { width: 1px; height: 16px; margin: 0 2px; background: rgba(255,255,255,0.16); }
2547
+ & .crisp-rte-tool { display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); min-width: 30px; height: 28px; padding: 0 7px; margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); font-family: inherit; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); cursor: pointer; transition: background-color .1s; }
2548
+ & .crisp-rte-tool--labelled { width: auto; }
2549
+ & .crisp-rte-tool:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
2550
+ & .crisp-rte-tool[data-active], & .crisp-rte-tool[aria-expanded="true"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); }
2551
+ & .crisp-rte-tool-sep { width: 1px; height: 16px; margin: 0 2px; background: var(--crisp-border-subtle); }
2552
+
2553
+ & .crisp-rte-swatchpanel { position: fixed; z-index: 71; display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--crisp-space-1); width: 168px; padding: var(--crisp-space-1-5); border-radius: var(--crisp-radius-lg); background: var(--crisp-bg-surface); 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); transform: translate(-50%, var(--crisp-space-1-5)); opacity: 1; transition: opacity 0.1s ease; }
2554
+ & .crisp-rte-swatchpanel { @starting-style { opacity: 0; } }
2555
+ & .crisp-rte-swatch { width: 28px; height: 28px; padding: 0; margin: 0; border: none; border-radius: 50%; background: none; font-family: inherit; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 10%, transparent); cursor: pointer; }
2556
+ & .crisp-rte-swatch--none { background: var(--crisp-bg-surface); position: relative; }
2557
+ & .crisp-rte-swatch--none::after { content: ""; position: absolute; inset: 6px; border-top: 1.5px solid color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); transform: rotate(-45deg); }
2558
+
2559
+ & .crisp-rte-blockmenu { position: fixed; z-index: 71; box-sizing: border-box; width: 356px; padding: 0; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); 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); opacity: 1; transition: opacity 0.1s ease; }
2560
+ & .crisp-rte-blockmenu { @starting-style { opacity: 0; } }
2561
+ & .crisp-rte-blockmenu-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-2-5) var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
2562
+ & .crisp-rte-blockmenu-input { flex: 1; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); height: 20px; color: var(--crisp-fg-primary); }
2563
+ & .crisp-rte-blockmenu-input::placeholder { color: color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); }
2564
+ & .crisp-rte-blockmenu-list { display: flex; flex-direction: column; padding: var(--crisp-space-1-5); gap: var(--crisp-space-px); }
2565
+ & .crisp-rte-blockmenu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: 52px; padding: var(--crisp-space-1-5) var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; font-family: inherit; text-align: start; cursor: pointer; }
2566
+ & .crisp-rte-blockmenu-item svg { flex-shrink: 0; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
2567
+ & .crisp-rte-blockmenu-item[data-highlighted] { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
2568
+ & .crisp-rte-blockmenu-item-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
2569
+ & .crisp-rte-blockmenu-item-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
2570
+ & .crisp-rte-blockmenu-item-desc { font-size: var(--crisp-text-sm); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
2571
+ & .crisp-rte-blockmenu-empty { padding: var(--crisp-space-4) var(--crisp-space-3); text-align: center; font-size: var(--crisp-text-md); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
2452
2572
  }
2453
2573
 
2454
2574
  @media (prefers-reduced-motion: reduce) {
@@ -2470,8 +2590,8 @@
2470
2590
  }
2471
2591
 
2472
2592
  .crisp-settingsshell {
2473
- display: flex; min-height: 0; box-sizing: border-box; font-family: var(--crisp-font-sans); color: var(--crisp-fg-primary); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
2474
- & .crisp-settingsshell-nav { display: flex; flex-direction: column; width: 256px; flex-shrink: 0; min-height: 0; padding: var(--crisp-space-3); border-inline-end: 1px solid var(--crisp-border-subtle); }
2593
+ display: flex; height: 100%; min-height: 0; box-sizing: border-box; font-family: var(--crisp-font-sans); color: var(--crisp-fg-primary); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
2594
+ & .crisp-settingsshell-nav { display: flex; flex-direction: column; width: 275px; flex-shrink: 0; min-height: 0; padding: var(--crisp-space-3); border-inline-end: 1px solid var(--crisp-border-subtle); }
2475
2595
  & .crisp-settingsshell-back { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: 28px; padding: 0 var(--crisp-space-1); margin: 0 0 var(--crisp-space-2); border: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); cursor: pointer; border-radius: var(--crisp-radius-md); }
2476
2596
  & .crisp-settingsshell-back svg { color: var(--crisp-fg-muted); }
2477
2597
  & .crisp-settingsshell-back:hover svg { color: var(--crisp-fg-primary); }
@@ -2507,6 +2627,9 @@
2507
2627
  }
2508
2628
  }
2509
2629
 
2630
+
2631
+ .crisp-sidebar-ws-menu-content { width: 280px; }
2632
+
2510
2633
  .crisp-sidebar {
2511
2634
  box-sizing: border-box; display: flex; flex-direction: column; width: 275px; height: 100%; background: var(--crisp-bg-sidebar); border-inline-end: 1px solid var(--crisp-border-subtle); padding: var(--crisp-space-2); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; overflow-y: auto;
2512
2635
  & .crisp-sidebar-section { display: flex; flex-direction: column; gap: var(--crisp-space-px); margin-top: var(--crisp-space-2); }
@@ -2515,10 +2638,12 @@
2515
2638
  & .crisp-sidebar-section-header { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; margin: 0; border: none; background: none; padding: var(--crisp-space-1-5) var(--crisp-space-2) var(--crisp-space-0-5); font-family: var(--crisp-font-sans); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); cursor: pointer; }
2516
2639
  & .crisp-sidebar-section-header svg { flex-shrink: 0; transition: transform .15s ease; }
2517
2640
  & .crisp-sidebar-section-header[data-collapsed] svg { transform: rotate(-90deg); }
2518
- & .crisp-sidebar-ws { display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-header); padding: 0 var(--crisp-space-2); border-radius: var(--crisp-radius-lg); cursor: pointer; transition: background-color 0.16s; }
2641
+ & .crisp-sidebar-ws-row { display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-header); padding: 0 var(--crisp-space-2); }
2642
+ & .crisp-sidebar-ws-menuroot { display: flex; flex: 1; min-width: 0; }
2643
+ & .crisp-sidebar-ws { box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-2); flex: 1; min-width: 0; height: 100%; margin: 0; padding: 0; border: none; background: none; border-radius: var(--crisp-radius-lg); font-family: inherit; font-size: inherit; color: inherit; text-align: start; cursor: pointer; transition: background-color 0.16s; }
2519
2644
  & .crisp-sidebar-ws:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 5%, transparent); }
2520
2645
  & .crisp-sidebar-ws-name { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2521
- & .crisp-sidebar-ws-collapse { margin-inline-start: auto; }
2646
+ & .crisp-sidebar-ws-collapse { flex-shrink: 0; }
2522
2647
  & .crisp-sidebar-searchrow { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-top: var(--crisp-space-2-5); padding-inline-end: var(--crisp-space-2); }
2523
2648
  & .crisp-sidebar-footer { margin-top: auto; display: flex; flex-direction: column; gap: var(--crisp-space-0-5); }
2524
2649
  & .crisp-sidebar-trial { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); padding: var(--crisp-space-1-5) var(--crisp-space-2); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }