@crisp-ui-kit/crisp 0.36.0 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/badge.css +5 -5
  2. package/dist/badge.layered.css +5 -5
  3. package/dist/cjs/components/badge/badge.recipe.js +11 -5
  4. package/dist/cjs/components/contextmenu/contextmenu.js +25 -8
  5. package/dist/cjs/components/contextmenu/contextmenu.recipe.js +5 -2
  6. package/dist/cjs/components/dialog/dialog.js +1 -1
  7. package/dist/cjs/components/dialog/dialog.recipe.js +1 -1
  8. package/dist/cjs/components/fileupload/fileupload.js +2 -2
  9. package/dist/cjs/components/menu/menu.js +20 -3
  10. package/dist/cjs/components/menu/menu.recipe.js +4 -3
  11. package/dist/cjs/components/multiselect/multiselect.js +29 -12
  12. package/dist/cjs/components/multiselect/multiselect.recipe.js +17 -5
  13. package/dist/cjs/components/popover/popover.js +25 -8
  14. package/dist/cjs/components/popover/popover.recipe.js +5 -3
  15. package/dist/cjs/components/select/select.js +32 -11
  16. package/dist/cjs/components/select/select.recipe.js +19 -4
  17. package/dist/cjs/components/tabletoolbar/tabletoolbar.js +50 -6
  18. package/dist/cjs/core/floating-portal.js +28 -0
  19. package/dist/cjs/core/floating-stack.js +54 -0
  20. package/dist/cjs/core/index.js +6 -1
  21. package/dist/cjs/product/recordstable/recordstable.js +15 -4
  22. package/dist/cjs/tokens/palette.js +23 -0
  23. package/dist/cjs/tokens/semantic.js +7 -0
  24. package/dist/contextmenu.css +1 -1
  25. package/dist/contextmenu.layered.css +1 -1
  26. package/dist/dialog.css +1 -1
  27. package/dist/dialog.layered.css +1 -1
  28. package/dist/esm/components/badge/badge.recipe.js +11 -5
  29. package/dist/esm/components/contextmenu/contextmenu.js +25 -8
  30. package/dist/esm/components/contextmenu/contextmenu.recipe.js +5 -2
  31. package/dist/esm/components/dialog/dialog.js +1 -1
  32. package/dist/esm/components/dialog/dialog.recipe.js +1 -1
  33. package/dist/esm/components/fileupload/fileupload.js +2 -2
  34. package/dist/esm/components/menu/menu.js +21 -4
  35. package/dist/esm/components/menu/menu.recipe.js +4 -3
  36. package/dist/esm/components/multiselect/multiselect.js +30 -13
  37. package/dist/esm/components/multiselect/multiselect.recipe.js +17 -5
  38. package/dist/esm/components/popover/popover.js +26 -9
  39. package/dist/esm/components/popover/popover.recipe.js +5 -3
  40. package/dist/esm/components/select/select.js +33 -12
  41. package/dist/esm/components/select/select.recipe.js +19 -4
  42. package/dist/esm/components/tabletoolbar/tabletoolbar.js +51 -7
  43. package/dist/esm/core/floating-portal.js +25 -0
  44. package/dist/esm/core/floating-stack.js +50 -0
  45. package/dist/esm/core/index.js +2 -0
  46. package/dist/esm/product/recordstable/recordstable.js +16 -5
  47. package/dist/esm/tokens/palette.js +23 -0
  48. package/dist/esm/tokens/semantic.js +7 -0
  49. package/dist/menu.css +1 -1
  50. package/dist/menu.layered.css +1 -1
  51. package/dist/multiselect.css +7 -1
  52. package/dist/multiselect.d.ts +2 -2
  53. package/dist/multiselect.layered.css +7 -1
  54. package/dist/native/tokens.d.ts +1 -1
  55. package/dist/native/tokens.js +24 -4
  56. package/dist/popover.css +1 -1
  57. package/dist/popover.layered.css +1 -1
  58. package/dist/select.css +7 -1
  59. package/dist/select.d.ts +2 -1
  60. package/dist/select.layered.css +7 -1
  61. package/dist/styles.css +33 -11
  62. package/dist/styles.layered.css +33 -11
  63. package/dist/tokens.css +10 -0
  64. package/dist/tokens.json +24 -4
  65. package/dist/types/components/fileupload/fileupload.d.ts +1 -1
  66. package/dist/types/components/multiselect/multiselect.d.ts +3 -1
  67. package/dist/types/components/multiselect/multiselect.recipe.d.ts +18 -3
  68. package/dist/types/components/select/select.d.ts +4 -1
  69. package/dist/types/components/select/select.recipe.d.ts +12 -0
  70. package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +10 -1
  71. package/dist/types/core/floating-portal.d.ts +25 -0
  72. package/dist/types/core/floating-stack.d.ts +13 -0
  73. package/dist/types/core/index.d.ts +2 -0
  74. package/dist/types/product/sidebar/index.d.ts +1 -1
  75. package/dist/types/tokens/contract.d.ts +5 -0
  76. package/dist/types/tokens/palette.d.ts +20 -0
  77. package/dist/types/tokens/semantic.d.ts +7 -0
  78. package/package.json +1 -1
