@crisp-ui-kit/crisp 0.54.6 → 0.54.8

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 (113) hide show
  1. package/dist/authshell.css +5 -1
  2. package/dist/authshell.layered.css +5 -1
  3. package/dist/badge.css +5 -5
  4. package/dist/badge.layered.css +5 -5
  5. package/dist/board.css +13 -9
  6. package/dist/board.layered.css +13 -9
  7. package/dist/button.css +3 -1
  8. package/dist/button.layered.css +3 -1
  9. package/dist/cjs/components/badge/badge.recipe.js +28 -5
  10. package/dist/cjs/components/button/button.js +33 -2
  11. package/dist/cjs/components/button/button.recipe.js +31 -5
  12. package/dist/cjs/components/datatable/datatable.js +66 -7
  13. package/dist/cjs/components/datatable/datatable.recipe.js +57 -2
  14. package/dist/cjs/components/dialog/dialog.js +8 -5
  15. package/dist/cjs/components/dialog/dialog.recipe.js +15 -1
  16. package/dist/cjs/components/tabletoolbar/tabletoolbar.chrome.js +19 -1
  17. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +239 -50
  18. package/dist/cjs/components/tabletoolbar/tabletoolbar.recipe.js +44 -0
  19. package/dist/cjs/components/tabs/tabs.recipe.js +11 -2
  20. package/dist/cjs/components/tooltip/tooltip.js +23 -9
  21. package/dist/cjs/components/tooltip/tooltip.recipe.js +10 -9
  22. package/dist/cjs/product/authshell/authshell.js +14 -1
  23. package/dist/cjs/product/authshell/authshell.recipe.js +13 -1
  24. package/dist/cjs/product/board/board.js +122 -27
  25. package/dist/cjs/product/board/board.recipe.js +14 -2
  26. package/dist/cjs/product/comments/comments.js +23 -10
  27. package/dist/cjs/product/comments/comments.recipe.js +17 -3
  28. package/dist/cjs/product/formdialog/formdialog.js +10 -4
  29. package/dist/cjs/product/navitem/navitem.js +7 -2
  30. package/dist/cjs/product/navitem/navitem.recipe.js +16 -0
  31. package/dist/cjs/product/objectsettings/index.js +1 -2
  32. package/dist/cjs/product/objectsettings/objectsettings.js +3 -13
  33. package/dist/cjs/product/richtext/richtext.js +76 -1
  34. package/dist/cjs/product/sidebar/sidebar.js +68 -15
  35. package/dist/cjs/product/sidebar/sidebar.recipe.js +6 -1
  36. package/dist/cjs/tokens/palette.js +32 -1
  37. package/dist/cjs/tokens/semantic.js +11 -0
  38. package/dist/comments.css +36 -10
  39. package/dist/comments.layered.css +36 -10
  40. package/dist/datatable.css +47 -9
  41. package/dist/datatable.layered.css +47 -9
  42. package/dist/dialog.css +13 -1
  43. package/dist/dialog.layered.css +13 -1
  44. package/dist/esm/components/badge/badge.recipe.js +28 -5
  45. package/dist/esm/components/button/button.js +34 -3
  46. package/dist/esm/components/button/button.recipe.js +31 -5
  47. package/dist/esm/components/datatable/datatable.js +67 -8
  48. package/dist/esm/components/datatable/datatable.recipe.js +57 -2
  49. package/dist/esm/components/dialog/dialog.js +8 -5
  50. package/dist/esm/components/dialog/dialog.recipe.js +15 -1
  51. package/dist/esm/components/tabletoolbar/tabletoolbar.chrome.js +19 -1
  52. package/dist/esm/components/tabletoolbar/tabletoolbar.js +240 -51
  53. package/dist/esm/components/tabletoolbar/tabletoolbar.recipe.js +44 -0
  54. package/dist/esm/components/tabs/tabs.recipe.js +11 -2
  55. package/dist/esm/components/tooltip/tooltip.js +23 -9
  56. package/dist/esm/components/tooltip/tooltip.recipe.js +10 -9
  57. package/dist/esm/product/authshell/authshell.js +15 -2
  58. package/dist/esm/product/authshell/authshell.recipe.js +13 -1
  59. package/dist/esm/product/authshell/index.js +1 -1
  60. package/dist/esm/product/board/board.js +122 -27
  61. package/dist/esm/product/board/board.recipe.js +14 -2
  62. package/dist/esm/product/comments/comments.js +23 -10
  63. package/dist/esm/product/comments/comments.recipe.js +17 -3
  64. package/dist/esm/product/formdialog/formdialog.js +10 -4
  65. package/dist/esm/product/navitem/index.js +1 -1
  66. package/dist/esm/product/navitem/navitem.js +7 -2
  67. package/dist/esm/product/navitem/navitem.recipe.js +16 -0
  68. package/dist/esm/product/objectsettings/index.js +1 -1
  69. package/dist/esm/product/objectsettings/objectsettings.js +2 -12
  70. package/dist/esm/product/richtext/richtext.js +76 -1
  71. package/dist/esm/product/sidebar/sidebar.js +69 -16
  72. package/dist/esm/product/sidebar/sidebar.recipe.js +6 -1
  73. package/dist/esm/tokens/palette.js +32 -1
  74. package/dist/esm/tokens/semantic.js +11 -0
  75. package/dist/native/tokens.d.ts +1 -1
  76. package/dist/native/tokens.js +16 -2
  77. package/dist/navitem.css +7 -0
  78. package/dist/navitem.layered.css +7 -0
  79. package/dist/recordstable.css +2 -1
  80. package/dist/recordstable.layered.css +2 -1
  81. package/dist/sidebar.css +6 -1
  82. package/dist/sidebar.layered.css +6 -1
  83. package/dist/styles.css +165 -42
  84. package/dist/styles.layered.css +165 -42
  85. package/dist/tabletoolbar.css +17 -1
  86. package/dist/tabletoolbar.layered.css +17 -1
  87. package/dist/tabs.css +1 -1
  88. package/dist/tabs.layered.css +1 -1
  89. package/dist/tokens.css +9 -1
  90. package/dist/tokens.json +16 -2
  91. package/dist/tooltip.css +1 -1
  92. package/dist/tooltip.layered.css +1 -1
  93. package/dist/types/components/badge/badge.recipe.d.ts +5 -1
  94. package/dist/types/components/button/button.recipe.d.ts +18 -5
  95. package/dist/types/components/datatable/datatable.d.ts +9 -0
  96. package/dist/types/components/dialog/dialog.d.ts +25 -2
  97. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +47 -5
  98. package/dist/types/components/tooltip/tooltip.d.ts +12 -4
  99. package/dist/types/components/tooltip/tooltip.recipe.d.ts +1 -1
  100. package/dist/types/product/authshell/authshell.d.ts +26 -2
  101. package/dist/types/product/authshell/index.d.ts +1 -1
  102. package/dist/types/product/board/board.d.ts +5 -4
  103. package/dist/types/product/comments/comments.d.ts +10 -2
  104. package/dist/types/product/formdialog/formdialog.d.ts +2 -1
  105. package/dist/types/product/navitem/index.d.ts +1 -1
  106. package/dist/types/product/navitem/navitem.d.ts +23 -0
  107. package/dist/types/product/objectsettings/index.d.ts +1 -1
  108. package/dist/types/product/objectsettings/objectsettings.d.ts +0 -10
  109. package/dist/types/product/sidebar/sidebar.d.ts +33 -5
  110. package/dist/types/tokens/contract.d.ts +4 -0
  111. package/dist/types/tokens/palette.d.ts +13 -1
  112. package/dist/types/tokens/semantic.d.ts +11 -0
  113. package/package.json +1 -1
