@crispy-seed/data-table 0.10.3 → 0.10.5

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.
@@ -174,6 +174,9 @@
174
174
  text-overflow: ellipsis;
175
175
  white-space: nowrap;
176
176
  }
177
+ .seed-data-table__cell:not([data-editable]) {
178
+ user-select: none;
179
+ }
177
180
  .seed-data-table__cell:last-child {
178
181
  border-inline-end: none;
179
182
  }
@@ -388,8 +391,9 @@ tr:hover .seed-data-table__entityActions {
388
391
  padding-inline: var(--seed-dimension-x3);
389
392
  padding-block: var(--seed-dimension-x3);
390
393
  background-color: var(--seed-color-bg-layer-floating);
391
- border-radius: var(--seed-radius-r5);
392
- box-shadow: inset 0 0 0 1px var(--seed-color-stroke-neutral-weak), var(--seed-shadow-s3);
394
+ border-radius: 4px;
395
+ box-shadow: none;
396
+ border: 1px solid #266df0;
393
397
  color: var(--seed-color-fg-neutral);
394
398
  font-size: var(--seed-font-size-t4);
395
399
  line-height: var(--seed-line-height-t4);
@@ -198,6 +198,11 @@
198
198
  overflow: clip;
199
199
  }
200
200
 
201
+ .seed-data-table__cell:not([data-editable]) {
202
+ -webkit-user-select: none;
203
+ user-select: none;
204
+ }
205
+
201
206
  .seed-data-table__cell:last-child {
202
207
  border-inline-end: none;
203
208
  }
@@ -429,13 +434,14 @@
429
434
  padding-inline: var(--seed-dimension-x3);
430
435
  padding-block: var(--seed-dimension-x3);
431
436
  background-color: var(--seed-color-bg-layer-floating);
432
- border-radius: var(--seed-radius-r5);
433
- box-shadow: inset 0 0 0 1px var(--seed-color-stroke-neutral-weak), var(--seed-shadow-s3);
437
+ box-shadow: none;
434
438
  color: var(--seed-color-fg-neutral);
435
439
  font-size: var(--seed-font-size-t4);
436
440
  line-height: var(--seed-line-height-t4);
437
441
  letter-spacing: -.14px;
438
442
  cursor: default;
443
+ border: 1px solid #266df0;
444
+ border-radius: 4px;
439
445
  align-items: flex-start;
440
446
  display: flex;
441
447
  position: absolute;
package/dist/index.cjs CHANGED
@@ -1696,24 +1696,33 @@ function useDataTableSort(props) {
1696
1696
  // already passes its "cleared" shape through unconditionally; this now matches.
1697
1697
  onChange: onSortChange
1698
1698
  });