@@ -14,7 +14,7 @@ import { Menu, MenuItem, useMenuKeyboard } from "../../components/menu/index.js"
14
14
  import { MultiSelect } from "../../components/multiselect/index.js";
15
15
  import { Select } from "../../components/select/index.js";
16
16
  import { Switch } from "../../components/switch/index.js";
17
- import { isRtlElement, usePrefersReducedMotion } from "../../core/index.js";
17
+ import { isInsideLaterFloatingLayer, isRtlElement, usePrefersReducedMotion, } from "../../core/index.js";
18
18
  import { companyLogos } from "./company-logos.js";
19
19
  import { recordstableRecipe } from "./recordstable.recipe.js";
20
20
  const EDITABLE = new Set(["text", "number", "url", "currency"]);
@@ -460,8 +460,15 @@ export function RecordsTable({ labels, columns: columnsProp = defaultColumns, ro
460
460
  return;
461
461
  const onDown = (e) => {
462
462
  const t = e.target;
463
- if (!t.closest(".crisp-recordstable-menu, [data-menu-trigger]"))
464
- setOpenMenu(null);
463
+ if (t.closest(".crisp-recordstable-menu, [data-menu-trigger]"))
464
+ return;
465
+ // #339: a Select/MultiSelect/Menu opened from inside this popover now
466
+ // portals to document.body, so it's no longer inside
467
+ // .crisp-recordstable-menu by DOM containment -- check the shared
468
+ // floating-layer stack too.
469
+ if (isInsideLaterFloatingLayer(t, null))
470
+ return;
471
+ setOpenMenu(null);
465
472
  };
466
473
  const onKey = (e) => e.key === "Escape" && setOpenMenu(null);
467
474
  document.addEventListener("mousedown", onDown);
@@ -476,8 +483,12 @@ export function RecordsTable({ labels, columns: columnsProp = defaultColumns, ro
476
483
  if (!ctxMenu)
477
484
  return;
478
485
  const onDown = (e) => {
479
- if (!e.target.closest(".crisp-recordstable-ctx"))
480
- setCtxMenu(null);
486
+ const t = e.target;
487
+ if (t.closest(".crisp-recordstable-ctx"))
488
+ return;
489
+ if (isInsideLaterFloatingLayer(t, null))
490
+ return;
491
+ setCtxMenu(null);
481
492
  };
482
493
  const onKey = (e) => e.key === "Escape" && setCtxMenu(null);
483
494
  document.addEventListener("mousedown", onDown);
@@ -57,4 +57,27 @@ export const palette = {
57
57
  cyan600: { light: "#00b9eb", dark: "#00b9eb" },
58
58
  purple600: { light: "#9b69ff", dark: "#9b69ff" },
59
59
  graySidebar: { light: "#fbfbfb", dark: "#0e0f10" },
60
+ // Soft Badge's text colour (#323): the *600 tones above, used directly as
61
+ // soft-badge text, fail AA on their own soft tint in light mode (2.97-3.87)
62
+ // and brand fails in dark too (3.83) -- everything else already brightens
63
+ // enough in dark to pass (measured: 5.60-6.77). Attio's own soft tag pills
64
+ // (a company's Categories field, app.attio.com, 2026-09-23) don't reuse the
65
+ // accent colour as text either: they shift it toward black (light) or white
66
+ // (dark) at roughly the same relative luminance regardless of hue --
67
+ // measured 5 different category colours in dark mode (L 0.61-0.75) and two
68
+ // in light (L 0.08-0.10), a tight enough cluster to generalise the SHIFT,
69
+ // not the exact colour, to crisp's own four accent hues. Computed to clear
70
+ // AA with the same margin Attio's pills measured at (5.5-6.5:1) against
71
+ // crisp's EXISTING soft-tint background -- the tint itself is unchanged.
72
+ // Dark values that already passed keep their *600 dark value unchanged.
73
+ softBrandText: { light: "#2057bd", dark: "#568df3" },
74
+ softSuccessText: { light: "#186b3d", dark: "#2ea968" },
75
+ softWarningText: { light: "#80520d", dark: "#e0982a" },
76
+ softDangerText: { light: "#a33539", dark: "#ff5a5f" },
77
+ // Same reasoning, for Badge's neutral tone: fg-muted on bg-raised measures
78
+ // 4.40 in light (just under AA) and 6.77 in dark (already fine). Unlike
79
+ // fg-muted/bg-raised themselves (system-wide, measured from Attio, kept
80
+ // as-is per build/spec-check.mjs's own note), this token exists only for
81
+ // Badge's soft-neutral text, so darkening it doesn't move any other surface.
82
+ softNeutralText: { light: "#686870", dark: "#9a9aa2" },
60
83
  };
@@ -51,4 +51,11 @@ export const semantic = {
51
51
  // #fbfbfb — the subtle raised fill; the active tab pill uses the same
52
52
  // value as the sidebar, so it shares the palette entry under a neutral name.
53
53
  bgSubtle: "graySidebar",
54
+ /** Soft Badge's text colour (#323) — see palette.ts's comment on the
55
+ * soft*Text entries for the Attio measurement this is derived from. */
56
+ fgBrandSoft: "softBrandText",
57
+ fgSuccessSoft: "softSuccessText",
58
+ fgWarningSoft: "softWarningText",
59
+ fgDangerSoft: "softDangerText",
60
+ fgNeutralSoft: "softNeutralText",
54
61
  };
package/dist/menu.css CHANGED
@@ -1,6 +1,6 @@
1
1
  .crisp-menu {
2
2
  position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
3
- & .crisp-menu-content { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
3
+ & .crisp-menu-content { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
4
4
  & .crisp-menu-content[data-align="end"] { transform-origin: top right; }
5
5
  & .crisp-menu-content[data-up] { transform-origin: bottom left; }
6
6
  & .crisp-menu-content[data-up][data-align="end"] { transform-origin: bottom right; }
@@ -1,7 +1,7 @@
1
1
  @layer crisp-components {
2
2
  .crisp-menu {
3
3
  position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
4
- & .crisp-menu-content { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
4
+ & .crisp-menu-content { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
5
5
  & .crisp-menu-content[data-align="end"] { transform-origin: top right; }
6
6
  & .crisp-menu-content[data-up] { transform-origin: bottom left; }
7
7
  & .crisp-menu-content[data-up][data-align="end"] { transform-origin: bottom right; }
@@ -8,7 +8,7 @@
8
8
  & .crisp-multiselect-placeholder { color: var(--crisp-fg-muted); }
9
9
  & .crisp-multiselect-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
10
10
  & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); }
11
- & .crisp-multiselect-listbox { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
11
+ & .crisp-multiselect-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
12
12
  & .crisp-multiselect-listbox[data-up] { transform-origin: bottom left; }
13
13
  & .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
14
14
  & .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
@@ -30,6 +30,12 @@
30
30
  & .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); }
31
31
  & .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
32
32
  }
33
+ .crisp-multiselect--invalid_true {
34
+ & .crisp-multiselect-trigger, & .crisp-multiselect-trigger:hover, & .crisp-multiselect-trigger[data-open], & .crisp-multiselect-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
35
+ }
36
+ .crisp-multiselect--invalid_false {
37
+
38
+ }
33
39
 
34
40
  @media (prefers-reduced-motion: reduce) {
35
41
  .crisp-multiselect, .crisp-multiselect * {
@@ -1,7 +1,7 @@
1
1
  import type { RecipeFn } from "../core/types";
2
2
 
3
3
  export interface MultiselectVariants {
4
-
4
+ invalid?: boolean;
5
5
  }
6
6
 
7
- export declare const multiselectRecipe: RecipeFn<{ }>;
7
+ export declare const multiselectRecipe: RecipeFn<{ invalid: { true: string; false: string } }>;
@@ -9,7 +9,7 @@
9
9
  & .crisp-multiselect-placeholder { color: var(--crisp-fg-muted); }
10
10
  & .crisp-multiselect-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
11
11
  & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); }
12
- & .crisp-multiselect-listbox { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
12
+ & .crisp-multiselect-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
13
13
  & .crisp-multiselect-listbox[data-up] { transform-origin: bottom left; }
14
14
  & .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
15
15
  & .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
@@ -31,6 +31,12 @@
31
31
  & .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); }
32
32
  & .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
33
33
  }
34
+ .crisp-multiselect--invalid_true {
35
+ & .crisp-multiselect-trigger, & .crisp-multiselect-trigger:hover, & .crisp-multiselect-trigger[data-open], & .crisp-multiselect-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
36
+ }
37
+ .crisp-multiselect--invalid_false {
38
+
39
+ }
34
40
 
35
41
  @media (prefers-reduced-motion: reduce) {
36
42
  .crisp-multiselect, .crisp-multiselect * {
@@ -2,7 +2,7 @@
2
2
  // The same tokens the CSS custom properties carry, resolved per theme, with
3
3
  // dimensions as numbers for React Native and Lynx style objects.
4
4
  export type Theme = "light" | "dark";
5
- export type ColorTokens = Record<"bgBrandSolid" | "bgBrandSolidPressed" | "fgOnBrand" | "fgOnTone" | "bgSurface" | "bgRaised" | "borderDefault" | "borderSubtle" | "ringNeutral" | "bgTileActive" | "shadowTileActive" | "bgOverlayFrost" | "shadowOverlay1" | "shadowOverlay2" | "shadowOverlay3" | "bgPopover" | "ringPopover" | "shadowPopover1" | "shadowPopover2" | "shadowPopover3" | "fgPrimary" | "fgMuted" | "bgDanger" | "bgDangerSolid" | "strokeFieldFocus" | "fgDisabled" | "bgNeutralWeak" | "bgNeutralInverted" | "fgOnNeutralInverted" | "fgNeutralSubtle" | "fgNeutralMuted" | "strokeFocusRing" | "bgSuccess" | "bgWarning" | "bgOrange" | "bgCyan" | "bgPurple" | "bgSidebar" | "bgSubtle", string>;
5
+ export type ColorTokens = Record<"bgBrandSolid" | "bgBrandSolidPressed" | "fgOnBrand" | "fgOnTone" | "bgSurface" | "bgRaised" | "borderDefault" | "borderSubtle" | "ringNeutral" | "bgTileActive" | "shadowTileActive" | "bgOverlayFrost" | "shadowOverlay1" | "shadowOverlay2" | "shadowOverlay3" | "bgPopover" | "ringPopover" | "shadowPopover1" | "shadowPopover2" | "shadowPopover3" | "fgPrimary" | "fgMuted" | "bgDanger" | "bgDangerSolid" | "strokeFieldFocus" | "fgDisabled" | "bgNeutralWeak" | "bgNeutralInverted" | "fgOnNeutralInverted" | "fgNeutralSubtle" | "fgNeutralMuted" | "strokeFocusRing" | "bgSuccess" | "bgWarning" | "bgOrange" | "bgCyan" | "bgPurple" | "bgSidebar" | "bgSubtle" | "fgBrandSoft" | "fgSuccessSoft" | "fgWarningSoft" | "fgDangerSoft" | "fgNeutralSoft", string>;
6
6
  export declare const tokens: {
7
7
  color: Record<Theme, ColorTokens>;
8
8
  palette: Record<Theme, Record<string, string>>;
@@ -42,7 +42,12 @@ export const tokens = {
42
42
  "bgCyan": "#00b9eb",
43
43
  "bgPurple": "#9b69ff",
44
44
  "bgSidebar": "#fbfbfb",
45
- "bgSubtle": "#fbfbfb"
45
+ "bgSubtle": "#fbfbfb",
46
+ "fgBrandSoft": "#2057bd",
47
+ "fgSuccessSoft": "#186b3d",
48
+ "fgWarningSoft": "#80520d",
49
+ "fgDangerSoft": "#a33539",
50
+ "fgNeutralSoft": "#686870"
46
51
  },
47
52
  "dark": {
48
53
  "bgBrandSolid": "#266df0",
@@ -83,7 +88,12 @@ export const tokens = {
83
88
  "bgCyan": "#00b9eb",
84
89
  "bgPurple": "#9b69ff",
85
90
  "bgSidebar": "#0e0f10",
86
- "bgSubtle": "#0e0f10"
91
+ "bgSubtle": "#0e0f10",
92
+ "fgBrandSoft": "#568df3",
93
+ "fgSuccessSoft": "#2ea968",
94
+ "fgWarningSoft": "#e0982a",
95
+ "fgDangerSoft": "#ff5a5f",
96
+ "fgNeutralSoft": "#9a9aa2"
87
97
  }
88
98
  },
89
99
  "palette": {
@@ -125,7 +135,12 @@ export const tokens = {
125
135
  "orange600": "#f97514",
126
136
  "cyan600": "#00b9eb",
127
137
  "purple600": "#9b69ff",
128
- "graySidebar": "#fbfbfb"
138
+ "graySidebar": "#fbfbfb",
139
+ "softBrandText": "#2057bd",
140
+ "softSuccessText": "#186b3d",
141
+ "softWarningText": "#80520d",
142
+ "softDangerText": "#a33539",
143
+ "softNeutralText": "#686870"
129
144
  },
130
145
  "dark": {
131
146
  "gray00": "#0a0a0a",
@@ -165,7 +180,12 @@ export const tokens = {
165
180
  "orange600": "#f97514",
166
181
  "cyan600": "#00b9eb",
167
182
  "purple600": "#9b69ff",
168
- "graySidebar": "#0e0f10"
183
+ "graySidebar": "#0e0f10",
184
+ "softBrandText": "#568df3",
185
+ "softSuccessText": "#2ea968",
186
+ "softWarningText": "#e0982a",
187
+ "softDangerText": "#ff5a5f",
188
+ "softNeutralText": "#9a9aa2"
169
189
  }
170
190
  },
171
191
  "space": {
package/dist/popover.css CHANGED
@@ -1,6 +1,6 @@
1
1
  .crisp-popover {
2
2
  display: contents; font-family: var(--crisp-font-sans);
3
- & .crisp-popover-content { position: fixed; z-index: 60; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
3
+ & .crisp-popover-content { position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
4
4
  & .crisp-popover-content[data-align="end"] { transform-origin: top right; }
5
5
  & .crisp-popover-content[data-up] { transform-origin: bottom left; }
6
6
  }
@@ -1,7 +1,7 @@
1
1
  @layer crisp-components {
2
2
  .crisp-popover {
3
3
  display: contents; font-family: var(--crisp-font-sans);
4
- & .crisp-popover-content { position: fixed; z-index: 60; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
4
+ & .crisp-popover-content { position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
5
5
  & .crisp-popover-content[data-align="end"] { transform-origin: top right; }
6
6
  & .crisp-popover-content[data-up] { transform-origin: bottom left; }
7
7
  }
package/dist/select.css CHANGED
@@ -8,7 +8,7 @@
8
8
  & .crisp-select-placeholder { color: var(--crisp-fg-muted); }
9
9
  & .crisp-select-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
10
10
  & .crisp-select-trigger[data-open] .crisp-select-chevron { transform: rotate(180deg); }
11
- & .crisp-select-listbox { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
11
+ & .crisp-select-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
12
12
  & .crisp-select-listbox[data-up] { transform-origin: bottom; }
13
13
  & .crisp-select-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
14
14
  & .crisp-select-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
@@ -37,6 +37,12 @@
37
37
  .crisp-select--width_auto {
38
38
  width: auto;
39
39
  }
40
+ .crisp-select--invalid_true {
41
+ & .crisp-select-trigger, & .crisp-select-trigger:hover, & .crisp-select-trigger[data-open], & .crisp-select-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
42
+ }
43
+ .crisp-select--invalid_false {
44
+
45
+ }
40
46
 
41
47
  @media (prefers-reduced-motion: reduce) {
42
48
  .crisp-select, .crisp-select * {
package/dist/select.d.ts CHANGED
@@ -3,6 +3,7 @@ import type { RecipeFn } from "../core/types";
3
3
  export interface SelectVariants {
4
4
  variant?: "default" | "ghost";
5
5
  width?: "full" | "auto";
6
+ invalid?: boolean;
6
7
  }
7
8
 
8
- export declare const selectRecipe: RecipeFn<{ variant: { default: string; ghost: string }; width: { full: string; auto: string } }>;
9
+ export declare const selectRecipe: RecipeFn<{ variant: { default: string; ghost: string }; width: { full: string; auto: string }; invalid: { true: string; false: string } }>;
@@ -9,7 +9,7 @@
9
9
  & .crisp-select-placeholder { color: var(--crisp-fg-muted); }
10
10
  & .crisp-select-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
11
11
  & .crisp-select-trigger[data-open] .crisp-select-chevron { transform: rotate(180deg); }
12
- & .crisp-select-listbox { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
12
+ & .crisp-select-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
13
13
  & .crisp-select-listbox[data-up] { transform-origin: bottom; }
14
14
  & .crisp-select-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
15
15
  & .crisp-select-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
@@ -38,6 +38,12 @@
38
38
  .crisp-select--width_auto {
39
39
  width: auto;
40
40
  }
41
+ .crisp-select--invalid_true {
42
+ & .crisp-select-trigger, & .crisp-select-trigger:hover, & .crisp-select-trigger[data-open], & .crisp-select-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
43
+ }
44
+ .crisp-select--invalid_false {
45
+
46
+ }
41
47
 
42
48
  @media (prefers-reduced-motion: reduce) {
43
49
  .crisp-select, .crisp-select * {
package/dist/styles.css CHANGED
@@ -38,6 +38,11 @@
38
38
  --crisp-bg-purple: #9b69ff;
39
39
  --crisp-bg-sidebar: #fbfbfb;
40
40
  --crisp-bg-subtle: #fbfbfb;
41
+ --crisp-fg-brand-soft: #2057bd;
42
+ --crisp-fg-success-soft: #186b3d;
43
+ --crisp-fg-warning-soft: #80520d;
44
+ --crisp-fg-danger-soft: #a33539;
45
+ --crisp-fg-neutral-soft: #686870;
41
46
  }
42
47
 
43
48
  [data-theme="dark"] {
@@ -80,6 +85,11 @@
80
85
  --crisp-bg-purple: #9b69ff;
81
86
  --crisp-bg-sidebar: #0e0f10;
82
87
  --crisp-bg-subtle: #0e0f10;
88
+ --crisp-fg-brand-soft: #568df3;
89
+ --crisp-fg-success-soft: #2ea968;
90
+ --crisp-fg-warning-soft: #e0982a;
91
+ --crisp-fg-danger-soft: #ff5a5f;
92
+ --crisp-fg-neutral-soft: #9a9aa2;
83
93
  }
84
94
 
85
95
  :root {
@@ -196,19 +206,19 @@
196
206
  & .crisp-badge-dot { width: 6px; height: 6px; flex-shrink: 0; border-radius: var(--crisp-radius-full); background: currentColor; }
197
207
  }
198
208
  .crisp-badge--tone_neutral {
199
- background: var(--crisp-bg-raised); color: var(--crisp-fg-muted); box-shadow: inset 0 0 0 1px var(--crisp-border-default);
209
+ background: var(--crisp-bg-raised); color: var(--crisp-fg-neutral-soft); box-shadow: inset 0 0 0 1px var(--crisp-border-default);
200
210
  }
201
211
  .crisp-badge--tone_brand {
202
- background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: var(--crisp-bg-brand-solid); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent);
212
+ background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: var(--crisp-fg-brand-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent);
203
213
  }
204
214
  .crisp-badge--tone_success {
205
- background: color-mix(in srgb, var(--crisp-bg-success) 14%, transparent); color: var(--crisp-bg-success); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-success) 30%, transparent);
215
+ background: color-mix(in srgb, var(--crisp-bg-success) 14%, transparent); color: var(--crisp-fg-success-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-success) 30%, transparent);
206
216
  }
207
217
  .crisp-badge--tone_warning {
208
- background: color-mix(in srgb, var(--crisp-bg-warning) 16%, transparent); color: var(--crisp-bg-warning); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-warning) 32%, transparent);
218
+ background: color-mix(in srgb, var(--crisp-bg-warning) 16%, transparent); color: var(--crisp-fg-warning-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-warning) 32%, transparent);
209
219
  }
210
220
  .crisp-badge--tone_danger {
211
- background: color-mix(in srgb, var(--crisp-bg-danger) 14%, transparent); color: var(--crisp-bg-danger); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-danger) 30%, transparent);
221
+ background: color-mix(in srgb, var(--crisp-bg-danger) 14%, transparent); color: var(--crisp-fg-danger-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-danger) 30%, transparent);
212
222
  }
213
223
  .crisp-badge--size_small {
214
224
  height: 16px; padding-inline: var(--crisp-space-1-5); font-size: var(--crisp-text-xs); border-radius: var(--crisp-radius-sm);
@@ -450,7 +460,7 @@
450
460
 
451
461
  .crisp-contextmenu {
452
462
  display: contents; font-family: var(--crisp-font-sans);
453
- & .crisp-contextmenu-content { position: fixed; z-index: 60; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
463
+ & .crisp-contextmenu-content { position: fixed; z-index: 70; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
454
464
  & .crisp-contextmenu-item { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; height: var(--crisp-size-menuRow); box-sizing: border-box; padding: 0 var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); text-align: start; white-space: nowrap; cursor: pointer; }
455
465
  & .crisp-contextmenu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
456
466
  & .crisp-contextmenu-item:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
@@ -710,7 +720,7 @@
710
720
  & .crisp-dialog-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); overflow: hidden; }
711
721
  & .crisp-dialog-header { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; height: 52px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-4); border-bottom: 1px solid var(--crisp-border-subtle); }
712
722
  & .crisp-dialog-header svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
713
- & .crisp-dialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
723
+ & .crisp-dialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); margin: 0; }
714
724
  & .crisp-dialog-close { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
715
725
  & .crisp-dialog-close:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
716
726
  & .crisp-dialog-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--crisp-space-4); padding: var(--crisp-space-5) var(--crisp-space-4); }
@@ -973,7 +983,7 @@
973
983
 
974
984
  .crisp-menu {
975
985
  position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
976
- & .crisp-menu-content { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
986
+ & .crisp-menu-content { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
977
987
  & .crisp-menu-content[data-align="end"] { transform-origin: top right; }
978
988
  & .crisp-menu-content[data-up] { transform-origin: bottom left; }
979
989
  & .crisp-menu-content[data-up][data-align="end"] { transform-origin: bottom right; }
@@ -1012,7 +1022,7 @@
1012
1022
  & .crisp-multiselect-placeholder { color: var(--crisp-fg-muted); }
1013
1023
  & .crisp-multiselect-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
1014
1024
  & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); }
1015
- & .crisp-multiselect-listbox { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1025
+ & .crisp-multiselect-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1016
1026
  & .crisp-multiselect-listbox[data-up] { transform-origin: bottom left; }
1017
1027
  & .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1018
1028
  & .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
@@ -1034,6 +1044,12 @@
1034
1044
  & .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); }
1035
1045
  & .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
1036
1046
  }
1047
+ .crisp-multiselect--invalid_true {
1048
+ & .crisp-multiselect-trigger, & .crisp-multiselect-trigger:hover, & .crisp-multiselect-trigger[data-open], & .crisp-multiselect-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
1049
+ }
1050
+ .crisp-multiselect--invalid_false {
1051
+
1052
+ }
1037
1053
 
1038
1054
  @media (prefers-reduced-motion: reduce) {
1039
1055
  .crisp-multiselect, .crisp-multiselect * {
@@ -1045,7 +1061,7 @@
1045
1061
 
1046
1062
  .crisp-popover {
1047
1063
  display: contents; font-family: var(--crisp-font-sans);
1048
- & .crisp-popover-content { position: fixed; z-index: 60; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1064
+ & .crisp-popover-content { position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1049
1065
  & .crisp-popover-content[data-align="end"] { transform-origin: top right; }
1050
1066
  & .crisp-popover-content[data-up] { transform-origin: bottom left; }
1051
1067
  }
@@ -1217,7 +1233,7 @@
1217
1233
  & .crisp-select-placeholder { color: var(--crisp-fg-muted); }
1218
1234
  & .crisp-select-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
1219
1235
  & .crisp-select-trigger[data-open] .crisp-select-chevron { transform: rotate(180deg); }
1220
- & .crisp-select-listbox { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1236
+ & .crisp-select-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1221
1237
  & .crisp-select-listbox[data-up] { transform-origin: bottom; }
1222
1238
  & .crisp-select-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1223
1239
  & .crisp-select-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
@@ -1246,6 +1262,12 @@
1246
1262
  .crisp-select--width_auto {
1247
1263
  width: auto;
1248
1264
  }
1265
+ .crisp-select--invalid_true {
1266
+ & .crisp-select-trigger, & .crisp-select-trigger:hover, & .crisp-select-trigger[data-open], & .crisp-select-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
1267
+ }
1268
+ .crisp-select--invalid_false {
1269
+
1270
+ }
1249
1271
 
1250
1272
  @media (prefers-reduced-motion: reduce) {
1251
1273
  .crisp-select, .crisp-select * {
@@ -38,6 +38,11 @@
38
38
  --crisp-bg-purple: #9b69ff;
39
39
  --crisp-bg-sidebar: #fbfbfb;
40
40
  --crisp-bg-subtle: #fbfbfb;
41
+ --crisp-fg-brand-soft: #2057bd;
42
+ --crisp-fg-success-soft: #186b3d;
43
+ --crisp-fg-warning-soft: #80520d;
44
+ --crisp-fg-danger-soft: #a33539;
45
+ --crisp-fg-neutral-soft: #686870;
41
46
  }
42
47
 
43
48
  [data-theme="dark"] {
@@ -80,6 +85,11 @@
80
85
  --crisp-bg-purple: #9b69ff;
81
86
  --crisp-bg-sidebar: #0e0f10;
82
87
  --crisp-bg-subtle: #0e0f10;
88
+ --crisp-fg-brand-soft: #568df3;
89
+ --crisp-fg-success-soft: #2ea968;
90
+ --crisp-fg-warning-soft: #e0982a;
91
+ --crisp-fg-danger-soft: #ff5a5f;
92
+ --crisp-fg-neutral-soft: #9a9aa2;
83
93
  }
84
94
 
85
95
  :root {
@@ -197,19 +207,19 @@
197
207
  & .crisp-badge-dot { width: 6px; height: 6px; flex-shrink: 0; border-radius: var(--crisp-radius-full); background: currentColor; }
198
208
  }
199
209
  .crisp-badge--tone_neutral {
200
- background: var(--crisp-bg-raised); color: var(--crisp-fg-muted); box-shadow: inset 0 0 0 1px var(--crisp-border-default);
210
+ background: var(--crisp-bg-raised); color: var(--crisp-fg-neutral-soft); box-shadow: inset 0 0 0 1px var(--crisp-border-default);
201
211
  }
202
212
  .crisp-badge--tone_brand {
203
- background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: var(--crisp-bg-brand-solid); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent);
213
+ background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: var(--crisp-fg-brand-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent);
204
214
  }
205
215
  .crisp-badge--tone_success {
206
- background: color-mix(in srgb, var(--crisp-bg-success) 14%, transparent); color: var(--crisp-bg-success); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-success) 30%, transparent);
216
+ background: color-mix(in srgb, var(--crisp-bg-success) 14%, transparent); color: var(--crisp-fg-success-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-success) 30%, transparent);
207
217
  }
208
218
  .crisp-badge--tone_warning {
209
- background: color-mix(in srgb, var(--crisp-bg-warning) 16%, transparent); color: var(--crisp-bg-warning); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-warning) 32%, transparent);
219
+ background: color-mix(in srgb, var(--crisp-bg-warning) 16%, transparent); color: var(--crisp-fg-warning-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-warning) 32%, transparent);
210
220
  }
211
221
  .crisp-badge--tone_danger {
212
- background: color-mix(in srgb, var(--crisp-bg-danger) 14%, transparent); color: var(--crisp-bg-danger); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-danger) 30%, transparent);
222
+ background: color-mix(in srgb, var(--crisp-bg-danger) 14%, transparent); color: var(--crisp-fg-danger-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-danger) 30%, transparent);
213
223
  }
214
224
  .crisp-badge--size_small {
215
225
  height: 16px; padding-inline: var(--crisp-space-1-5); font-size: var(--crisp-text-xs); border-radius: var(--crisp-radius-sm);
@@ -451,7 +461,7 @@
451
461
 
452
462
  .crisp-contextmenu {
453
463
  display: contents; font-family: var(--crisp-font-sans);
454
- & .crisp-contextmenu-content { position: fixed; z-index: 60; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
464
+ & .crisp-contextmenu-content { position: fixed; z-index: 70; min-width: 200px; box-sizing: border-box; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
455
465
  & .crisp-contextmenu-item { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; height: var(--crisp-size-menuRow); box-sizing: border-box; padding: 0 var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); text-align: start; white-space: nowrap; cursor: pointer; }
456
466
  & .crisp-contextmenu-item svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
457
467
  & .crisp-contextmenu-item:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
@@ -711,7 +721,7 @@
711
721
  & .crisp-dialog-card { display: flex; flex-direction: column; flex: 1; min-height: 0; box-sizing: border-box; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 8%, transparent); overflow: hidden; }
712
722
  & .crisp-dialog-header { display: flex; align-items: center; gap: var(--crisp-space-2); flex-shrink: 0; height: 52px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-4); border-bottom: 1px solid var(--crisp-border-subtle); }
713
723
  & .crisp-dialog-header svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
714
- & .crisp-dialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
724
+ & .crisp-dialog-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); margin: 0; }
715
725
  & .crisp-dialog-close { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; }
716
726
  & .crisp-dialog-close:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
717
727
  & .crisp-dialog-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--crisp-space-4); padding: var(--crisp-space-5) var(--crisp-space-4); }