package/dist/styles.css CHANGED
@@ -5,14 +5,18 @@
5
5
  --crisp-fg-on-tone: #101112;
6
6
  --crisp-bg-surface: #ffffff;
7
7
  --crisp-bg-raised: #f4f4f5;
8
+ --crisp-bg-surface-muted: #f6f7f7;
8
9
  --crisp-border-default: #e4e4e7;
9
10
  --crisp-border-subtle: #eeeff1;
10
11
  --crisp-border-dropzone: #e6e7ea;
12
+ --crisp-border-divider: #e6e7ea;
11
13
  --crisp-ring-neutral: transparent;
12
14
  --crisp-ring-field: rgba(0,0,0,0.06);
13
15
  --crisp-ring-switch: #d9dade;
14
16
  --crisp-bg-tile-active: #ffffff;
15
17
  --crisp-shadow-tile-active: rgba(0,0,0,0.04);
18
+ --crisp-bg-scrim: rgba(0,0,0,0.25);
19
+ --crisp-fg-alert-description: rgba(0,0,0,0.63);
16
20
  --crisp-bg-overlay-frost: #ffffff;
17
21
  --crisp-shadow-overlay1: rgba(28,40,64,0.12);
18
22
  --crisp-shadow-overlay2: rgba(28,40,64,0.16);
@@ -46,7 +50,7 @@
46
50
  --crisp-fg-success-soft: #186b3d;
47
51
  --crisp-fg-warning-soft: #80520d;
48
52
  --crisp-fg-danger-soft: #a33539;
49
- --crisp-fg-neutral-soft: #686870;
53
+ --crisp-fg-neutral-soft: #505155;
50
54
  --crisp-bg-purple-soft: #f5f0ff;
51
55
  --crisp-fg-purple-soft: #6238b5;
52
56
  --crisp-ring-purple-soft: #e8ddfe;
@@ -59,14 +63,18 @@
59
63
  --crisp-fg-on-tone: #101112;
60
64
  --crisp-bg-surface: #0a0a0a;
61
65
  --crisp-bg-raised: #101112;
66
+ --crisp-bg-surface-muted: #101112;
62
67
  --crisp-border-default: #212224;
63
68
  --crisp-border-subtle: #1c1d1f;
64
69
  --crisp-border-dropzone: #212224;
70
+ --crisp-border-divider: #212224;
65
71
  --crisp-ring-neutral: #212224;
66
72
  --crisp-ring-field: #212224;
67
73
  --crisp-ring-switch: #212224;
68
74
  --crisp-bg-tile-active: #101112;
69
75
  --crisp-shadow-tile-active: rgba(0,0,0,0);
76
+ --crisp-bg-scrim: rgba(0,0,0,0.55);
77
+ --crisp-fg-alert-description: rgba(255,255,255,0.6);
70
78
  --crisp-bg-overlay-frost: #1c1d1f;
71
79
  --crisp-shadow-overlay1: rgba(0,0,0,0.48);
72
80
  --crisp-shadow-overlay2: rgba(0,0,0,0.64);
@@ -216,11 +224,11 @@
216
224
  }
217
225
 
218
226
  .crisp-badge {
219
- display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); font-family: var(--crisp-font-sans); font-weight: var(--crisp-weight-medium); letter-spacing: -0.1px; white-space: nowrap;
227
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); font-family: var(--crisp-font-sans); font-weight: var(--crisp-weight-medium); letter-spacing: normal; white-space: nowrap;
220
228
  & .crisp-badge-dot { width: 6px; height: 6px; flex-shrink: 0; border-radius: var(--crisp-radius-full); background: currentColor; }
221
229
  }
222
230
  .crisp-badge--tone_neutral {
223
- background: var(--crisp-bg-raised); color: var(--crisp-fg-neutral-soft); box-shadow: inset 0 0 0 1px var(--crisp-border-default);
231
+ background: var(--crisp-bg-raised); color: var(--crisp-fg-neutral-soft); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle);
224
232
  }
225
233
  .crisp-badge--tone_brand {
226
234
  background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: var(--crisp-fg-brand-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent);
@@ -238,13 +246,13 @@
238
246
  background: var(--crisp-bg-purple-soft); color: var(--crisp-fg-purple-soft); box-shadow: inset 0 0 0 1px var(--crisp-ring-purple-soft);
239
247
  }
240
248
  .crisp-badge--size_small {
241
- height: 16px; padding-inline: var(--crisp-space-1-5); font-size: var(--crisp-text-xs); border-radius: var(--crisp-radius-sm);
249
+ height: 16px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; border-radius: var(--crisp-radius-sm);
242
250
  }
243
251
  .crisp-badge--size_medium {
244
- height: 20px; padding-inline: var(--crisp-space-2); font-size: var(--crisp-text-sm); border-radius: var(--crisp-radius-sm);
252
+ height: 20px; padding-inline: var(--crisp-space-1); font-size: var(--crisp-text-sm); line-height: 16px; gap: 3px; border-radius: var(--crisp-radius-sm);
245
253
  }
246
254
  .crisp-badge--size_large {
247
- height: var(--crisp-size-chip); padding-inline: 9px; font-size: var(--crisp-text-lg); border-radius: var(--crisp-radius-chip);
255
+ height: var(--crisp-size-chip); padding-inline: 9px; font-size: var(--crisp-text-lg); letter-spacing: -0.1px; border-radius: var(--crisp-radius-chip);
248
256
  }
249
257
  .crisp-badge--variant_soft {
250
258
 
@@ -330,7 +338,7 @@
330
338
  }
331
339
 