1699
+ // 3-state cycle (DATATABLE-ATTIO-SPEC.md: "asc/desc/none cycle") -- clicking a
1700
+ // DIFFERENT column always starts it fresh at asc, discarding whatever the previous
1701
+ // column's direction was (this stays a SINGLE-column secondary affordance, never a
1702
+ // second multi-sort list of its own). Clicking the SAME column steps asc -> desc ->
1703
+ // undefined ("none", i.e. this column drops out of the sort entirely) -> asc again.
1704
+ // Before this, the cycle wrapped desc -> asc forever, with no click-driven way back
1705
+ // to unsorted at all (a reported gap: "sort asc/desc has no option for no sort on
1706
+ // columns") -- `clearSort` below was the ONLY way there, now it's one of two.
1699
1707
  const toggleSort = React.useCallback((key)=>{
1700
1708
  setSort((current)=>{
1701
1709
  if (!current || current.key !== key) return {
1702
1710
  key,
1703
1711
  dir: "asc"
1704
1712
  };
1705
- return {
1713
+ if (current.dir === "asc") return {
1706
1714
  key,
1707
- dir: current.dir === "asc" ? "desc" : "asc"
1715
+ dir: "desc"
1708
1716
  };
1717
+ return undefined;
1709
1718
  });
1710
1719
  }, [
1711
1720
  setSort
1712
1721
  ]);
1713
- /** Attio/GRC's "Remove sort" -- the header click cycle (above) only ever toggles
1714
- * asc/desc once a column has been clicked once; this is the only way back to no
1715
- * sort at all. Exposed for a column's own header menu (`column-menu.tsx`'s
1716
- * `ColumnMenu`) to offer as a "Clear sort" item when that column is the sorted one. */ const clearSort = React.useCallback(()=>setSort(undefined), [
1722
+ /** Attio/GRC's "Remove sort" -- a second way back to no sort at all (the header
1723
+ * click cycle above reaches it too, on a column's third click), exposed for a
1724
+ * column's own header menu (`column-menu.tsx`'s `ColumnMenu`) to offer as a
1725
+ * "Clear sort" item when that column is the sorted one, without three clicks. */ const clearSort = React.useCallback(()=>setSort(undefined), [
1717
1726
  setSort
1718
1727
  ]);
1719
1728
  const getHeaderCellProps = React.useCallback((columnKey, sortable)=>{
@@ -1746,7 +1755,12 @@ function useDataTableSort(props) {
1746
1755
  sort,
1747
1756
  toggleSort,
1748
1757
  clearSort,
1749
- getHeaderCellProps
1758
+ getHeaderCellProps,
1759
+ // Exposed for `useDataTable.ts`'s own composition ONLY (unifying this single
1760
+ // click-to-sort column with `useDataTableToolbarSort`'s ordered list) -- not part
1761
+ // of the documented header-click contract (`toggleSort`/`clearSort` above are),
1762
+ // so no consumer-facing doc comment promotes it as a control of its own.
1763
+ setSort
1750
1764
  };
1751
1765
  }
1752
1766
 
@@ -1850,11 +1864,14 @@ const EMPTY_SORTS = [];
1850
1864
  * concern rather than folded into `useDataTableSort` (DATATABLE-ATTIO-SPEC.md: "compose,
1851
1865
  * don't fatten one hook"). `useDataTableSort` still owns the single click-to-sort
1852
1866
  * column/direction a header's own click toggles -- that stays Attio's SECONDARY sort
1853
- * affordance, untouched by this hook. This one is the PRIMARY toolbar Sort control: add
1854
- * a condition, pick its field/direction, reorder, remove -- multiple conditions apply in
1855
- * list order (sort[0] wins, later ones break ties; see the styled layer's
1856
- * `applyToolbarSorts`). The styled layer decides how the two combine (DataTable.tsx:
1857
- * toolbar sorts win when any exist, the single click-to-sort column otherwise).
1867
+ * affordance, a separate hook from this one. They are NOT independent state, though:
1868
+ * `useDataTable.ts`'s own composition keeps a header-driven column's entry in THIS
1869
+ * array in sync (added/updated/removed as that column's header cycles asc/desc/none),
1870
+ * so a consumer controlling only `toolbarSorts`/`onToolbarSortsChange` still sees a
1871
+ * header click, and the toolbar's own "Remove sort" x on that same entry clears the
1872
+ * header's side too. Multiple conditions apply in list order (sort[0] wins, later ones
1873
+ * break ties; see the styled layer's `applyToolbarSorts`). The styled layer
1874
+ * (`DataTable.tsx`) decides how the merged result actually sorts `data`.
1858
1875
  */ function useDataTableToolbarSort(props) {
1859
1876
  const { toolbarSorts: sortsProp, defaultToolbarSorts = EMPTY_SORTS, onToolbarSortsChange } = props;
1860
1877
  const [toolbarSorts = EMPTY_SORTS, setToolbarSorts] = useControllableState$1({
@@ -1939,8 +1956,13 @@ const EMPTY_SORTS = [];
1939
1956
  // header "is/is not" picker) -- DATATABLE-ATTIO-SPEC.md's Attio/crisp `TableToolbar`
1940
1957
  // model is now the PRIMARY filter/sort UX, not a per-column header affordance. They stay
1941
1958
  // SEPARATE sub-hooks from `useDataTableSort` rather than folded into it ("compose, don't
1942
- // fatten one hook") -- the styled layer decides how the toolbar's multi-condition sort
1943
- // and the header's single click-to-sort combine (DataTable.tsx).
1959
+ // fatten one hook") -- but this composition point below DOES reconcile the two into one
1960
+ // state (the two `useEffect`s after `infiniteScroll`), so a header click and the
1961
+ // toolbar's own Sort popover always agree on what's sorted, regardless of which prop
1962
+ // pair (`sort`/`onSortChange` or `toolbarSorts`/`onToolbarSortsChange`) a consumer
1963
+ // actually controls. `DataTable.tsx` (styled) still decides how the RESULT actually
1964
+ // sorts `data` (`effectiveSorts`/`applyToolbarSorts`) -- this layer only keeps the two
1965
+ // STATE pools in agreement.
1944
1966
  function useDataTable(props) {
1945
1967
  const sort = useDataTableSort(props);
1946
1968
  const selection = useDataTableSelection(props);
@@ -1963,6 +1985,105 @@ function useDataTable(props) {
1963
1985
  ...props,
1964
1986
  scrollRootRef: scroll.elementRef
1965
1987
  });
1988
+ // Unifies `sort` (the header's own single click-to-sort column, above) with
1989
+ // `toolbarSort.toolbarSorts` (the toolbar Sort popover's ordered list, above) into
1990
+ // ONE state instead of two -- before this, a header click only ever moved `sort`,
1991
+ // invisible to a consumer controlling `toolbarSorts`/`onToolbarSortsChange` (the
1992
+ // reported bug: clicking a header did nothing to the array the consumer's own Sort
1993
+ // popover reads, so the toolbar's "Sort" trigger/count and its popover rows silently
1994
+ // ignored every header click).
1995
+ //
1996
+ // ONE effect, not two -- an earlier version split this into a forward
1997
+ // (`sort` -> `toolbarSorts`) and a reverse (`toolbarSorts` -> `sort`) effect, each
1998
+ // keyed off its own dependency. That raced on the very first render: `useEffect`
1999
+ // runs every effect once on mount regardless of what "changed", so with
2000
+ // `defaultSort` set, the reverse effect ran in the SAME commit as the forward one,
2001
+ // read `toolbarSorts` BEFORE the forward effect's own (still-queued, not yet
2002
+ // re-rendered) write had landed, saw no entry for the column yet, and immediately
2003
+ // cleared `sort` right back out -- the defaultSort silently never took effect.
2004
+ // `settledRef` sidesteps this: it remembers the last `{key,dir}` this effect itself
2005
+ // confirmed, so on every run it can tell WHICH side moved since then, instead of
2006
+ // guessing from which dependency happens to have triggered the re-run.
2007
+ const settledRef = React.useRef({
2008
+ key: undefined,
2009
+ dir: undefined
2010
+ });
2011
+ React.useEffect(()=>{
2012
+ const curSort = sort.sort;
2013
+ const curEntry = curSort ? toolbarSort.toolbarSorts.find((s)=>s.key === curSort.key) : undefined;
2014
+ const settled = settledRef.current;
2015
+ const sortUnchangedSinceSettled = settled.key === curSort?.key && settled.dir === curSort?.dir;
2016
+ if (sortUnchangedSinceSettled) {
2017
+ // `sort` itself hasn't moved since we last settled -- if this effect is running
2018
+ // at all, `toolbarSorts` is what changed, so REVERSE-sync: the toolbar Sort
2019
+ // popover's own "Remove sort" x, or its direction select, touching this exact
2020
+ // column. Never reaches across to adopt some OTHER column added independently
2021
+ // via that popover -- only the column `sort` is already tracking.
2022
+ if (!curSort) return;
2023
+ if (!curEntry) {
2024
+ sort.clearSort();
2025
+ settledRef.current = {
2026
+ key: undefined,
2027
+ dir: undefined
2028
+ };
2029
+ } else if (curEntry.dir !== curSort.dir) {
2030
+ sort.setSort({
2031
+ key: curSort.key,
2032
+ dir: curEntry.dir
2033
+ });
2034
+ settledRef.current = {
2035
+ key: curSort.key,
2036
+ dir: curEntry.dir
2037
+ };
2038
+ }
2039
+ return;
2040
+ }
2041
+ // `sort` moved (a header click, Enter/Space, or `clearSort` -- column-menu.tsx's
2042
+ // menu item calls that directly, bypassing `toggleSort`) -- FORWARD-sync:
2043
+ // add/update/remove THIS column's own entry in `toolbarSorts`, leaving every
2044
+ // OTHER entry (added independently via the toolbar's own "+ Add sort") untouched.
2045
+ // The functional updater reads the CURRENT array off `current`, never off
2046
+ // `toolbarSort.toolbarSorts` in this closure, so a stale render can never clobber
2047
+ // an entry the toolbar's own popover added a moment earlier.
2048
+ const prevKey = settled.key;
2049
+ toolbarSort.setToolbarSorts((current)=>{
2050
+ let updated = current;
2051
+ if (prevKey && prevKey !== curSort?.key) {
2052
+ updated = updated.filter((s)=>s.key !== prevKey);
2053
+ }
2054
+ if (curSort) {
2055
+ const idx = updated.findIndex((s)=>s.key === curSort.key);
2056
+ if (idx === -1) {
2057
+ updated = [
2058
+ ...updated,
2059
+ {
2060
+ key: curSort.key,
2061
+ dir: curSort.dir
2062
+ }
2063
+ ];
2064
+ } else if (updated[idx].dir !== curSort.dir) {
2065
+ updated = updated.map((s, i)=>i === idx ? {
2066
+ ...s,
2067
+ dir: curSort.dir
2068
+ } : s);
2069
+ }
2070
+ }
2071
+ return updated;
2072
+ });
2073
+ settledRef.current = curSort ? {
2074
+ key: curSort.key,
2075
+ dir: curSort.dir
2076
+ } : {
2077
+ key: undefined,
2078
+ dir: undefined
2079
+ };
2080
+ }, [
2081
+ sort.sort,
2082
+ toolbarSort.toolbarSorts,
2083
+ toolbarSort.setToolbarSorts,
2084
+ sort.clearSort,
2085
+ sort.setSort
2086
+ ]);
1966
2087
  return {
1967
2088
  ...sort,
1968
2089
  ...selection,
@@ -2658,29 +2779,56 @@ function toneFor(value) {
2658
2779
  }
2659
2780
  return BADGE_TONES[hash % BADGE_TONES.length];
2660
2781
  }
2661
- // Feature A/B (#9/#8) -- Attio's own flat 12-swatch chip palette, ported from
2662
- // crisp's `tokens/palette.ts` (`tagSwatch1..12`, measured live off Attio) rather
2663
- // than seed's own 6-tone `Badge` (`BADGE_TONES` above): a swatch, unlike a Badge
2664
- // tone, has no ring/border and its ink is a FLAT black on every swatch (crisp's own
2665
- // `tagSwatchInk`, `#000000` -- every swatch background is already a pale tint, so
2666
- // one dark foreground reads on all 12), not a per-tone contrast color. No seed token
2667
- // lands on any of these 12 hex values, so -- same footnote as the qvism recipe's own
2668
- // `ATTIO_BRAND_BLUE`/`RATING_FILLED` literals -- they stay literal here too.
2669
2782
  const CHIP_SWATCHES = [
2670
- "#fff3cc",
2671
- "#f4fbcb",
2672
- "#fdf7c4",
2673
- "#feecf3",
2674
- "#e0fced",
2675
- "#ddf7ff",
2676
- "#f6f7f7",
2677
- "#ffebeb",
2678
- "#feeee1",
2679
- "#e5eeff",
2680
- "#f5f0ff",
2681
- "#fdedff"
2783
+ {
2784
+ background: "#dbeafe",
2785
+ color: "#1e40af"
2786
+ },
2787
+ {
2788
+ background: "#dcfce7",
2789
+ color: "#166534"
2790
+ },
2791
+ {
2792
+ background: "#ede9fe",
2793
+ color: "#5b21b6"
2794
+ },
2795
+ {
2796
+ background: "#fef3c7",
2797
+ color: "#92400e"
2798
+ },
2799
+ {
2800
+ background: "#fee2e2",
2801
+ color: "#991b1b"
2802
+ },
2803
+ {
2804
+ background: "#ccfbf1",
2805
+ color: "#115e59"
2806
+ },
2807
+ {
2808
+ background: "#fce7f3",
2809
+ color: "#9d174d"
2810
+ },
2811
+ {
2812
+ background: "#e0e7ff",
2813
+ color: "#3730a3"
2814
+ },
2815
+ {
2816
+ background: "#cffafe",
2817
+ color: "#155e75"
2818
+ },
2819
+ {
2820
+ background: "#ecfccb",
2821
+ color: "#3f6212"
2822
+ },
2823
+ {
2824
+ background: "#ffe4e6",
2825
+ color: "#9f1239"
2826
+ },
2827
+ {
2828
+ background: "#e2e8f0",
2829
+ color: "#334155"
2830
+ }
2682
2831
  ];
2683
- const CHIP_SWATCH_INK = "#000000";
2684
2832
  /** Same stable multiply-and-add hash `toneFor` above already uses over seed's 6
2685
2833
  * Badge tones, just over this file's own 12-swatch palette instead -- same value,
2686
2834
  * same swatch, every render (crisp's own `toneFor`, `datatable.tsx`). */ function swatchIndexFor(value) {
@@ -2691,7 +2839,13 @@ const CHIP_SWATCH_INK = "#000000";
2691
2839
  return hash % CHIP_SWATCHES.length;
2692
2840
  }
2693
2841
  function swatchColorFor(value) {
2694
- return CHIP_SWATCHES[swatchIndexFor(value)];
2842
+ return CHIP_SWATCHES[swatchIndexFor(value)].background;
2843
+ }
2844
+ /** The per-hue dark text paired with `swatchColorFor`'s background, at the SAME
2845
+ * index (`swatchIndexFor`) -- replaces the old single flat `CHIP_SWATCH_INK`
2846
+ * (`#000000`) now that each background is saturated enough that one foreground no
2847
+ * longer reads well on all 12. */ function swatchInkFor(value) {
2848
+ return CHIP_SWATCHES[swatchIndexFor(value)].color;
2695
2849
  }
2696
2850
  function initialsFor(name) {
2697
2851
  const parts = name.trim().split(/\s+/);
@@ -2808,7 +2962,7 @@ function StatusCell({ value }) {
2808
2962
  });
2809
2963
  }
2810
2964
  /** One swatch chip -- `style` carries the per-value background/ink (computed by
2811
- * `swatchColorFor`/`CHIP_SWATCH_INK` above) since neither is a recipe token, the
2965
+ * `swatchColorFor`/`swatchInkFor` above) since neither is a recipe token, the
2812
2966
  * same "literal color as a computed prop" call `RatingCell`'s star fill already
2813
2967
  * makes. Shared by `ChipCell` (Feature A, single value) and `ChipListCell`/
2814
2968
  * editors.tsx's `ChipListEditor` (Feature B, multi value) so all three chip
@@ -2817,7 +2971,7 @@ function StatusCell({ value }) {
2817
2971
  className: className,
2818
2972
  style: {
2819
2973
  backgroundColor: swatchColorFor(value),
2820
- color: CHIP_SWATCH_INK
2974
+ color: swatchInkFor(value)
2821
2975
  },
2822
2976
  children: [
2823
2977
  value,
@@ -3121,8 +3275,28 @@ function RatingCell({ value, maxRating = 5 }) {
3121
3275
  let cursor = selectable ? 40 : 0;
3122
3276
  let pinnedCount = 0;
3123
3277
  const entries = ordered.map((key)=>byKey.get(key)).filter((column)=>Boolean(column)).map((column)=>{
3124
- const width = getColumnWidth(column.key) ?? column.width;
3278
+ const rawWidth = getColumnWidth(column.key) ?? column.width;
3125
3279
  const pinned = pinnedSet.has(column.key);
3280
+ // Fix (0.10.4, screenshot-confirmed pinned-column overlay): a pinned column
3281
+ // with no explicit/resized width used to keep `width` as `undefined` here,
3282
+ // which `DataTableColGroup` (DataTable.tsx) renders as an AUTO `<col>` --
3283
+ // under `table-layout: fixed`, the browser then sizes it from whatever
3284
+ // remaining space is left (anywhere from its full share down to 0, e.g. once
3285
+ // the OTHER explicit-width columns already exceed the container). Meanwhile
3286
+ // `cursor` below used `DEFAULT_PINNED_COLUMN_WIDTH` (180) as its OWN guess for
3287
+ // that same column's width, to compute every LATER pinned column's
3288
+ // `insetInlineStart`. Those two numbers -- the browser's real rendered width
3289
+ // and this file's 180px guess -- had no reason to agree, and whenever they
3290
+ // didn't, every pinned/unpinned column after the mismatched one landed at the
3291
+ // wrong screen position: the next pinned column's sticky box (positioned at
3292
+ // the WRONG, JS-assumed offset) then visually overlapped whatever unpinned
3293
+ // content actually continues from the browser's REAL (different) offset.
3294
+ // Forcing the SAME fallback into the `<col>` itself (not just the cursor
3295
+ // math) is what makes the two agree by construction -- a pinned column
3296
+ // without its own width now always renders at exactly
3297
+ // `DEFAULT_PINNED_COLUMN_WIDTH`, matching what every other pinned column's
3298
+ // offset already assumed it would be.
3299
+ const width = pinned && rawWidth === undefined ? DEFAULT_PINNED_COLUMN_WIDTH : rawWidth;
3126
3300
  const pinOffset = pinned ? cursor : 0;
3127
3301
  if (pinned) {
3128
3302
  cursor += width ?? DEFAULT_PINNED_COLUMN_WIDTH;
@@ -3527,7 +3701,7 @@ const TextFieldTextarea = /*#__PURE__*/ React.forwardRef(({ className, autoresiz
3527
3701
  });
3528
3702
  TextFieldTextarea.displayName = "TextFieldTextarea";
3529
3703
 
3530
- __insertCSS(".seed-data-table__root{box-sizing:border-box;display:flex;flex-direction:column;width:100%;border-width:1px;border-style:solid;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}.seed-data-table__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.seed-data-table__headerCell{box-sizing:border-box;position:sticky;top:0;z-index:2;vertical-align:middle;text-align:start;padding:0;height:var(--seed-dimension-x10);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium);letter-spacing:-.14px}.seed-data-table__headerCell:last-child{border-inline-end:none}.seed-data-table__headerCell[data-sortable]{cursor:pointer;user-select:none}.seed-data-table__headerCell [data-chevron]{opacity:0;transition:opacity .12s}.seed-data-table__headerCell[data-sortable]:hover [data-chevron]{opacity:.6}.seed-data-table__headerCell[data-sorted] [data-chevron]{opacity:1;color:var(--seed-color-fg-neutral)}.seed-data-table__headerCell:hover [data-column-menu]{opacity:1}.seed-data-table__headerCell [data-column-menu]:focus-visible,.seed-data-table__headerCell [data-column-menu][data-open]{opacity:1}.seed-data-table__headerCell[data-dragging]{opacity:.5}.seed-data-table__headerCell[data-sticky]{position:sticky;z-index:3;background-color:var(--seed-color-bg-layer-default)}.seed-data-table__headerCell{outline:var(--seed-dimension-x0_5) solid transparent;outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell:is(:focus-visible,[data-focus-visible]){outline:var(--seed-dimension-x0_5) solid var(--seed-color-stroke-focus-ring);outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell .seed-data-table-resize-handle{position:absolute;top:0;inset-inline-end:calc(7px / -2);width:7px;height:100%;z-index:4;display:flex;align-items:center;justify-content:center;cursor:col-resize;touch-action:none}.seed-data-table__headerCell .seed-data-table-resize-handle-inner{width:3px;height:100%;border-radius:3px;background-color:#0298d9;opacity:0;transition:opacity .1s}.seed-data-table__headerCell .seed-data-table-resize-handle:hover .seed-data-table-resize-handle-inner,.seed-data-table__headerCell .seed-data-table-resize-handle[data-resizing] .seed-data-table-resize-handle-inner{opacity:1}.seed-data-table__headerCellInner{box-sizing:border-box;display:flex;align-items:center;width:100%;height:100%;min-width:0;gap:var(--seed-dimension-x1_5);padding-inline:var(--seed-dimension-x3)}.seed-data-table__headerCellLabel{min-width:0;flex:1 1 0%;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__headerCellIcon{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;justify-content:center;width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-subtle);border:none;background:0 0;padding:0;font:inherit;cursor:pointer}.seed-data-table__headerCellIcon[data-active]{color:var(--seed-color-fg-neutral)}.seed-data-table__headerCellIcon[data-column-menu]{opacity:0;transition:opacity .12s}.seed-data-table__row{position:relative;background-color:var(--seed-color-bg-layer-default);--seed-data-table-row-bg:var(--seed-color-bg-layer-default)}.seed-data-table__row[data-clickable]{cursor:pointer}.seed-data-table__row:is([aria-selected=true],[data-selected]){background-color:color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default));--seed-data-table-row-bg:color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default))}.seed-data-table__row:is([aria-selected=true],[data-selected]):is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default)));--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default)))}.seed-data-table__cell{box-sizing:border-box;position:relative;vertical-align:middle;text-align:start;height:var(--seed-dimension-x9);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-top:none;border-inline-start:none;padding-block:0;padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-regular);letter-spacing:-.14px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cell:last-child{border-inline-end:none}tbody tr:last-child .seed-data-table__cell{border-bottom:none}.seed-data-table__cell[data-numeric]{text-align:end;font-variant-numeric:tabular-nums}.seed-data-table__cell[data-sticky]{position:sticky;z-index:1;background-color:var(--seed-data-table-row-bg)}.seed-data-table__cell[data-overlay-open]{overflow:visible;z-index:20}.seed-data-table__cell[data-editable]{cursor:default}.seed-data-table__cell .seed-data-table-edit-picker{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);min-width:0}.seed-data-table__cell .seed-data-table-edit-pending{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);animation:rotate .6s linear infinite}.seed-data-table__cell .seed-data-table-edit-error{position:absolute;top:100%;inset-inline-start:var(--seed-dimension-x3);inset-inline-end:var(--seed-dimension-x3);z-index:2;padding-top:2px;font-size:12px;line-height:1.3;color:var(--seed-color-fg-critical);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__entity{display:flex;align-items:center;min-width:0;gap:var(--seed-dimension-x1_5)}.seed-data-table__entityName{min-width:0;font-weight:var(--seed-font-weight-medium);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__tagList{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);overflow:hidden;min-width:0}.seed-data-table__entityActions{display:flex;align-items:center;gap:6px;margin-inline-start:auto;flex-shrink:0;opacity:0;transition:opacity .15s}tr:hover .seed-data-table__entityActions{opacity:1}.seed-data-table__entityActions:focus-within{opacity:1}.seed-data-table__entityAction{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin:0;padding:2px;border:none;border-radius:6px;background:0 0;font-family:inherit;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent);cursor:pointer;flex-shrink:0;transition:background-color .2s,color .2s,box-shadow .2s}.seed-data-table__entityAction:hover{background:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__link{color:var(--seed-color-fg-neutral);text-decoration:none;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__link:is(:hover,[data-hover]){text-decoration:underline}.seed-data-table__chip{box-sizing:border-box;display:inline-flex;align-items:center;flex-shrink:0;max-width:100%;height:22px;padding:0 4px;border-radius:7px;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__chipList{position:relative;display:flex;align-items:center;flex-wrap:nowrap;gap:3px;overflow:hidden;min-width:0;width:100%}.seed-data-table__chipOverflow{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;height:20px;padding:0 4px;border-radius:6px;background-color:#f6f7f7;color:#000;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;white-space:nowrap}.seed-data-table__chipListEditor{display:flex;align-items:center;flex-wrap:wrap;gap:3px;min-width:0;width:100%}.seed-data-table__chipRemove{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:12px;height:12px;margin:0;margin-inline-start:2px;padding:0;border:none;border-radius:999px;background:0 0;color:inherit;opacity:.6;cursor:pointer;transition:opacity .12s,background-color .12s}.seed-data-table__chipRemove:hover{opacity:1;background-color:rgba(0,0,0,.08)}.seed-data-table__chipInput{flex:1 1 auto;min-width:40px;height:22px;margin:0;padding:0;border:none;outline:0;background:0 0;font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);letter-spacing:-.14px}.seed-data-table__expandOverlay{box-sizing:border-box;position:absolute;top:-1px;inset-inline-start:-1px;inset-inline-end:-1px;z-index:10;min-height:calc(100% + 2px);display:flex;align-items:flex-start;padding-inline:var(--seed-dimension-x3);padding-block:var(--seed-dimension-x3);background-color:var(--seed-color-bg-layer-floating);border-radius:var(--seed-radius-r5);box-shadow:inset 0 0 0 1px var(--seed-color-stroke-neutral-weak),var(--seed-shadow-s3);color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);letter-spacing:-.14px;cursor:default}.seed-data-table__expandOverlayText{width:100%;min-width:0;white-space:normal;word-break:break-word}.seed-data-table__cellSuffixRow{display:flex;align-items:center;gap:4px;min-width:0;width:100%}.seed-data-table__cellSuffixText{flex:1 1 0%;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cellSuffixIcon{flex-shrink:0;display:inline-flex;align-items:center;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent)}.seed-data-table__toolbar{box-sizing:border-box;display:flex;align-items:center;width:100%;flex-shrink:0;min-height:49px;gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x3);border-top:1px solid var(--seed-color-stroke-neutral-muted)}.seed-data-table__search{position:relative;display:inline-flex;align-items:center;flex:1 1 0%;max-width:280px}.seed-data-table__search svg{position:absolute;inset-inline-start:var(--seed-dimension-x2);width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-muted);pointer-events:none}.seed-data-table__search input{width:100%;height:var(--seed-dimension-x8);padding-inline-start:var(--seed-dimension-x7);padding-inline-end:var(--seed-dimension-x2);border:none;border-radius:var(--seed-radius-r2);background-color:var(--seed-color-bg-layer-default);box-shadow:inset 0 0 0 1px var(--seed-color-stroke-neutral-weak);font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);outline:0;transition:box-shadow .1s var(--seed-timing-function-easing)}.seed-data-table__search input::placeholder{color:var(--seed-color-fg-neutral-subtle)}.seed-data-table__search input:focus{box-shadow:inset 0 0 0 2px var(--seed-color-stroke-neutral-contrast)}.seed-data-table__count{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t3);font-variant-numeric:tabular-nums}.seed-data-table__toolbarEnd{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;gap:var(--seed-dimension-x2)}.seed-data-table__scrollArea{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;flex:1 1 auto;min-height:0;overflow-x:auto;overflow-y:auto}.seed-data-table__scrollArea[data-scrolled-start] [data-sticky-edge]{clip-path:inset(0 -38px 0 0);box-shadow:6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__scrollArea[data-scrolled-end] [data-sticky-edge-end]{clip-path:inset(0 0 0 -38px);box-shadow:-6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__footerCell{box-sizing:border-box;position:sticky;bottom:0;z-index:2;vertical-align:middle;padding:0;height:var(--seed-dimension-x9);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none}.seed-data-table__footerCell:last-child{border-inline-end:none}.seed-data-table__footerCell .seed-data-table-column-calc-trigger{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);width:100%;height:100%;min-width:0;margin:0;padding:0 var(--seed-dimension-x3);border:none;background:0 0;color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);font-weight:var(--seed-font-weight-medium);white-space:nowrap;overflow:clip;cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__footerCell .seed-data-table-column-calc-trigger:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__footerCell .seed-data-table-column-calc-trigger[data-align=right]{justify-content:flex-end}.seed-data-table__footerCell .seed-data-table-column-calc-trigger svg{flex-shrink:0;opacity:.7}.seed-data-table__footerCell .seed-data-table-column-calc-placeholder{overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-value{min-width:0;flex-shrink:1;color:var(--seed-color-fg-neutral);font-variant-numeric:tabular-nums;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-op{min-width:0;flex-shrink:1;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__emptyState{box-sizing:border-box;text-align:center;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t4)}.seed-data-table__loadingState{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:10px;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium)}.seed-data-table__loadingState[data-inline]{padding-block:0;padding-inline:0;height:var(--seed-dimension-x9)}.seed-data-table__loadingState .seed-data-table-loading-spinner{flex-shrink:0;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);animation:rotate .6s linear infinite}.seed-data-table__addRowCell{box-sizing:border-box;padding:0;border-top:none}.seed-data-table__addRow{box-sizing:border-box;display:flex;align-items:center;width:100%;margin:0;border:none;border-top:1px solid var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);height:var(--seed-dimension-x9);gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x2);color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__addRow:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,var(--seed-color-bg-layer-default));color:var(--seed-color-fg-neutral)}.seed-data-table__addRow svg{flex-shrink:0}.seed-data-table__selectionCell{text-align:center;padding:0}.seed-data-table__root--surface_card{border-color:var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);border-radius:var(--seed-radius-r3)}.seed-data-table__root--surface_bleed{border-color:var(--seed-color-bg-transparent);background-color:var(--seed-color-bg-transparent)}.seed-data-table__row--interactive_true{transition:background-color .12s}.seed-data-table__row--interactive_true:is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,transparent);--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, var(--seed-color-bg-layer-default))}");
3704
+ __insertCSS(".seed-data-table__root{box-sizing:border-box;display:flex;flex-direction:column;width:100%;border-width:1px;border-style:solid;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}.seed-data-table__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.seed-data-table__headerCell{box-sizing:border-box;position:sticky;top:0;z-index:2;vertical-align:middle;text-align:start;padding:0;height:var(--seed-dimension-x10);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium);letter-spacing:-.14px}.seed-data-table__headerCell:last-child{border-inline-end:none}.seed-data-table__headerCell[data-sortable]{cursor:pointer;user-select:none}.seed-data-table__headerCell [data-chevron]{opacity:0;transition:opacity .12s}.seed-data-table__headerCell[data-sortable]:hover [data-chevron]{opacity:.6}.seed-data-table__headerCell[data-sorted] [data-chevron]{opacity:1;color:var(--seed-color-fg-neutral)}.seed-data-table__headerCell:hover [data-column-menu]{opacity:1}.seed-data-table__headerCell [data-column-menu]:focus-visible,.seed-data-table__headerCell [data-column-menu][data-open]{opacity:1}.seed-data-table__headerCell[data-dragging]{opacity:.5}.seed-data-table__headerCell[data-sticky]{position:sticky;z-index:3;background-color:var(--seed-color-bg-layer-default)}.seed-data-table__headerCell{outline:var(--seed-dimension-x0_5) solid transparent;outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell:is(:focus-visible,[data-focus-visible]){outline:var(--seed-dimension-x0_5) solid var(--seed-color-stroke-focus-ring);outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell .seed-data-table-resize-handle{position:absolute;top:0;inset-inline-end:calc(7px / -2);width:7px;height:100%;z-index:4;display:flex;align-items:center;justify-content:center;cursor:col-resize;touch-action:none}.seed-data-table__headerCell .seed-data-table-resize-handle-inner{width:3px;height:100%;border-radius:3px;background-color:#0298d9;opacity:0;transition:opacity .1s}.seed-data-table__headerCell .seed-data-table-resize-handle:hover .seed-data-table-resize-handle-inner,.seed-data-table__headerCell .seed-data-table-resize-handle[data-resizing] .seed-data-table-resize-handle-inner{opacity:1}.seed-data-table__headerCellInner{box-sizing:border-box;display:flex;align-items:center;width:100%;height:100%;min-width:0;gap:var(--seed-dimension-x1_5);padding-inline:var(--seed-dimension-x3)}.seed-data-table__headerCellLabel{min-width:0;flex:1 1 0%;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__headerCellIcon{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;justify-content:center;width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-subtle);border:none;background:0 0;padding:0;font:inherit;cursor:pointer}.seed-data-table__headerCellIcon[data-active]{color:var(--seed-color-fg-neutral)}.seed-data-table__headerCellIcon[data-column-menu]{opacity:0;transition:opacity .12s}.seed-data-table__row{position:relative;background-color:var(--seed-color-bg-layer-default);--seed-data-table-row-bg:var(--seed-color-bg-layer-default)}.seed-data-table__row[data-clickable]{cursor:pointer}.seed-data-table__row:is([aria-selected=true],[data-selected]){background-color:color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default));--seed-data-table-row-bg:color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default))}.seed-data-table__row:is([aria-selected=true],[data-selected]):is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default)));--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default)))}.seed-data-table__cell{box-sizing:border-box;position:relative;vertical-align:middle;text-align:start;height:var(--seed-dimension-x9);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-top:none;border-inline-start:none;padding-block:0;padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-regular);letter-spacing:-.14px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cell:not([data-editable]){user-select:none}.seed-data-table__cell:last-child{border-inline-end:none}tbody tr:last-child .seed-data-table__cell{border-bottom:none}.seed-data-table__cell[data-numeric]{text-align:end;font-variant-numeric:tabular-nums}.seed-data-table__cell[data-sticky]{position:sticky;z-index:1;background-color:var(--seed-data-table-row-bg)}.seed-data-table__cell[data-overlay-open]{overflow:visible;z-index:20}.seed-data-table__cell[data-editable]{cursor:default}.seed-data-table__cell .seed-data-table-edit-picker{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);min-width:0}.seed-data-table__cell .seed-data-table-edit-pending{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);animation:rotate .6s linear infinite}.seed-data-table__cell .seed-data-table-edit-error{position:absolute;top:100%;inset-inline-start:var(--seed-dimension-x3);inset-inline-end:var(--seed-dimension-x3);z-index:2;padding-top:2px;font-size:12px;line-height:1.3;color:var(--seed-color-fg-critical);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__entity{display:flex;align-items:center;min-width:0;gap:var(--seed-dimension-x1_5)}.seed-data-table__entityName{min-width:0;font-weight:var(--seed-font-weight-medium);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__tagList{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);overflow:hidden;min-width:0}.seed-data-table__entityActions{display:flex;align-items:center;gap:6px;margin-inline-start:auto;flex-shrink:0;opacity:0;transition:opacity .15s}tr:hover .seed-data-table__entityActions{opacity:1}.seed-data-table__entityActions:focus-within{opacity:1}.seed-data-table__entityAction{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin:0;padding:2px;border:none;border-radius:6px;background:0 0;font-family:inherit;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent);cursor:pointer;flex-shrink:0;transition:background-color .2s,color .2s,box-shadow .2s}.seed-data-table__entityAction:hover{background:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__link{color:var(--seed-color-fg-neutral);text-decoration:none;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__link:is(:hover,[data-hover]){text-decoration:underline}.seed-data-table__chip{box-sizing:border-box;display:inline-flex;align-items:center;flex-shrink:0;max-width:100%;height:22px;padding:0 4px;border-radius:7px;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__chipList{position:relative;display:flex;align-items:center;flex-wrap:nowrap;gap:3px;overflow:hidden;min-width:0;width:100%}.seed-data-table__chipOverflow{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;height:20px;padding:0 4px;border-radius:6px;background-color:#f6f7f7;color:#000;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;white-space:nowrap}.seed-data-table__chipListEditor{display:flex;align-items:center;flex-wrap:wrap;gap:3px;min-width:0;width:100%}.seed-data-table__chipRemove{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:12px;height:12px;margin:0;margin-inline-start:2px;padding:0;border:none;border-radius:999px;background:0 0;color:inherit;opacity:.6;cursor:pointer;transition:opacity .12s,background-color .12s}.seed-data-table__chipRemove:hover{opacity:1;background-color:rgba(0,0,0,.08)}.seed-data-table__chipInput{flex:1 1 auto;min-width:40px;height:22px;margin:0;padding:0;border:none;outline:0;background:0 0;font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);letter-spacing:-.14px}.seed-data-table__expandOverlay{box-sizing:border-box;position:absolute;top:-1px;inset-inline-start:-1px;inset-inline-end:-1px;z-index:10;min-height:calc(100% + 2px);display:flex;align-items:flex-start;padding-inline:var(--seed-dimension-x3);padding-block:var(--seed-dimension-x3);background-color:var(--seed-color-bg-layer-floating);border-radius:4px;box-shadow:none;border:1px solid #266df0;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);letter-spacing:-.14px;cursor:default}.seed-data-table__expandOverlayText{width:100%;min-width:0;white-space:normal;word-break:break-word}.seed-data-table__cellSuffixRow{display:flex;align-items:center;gap:4px;min-width:0;width:100%}.seed-data-table__cellSuffixText{flex:1 1 0%;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cellSuffixIcon{flex-shrink:0;display:inline-flex;align-items:center;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent)}.seed-data-table__toolbar{box-sizing:border-box;display:flex;align-items:center;width:100%;flex-shrink:0;min-height:49px;gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x3);border-top:1px solid var(--seed-color-stroke-neutral-muted)}.seed-data-table__search{position:relative;display:inline-flex;align-items:center;flex:1 1 0%;max-width:280px}.seed-data-table__search svg{position:absolute;inset-inline-start:var(--seed-dimension-x2);width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-muted);pointer-events:none}.seed-data-table__search input{width:100%;height:var(--seed-dimension-x8);padding-inline-start:var(--seed-dimension-x7);padding-inline-end:var(--seed-dimension-x2);border:none;border-radius:var(--seed-radius-r2);background-color:var(--seed-color-bg-layer-default);box-shadow:inset 0 0 0 1px var(--seed-color-stroke-neutral-weak);font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);outline:0;transition:box-shadow .1s var(--seed-timing-function-easing)}.seed-data-table__search input::placeholder{color:var(--seed-color-fg-neutral-subtle)}.seed-data-table__search input:focus{box-shadow:inset 0 0 0 2px var(--seed-color-stroke-neutral-contrast)}.seed-data-table__count{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t3);font-variant-numeric:tabular-nums}.seed-data-table__toolbarEnd{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;gap:var(--seed-dimension-x2)}.seed-data-table__scrollArea{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;flex:1 1 auto;min-height:0;overflow-x:auto;overflow-y:auto}.seed-data-table__scrollArea[data-scrolled-start] [data-sticky-edge]{clip-path:inset(0 -38px 0 0);box-shadow:6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__scrollArea[data-scrolled-end] [data-sticky-edge-end]{clip-path:inset(0 0 0 -38px);box-shadow:-6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__footerCell{box-sizing:border-box;position:sticky;bottom:0;z-index:2;vertical-align:middle;padding:0;height:var(--seed-dimension-x9);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none}.seed-data-table__footerCell:last-child{border-inline-end:none}.seed-data-table__footerCell .seed-data-table-column-calc-trigger{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);width:100%;height:100%;min-width:0;margin:0;padding:0 var(--seed-dimension-x3);border:none;background:0 0;color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);font-weight:var(--seed-font-weight-medium);white-space:nowrap;overflow:clip;cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__footerCell .seed-data-table-column-calc-trigger:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__footerCell .seed-data-table-column-calc-trigger[data-align=right]{justify-content:flex-end}.seed-data-table__footerCell .seed-data-table-column-calc-trigger svg{flex-shrink:0;opacity:.7}.seed-data-table__footerCell .seed-data-table-column-calc-placeholder{overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-value{min-width:0;flex-shrink:1;color:var(--seed-color-fg-neutral);font-variant-numeric:tabular-nums;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-op{min-width:0;flex-shrink:1;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__emptyState{box-sizing:border-box;text-align:center;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t4)}.seed-data-table__loadingState{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:10px;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium)}.seed-data-table__loadingState[data-inline]{padding-block:0;padding-inline:0;height:var(--seed-dimension-x9)}.seed-data-table__loadingState .seed-data-table-loading-spinner{flex-shrink:0;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);animation:rotate .6s linear infinite}.seed-data-table__addRowCell{box-sizing:border-box;padding:0;border-top:none}.seed-data-table__addRow{box-sizing:border-box;display:flex;align-items:center;width:100%;margin:0;border:none;border-top:1px solid var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);height:var(--seed-dimension-x9);gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x2);color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__addRow:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,var(--seed-color-bg-layer-default));color:var(--seed-color-fg-neutral)}.seed-data-table__addRow svg{flex-shrink:0}.seed-data-table__selectionCell{text-align:center;padding:0}.seed-data-table__root--surface_card{border-color:var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);border-radius:var(--seed-radius-r3)}.seed-data-table__root--surface_bleed{border-color:var(--seed-color-bg-transparent);background-color:var(--seed-color-bg-transparent)}.seed-data-table__row--interactive_true{transition:background-color .12s}.seed-data-table__row--interactive_true:is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,transparent);--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, var(--seed-color-bg-layer-default))}");
3531
3705
 
3532
3706
  const createClassName = (className, variants, compoundVariants = [])=>{
3533
3707
  const variantKeys = Object.keys(variants);
@@ -5347,9 +5521,9 @@ function ColumnRenameInput({ column, initialLabel, onDone }) {
5347
5521
  const columnLabel = typeof label === "string" ? label : column.key;
5348
5522
  const pinned = isColumnPinned(column.key);
5349
5523
  // Attio/GRC's "Remove sort" (live-review fix D) -- the header's own click-to-sort
5350
- // (`SortIndicator`/`toggleSort`, above) only cycles asc/desc once a column has been
5351
- // clicked; this is the only affordance back to no sort at all, so it only makes
5352
- // sense to show on the column that IS currently sorted.
5524
+ // (`SortIndicator`/`toggleSort`, above) already cycles asc -> desc -> none on its
5525
+ // own third click, but this stays as a one-click shortcut to the same place, so it
5526
+ // only makes sense to show on the column that IS currently sorted.
5353
5527
  const isSorted = sort?.key === column.key;
5354
5528
  const stopPropagation = (event)=>event.stopPropagation();
5355
5529
  return(// Live-review fix (D): a `MenuItem` inside `MenuPositioner` renders through a
package/dist/index.js CHANGED
@@ -1677,24 +1677,33 @@ function useDataTableSort(props) {
1677
1677
  // already passes its "cleared" shape through unconditionally; this now matches.
1678
1678
  onChange: onSortChange
1679
1679
  });
1680
+ // 3-state cycle (DATATABLE-ATTIO-SPEC.md: "asc/desc/none cycle") -- clicking a
1681
+ // DIFFERENT column always starts it fresh at asc, discarding whatever the previous
1682
+ // column's direction was (this stays a SINGLE-column secondary affordance, never a
1683
+ // second multi-sort list of its own). Clicking the SAME column steps asc -> desc ->
1684
+ // undefined ("none", i.e. this column drops out of the sort entirely) -> asc again.
1685
+ // Before this, the cycle wrapped desc -> asc forever, with no click-driven way back
1686
+ // to unsorted at all (a reported gap: "sort asc/desc has no option for no sort on
1687
+ // columns") -- `clearSort` below was the ONLY way there, now it's one of two.
1680
1688
  const toggleSort = useCallback((key)=>{
1681
1689
  setSort((current)=>{
1682
1690
  if (!current || current.key !== key) return {
1683
1691
  key,
1684
1692
  dir: "asc"
1685
1693
  };
1686
- return {
1694
+ if (current.dir === "asc") return {
1687
1695
  key,
1688
- dir: current.dir === "asc" ? "desc" : "asc"
1696
+ dir: "desc"
1689
1697
  };
1698
+ return undefined;
1690
1699
  });
1691
1700
  }, [
1692
1701
  setSort
1693
1702
  ]);
1694
- /** Attio/GRC's "Remove sort" -- the header click cycle (above) only ever toggles
1695
- * asc/desc once a column has been clicked once; this is the only way back to no
1696
- * sort at all. Exposed for a column's own header menu (`column-menu.tsx`'s
1697
- * `ColumnMenu`) to offer as a "Clear sort" item when that column is the sorted one. */ const clearSort = useCallback(()=>setSort(undefined), [
1703
+ /** Attio/GRC's "Remove sort" -- a second way back to no sort at all (the header
1704
+ * click cycle above reaches it too, on a column's third click), exposed for a
1705
+ * column's own header menu (`column-menu.tsx`'s `ColumnMenu`) to offer as a
1706
+ * "Clear sort" item when that column is the sorted one, without three clicks. */ const clearSort = useCallback(()=>setSort(undefined), [
1698
1707
  setSort
1699
1708
  ]);
1700
1709
  const getHeaderCellProps = useCallback((columnKey, sortable)=>{
@@ -1727,7 +1736,12 @@ function useDataTableSort(props) {
1727
1736
  sort,
1728
1737
  toggleSort,
1729
1738
  clearSort,
1730
- getHeaderCellProps
1739
+ getHeaderCellProps,
1740
+ // Exposed for `useDataTable.ts`'s own composition ONLY (unifying this single
1741
+ // click-to-sort column with `useDataTableToolbarSort`'s ordered list) -- not part
1742
+ // of the documented header-click contract (`toggleSort`/`clearSort` above are),
1743
+ // so no consumer-facing doc comment promotes it as a control of its own.
1744
+ setSort
1731
1745
  };
1732
1746
  }
1733
1747
 
@@ -1831,11 +1845,14 @@ const EMPTY_SORTS = [];
1831
1845
  * concern rather than folded into `useDataTableSort` (DATATABLE-ATTIO-SPEC.md: "compose,
1832
1846
  * don't fatten one hook"). `useDataTableSort` still owns the single click-to-sort
1833
1847
  * column/direction a header's own click toggles -- that stays Attio's SECONDARY sort
1834
- * affordance, untouched by this hook. This one is the PRIMARY toolbar Sort control: add
1835
- * a condition, pick its field/direction, reorder, remove -- multiple conditions apply in
1836
- * list order (sort[0] wins, later ones break ties; see the styled layer's
1837
- * `applyToolbarSorts`). The styled layer decides how the two combine (DataTable.tsx:
1838
- * toolbar sorts win when any exist, the single click-to-sort column otherwise).
1848
+ * affordance, a separate hook from this one. They are NOT independent state, though:
1849
+ * `useDataTable.ts`'s own composition keeps a header-driven column's entry in THIS
1850
+ * array in sync (added/updated/removed as that column's header cycles asc/desc/none),
1851
+ * so a consumer controlling only `toolbarSorts`/`onToolbarSortsChange` still sees a
1852
+ * header click, and the toolbar's own "Remove sort" x on that same entry clears the
1853
+ * header's side too. Multiple conditions apply in list order (sort[0] wins, later ones
1854
+ * break ties; see the styled layer's `applyToolbarSorts`). The styled layer
1855
+ * (`DataTable.tsx`) decides how the merged result actually sorts `data`.
1839
1856
  */ function useDataTableToolbarSort(props) {
1840
1857
  const { toolbarSorts: sortsProp, defaultToolbarSorts = EMPTY_SORTS, onToolbarSortsChange } = props;
1841
1858
  const [toolbarSorts = EMPTY_SORTS, setToolbarSorts] = useControllableState$1({
@@ -1920,8 +1937,13 @@ const EMPTY_SORTS = [];
1920
1937
  // header "is/is not" picker) -- DATATABLE-ATTIO-SPEC.md's Attio/crisp `TableToolbar`
1921
1938
  // model is now the PRIMARY filter/sort UX, not a per-column header affordance. They stay
1922
1939
  // SEPARATE sub-hooks from `useDataTableSort` rather than folded into it ("compose, don't
1923
- // fatten one hook") -- the styled layer decides how the toolbar's multi-condition sort
1924
- // and the header's single click-to-sort combine (DataTable.tsx).
1940
+ // fatten one hook") -- but this composition point below DOES reconcile the two into one
1941
+ // state (the two `useEffect`s after `infiniteScroll`), so a header click and the
1942
+ // toolbar's own Sort popover always agree on what's sorted, regardless of which prop
1943
+ // pair (`sort`/`onSortChange` or `toolbarSorts`/`onToolbarSortsChange`) a consumer
1944
+ // actually controls. `DataTable.tsx` (styled) still decides how the RESULT actually
1945
+ // sorts `data` (`effectiveSorts`/`applyToolbarSorts`) -- this layer only keeps the two
1946
+ // STATE pools in agreement.
1925
1947
  function useDataTable(props) {
1926
1948
  const sort = useDataTableSort(props);
1927
1949
  const selection = useDataTableSelection(props);
@@ -1944,6 +1966,105 @@ function useDataTable(props) {
1944
1966
  ...props,
1945
1967
  scrollRootRef: scroll.elementRef
1946
1968
  });
1969
+ // Unifies `sort` (the header's own single click-to-sort column, above) with
1970
+ // `toolbarSort.toolbarSorts` (the toolbar Sort popover's ordered list, above) into
1971
+ // ONE state instead of two -- before this, a header click only ever moved `sort`,
1972
+ // invisible to a consumer controlling `toolbarSorts`/`onToolbarSortsChange` (the
1973
+ // reported bug: clicking a header did nothing to the array the consumer's own Sort
1974
+ // popover reads, so the toolbar's "Sort" trigger/count and its popover rows silently
1975
+ // ignored every header click).
1976
+ //
1977
+ // ONE effect, not two -- an earlier version split this into a forward
1978
+ // (`sort` -> `toolbarSorts`) and a reverse (`toolbarSorts` -> `sort`) effect, each
1979
+ // keyed off its own dependency. That raced on the very first render: `useEffect`
1980
+ // runs every effect once on mount regardless of what "changed", so with
1981
+ // `defaultSort` set, the reverse effect ran in the SAME commit as the forward one,
1982
+ // read `toolbarSorts` BEFORE the forward effect's own (still-queued, not yet
1983
+ // re-rendered) write had landed, saw no entry for the column yet, and immediately
1984
+ // cleared `sort` right back out -- the defaultSort silently never took effect.
1985
+ // `settledRef` sidesteps this: it remembers the last `{key,dir}` this effect itself
1986
+ // confirmed, so on every run it can tell WHICH side moved since then, instead of
1987
+ // guessing from which dependency happens to have triggered the re-run.
1988
+ const settledRef = useRef({
1989
+ key: undefined,
1990
+ dir: undefined
1991
+ });
1992
+ useEffect(()=>{
1993
+ const curSort = sort.sort;
1994
+ const curEntry = curSort ? toolbarSort.toolbarSorts.find((s)=>s.key === curSort.key) : undefined;
1995
+ const settled = settledRef.current;
1996
+ const sortUnchangedSinceSettled = settled.key === curSort?.key && settled.dir === curSort?.dir;
1997
+ if (sortUnchangedSinceSettled) {
1998
+ // `sort` itself hasn't moved since we last settled -- if this effect is running
1999
+ // at all, `toolbarSorts` is what changed, so REVERSE-sync: the toolbar Sort
2000
+ // popover's own "Remove sort" x, or its direction select, touching this exact
2001
+ // column. Never reaches across to adopt some OTHER column added independently
2002
+ // via that popover -- only the column `sort` is already tracking.
2003
+ if (!curSort) return;
2004
+ if (!curEntry) {
2005
+ sort.clearSort();
2006
+ settledRef.current = {
2007
+ key: undefined,
2008
+ dir: undefined
2009
+ };
2010
+ } else if (curEntry.dir !== curSort.dir) {
2011
+ sort.setSort({
2012
+ key: curSort.key,
2013
+ dir: curEntry.dir
2014
+ });
2015
+ settledRef.current = {
2016
+ key: curSort.key,
2017
+ dir: curEntry.dir
2018
+ };
2019
+ }
2020
+ return;
2021
+ }
2022
+ // `sort` moved (a header click, Enter/Space, or `clearSort` -- column-menu.tsx's
2023
+ // menu item calls that directly, bypassing `toggleSort`) -- FORWARD-sync:
2024
+ // add/update/remove THIS column's own entry in `toolbarSorts`, leaving every
2025
+ // OTHER entry (added independently via the toolbar's own "+ Add sort") untouched.
2026
+ // The functional updater reads the CURRENT array off `current`, never off
2027
+ // `toolbarSort.toolbarSorts` in this closure, so a stale render can never clobber
2028
+ // an entry the toolbar's own popover added a moment earlier.
2029
+ const prevKey = settled.key;
2030
+ toolbarSort.setToolbarSorts((current)=>{
2031
+ let updated = current;
2032
+ if (prevKey && prevKey !== curSort?.key) {
2033
+ updated = updated.filter((s)=>s.key !== prevKey);
2034
+ }
2035
+ if (curSort) {
2036
+ const idx = updated.findIndex((s)=>s.key === curSort.key);
2037
+ if (idx === -1) {
2038
+ updated = [
2039
+ ...updated,
2040
+ {
2041
+ key: curSort.key,
2042
+ dir: curSort.dir
2043
+ }
2044
+ ];
2045
+ } else if (updated[idx].dir !== curSort.dir) {
2046
+ updated = updated.map((s, i)=>i === idx ? {
2047
+ ...s,
2048
+ dir: curSort.dir
2049
+ } : s);
2050
+ }
2051
+ }
2052
+ return updated;
2053
+ });
2054
+ settledRef.current = curSort ? {
2055
+ key: curSort.key,
2056
+ dir: curSort.dir
2057
+ } : {
2058
+ key: undefined,
2059
+ dir: undefined
2060
+ };
2061
+ }, [
2062
+ sort.sort,
2063
+ toolbarSort.toolbarSorts,
2064
+ toolbarSort.setToolbarSorts,
2065
+ sort.clearSort,
2066
+ sort.setSort
2067
+ ]);
1947
2068
  return {
1948
2069
  ...sort,
1949
2070
  ...selection,
@@ -2639,29 +2760,56 @@ function toneFor(value) {
2639
2760
  }
2640
2761
  return BADGE_TONES[hash % BADGE_TONES.length];
2641
2762
  }
2642
- // Feature A/B (#9/#8) -- Attio's own flat 12-swatch chip palette, ported from
2643
- // crisp's `tokens/palette.ts` (`tagSwatch1..12`, measured live off Attio) rather
2644
- // than seed's own 6-tone `Badge` (`BADGE_TONES` above): a swatch, unlike a Badge
2645
- // tone, has no ring/border and its ink is a FLAT black on every swatch (crisp's own
2646
- // `tagSwatchInk`, `#000000` -- every swatch background is already a pale tint, so
2647
- // one dark foreground reads on all 12), not a per-tone contrast color. No seed token
2648
- // lands on any of these 12 hex values, so -- same footnote as the qvism recipe's own
2649
- // `ATTIO_BRAND_BLUE`/`RATING_FILLED` literals -- they stay literal here too.
2650
2763
  const CHIP_SWATCHES = [
2651
- "#fff3cc",
2652
- "#f4fbcb",
2653
- "#fdf7c4",
2654
- "#feecf3",
2655
- "#e0fced",
2656
- "#ddf7ff",
2657
- "#f6f7f7",
2658
- "#ffebeb",
2659
- "#feeee1",
2660
- "#e5eeff",
2661
- "#f5f0ff",
2662
- "#fdedff"
2764
+ {
2765
+ background: "#dbeafe",
2766
+ color: "#1e40af"
2767
+ },
2768
+ {
2769
+ background: "#dcfce7",
2770
+ color: "#166534"
2771
+ },
2772
+ {
2773
+ background: "#ede9fe",
2774
+ color: "#5b21b6"
2775
+ },
2776
+ {
2777
+ background: "#fef3c7",
2778
+ color: "#92400e"
2779
+ },
2780
+ {
2781
+ background: "#fee2e2",
2782
+ color: "#991b1b"
2783
+ },
2784
+ {
2785
+ background: "#ccfbf1",
2786
+ color: "#115e59"
2787
+ },
2788
+ {
2789
+ background: "#fce7f3",
2790
+ color: "#9d174d"
2791
+ },
2792
+ {
2793
+ background: "#e0e7ff",
2794
+ color: "#3730a3"
2795
+ },
2796
+ {
2797
+ background: "#cffafe",
2798
+ color: "#155e75"
2799
+ },
2800
+ {
2801
+ background: "#ecfccb",
2802
+ color: "#3f6212"
2803
+ },
2804
+ {
2805
+ background: "#ffe4e6",
2806
+ color: "#9f1239"
2807
+ },
2808
+ {
2809
+ background: "#e2e8f0",
2810
+ color: "#334155"
2811
+ }
2663
2812
  ];
2664
- const CHIP_SWATCH_INK = "#000000";
2665
2813
  /** Same stable multiply-and-add hash `toneFor` above already uses over seed's 6
2666
2814
  * Badge tones, just over this file's own 12-swatch palette instead -- same value,
2667
2815
  * same swatch, every render (crisp's own `toneFor`, `datatable.tsx`). */ function swatchIndexFor(value) {
@@ -2672,7 +2820,13 @@ const CHIP_SWATCH_INK = "#000000";
2672
2820
  return hash % CHIP_SWATCHES.length;
2673
2821
  }
2674
2822
  function swatchColorFor(value) {
2675
- return CHIP_SWATCHES[swatchIndexFor(value)];
2823
+ return CHIP_SWATCHES[swatchIndexFor(value)].background;
2824
+ }
2825
+ /** The per-hue dark text paired with `swatchColorFor`'s background, at the SAME
2826
+ * index (`swatchIndexFor`) -- replaces the old single flat `CHIP_SWATCH_INK`
2827
+ * (`#000000`) now that each background is saturated enough that one foreground no
2828
+ * longer reads well on all 12. */ function swatchInkFor(value) {
2829
+ return CHIP_SWATCHES[swatchIndexFor(value)].color;
2676
2830
  }
2677
2831
  function initialsFor(name) {
2678
2832
  const parts = name.trim().split(/\s+/);
@@ -2789,7 +2943,7 @@ function StatusCell({ value }) {
2789
2943
  });
2790
2944
  }
2791
2945
  /** One swatch chip -- `style` carries the per-value background/ink (computed by
2792
- * `swatchColorFor`/`CHIP_SWATCH_INK` above) since neither is a recipe token, the
2946
+ * `swatchColorFor`/`swatchInkFor` above) since neither is a recipe token, the
2793
2947
  * same "literal color as a computed prop" call `RatingCell`'s star fill already
2794
2948
  * makes. Shared by `ChipCell` (Feature A, single value) and `ChipListCell`/
2795
2949
  * editors.tsx's `ChipListEditor` (Feature B, multi value) so all three chip
@@ -2798,7 +2952,7 @@ function StatusCell({ value }) {
2798
2952
  className: className,
2799
2953
  style: {
2800
2954
  backgroundColor: swatchColorFor(value),
2801
- color: CHIP_SWATCH_INK
2955
+ color: swatchInkFor(value)
2802
2956
  },
2803
2957
  children: [
2804
2958
  value,
@@ -3102,8 +3256,28 @@ function RatingCell({ value, maxRating = 5 }) {
3102
3256
  let cursor = selectable ? 40 : 0;
3103
3257
  let pinnedCount = 0;
3104
3258
  const entries = ordered.map((key)=>byKey.get(key)).filter((column)=>Boolean(column)).map((column)=>{
3105
- const width = getColumnWidth(column.key) ?? column.width;
3259
+ const rawWidth = getColumnWidth(column.key) ?? column.width;
3106
3260
  const pinned = pinnedSet.has(column.key);
3261
+ // Fix (0.10.4, screenshot-confirmed pinned-column overlay): a pinned column
3262
+ // with no explicit/resized width used to keep `width` as `undefined` here,
3263
+ // which `DataTableColGroup` (DataTable.tsx) renders as an AUTO `<col>` --
3264
+ // under `table-layout: fixed`, the browser then sizes it from whatever
3265
+ // remaining space is left (anywhere from its full share down to 0, e.g. once
3266
+ // the OTHER explicit-width columns already exceed the container). Meanwhile
3267
+ // `cursor` below used `DEFAULT_PINNED_COLUMN_WIDTH` (180) as its OWN guess for
3268
+ // that same column's width, to compute every LATER pinned column's
3269
+ // `insetInlineStart`. Those two numbers -- the browser's real rendered width
3270
+ // and this file's 180px guess -- had no reason to agree, and whenever they
3271
+ // didn't, every pinned/unpinned column after the mismatched one landed at the
3272
+ // wrong screen position: the next pinned column's sticky box (positioned at
3273
+ // the WRONG, JS-assumed offset) then visually overlapped whatever unpinned
3274
+ // content actually continues from the browser's REAL (different) offset.
3275
+ // Forcing the SAME fallback into the `<col>` itself (not just the cursor
3276
+ // math) is what makes the two agree by construction -- a pinned column
3277
+ // without its own width now always renders at exactly
3278
+ // `DEFAULT_PINNED_COLUMN_WIDTH`, matching what every other pinned column's
3279
+ // offset already assumed it would be.
3280
+ const width = pinned && rawWidth === undefined ? DEFAULT_PINNED_COLUMN_WIDTH : rawWidth;
3107
3281
  const pinOffset = pinned ? cursor : 0;
3108
3282
  if (pinned) {
3109
3283
  cursor += width ?? DEFAULT_PINNED_COLUMN_WIDTH;
@@ -3508,7 +3682,7 @@ const TextFieldTextarea = /*#__PURE__*/ forwardRef(({ className, autoresize = tr
3508
3682
  });
3509
3683
  TextFieldTextarea.displayName = "TextFieldTextarea";
3510
3684
 
3511
- __insertCSS(".seed-data-table__root{box-sizing:border-box;display:flex;flex-direction:column;width:100%;border-width:1px;border-style:solid;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}.seed-data-table__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.seed-data-table__headerCell{box-sizing:border-box;position:sticky;top:0;z-index:2;vertical-align:middle;text-align:start;padding:0;height:var(--seed-dimension-x10);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium);letter-spacing:-.14px}.seed-data-table__headerCell:last-child{border-inline-end:none}.seed-data-table__headerCell[data-sortable]{cursor:pointer;user-select:none}.seed-data-table__headerCell [data-chevron]{opacity:0;transition:opacity .12s}.seed-data-table__headerCell[data-sortable]:hover [data-chevron]{opacity:.6}.seed-data-table__headerCell[data-sorted] [data-chevron]{opacity:1;color:var(--seed-color-fg-neutral)}.seed-data-table__headerCell:hover [data-column-menu]{opacity:1}.seed-data-table__headerCell [data-column-menu]:focus-visible,.seed-data-table__headerCell [data-column-menu][data-open]{opacity:1}.seed-data-table__headerCell[data-dragging]{opacity:.5}.seed-data-table__headerCell[data-sticky]{position:sticky;z-index:3;background-color:var(--seed-color-bg-layer-default)}.seed-data-table__headerCell{outline:var(--seed-dimension-x0_5) solid transparent;outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell:is(:focus-visible,[data-focus-visible]){outline:var(--seed-dimension-x0_5) solid var(--seed-color-stroke-focus-ring);outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell .seed-data-table-resize-handle{position:absolute;top:0;inset-inline-end:calc(7px / -2);width:7px;height:100%;z-index:4;display:flex;align-items:center;justify-content:center;cursor:col-resize;touch-action:none}.seed-data-table__headerCell .seed-data-table-resize-handle-inner{width:3px;height:100%;border-radius:3px;background-color:#0298d9;opacity:0;transition:opacity .1s}.seed-data-table__headerCell .seed-data-table-resize-handle:hover .seed-data-table-resize-handle-inner,.seed-data-table__headerCell .seed-data-table-resize-handle[data-resizing] .seed-data-table-resize-handle-inner{opacity:1}.seed-data-table__headerCellInner{box-sizing:border-box;display:flex;align-items:center;width:100%;height:100%;min-width:0;gap:var(--seed-dimension-x1_5);padding-inline:var(--seed-dimension-x3)}.seed-data-table__headerCellLabel{min-width:0;flex:1 1 0%;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__headerCellIcon{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;justify-content:center;width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-subtle);border:none;background:0 0;padding:0;font:inherit;cursor:pointer}.seed-data-table__headerCellIcon[data-active]{color:var(--seed-color-fg-neutral)}.seed-data-table__headerCellIcon[data-column-menu]{opacity:0;transition:opacity .12s}.seed-data-table__row{position:relative;background-color:var(--seed-color-bg-layer-default);--seed-data-table-row-bg:var(--seed-color-bg-layer-default)}.seed-data-table__row[data-clickable]{cursor:pointer}.seed-data-table__row:is([aria-selected=true],[data-selected]){background-color:color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default));--seed-data-table-row-bg:color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default))}.seed-data-table__row:is([aria-selected=true],[data-selected]):is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default)));--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default)))}.seed-data-table__cell{box-sizing:border-box;position:relative;vertical-align:middle;text-align:start;height:var(--seed-dimension-x9);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-top:none;border-inline-start:none;padding-block:0;padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-regular);letter-spacing:-.14px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cell:last-child{border-inline-end:none}tbody tr:last-child .seed-data-table__cell{border-bottom:none}.seed-data-table__cell[data-numeric]{text-align:end;font-variant-numeric:tabular-nums}.seed-data-table__cell[data-sticky]{position:sticky;z-index:1;background-color:var(--seed-data-table-row-bg)}.seed-data-table__cell[data-overlay-open]{overflow:visible;z-index:20}.seed-data-table__cell[data-editable]{cursor:default}.seed-data-table__cell .seed-data-table-edit-picker{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);min-width:0}.seed-data-table__cell .seed-data-table-edit-pending{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);animation:rotate .6s linear infinite}.seed-data-table__cell .seed-data-table-edit-error{position:absolute;top:100%;inset-inline-start:var(--seed-dimension-x3);inset-inline-end:var(--seed-dimension-x3);z-index:2;padding-top:2px;font-size:12px;line-height:1.3;color:var(--seed-color-fg-critical);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__entity{display:flex;align-items:center;min-width:0;gap:var(--seed-dimension-x1_5)}.seed-data-table__entityName{min-width:0;font-weight:var(--seed-font-weight-medium);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__tagList{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);overflow:hidden;min-width:0}.seed-data-table__entityActions{display:flex;align-items:center;gap:6px;margin-inline-start:auto;flex-shrink:0;opacity:0;transition:opacity .15s}tr:hover .seed-data-table__entityActions{opacity:1}.seed-data-table__entityActions:focus-within{opacity:1}.seed-data-table__entityAction{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin:0;padding:2px;border:none;border-radius:6px;background:0 0;font-family:inherit;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent);cursor:pointer;flex-shrink:0;transition:background-color .2s,color .2s,box-shadow .2s}.seed-data-table__entityAction:hover{background:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__link{color:var(--seed-color-fg-neutral);text-decoration:none;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__link:is(:hover,[data-hover]){text-decoration:underline}.seed-data-table__chip{box-sizing:border-box;display:inline-flex;align-items:center;flex-shrink:0;max-width:100%;height:22px;padding:0 4px;border-radius:7px;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__chipList{position:relative;display:flex;align-items:center;flex-wrap:nowrap;gap:3px;overflow:hidden;min-width:0;width:100%}.seed-data-table__chipOverflow{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;height:20px;padding:0 4px;border-radius:6px;background-color:#f6f7f7;color:#000;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;white-space:nowrap}.seed-data-table__chipListEditor{display:flex;align-items:center;flex-wrap:wrap;gap:3px;min-width:0;width:100%}.seed-data-table__chipRemove{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:12px;height:12px;margin:0;margin-inline-start:2px;padding:0;border:none;border-radius:999px;background:0 0;color:inherit;opacity:.6;cursor:pointer;transition:opacity .12s,background-color .12s}.seed-data-table__chipRemove:hover{opacity:1;background-color:rgba(0,0,0,.08)}.seed-data-table__chipInput{flex:1 1 auto;min-width:40px;height:22px;margin:0;padding:0;border:none;outline:0;background:0 0;font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);letter-spacing:-.14px}.seed-data-table__expandOverlay{box-sizing:border-box;position:absolute;top:-1px;inset-inline-start:-1px;inset-inline-end:-1px;z-index:10;min-height:calc(100% + 2px);display:flex;align-items:flex-start;padding-inline:var(--seed-dimension-x3);padding-block:var(--seed-dimension-x3);background-color:var(--seed-color-bg-layer-floating);border-radius:var(--seed-radius-r5);box-shadow:inset 0 0 0 1px var(--seed-color-stroke-neutral-weak),var(--seed-shadow-s3);color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);letter-spacing:-.14px;cursor:default}.seed-data-table__expandOverlayText{width:100%;min-width:0;white-space:normal;word-break:break-word}.seed-data-table__cellSuffixRow{display:flex;align-items:center;gap:4px;min-width:0;width:100%}.seed-data-table__cellSuffixText{flex:1 1 0%;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cellSuffixIcon{flex-shrink:0;display:inline-flex;align-items:center;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent)}.seed-data-table__toolbar{box-sizing:border-box;display:flex;align-items:center;width:100%;flex-shrink:0;min-height:49px;gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x3);border-top:1px solid var(--seed-color-stroke-neutral-muted)}.seed-data-table__search{position:relative;display:inline-flex;align-items:center;flex:1 1 0%;max-width:280px}.seed-data-table__search svg{position:absolute;inset-inline-start:var(--seed-dimension-x2);width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-muted);pointer-events:none}.seed-data-table__search input{width:100%;height:var(--seed-dimension-x8);padding-inline-start:var(--seed-dimension-x7);padding-inline-end:var(--seed-dimension-x2);border:none;border-radius:var(--seed-radius-r2);background-color:var(--seed-color-bg-layer-default);box-shadow:inset 0 0 0 1px var(--seed-color-stroke-neutral-weak);font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);outline:0;transition:box-shadow .1s var(--seed-timing-function-easing)}.seed-data-table__search input::placeholder{color:var(--seed-color-fg-neutral-subtle)}.seed-data-table__search input:focus{box-shadow:inset 0 0 0 2px var(--seed-color-stroke-neutral-contrast)}.seed-data-table__count{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t3);font-variant-numeric:tabular-nums}.seed-data-table__toolbarEnd{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;gap:var(--seed-dimension-x2)}.seed-data-table__scrollArea{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;flex:1 1 auto;min-height:0;overflow-x:auto;overflow-y:auto}.seed-data-table__scrollArea[data-scrolled-start] [data-sticky-edge]{clip-path:inset(0 -38px 0 0);box-shadow:6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__scrollArea[data-scrolled-end] [data-sticky-edge-end]{clip-path:inset(0 0 0 -38px);box-shadow:-6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__footerCell{box-sizing:border-box;position:sticky;bottom:0;z-index:2;vertical-align:middle;padding:0;height:var(--seed-dimension-x9);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none}.seed-data-table__footerCell:last-child{border-inline-end:none}.seed-data-table__footerCell .seed-data-table-column-calc-trigger{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);width:100%;height:100%;min-width:0;margin:0;padding:0 var(--seed-dimension-x3);border:none;background:0 0;color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);font-weight:var(--seed-font-weight-medium);white-space:nowrap;overflow:clip;cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__footerCell .seed-data-table-column-calc-trigger:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__footerCell .seed-data-table-column-calc-trigger[data-align=right]{justify-content:flex-end}.seed-data-table__footerCell .seed-data-table-column-calc-trigger svg{flex-shrink:0;opacity:.7}.seed-data-table__footerCell .seed-data-table-column-calc-placeholder{overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-value{min-width:0;flex-shrink:1;color:var(--seed-color-fg-neutral);font-variant-numeric:tabular-nums;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-op{min-width:0;flex-shrink:1;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__emptyState{box-sizing:border-box;text-align:center;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t4)}.seed-data-table__loadingState{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:10px;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium)}.seed-data-table__loadingState[data-inline]{padding-block:0;padding-inline:0;height:var(--seed-dimension-x9)}.seed-data-table__loadingState .seed-data-table-loading-spinner{flex-shrink:0;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);animation:rotate .6s linear infinite}.seed-data-table__addRowCell{box-sizing:border-box;padding:0;border-top:none}.seed-data-table__addRow{box-sizing:border-box;display:flex;align-items:center;width:100%;margin:0;border:none;border-top:1px solid var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);height:var(--seed-dimension-x9);gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x2);color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__addRow:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,var(--seed-color-bg-layer-default));color:var(--seed-color-fg-neutral)}.seed-data-table__addRow svg{flex-shrink:0}.seed-data-table__selectionCell{text-align:center;padding:0}.seed-data-table__root--surface_card{border-color:var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);border-radius:var(--seed-radius-r3)}.seed-data-table__root--surface_bleed{border-color:var(--seed-color-bg-transparent);background-color:var(--seed-color-bg-transparent)}.seed-data-table__row--interactive_true{transition:background-color .12s}.seed-data-table__row--interactive_true:is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,transparent);--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, var(--seed-color-bg-layer-default))}");
3685
+ __insertCSS(".seed-data-table__root{box-sizing:border-box;display:flex;flex-direction:column;width:100%;border-width:1px;border-style:solid;font-family:Inter,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}.seed-data-table__table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed}.seed-data-table__headerCell{box-sizing:border-box;position:sticky;top:0;z-index:2;vertical-align:middle;text-align:start;padding:0;height:var(--seed-dimension-x10);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium);letter-spacing:-.14px}.seed-data-table__headerCell:last-child{border-inline-end:none}.seed-data-table__headerCell[data-sortable]{cursor:pointer;user-select:none}.seed-data-table__headerCell [data-chevron]{opacity:0;transition:opacity .12s}.seed-data-table__headerCell[data-sortable]:hover [data-chevron]{opacity:.6}.seed-data-table__headerCell[data-sorted] [data-chevron]{opacity:1;color:var(--seed-color-fg-neutral)}.seed-data-table__headerCell:hover [data-column-menu]{opacity:1}.seed-data-table__headerCell [data-column-menu]:focus-visible,.seed-data-table__headerCell [data-column-menu][data-open]{opacity:1}.seed-data-table__headerCell[data-dragging]{opacity:.5}.seed-data-table__headerCell[data-sticky]{position:sticky;z-index:3;background-color:var(--seed-color-bg-layer-default)}.seed-data-table__headerCell{outline:var(--seed-dimension-x0_5) solid transparent;outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell:is(:focus-visible,[data-focus-visible]){outline:var(--seed-dimension-x0_5) solid var(--seed-color-stroke-focus-ring);outline-offset:calc(var(--seed-dimension-x0_5) * -1)}.seed-data-table__headerCell .seed-data-table-resize-handle{position:absolute;top:0;inset-inline-end:calc(7px / -2);width:7px;height:100%;z-index:4;display:flex;align-items:center;justify-content:center;cursor:col-resize;touch-action:none}.seed-data-table__headerCell .seed-data-table-resize-handle-inner{width:3px;height:100%;border-radius:3px;background-color:#0298d9;opacity:0;transition:opacity .1s}.seed-data-table__headerCell .seed-data-table-resize-handle:hover .seed-data-table-resize-handle-inner,.seed-data-table__headerCell .seed-data-table-resize-handle[data-resizing] .seed-data-table-resize-handle-inner{opacity:1}.seed-data-table__headerCellInner{box-sizing:border-box;display:flex;align-items:center;width:100%;height:100%;min-width:0;gap:var(--seed-dimension-x1_5);padding-inline:var(--seed-dimension-x3)}.seed-data-table__headerCellLabel{min-width:0;flex:1 1 0%;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__headerCellIcon{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;justify-content:center;width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-subtle);border:none;background:0 0;padding:0;font:inherit;cursor:pointer}.seed-data-table__headerCellIcon[data-active]{color:var(--seed-color-fg-neutral)}.seed-data-table__headerCellIcon[data-column-menu]{opacity:0;transition:opacity .12s}.seed-data-table__row{position:relative;background-color:var(--seed-color-bg-layer-default);--seed-data-table-row-bg:var(--seed-color-bg-layer-default)}.seed-data-table__row[data-clickable]{cursor:pointer}.seed-data-table__row:is([aria-selected=true],[data-selected]){background-color:color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default));--seed-data-table-row-bg:color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default))}.seed-data-table__row:is([aria-selected=true],[data-selected]):is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,color-mix(in srgb,#0298d9 10%,var(--seed-color-bg-layer-default)));--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, color-mix(in srgb, #0298d9 10%, var(--seed-color-bg-layer-default)))}.seed-data-table__cell{box-sizing:border-box;position:relative;vertical-align:middle;text-align:start;height:var(--seed-dimension-x9);border-bottom:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-top:none;border-inline-start:none;padding-block:0;padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-regular);letter-spacing:-.14px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cell:not([data-editable]){user-select:none}.seed-data-table__cell:last-child{border-inline-end:none}tbody tr:last-child .seed-data-table__cell{border-bottom:none}.seed-data-table__cell[data-numeric]{text-align:end;font-variant-numeric:tabular-nums}.seed-data-table__cell[data-sticky]{position:sticky;z-index:1;background-color:var(--seed-data-table-row-bg)}.seed-data-table__cell[data-overlay-open]{overflow:visible;z-index:20}.seed-data-table__cell[data-editable]{cursor:default}.seed-data-table__cell .seed-data-table-edit-picker{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);min-width:0}.seed-data-table__cell .seed-data-table-edit-pending{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);animation:rotate .6s linear infinite}.seed-data-table__cell .seed-data-table-edit-error{position:absolute;top:100%;inset-inline-start:var(--seed-dimension-x3);inset-inline-end:var(--seed-dimension-x3);z-index:2;padding-top:2px;font-size:12px;line-height:1.3;color:var(--seed-color-fg-critical);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__entity{display:flex;align-items:center;min-width:0;gap:var(--seed-dimension-x1_5)}.seed-data-table__entityName{min-width:0;font-weight:var(--seed-font-weight-medium);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__tagList{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);overflow:hidden;min-width:0}.seed-data-table__entityActions{display:flex;align-items:center;gap:6px;margin-inline-start:auto;flex-shrink:0;opacity:0;transition:opacity .15s}tr:hover .seed-data-table__entityActions{opacity:1}.seed-data-table__entityActions:focus-within{opacity:1}.seed-data-table__entityAction{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin:0;padding:2px;border:none;border-radius:6px;background:0 0;font-family:inherit;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent);cursor:pointer;flex-shrink:0;transition:background-color .2s,color .2s,box-shadow .2s}.seed-data-table__entityAction:hover{background:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__link{color:var(--seed-color-fg-neutral);text-decoration:none;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__link:is(:hover,[data-hover]){text-decoration:underline}.seed-data-table__chip{box-sizing:border-box;display:inline-flex;align-items:center;flex-shrink:0;max-width:100%;height:22px;padding:0 4px;border-radius:7px;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__chipList{position:relative;display:flex;align-items:center;flex-wrap:nowrap;gap:3px;overflow:hidden;min-width:0;width:100%}.seed-data-table__chipOverflow{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;height:20px;padding:0 4px;border-radius:6px;background-color:#f6f7f7;color:#000;font-size:10px;font-weight:var(--seed-font-weight-regular);line-height:15px;white-space:nowrap}.seed-data-table__chipListEditor{display:flex;align-items:center;flex-wrap:wrap;gap:3px;min-width:0;width:100%}.seed-data-table__chipRemove{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:12px;height:12px;margin:0;margin-inline-start:2px;padding:0;border:none;border-radius:999px;background:0 0;color:inherit;opacity:.6;cursor:pointer;transition:opacity .12s,background-color .12s}.seed-data-table__chipRemove:hover{opacity:1;background-color:rgba(0,0,0,.08)}.seed-data-table__chipInput{flex:1 1 auto;min-width:40px;height:22px;margin:0;padding:0;border:none;outline:0;background:0 0;font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);letter-spacing:-.14px}.seed-data-table__expandOverlay{box-sizing:border-box;position:absolute;top:-1px;inset-inline-start:-1px;inset-inline-end:-1px;z-index:10;min-height:calc(100% + 2px);display:flex;align-items:flex-start;padding-inline:var(--seed-dimension-x3);padding-block:var(--seed-dimension-x3);background-color:var(--seed-color-bg-layer-floating);border-radius:4px;box-shadow:none;border:1px solid #266df0;color:var(--seed-color-fg-neutral);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);letter-spacing:-.14px;cursor:default}.seed-data-table__expandOverlayText{width:100%;min-width:0;white-space:normal;word-break:break-word}.seed-data-table__cellSuffixRow{display:flex;align-items:center;gap:4px;min-width:0;width:100%}.seed-data-table__cellSuffixText{flex:1 1 0%;min-width:0;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__cellSuffixIcon{flex-shrink:0;display:inline-flex;align-items:center;color:color-mix(in srgb,var(--seed-color-fg-neutral) 55%,transparent)}.seed-data-table__toolbar{box-sizing:border-box;display:flex;align-items:center;width:100%;flex-shrink:0;min-height:49px;gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x3);border-top:1px solid var(--seed-color-stroke-neutral-muted)}.seed-data-table__search{position:relative;display:inline-flex;align-items:center;flex:1 1 0%;max-width:280px}.seed-data-table__search svg{position:absolute;inset-inline-start:var(--seed-dimension-x2);width:var(--seed-dimension-x4);height:var(--seed-dimension-x4);color:var(--seed-color-fg-neutral-muted);pointer-events:none}.seed-data-table__search input{width:100%;height:var(--seed-dimension-x8);padding-inline-start:var(--seed-dimension-x7);padding-inline-end:var(--seed-dimension-x2);border:none;border-radius:var(--seed-radius-r2);background-color:var(--seed-color-bg-layer-default);box-shadow:inset 0 0 0 1px var(--seed-color-stroke-neutral-weak);font-family:inherit;font-size:var(--seed-font-size-t4);color:var(--seed-color-fg-neutral);outline:0;transition:box-shadow .1s var(--seed-timing-function-easing)}.seed-data-table__search input::placeholder{color:var(--seed-color-fg-neutral-subtle)}.seed-data-table__search input:focus{box-shadow:inset 0 0 0 2px var(--seed-color-stroke-neutral-contrast)}.seed-data-table__count{flex-shrink:0;color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t3);font-variant-numeric:tabular-nums}.seed-data-table__toolbarEnd{flex-shrink:0;margin-inline-start:auto;display:inline-flex;align-items:center;gap:var(--seed-dimension-x2)}.seed-data-table__scrollArea{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;flex:1 1 auto;min-height:0;overflow-x:auto;overflow-y:auto}.seed-data-table__scrollArea[data-scrolled-start] [data-sticky-edge]{clip-path:inset(0 -38px 0 0);box-shadow:6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__scrollArea[data-scrolled-end] [data-sticky-edge-end]{clip-path:inset(0 0 0 -38px);box-shadow:-6px 0 16px 4px rgba(0,0,0,.12)}.seed-data-table__footerCell{box-sizing:border-box;position:sticky;bottom:0;z-index:2;vertical-align:middle;padding:0;height:var(--seed-dimension-x9);background-color:var(--seed-color-bg-layer-default);border-top:1px solid var(--seed-color-stroke-neutral-muted);border-inline-end:1px solid var(--seed-color-stroke-neutral-muted);border-inline-start:none}.seed-data-table__footerCell:last-child{border-inline-end:none}.seed-data-table__footerCell .seed-data-table-column-calc-trigger{display:flex;align-items:center;gap:var(--seed-dimension-x1_5);width:100%;height:100%;min-width:0;margin:0;padding:0 var(--seed-dimension-x3);border:none;background:0 0;color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);font-weight:var(--seed-font-weight-medium);white-space:nowrap;overflow:clip;cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__footerCell .seed-data-table-column-calc-trigger:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,transparent);color:var(--seed-color-fg-neutral)}.seed-data-table__footerCell .seed-data-table-column-calc-trigger[data-align=right]{justify-content:flex-end}.seed-data-table__footerCell .seed-data-table-column-calc-trigger svg{flex-shrink:0;opacity:.7}.seed-data-table__footerCell .seed-data-table-column-calc-placeholder{overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-value{min-width:0;flex-shrink:1;color:var(--seed-color-fg-neutral);font-variant-numeric:tabular-nums;overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__footerCell .seed-data-table-column-calc-op{min-width:0;flex-shrink:1;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);overflow:clip;text-overflow:ellipsis;white-space:nowrap}.seed-data-table__emptyState{box-sizing:border-box;text-align:center;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:var(--seed-color-fg-neutral-subtle);font-size:var(--seed-font-size-t4)}.seed-data-table__loadingState{box-sizing:border-box;display:flex;align-items:center;justify-content:center;gap:10px;padding-block:var(--seed-dimension-x8);padding-inline:var(--seed-dimension-x3);color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);font-size:var(--seed-font-size-t4);line-height:var(--seed-line-height-t4);font-weight:var(--seed-font-weight-medium)}.seed-data-table__loadingState[data-inline]{padding-block:0;padding-inline:0;height:var(--seed-dimension-x9)}.seed-data-table__loadingState .seed-data-table-loading-spinner{flex-shrink:0;color:color-mix(in srgb,var(--seed-color-fg-neutral) 63%,transparent);animation:rotate .6s linear infinite}.seed-data-table__addRowCell{box-sizing:border-box;padding:0;border-top:none}.seed-data-table__addRow{box-sizing:border-box;display:flex;align-items:center;width:100%;margin:0;border:none;border-top:1px solid var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);height:var(--seed-dimension-x9);gap:var(--seed-dimension-x2);padding-inline:var(--seed-dimension-x2);color:var(--seed-color-fg-neutral-subtle);font-family:inherit;font-size:var(--seed-font-size-t4);cursor:pointer;transition:background-color .12s,color .12s}.seed-data-table__addRow:hover{background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 4%,var(--seed-color-bg-layer-default));color:var(--seed-color-fg-neutral)}.seed-data-table__addRow svg{flex-shrink:0}.seed-data-table__selectionCell{text-align:center;padding:0}.seed-data-table__root--surface_card{border-color:var(--seed-color-stroke-neutral-muted);background-color:var(--seed-color-bg-layer-default);border-radius:var(--seed-radius-r3)}.seed-data-table__root--surface_bleed{border-color:var(--seed-color-bg-transparent);background-color:var(--seed-color-bg-transparent)}.seed-data-table__row--interactive_true{transition:background-color .12s}.seed-data-table__row--interactive_true:is(:hover,[data-hover]){background-color:color-mix(in srgb,var(--seed-color-fg-neutral) 3%,transparent);--seed-data-table-row-bg:color-mix(in srgb, var(--seed-color-fg-neutral) 3%, var(--seed-color-bg-layer-default))}");
3512
3686
 
3513
3687
  const createClassName = (className, variants, compoundVariants = [])=>{
3514
3688
  const variantKeys = Object.keys(variants);
@@ -5328,9 +5502,9 @@ function ColumnRenameInput({ column, initialLabel, onDone }) {
5328
5502
  const columnLabel = typeof label === "string" ? label : column.key;
5329
5503
  const pinned = isColumnPinned(column.key);
5330
5504
  // Attio/GRC's "Remove sort" (live-review fix D) -- the header's own click-to-sort
5331
- // (`SortIndicator`/`toggleSort`, above) only cycles asc/desc once a column has been
5332
- // clicked; this is the only affordance back to no sort at all, so it only makes
5333
- // sense to show on the column that IS currently sorted.
5505
+ // (`SortIndicator`/`toggleSort`, above) already cycles asc -> desc -> none on its
5506
+ // own third click, but this stays as a one-click shortcut to the same place, so it
5507
+ // only makes sense to show on the column that IS currently sorted.
5334
5508
  const isSorted = sort?.key === column.key;
5335
5509
  const stopPropagation = (event)=>event.stopPropagation();
5336
5510
  return(// Live-review fix (D): a `MenuItem` inside `MenuPositioner` renders through a
package/dist/styles.css CHANGED
@@ -4857,6 +4857,11 @@
4857
4857
  overflow: clip;
4858
4858
  }
4859
4859
 
4860
+ .seed-data-table__cell:not([data-editable]) {
4861
+ -webkit-user-select: none;
4862
+ user-select: none;
4863
+ }
4864
+
4860
4865
  .seed-data-table__cell:last-child {
4861
4866
  border-inline-end: none;
4862
4867
  }
@@ -5088,13 +5093,14 @@ tr:hover .seed-data-table__entityActions, .seed-data-table__entityActions:focus-
5088
5093
  padding-inline: var(--seed-dimension-x3);
5089
5094
  padding-block: var(--seed-dimension-x3);
5090
5095
  background-color: var(--seed-color-bg-layer-floating);
5091
- border-radius: var(--seed-radius-r5);
5092
- box-shadow: inset 0 0 0 1px var(--seed-color-stroke-neutral-weak), var(--seed-shadow-s3);
5096
+ box-shadow: none;
5093
5097
  color: var(--seed-color-fg-neutral);
5094
5098
  font-size: var(--seed-font-size-t4);
5095
5099
  line-height: var(--seed-line-height-t4);
5096
5100
  letter-spacing: -.14px;
5097
5101
  cursor: default;
5102
+ border: 1px solid #266df0;
5103
+ border-radius: 4px;
5098
5104
  align-items: flex-start;
5099
5105
  display: flex;
5100
5106
  position: absolute;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crispy-seed/data-table",
3
- "version": "0.10.3",
3
+ "version": "0.10.5",
4
4
  "description": "Self-contained, publishable build of seed-design's Attio-measured DataTable, ResizablePanel and RecordPreview — one install, one CSS import.",
5
5
  "repository": {
6
6
  "type": "git",