@@ -974,7 +984,7 @@
974
984
 
975
985
  .crisp-menu {
976
986
  position: relative; display: inline-flex; font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
977
- & .crisp-menu-content { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
987
+ & .crisp-menu-content { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); min-width: 200px; max-height: 360px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
978
988
  & .crisp-menu-content[data-align="end"] { transform-origin: top right; }
979
989
  & .crisp-menu-content[data-up] { transform-origin: bottom left; }
980
990
  & .crisp-menu-content[data-up][data-align="end"] { transform-origin: bottom right; }
@@ -1013,7 +1023,7 @@
1013
1023
  & .crisp-multiselect-placeholder { color: var(--crisp-fg-muted); }
1014
1024
  & .crisp-multiselect-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
1015
1025
  & .crisp-multiselect-trigger[data-open] .crisp-multiselect-chevron { transform: rotate(180deg); }
1016
- & .crisp-multiselect-listbox { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1026
+ & .crisp-multiselect-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 300px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1017
1027
  & .crisp-multiselect-listbox[data-up] { transform-origin: bottom left; }
1018
1028
  & .crisp-multiselect-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1019
1029
  & .crisp-multiselect-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
@@ -1035,6 +1045,12 @@
1035
1045
  & .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); }
1036
1046
  & .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
1037
1047
  }