332
340
  .crisp-button {
333
- display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1-5); font-family: var(--crisp-font-sans); font-weight: var(--crisp-weight-medium); letter-spacing: -0.14px; line-height: 20px; white-space: nowrap; border: none; cursor: pointer; transition: background-color .2s, box-shadow .2s, color .2s;
341
+ display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1-5); font-family: var(--crisp-font-sans); font-weight: var(--crisp-weight-medium); letter-spacing: -0.07px; line-height: 20px; white-space: nowrap; border: none; cursor: pointer; transition: background-color .2s, box-shadow .2s, color .2s;
334
342
  &:disabled { opacity: 0.5; cursor: not-allowed; }
335
343
  }
336
344
  .crisp-button--intent_primary {
@@ -356,6 +364,8 @@
356
364
  }
357
365
  .crisp-button--size_md {
358
366
  height: 28px; padding-inline: var(--crisp-space-2); font-size: var(--crisp-text-lg); border-radius: var(--crisp-radius-md);
367
+ &[data-icon-start] { padding-inline-start: var(--crisp-space-1-5); }
368
+ &[data-icon-end] { padding-inline-end: var(--crisp-space-1-5); }
359
369
  }
360
370
  .crisp-button--size_lg {
361
371
  height: 40px; padding-inline: 14px; font-size: var(--crisp-text-lg); border-radius: 10px;
@@ -574,8 +584,15 @@
574
584
  & .crisp-datatable-count { margin-inline-start: auto; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
575
585
  /* announced, never drawn */
576
586
  & .crisp-datatable-live { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
577
- /* The header cell has no padding of its own -- the button owns the full cell so the whole header is clickable (its own inset is 12px). Mirrors the summary-row fix. */
578
- & th { padding: 0; }
587
+ /* The header cell has no padding of its own -- the button owns the full cell so the whole header is clickable (its own inset is 12px). Mirrors the summary-row fix. `& .crisp-table th`, not bare `& th` (found while re-checking #691's
588
+ own fix live): DataTable's root nests `Table`'s own wrapper, whose
589
+ `table.recipe.ts` carries `& th, & td { padding: 0 12px }` at the
590
+ SAME specificity (.crisp-table th vs .crisp-datatable th, both one
591
+ class + one element) -- a bare `& th` here only won by source
592
+ order, which flipped the moment table.recipe.ts's own CSS file happened to land after datatable's in the build (alphabetical:
593
+ datatable < table), silently reinstating 12px on every header cell
594
+ in the whole product and making every interactive column's button double it to 24px. Scoping through `.crisp-table` adds a second class to the selector (0,2,1 beats 0,1,1) so this can never lose a specificity tie to source order again. */
595
+ & .crisp-table th { padding: 0; }
579
596
  /* Same wrapper trap as AUTHORING.md Lesson 40 (ColumnCalc's summary trigger):
580
597
  Menu wraps its trigger in a flex div that sizes to its content, so a
581
598
  long header grew past the column instead of filling it -- with nothing
@@ -584,6 +601,15 @@
584
601
  & th .crisp-menu { width: 100%; height: 100%; }
585
602
  & .crisp-datatable-th-inner { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; min-width: 0; height: 100%; }
586
603
  & .crisp-datatable-th-inner > svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
604
+ /* crisp/#605 follow-up: a header with neither a Menu nor a sort button (the primary/entity column's now-inert path, or any column with no
605
+ columnMenu/sortable at all) renders .crisp-datatable-th-inner as a
606
+ DIRECT child of th instead of nested inside a button -- and loses
607
+ the button's own 12px inset, drifting left of the td's 12px base
608
+ inset. Measured live on Attio's own Companies grid: the header label and the cell's own text land at the exact same x (335px from the
609
+ viewport, both 40px from the column's left edge) via two different padding+icon+gap combinations -- Attio does not leave the inert primary header flush left either. The `>` combinator targets only the button-less case: Menu's own wrapper (`.crisp-menu`) and the
610
+ plain sort `button` both put >=1 more level between `th` and this
611
+ span, so their own 12px (already on the button) isn't doubled. */
612
+ & th > .crisp-datatable-th-inner { box-sizing: border-box; padding: 0 var(--crisp-space-3); }
587
613
  /* The summary cell has NO padding of its own -- the calculation trigger owns the whole 246x37 area so a click anywhere in the cell opens the menu. Zero the cell's inset and let ColumnCalc supply the 12px. */
588
614
  & tfoot td { padding: 0; }
589
615
  /* Group heading row -- a view is grouped under a subtle label with the
@@ -654,8 +680,23 @@
654
680
  & .crisp-datatable-refoption-avatar { flex-shrink: 0; }
655
681
  & .crisp-datatable-refoption--create { color: var(--crisp-fg-muted); }
656
682
  & .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); }
683
+ /* #579: click-to-expand overlay for a truncated cell -- a read-only,
684
+ full-value card, settled live as click (not Attio's usual hover-expand) and measured position: absolute, unlike this file's
685
+ floating chrome (Menu/Select popovers) which portals and escapes the
686
+ scroll container. Deliberately NOT the edit-error pattern above
687
+ (grow the row, block-level, never clipped): a virtualized grid
688
+ assumes a fixed row height for its scroll math (owned by the grid
689
+ core, not this cell), so growing a row here would fight it. Anchored
690
+ to the SAME column width the cell itself renders at (measured:
691
+ Attio's own overlay came out only slightly wider than the triggering cell's clientWidth -- the overshoot is this padding),
692
+ wrapping onto as many lines as the value needs; it CAN be clipped by
693
+ `.crisp-table-scroll`'s own `overflow: auto` if it grows past the visible viewport, same as the edit-error comment above already notes for any position:absolute escape -- unmeasured against Attio for this exact case, flagged rather than guessed. */
694
+ & td[data-cell-expanded] { overflow: visible; z-index: 7; }
695
+ & .crisp-datatable-cell-overlay { position: absolute; inset-inline-start: 0; top: 0; width: 100%; box-sizing: border-box; padding: var(--crisp-space-2) var(--crisp-space-3); background: var(--crisp-bg-surface); border: 1px solid var(--crisp-bg-brand-solid); border-radius: 4px; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); white-space: normal; word-break: break-word; cursor: default; }
657
696
  /* fixed layout so column widths (and resize) are exact — like RecordsTable */
658
697
  & table { table-layout: fixed; }
698
+ /* read-only/computed column marker (#596) -- sits just inside the resize handle, same absolute-positioned-against-the-th approach the handle itself uses, since th has zero padding and the button/inner row fills the whole cell with no room left for a trailing sibling. */
699
+ & .crisp-datatable-readonly { position: absolute; top: 50%; inset-inline-end: 11px; transform: translateY(-50%); color: var(--crisp-fg-muted); pointer-events: none; z-index: 5; }
659
700
  /* column resize grip */
660
701
  & .crisp-datatable-resize { position: absolute; top: 0; inset-inline-end: -3px; width: 9px; height: 100%; cursor: col-resize; z-index: 6; touch-action: none; }
661
702
  & .crisp-datatable-resize::after { content: ""; position: absolute; top: 0; inset-inline-start: 3px; width: 2px; height: 100%; background: var(--crisp-bg-brand-solid); opacity: 0; transition: opacity .12s; }
@@ -666,7 +707,12 @@
666
707
  & .crisp-datatable-entity:hover .crisp-datatable-entity-name { text-decoration: underline; }
667
708
  & button.crisp-datatable-entity-name--link { margin: 0; padding: 0; border: none; background: none; font: inherit; color: inherit; letter-spacing: inherit; text-align: start; cursor: pointer; max-width: 100%; }
668
709
  & .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); }