1048
+ .crisp-multiselect--invalid_true {
1049
+ & .crisp-multiselect-trigger, & .crisp-multiselect-trigger:hover, & .crisp-multiselect-trigger[data-open], & .crisp-multiselect-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
1050
+ }
1051
+ .crisp-multiselect--invalid_false {
1052
+
1053
+ }
1038
1054
 
1039
1055
  @media (prefers-reduced-motion: reduce) {
1040
1056
  .crisp-multiselect, .crisp-multiselect * {
@@ -1046,7 +1062,7 @@
1046
1062
 
1047
1063
  .crisp-popover {
1048
1064
  display: contents; font-family: var(--crisp-font-sans);
1049
- & .crisp-popover-content { position: fixed; z-index: 60; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1065
+ & .crisp-popover-content { position: fixed; z-index: 70; box-sizing: border-box; min-width: 200px; max-width: min(360px, 92vw); padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); color: var(--crisp-fg-primary); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); opacity: 1; transform: none; transition: opacity 0.08s ease, transform 0.08s ease; transform-origin: top left; @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1050
1066
  & .crisp-popover-content[data-align="end"] { transform-origin: top right; }
1051
1067
  & .crisp-popover-content[data-up] { transform-origin: bottom left; }
1052
1068
  }
@@ -1218,7 +1234,7 @@
1218
1234
  & .crisp-select-placeholder { color: var(--crisp-fg-muted); }
1219
1235
  & .crisp-select-chevron { flex-shrink: 0; color: var(--crisp-fg-muted); transition: transform .15s ease; }
1220
1236
  & .crisp-select-trigger[data-open] .crisp-select-chevron { transform: rotate(180deg); }
1221
- & .crisp-select-listbox { position: fixed; z-index: 60; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1237
+ & .crisp-select-listbox { position: fixed; z-index: 70; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--crisp-space-px); max-height: 280px; overflow-y: auto; padding: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-popover); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); transform-origin: top left; opacity: 1; transform: none; transition: opacity .08s ease, transform .08s ease; }
1222
1238
  & .crisp-select-listbox[data-up] { transform-origin: bottom; }