669
- & .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); }
710
+ & .crisp-datatable-avatar[data-tone="success"] { background: var(--crisp-bg-success); }
711
+ & .crisp-datatable-avatar[data-tone="warning"] { background: var(--crisp-bg-warning); }
712
+ & .crisp-datatable-avatar[data-tone="danger"] { background: var(--crisp-bg-danger); }
713
+ & .crisp-datatable-avatar[data-tone="purple"] { background: var(--crisp-bg-purple); }
714
+ & .crisp-datatable-avatar[data-tone="cyan"] { background: var(--crisp-bg-cyan); }
715
+ & .crisp-datatable-avatar[data-tone="orange"] { background: var(--crisp-bg-orange); }
670
716
  & .crisp-datatable-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
671
717
  & .crisp-datatable-tags { display: flex; align-items: center; gap: var(--crisp-space-1); overflow: hidden; }
672
718
  & .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); }
@@ -679,14 +725,16 @@
679
725
  & .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)); }
680
726
  & .crisp-datatable-num { font-variant-numeric: tabular-nums; }
681
727
  & .crisp-datatable-muted { color: var(--crisp-fg-muted); }
682
- /* url/email cell types (#654) -- same measured values as RecordsTable's own .crisp-recordstable-link, which this mirrors: no underline at rest, underline on hover, own-colour text rather than a browser-blue link. */
728
+ /* url/email cell types (#654) -- same measured values as RecordsTable's
729
+ own .crisp-recordstable-link, which this mirrors: no underline at
730
+ rest, underline on hover, own-colour text rather than a browser-blue
731
+ link. */
683
732
  & .crisp-datatable-link { color: var(--crisp-fg-primary); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
684
733
  & .crisp-datatable-link:hover { text-decoration: underline; }
685
- /* row drag-to-reorder -- a Settings > Objects > Attributes screen measures a leading 20px grip column, a 16px grip icon, and the row's own
686
- hairline doubling as the drop indicator (it tints toward the brand
687
- colour as the active drop target). The affordance + geometry are
688
- 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
689
- pointer-events implementation. */
734
+ /* row drag-to-reorder -- a Settings > Objects > Attributes screen measures
735
+ 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
736
+ draggable + dataTransfer, the same one column reorder already uses
737
+ (RecordsTable's reorderColumn) -- not a proprietary pointer-events implementation. */
690
738
  & .crisp-datatable-col-grip { width: 20px; padding: 0; text-align: center; }
691
739
  & .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; }
692
740
  & .crisp-datatable-grip:active { cursor: grabbing; }
@@ -835,17 +883,29 @@
835
883
 
836
884
  .crisp-dialog {
837
885
  display: contents; font-family: var(--crisp-font-sans);
838
- & .crisp-dialog-backdrop { position: fixed; inset: 0; z-index: 60; background: transparent; }
886
+ & .crisp-dialog-backdrop { position: fixed; inset: 0; z-index: 60; background: var(--crisp-bg-scrim); }
839
887
  & .crisp-dialog-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); }
888
+ & .crisp-dialog-positioner[data-variant="alert"] { align-items: center; padding: var(--crisp-space-4); }
840
889
  & .crisp-dialog-content { -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); } }
890
+ & .crisp-dialog-content[data-variant="alert"] { padding: 0; background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none; }
841
891
  & .crisp-dialog-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; }
892
+ & .crisp-dialog-content[data-variant="alert"] .crisp-dialog-card { border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); 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); }
842
893
  & .crisp-dialog-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-4); border-bottom: 1px solid var(--crisp-border-subtle); }
843
894
  & .crisp-dialog-header svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
844
895
  & .crisp-dialog-title { 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); margin: 0; }
845
896
  & .crisp-dialog-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; }
846
897
  & .crisp-dialog-close:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
898
+ /* The discard-confirm's own stacked title + sentence (crisp#677) — no
899
+ border, no close button, unlike the panel header above: measured
900
+ live, both themes, 18px/24px 600-weight title (no scale token
901
+ reaches 18px — the scale tops out at text.xl's 16px, so this is raw px per Golden Rule 3's "genuinely intrinsic size" exception, same as
902
+ this file's own submit-key glyphs) then a 14px/20px 500-weight sentence 4px below it. */
903
+ & .crisp-dialog-alert-header { display: flex; flex-direction: column; gap: var(--crisp-space-1); padding: var(--crisp-space-4) var(--crisp-space-4) 0; }
904
+ & .crisp-dialog-alert-title { margin: 0; font-size: 18px; line-height: 24px; font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
905
+ & .crisp-dialog-alert-description { margin: 0; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-alert-description); }
847
906
  & .crisp-dialog-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--crisp-space-4); padding: var(--crisp-space-5) var(--crisp-space-4); }
848
907
  & .crisp-dialog-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-4); border-top: 1px solid var(--crisp-border-subtle); }
908
+ & .crisp-dialog-footer[data-variant="alert"] { min-height: 45px; padding: var(--crisp-space-2); }
849
909
  & .crisp-dialog-field { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); }
850
910
  & .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); }
851
911
  & .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; }
@@ -1746,7 +1806,7 @@
1746
1806
  & .crisp-tabletoolbar-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
1747
1807
  & .crisp-tabletoolbar-sort-learn svg { flex-shrink: 0; }
1748
1808
  & .crisp-tabletoolbar-sort-learn:hover { color: var(--crisp-fg-primary); }
1749
- & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
1809
+ & .crisp-tabletoolbar-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
1750
1810
  & .crisp-tabletoolbar-menu-item:hover { background: var(--crisp-bg-raised); }
1751
1811
  & .crisp-tabletoolbar-menu-item:disabled { opacity: 0.4; cursor: default; }
1752
1812
  & .crisp-tabletoolbar-menu-item:disabled:hover { background: none; }
@@ -1759,6 +1819,7 @@
1759
1819
  & .crisp-tabletoolbar-menu--right { left: auto; right: 0; }
1760
1820
  & .crisp-tabletoolbar-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
1761
1821
  & .crisp-tabletoolbar-menu--hdr { min-width: 200px; }
1822
+ & .crisp-tabletoolbar-menu--op { min-width: 0; }
1762
1823
  & .crisp-tabletoolbar-menu-item--danger { color: var(--crisp-bg-danger); }
1763
1824
  & .crisp-tabletoolbar-menu-item--danger svg { color: var(--crisp-bg-danger); }
1764
1825
  & .crisp-tabletoolbar-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -1774,6 +1835,21 @@
1774
1835
  & .crisp-tabletoolbar-count { font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
1775
1836
  & .crisp-tabletoolbar-new { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: var(--crisp-size-row); padding: 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; transition: background-color .12s; }
1776
1837
  & .crisp-tabletoolbar-new:hover { background: var(--crisp-bg-brand-solid-pressed); }
1838
+ & .crisp-tabletoolbar-fcond { display: inline-flex; align-items: center; height: var(--crisp-size-row); font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); white-space: nowrap; }
1839
+ & .crisp-tabletoolbar-fcond-seg { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: 100%; margin: 0; padding: 0 var(--crisp-space-2); border: none; background: var(--crisp-bg-surface-muted); box-shadow: inset 0 0 0 1px var(--crisp-border-divider); font-family: inherit; font-size: inherit; color: inherit; cursor: pointer; }
1840
+ & .crisp-tabletoolbar-fcond-seg svg { flex-shrink: 0; }
1841
+ & .crisp-tabletoolbar-fcond[data-complete] .crisp-tabletoolbar-fcond-seg--field, & .crisp-tabletoolbar-fcond[data-complete] .crisp-tabletoolbar-fcond-seg--val { background: var(--crisp-bg-surface); }
1842
+ & .crisp-tabletoolbar-fcond-seg--field { border-radius: var(--crisp-radius-md) 0 0 var(--crisp-radius-md); font-weight: var(--crisp-weight-medium); }
1843
+ & .crisp-tabletoolbar-fcond-seg--field svg { color: var(--crisp-fg-muted); }
1844
+ & .crisp-tabletoolbar-fcond-seg--op { background: var(--crisp-bg-surface); color: var(--crisp-fg-muted); }
1845
+ & .crisp-tabletoolbar-fcond-seg--val { font-weight: var(--crisp-weight-medium); max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
1846
+ & .crisp-tabletoolbar-fcond-seg--kebab { background: var(--crisp-bg-surface); justify-content: center; width: 28px; padding: 0; border-radius: 0 var(--crisp-radius-md) var(--crisp-radius-md) 0; color: var(--crisp-fg-muted); }
1847
+ & .crisp-tabletoolbar-fcond-seg--kebab:hover { color: var(--crisp-fg-primary); }
1848
+ & .crisp-tabletoolbar-menu--val { min-width: 134px; }
1849
+ & .crisp-tabletoolbar-datepop { width: 300px; }
1850
+ & .crisp-tabletoolbar-datepop-presets { display: flex; flex-wrap: wrap; gap: var(--crisp-space-1); margin-top: var(--crisp-space-2); padding: 0 var(--crisp-space-1); }
1851
+ & .crisp-tabletoolbar-datepop-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; }
1852
+ & .crisp-tabletoolbar-datepop-preset:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); }
1777
1853
  }
1778
1854
 
1779
1855
  @media (prefers-reduced-motion: reduce) {
@@ -1794,7 +1870,7 @@
1794
1870
  & .crisp-tabs-tab:hover:not([data-selected]) { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-primary); }
1795
1871
  & .crisp-tabs-tab[data-selected] { color: var(--crisp-fg-primary); background: var(--crisp-bg-subtle); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
1796
1872
  & .crisp-tabs-tab:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
1797
- & .crisp-tabs-tab-badge { 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); }
1873
+ & .crisp-tabs-tab-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 14px; height: 14px; padding: 0 var(--crisp-space-1); border-radius: 4px; background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: 10px; line-height: 14px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
1798
1874
  & .crisp-tabs-tab[data-selected] .crisp-tabs-tab-badge { color: var(--crisp-fg-primary); }
1799
1875
  & .crisp-tabs-indicator { position: absolute; bottom: 0; left: 0; z-index: 1; height: 1px; background: var(--crisp-fg-primary); border-radius: 2px 2px 0 0; transition: transform .2s cubic-bezier(.4,0,.2,1), width .2s cubic-bezier(.4,0,.2,1); pointer-events: none; }
1800
1876
  & .crisp-tabs-panel { display: flex; flex-direction: column; flex: 1; min-height: 0; padding-top: var(--crisp-space-8); }
@@ -1894,7 +1970,7 @@
1894
1970
  }
1895
1971
 
1896
1972
  .crisp-tooltip {
1897
- position: fixed; z-index: 70; box-sizing: border-box; pointer-events: none; max-width: 260px; padding: var(--crisp-space-1-5) var(--crisp-space-2); border-radius: var(--crisp-radius-md); background: #101112; color: #eeeff1; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); line-height: 1.45; box-shadow: 0 4px 14px -2px rgba(28,40,64,0.28), 0 0 0 1px rgba(255,255,255,0.04); opacity: 1; transition: opacity 0.12s ease;
1973
+ position: fixed; z-index: 70; box-sizing: border-box; pointer-events: none; max-width: 260px; padding: var(--crisp-space-1-5) var(--crisp-space-2); border-radius: var(--crisp-radius-md); background: #101112; color: #eeeff1; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); line-height: 1.45; box-shadow: rgb(33,34,36) 0 0 0 1px inset, rgba(0,0,0,0.04) 0 0 2px 0, rgba(0,0,0,0.12) 0 1px 3px 0; opacity: 1; transition: opacity 0.12s ease;
1898
1974
  @starting-style { opacity: 0; }
1899
1975
  & .crisp-tooltip-reference-row { display: inline-flex; align-items: center; gap: var(--crisp-space-1); }
1900
1976
  }
@@ -1980,7 +2056,11 @@
1980
2056
  &[data-single-pane] { justify-content: center; }
1981
2057
  & .crisp-authshell-progress { position: absolute; top: 0; left: 0; width: 100%; height: 2px; background: var(--crisp-border-default); }
1982
2058
  & .crisp-authshell-progress-fill { height: 2px; background: var(--crisp-fg-primary); border-radius: 4px; transition: width .2s; }