1223
1239
  & .crisp-select-listbox { @starting-style { opacity: 0; transform: scale(0.97) translateY(-1px); } }
1224
1240
  & .crisp-select-search { display: flex; align-items: center; gap: var(--crisp-space-2); height: 34px; flex-shrink: 0; margin: calc(-1 * var(--crisp-space-1)) calc(-1 * var(--crisp-space-1)) var(--crisp-space-1); padding: 0 var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); color: var(--crisp-fg-muted); }
@@ -1247,6 +1263,12 @@
1247
1263
  .crisp-select--width_auto {
1248
1264
  width: auto;
1249
1265
  }
1266
+ .crisp-select--invalid_true {
1267
+ & .crisp-select-trigger, & .crisp-select-trigger:hover, & .crisp-select-trigger[data-open], & .crisp-select-trigger:focus-visible { box-shadow: inset 0 0 0 1px var(--crisp-bg-danger); }
1268
+ }
1269
+ .crisp-select--invalid_false {
1270
+
1271
+ }
1250
1272
 
1251
1273
  @media (prefers-reduced-motion: reduce) {
1252
1274
  .crisp-select, .crisp-select * {
package/dist/tokens.css CHANGED
@@ -38,6 +38,11 @@
38
38
  --crisp-bg-purple: #9b69ff;
39
39
  --crisp-bg-sidebar: #fbfbfb;
40
40
  --crisp-bg-subtle: #fbfbfb;
41
+ --crisp-fg-brand-soft: #2057bd;
42
+ --crisp-fg-success-soft: #186b3d;
43
+ --crisp-fg-warning-soft: #80520d;
44
+ --crisp-fg-danger-soft: #a33539;
45
+ --crisp-fg-neutral-soft: #686870;
41
46
  }
42
47
 
43
48
  [data-theme="dark"] {
@@ -80,6 +85,11 @@
80
85
  --crisp-bg-purple: #9b69ff;
81
86
  --crisp-bg-sidebar: #0e0f10;
82
87
  --crisp-bg-subtle: #0e0f10;
88
+ --crisp-fg-brand-soft: #568df3;
89
+ --crisp-fg-success-soft: #2ea968;
90
+ --crisp-fg-warning-soft: #e0982a;
91
+ --crisp-fg-danger-soft: #ff5a5f;
92
+ --crisp-fg-neutral-soft: #9a9aa2;
83
93
  }
84
94
 
85
95
  :root {