1983
- & .crisp-authshell-logo { margin-top: var(--crisp-space-8); height: 24px; display: flex; align-items: center; }
2059
+ & .crisp-authshell-logo { margin-top: var(--crisp-space-8); min-height: 24px; display: flex; align-items: center; gap: var(--crisp-space-2-5); }
2060
+ & .crisp-authshell-logo-badge { flex-shrink: 0; box-sizing: border-box; width: 32px; height: 32px; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-brand-solid); color: #fff; display: flex; align-items: center; justify-content: center; }
2061
+ & .crisp-authshell-logo-text { display: flex; flex-direction: column; line-height: 1.2; }
2062
+ & .crisp-authshell-logo-title { font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-bold); letter-spacing: -0.2px; color: var(--crisp-fg-primary); }
2063
+ & .crisp-authshell-logo-subtitle { font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
1984
2064
  & .crisp-authshell-card { margin-top: var(--crisp-space-6); display: flex; height: 692px; border-radius: 20px; border: 1px solid var(--crisp-border-subtle); overflow: hidden; }
1985
2065
  &[data-single-pane] .crisp-authshell-card { height: auto; border: none; border-radius: 0; overflow: visible; }
1986
2066
  & .crisp-authshell-pane { flex: 0 0 564px; padding: 72px; display: flex; flex-direction: column; box-sizing: border-box; }
@@ -2028,21 +2108,28 @@
2028
2108
  & .crisp-board-col-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 36px; padding: 0 var(--crisp-space-1); flex-shrink: 0; }
2029
2109
  & .crisp-board-col-dot { width: 12px; height: 12px; border-radius: var(--crisp-radius-full); flex-shrink: 0; }
2030
2110
  & .crisp-board-col-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
2031
- & .crisp-board-col-count { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
2111
+ /* crisp#697: HANDOFF's #472 note claimed the count pill's color-mix(fgPrimary, 63%, transparent) reproduced the measured rgb(80,81,85) -- it doesn't; 63% of fgPrimary composited on white
2112
+ paints rgb(104,105,105), visibly lighter. Text now reads
2113
+ fgNeutralSoft directly (the same rgb(80,81,85) token Badge's neutral tone uses, #696), and the ring the pill was also missing (inset 0 0 0 1px borderSubtle, measured rgb(238,239,241)) is added. */
2114
+ & .crisp-board-col-count { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); font-size: var(--crisp-text-sm); line-height: 16px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
2032
2115
  & .crisp-board-col-add { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin-inline-start: auto; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
2033
2116
  & .crisp-board-col-add:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
2034
2117
  & .crisp-board-col-body { display: flex; flex-direction: column; gap: var(--crisp-space-2); flex: 1; min-height: 48px; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-lg); overflow-y: auto; transition: background 0.12s; }
2035
2118
  & .crisp-board-col[data-over] .crisp-board-col-body { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 7%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent); }
2036
2119
  & .crisp-board-newcard { display: flex; align-items: center; justify-content: center; gap: var(--crisp-space-1-5); height: 32px; flex-shrink: 0; border: none; border-radius: var(--crisp-radius-md); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); cursor: pointer; }
2037
2120
  & .crisp-board-newcard:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 7%, transparent); color: var(--crisp-fg-primary); }
2038
- & .crisp-board-card { display: flex; flex-direction: column; gap: var(--crisp-space-2); box-sizing: border-box; padding: var(--crisp-space-2-5) var(--crisp-space-3); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); cursor: grab; }
2121
+ & .crisp-board-card { display: flex; flex-direction: column; gap: var(--crisp-space-2); box-sizing: border-box; padding: var(--crisp-space-2-5) var(--crisp-space-3); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); cursor: grab; touch-action: none; }
2039
2122
  & .crisp-board-card:active { cursor: grabbing; }
2040
2123
  & .crisp-board-card[data-dragging] { opacity: 0.4; }
2041
2124
  & .crisp-board-card:focus { outline: none; }
2042
2125
  & .crisp-board-card:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
2043
- /* #604: a per-column calc footer, mirroring the table's own (measured
2044
- live, Deals pipeline). Sits below the scrollable card body, not
2045
- inside it or pinned to it -- Attio's own is position: static, not sticky, so it's a plain flex-shrink:0 sibling here too. */
2126
+ /* #674: the pointer-events drag's own drag image -- the same card
2127
+ surface above, just pinned to the pointer instead of the flex flow.
2128
+ No shadow lift or scale: neither was measured against Attio, and this
2129
+ is the same card, momentarily somewhere else, not a new look. */
2130
+ & .crisp-board-ghost { position: fixed; z-index: 1; pointer-events: none; cursor: grabbing; }
2131
+ /* #604: a per-column calc footer, mirroring the table's own (measured live, Deals pipeline). Sits below the scrollable card body, not inside it or pinned to it -- Attio's own is position: static, not
2132
+ sticky, so it's a plain flex-shrink:0 sibling here too. */
2046
2133
  & .crisp-board-col-footer { flex-shrink: 0; padding: var(--crisp-space-1) 0; }
2047
2134
  & .crisp-board-col-calc { display: flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); width: 100%; height: 28px; padding: var(--crisp-space-1) var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); cursor: pointer; }
2048
2135
  & .crisp-board-col-calc:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
@@ -2050,10 +2137,7 @@
2050
2137
  & .crisp-board-col-calc-label { text-transform: capitalize; }
2051
2138
  & .crisp-board-col-calc-value { color: var(--crisp-fg-primary); font-variant-numeric: tabular-nums; }
2052
2139
  /* announced, never drawn */
2053
- & .crisp-board-live {
2054
- position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
2055
- overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
2056
- }
2140
+ & .crisp-board-live { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
2057
2141
  }
2058
2142
 
2059
2143
  @media (prefers-reduced-motion: reduce) {
@@ -2137,31 +2221,50 @@
2137
2221
  & .crisp-comments-breadcrumb { display: flex; align-items: center; gap: var(--crisp-space-1); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2138
2222
  & .crisp-comments-body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--crisp-space-4); display: flex; flex-direction: column; gap: var(--crisp-space-4); }
2139
2223
  & .crisp-comments-body--pad-top { padding-top: var(--crisp-space-3); }
2140
- /* One comment row -- avatar 16px (Avatar size="sm"), 6px gap to the name/time line, 14px/600 name + 12px/500 63%-muted time, 14px/400 body two lines below. Hover actions fade in flush with the name line. */
2224
+ /* One comment row -- avatar 16px (Avatar size="sm"), 6px gap to the name/time line, 14px/600 name + 12px/500 63%-muted time, 14px/400 body two lines below. Hover actions fade in flush with the name line. .crisp-comments-row-head's own height: 20px (above) is a single
2225
+ text-line's worth, on the same assumption .crisp-comments-title/ .crisp-comments-breadcrumb already act on higher up in this same recipe -- a name that doesn't fit wraps to two lines with nothing
2226
+ reserving room for the second one, overflowing straight into the
2227
+ body text underneath (found live: this app's own dev-bypass author name, an email long enough to wrap, sat on top of the comment's own
2228
+ body text). .crisp-comments-author gets the identical nowrap-
2229
+ ellipsis treatment those two already have, plus min-width: 0 so a
2230
+ flex item is actually allowed to shrink below its own text's natural width in the first place; .crisp-comments-time gets flex-shrink: 0 so it's the name that gives, never the timestamp -- the same "one
2231
+ side shrinks, the other one doesn't" split PersonChip's own name/
2232
+ avatar pair already uses (crisp#668/#671). */
2141
2233
  & .crisp-comments-row { position: relative; display: flex; gap: var(--crisp-space-1-5); }
2142
2234
  & .crisp-comments-row-main { flex: 1; min-width: 0; }
2143
2235
  & .crisp-comments-row-head { display: flex; align-items: baseline; gap: var(--crisp-space-1-5); height: 20px; }
2144
- & .crisp-comments-author { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
2145
- & .crisp-comments-time { font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); white-space: nowrap; }
2236
+ & .crisp-comments-author { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
2237
+ & .crisp-comments-time { flex-shrink: 0; font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); white-space: nowrap; }
2146
2238
  & .crisp-comments-resolved-label { display: flex; align-items: center; gap: var(--crisp-space-1); margin-bottom: var(--crisp-space-1); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
2147
2239
  & .crisp-comments-body-text { font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-primary); white-space: pre-wrap; word-break: break-word; }
2148
- /* Hover actions -- measured: 4 buttons, 28x28, radius 8, flush side-by-side (0 gap), transparent by default, 16px icon at 55% ink. */
2240
+
2241
+ /* Hover actions -- measured: 4 buttons, 28x28, radius 8, flush
2242
+ side-by-side (0 gap), transparent by default, 16px icon at 55% ink. */
2149
2243
  & .crisp-comments-row-actions { position: absolute; top: 0; inset-inline-end: 0; display: flex; opacity: 0; pointer-events: none; background: var(--crisp-bg-surface); }
2150
- & .crisp-comments-row:hover .crisp-comments-row-actions, & .crisp-comments-row-actions:focus-within { opacity: 1; pointer-events: auto; }
2244
+ & .crisp-comments-row:hover .crisp-comments-row-actions,
2245
+ & .crisp-comments-row-actions:focus-within { opacity: 1; pointer-events: auto; }
2151
2246
  & .crisp-comments-action { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s, color .12s; }
2152
2247
  & .crisp-comments-action:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
2153
2248
  & .crisp-comments-action[data-active] { color: var(--crisp-bg-brand-solid); }
2154
- /* Reactions -- measured: 28px pill, radius 8, subtle 4% ink fill, padding 4px 8px 4px 6px, gap 4px between the emoji glyph and count. */
2249
+
2250
+ /* Reactions -- measured: 28px pill, radius 8, subtle 4% ink fill,
2251
+ padding 4px 8px 4px 6px, gap 4px between the emoji glyph and count. */
2155
2252
  & .crisp-comments-reactions { display: flex; flex-wrap: wrap; gap: var(--crisp-space-1); margin-top: var(--crisp-space-1-5); }
2156
2253
  & .crisp-comments-reaction { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: 28px; padding: 4px 8px 4px 6px; border: none; border-radius: var(--crisp-radius-md); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); font-family: inherit; font-size: 12px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); cursor: pointer; }
2157
2254
  & .crisp-comments-reaction[data-reacted] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); }
2158
2255
  & .crisp-comments-reaction-add { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; border-radius: var(--crisp-radius-md); background: transparent; font-family: inherit; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; opacity: 0; transition: opacity .12s, background-color .12s; }
2159
2256
  & .crisp-comments-row:hover .crisp-comments-reaction-add { opacity: 1; }
2160
2257
  & .crisp-comments-reaction-add:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
2258
+
2161
2259
  /* Reply-in-thread view -- an indented block of replies below the root. */
2162
2260
  & .crisp-comments-replies { display: flex; flex-direction: column; gap: var(--crisp-space-4); margin-top: var(--crisp-space-3); padding-inline-start: var(--crisp-space-4); border-inline-start: 1px solid var(--crisp-border-subtle); }
2261
+
2163
2262
  & .crisp-comments-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--crisp-space-1); padding: var(--crisp-space-6) var(--crisp-space-4); text-align: center; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-size: var(--crisp-text-lg); }
2164
- /* Composer -- measured: 14px/20px body text, 16px gap above the reply/mention icon row, Comment button 84x32 padding 6px 10px radius 9 (= radius.lg) brand-solid fill, 14px/500 white label, opacity .4 disabled / 1 enabled (no color/background change between the two). */
2263
+
2264
+ /* Composer -- measured: 14px/20px body text, 16px gap above the
2265
+ reply/mention icon row, Comment button 84x32 padding 6px 10px radius
2266
+ 9 (= radius.lg) brand-solid fill, 14px/500 white label, opacity .4
2267
+ disabled / 1 enabled (no color/background change between the two). */
2165
2268
  & .crisp-comments-composer { flex-shrink: 0; padding: var(--crisp-space-3) var(--crisp-space-4) var(--crisp-space-4); border-top: 1px solid var(--crisp-border-subtle); }
2166
2269
  & .crisp-comments-field { min-height: 20px; max-height: 120px; overflow-y: auto; font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-primary); outline: none; white-space: pre-wrap; word-break: break-word; }
2167
2270
  & .crisp-comments-field:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: 2px; }
@@ -2171,15 +2274,22 @@
2171
2274
  & .crisp-comments-tool { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 45%, transparent); font-family: inherit; cursor: pointer; }
2172
2275
  & .crisp-comments-tool:hover { color: var(--crisp-fg-primary); }
2173
2276
  /* Same fill/shadow as Button's own intent="primary" (crisp/button.recipe.ts) --
2174
- confirmed byte-identical against the live "Comment" button's computed box-shadow, so this reuses that literal rather than re-deriving it. 32px/radius.lg/6px-10px padding has no matching Button `size` yet (24/28/40 are the three that exist), so this stays hand-rolled instead of stretching one of those. */
2277
+ confirmed byte-identical against the live "Comment" button's computed
2278
+ box-shadow, so this reuses that literal rather than re-deriving it.
2279
+ 32px/radius.lg/6px-10px padding has no matching Button `size` yet
2280
+ (24/28/40 are the three that exist), so this stays hand-rolled instead
2281
+ of stretching one of those. */
2175
2282
  & .crisp-comments-post { display: inline-flex; align-items: center; justify-content: center; height: 32px; padding: 6px var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-lg); background: var(--crisp-bg-brand-solid); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06), 0 2px 4px -2px rgba(38,109,240,0.12), 0 3px 6px -2px rgba(38,109,240,0.08); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-on-brand); cursor: pointer; opacity: 1; transition: opacity .12s, background-color .12s; }
2176
2283
  & .crisp-comments-post:hover:not(:disabled) { background: var(--crisp-bg-brand-solid-pressed); }
2177
2284
  & .crisp-comments-post:disabled { opacity: .4; cursor: default; }
2178
- /* Filter menu -- measured: 220px, radius 12 (radius.xl), 4px padding, elevation.floating -- a plain reuse of crisp's own Menu, so no rules
2285
+
2286
+ /* Filter menu -- measured: 220px, radius 12 (radius.xl), 4px padding,
2287
+ elevation.floating -- a plain reuse of crisp's own Menu, so no rules
2179
2288
  live here; kept as a comment for the record. */
2180
2289
 
2181
2290
  /* An inserted "@mention" chip in the composer -- same shape as
2182
- RichTextEditor's own `.crisp-rte-mention` (crisp#428), reused here rather than re-derived since it's the same atomic-chip affordance. */
2291
+ RichTextEditor's own `.crisp-rte-mention` (crisp#428), reused here
2292
+ rather than re-derived since it's the same atomic-chip affordance. */
2183
2293
  & .crisp-comments-mention { display: inline; padding: 0 2px; border-radius: 4px; background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); font-weight: var(--crisp-weight-medium); user-select: none; }
2184
2294
  [dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
2185
2295
  }
@@ -2354,6 +2464,13 @@
2354
2464
  }
2355
2465
  }
2356
2466
 
2467
+
2468
+ .crisp-navitem-shortcut { display: flex; align-items: baseline; justify-content: space-between; gap: var(--crisp-space-3); }
2469
+ .crisp-navitem-shortcut-desc { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); line-height: 16px; white-space: nowrap; }
2470
+ .crisp-navitem-shortcut-chord { display: inline-flex; align-items: center; gap: var(--crisp-space-1); flex-shrink: 0; }
2471
+ .crisp-navitem-shortcut-then { font-size: var(--crisp-text-xs); font-weight: var(--crisp-weight-medium); color: #898a8d; }
2472
+ .crisp-navitem-shortcut-chord .crisp-kbd { text-transform: uppercase; font-weight: var(--crisp-weight-regular); color: #a2a4a7; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2); }
2473
+
2357
2474
  .crisp-navitem {
2358
2475
  box-sizing: border-box; display: flex; align-items: center; gap: var(--crisp-space-1-5); height: 28px; padding-inline: var(--crisp-space-2); padding-inline-end: var(--crisp-space-1); border-radius: var(--crisp-radius-lg); font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); letter-spacing: -0.14px; line-height: 20px; color: var(--crisp-fg-primary); text-decoration: none; cursor: pointer; user-select: none; width: 100%; transition: background-color 0.16s;
2359
2476
  & .crisp-navitem-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -2753,7 +2870,7 @@
2753
2870
  & .crisp-recordstable-sort-learn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); font-size: var(--crisp-text-lg); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); text-decoration: none; }
2754
2871
  & .crisp-recordstable-sort-learn svg { flex-shrink: 0; }
2755
2872
  & .crisp-recordstable-sort-learn:hover { color: var(--crisp-fg-primary); }
2756
- & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
2873
+ & .crisp-recordstable-menu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); width: 100%; height: var(--crisp-size-menuRow); margin: 0; padding: 0 var(--crisp-space-2); border: none; background: none; border-radius: var(--crisp-radius-md); font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); text-align: left; cursor: pointer; }
2757
2874
  & .crisp-recordstable-menu-item:hover { background: var(--crisp-bg-raised); }
2758
2875
  & .crisp-recordstable-menu-item:disabled { opacity: 0.4; cursor: default; }
2759
2876
  & .crisp-recordstable-menu-item:disabled:hover { background: none; }
@@ -2766,6 +2883,7 @@
2766
2883
  & .crisp-recordstable-menu--right { left: auto; right: 0; }
2767
2884
  & .crisp-recordstable-menu--fixed { position: fixed; top: auto; left: auto; z-index: 40; }
2768
2885
  & .crisp-recordstable-menu--hdr { min-width: 200px; }
2886
+ & .crisp-recordstable-menu--op { min-width: 0; }
2769
2887
  & .crisp-recordstable-menu-item--danger { color: var(--crisp-bg-danger); }
2770
2888
  & .crisp-recordstable-menu-item--danger svg { color: var(--crisp-bg-danger); }
2771
2889
  & .crisp-recordstable-menu-item--danger:hover { background: color-mix(in srgb, var(--crisp-bg-danger) 10%, transparent); }
@@ -3133,9 +3251,14 @@
3133
3251
  & .crisp-sidebar-section { display: flex; flex-direction: column; gap: var(--crisp-space-px); margin-top: var(--crisp-space-2); }
3134
3252
  & .crisp-sidebar-section[data-collapsed] { display: none; }
3135
3253
  & .crisp-sidebar-label { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); padding: var(--crisp-space-1-5) var(--crisp-space-2) var(--crisp-space-0-5); }
3136
- & .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; }
3254
+ & .crisp-sidebar-section-header-row { display: flex; align-items: center; }
3255
+ & .crisp-sidebar-section-header { display: flex; align-items: center; gap: var(--crisp-space-1); flex: 1; min-width: 0; 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; }
3137
3256
  & .crisp-sidebar-section-header svg { flex-shrink: 0; transition: transform .15s ease; }
3138
3257
  & .crisp-sidebar-section-header[data-collapsed] svg { transform: rotate(-90deg); }
3258
+ & .crisp-sidebar-section-actions { display: flex; align-items: center; gap: var(--crisp-space-1); flex-shrink: 0; padding-inline-end: var(--crisp-space-1); opacity: 0; transition: opacity .12s ease; }
3259
+ & .crisp-sidebar-section-header-row:hover .crisp-sidebar-section-actions, & .crisp-sidebar-section-header-row:focus-within .crisp-sidebar-section-actions { opacity: 1; }
3260
+ & .crisp-sidebar-section-action { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: var(--crisp-space-5); height: var(--crisp-space-5); margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); font-family: inherit; cursor: pointer; text-decoration: none; transition: background-color 0.14s, color 0.14s; }
3261
+ & .crisp-sidebar-section-action:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
3139
3262
  & .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); }
3140
3263
  & .crisp-sidebar-ws-menuroot { display: flex; flex: 1; min-width: 0; }
3141
3264
  & .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; }