@burdenoff/fe-libs 2026.624.2 → 2026.625.2

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 (39) hide show
  1. package/dist/chrome/SideNavigation.d.ts.map +1 -1
  2. package/dist/chrome/SideNavigation.js +2 -1
  3. package/dist/chrome/ThemePreferences.d.ts +15 -0
  4. package/dist/chrome/ThemePreferences.d.ts.map +1 -0
  5. package/dist/chrome/ThemePreferences.js +604 -0
  6. package/dist/chrome/index.d.ts +1 -0
  7. package/dist/chrome/index.d.ts.map +1 -1
  8. package/dist/chrome.js +2 -1
  9. package/dist/shared/providers/AppShellProvider.d.ts +10 -2
  10. package/dist/shared/providers/AppShellProvider.d.ts.map +1 -1
  11. package/dist/shared/providers/AppShellProvider.js +183 -175
  12. package/dist/shared/providers/shell/ThemeProvider.d.ts +40 -8
  13. package/dist/shared/providers/shell/ThemeProvider.d.ts.map +1 -1
  14. package/dist/shared/providers/shell/ThemeProvider.js +165 -54
  15. package/dist/ui/cta-overflow-menu.d.ts +39 -0
  16. package/dist/ui/cta-overflow-menu.d.ts.map +1 -0
  17. package/dist/ui/cta-overflow-menu.js +38 -0
  18. package/dist/ui/emphasis-panel.d.ts +18 -0
  19. package/dist/ui/emphasis-panel.d.ts.map +1 -0
  20. package/dist/ui/emphasis-panel.js +14 -0
  21. package/dist/ui/glass-card.d.ts +24 -0
  22. package/dist/ui/glass-card.d.ts.map +1 -0
  23. package/dist/ui/glass-card.js +27 -0
  24. package/dist/ui/index.d.ts +4 -0
  25. package/dist/ui/index.d.ts.map +1 -1
  26. package/dist/ui/show-more.d.ts +28 -0
  27. package/dist/ui/show-more.d.ts.map +1 -0
  28. package/dist/ui/show-more.js +31 -0
  29. package/dist/ui.js +5 -1
  30. package/package.json +1 -1
  31. package/src/shared/tokens/build/brands/fluidgrids.css +2 -2
  32. package/src/shared/tokens/build/brands/healthybowl.css +2 -2
  33. package/src/shared/tokens/build/brands/tenant.css +2 -2
  34. package/src/shared/tokens/build/brands/workspaces.css +2 -2
  35. package/src/shared/tokens/build/foundation.css +9 -0
  36. package/src/shared/tokens/build/semantic.css +38 -0
  37. package/src/shared/tokens/build/tailwind.preset.js +12 -0
  38. package/src/shared/tokens/build/themes.css +12 -0
  39. package/src/shared/tokens/tokens.css +37 -0
@@ -1,17 +1,37 @@
1
1
  import { ReactNode } from 'react';
2
2
  /**
3
3
  * Boff UI theme axis. `mode` is the user's stored choice and may be any of the
4
- * six concrete Boff UI themes or `system` (which resolves to light/dark from the
5
- * OS preference). The light/dark *family* is exposed separately as
6
- * `resolvedTheme` (used by color-scheme, the native status bar, and the
7
- * `colorMode` alias), while `resolvedThemeName` is the concrete theme written to
8
- * `data-theme` on the document root.
4
+ * six concrete Boff UI themes, `system` (resolves to light/dark from the OS), or
5
+ * `custom` (a user-designed theme — see {@link CustomTheme}). The light/dark
6
+ * *family* is exposed separately as `resolvedTheme`, while `resolvedThemeName` is
7
+ * the concrete CSS theme written to `data-theme` on the document root.
9
8
  */
10
- export type ThemeMode = 'light' | 'dark' | 'forest' | 'ocean' | 'sunset' | 'high-contrast' | 'system';
11
- export type ThemeName = Exclude<ThemeMode, 'system'>;
9
+ export type ThemeMode = 'light' | 'dark' | 'forest' | 'ocean' | 'sunset' | 'high-contrast' | 'system' | 'custom';
10
+ /** The six concrete CSS themes (`data-theme` only ever receives one of these). */
11
+ export type ThemeName = Exclude<ThemeMode, 'system' | 'custom'>;
12
12
  export type Brand = 'workspaces' | 'fluidgrids' | 'bigconsole' | 'botlit' | 'vibecontrols' | 'healthybowl' | 'default';
13
13
  export type Density = 'compact' | 'comfortable' | 'spacious';
14
14
  export type Typography = 'default' | 'large' | 'small';
15
+ /** Glass intensity preference (drives `data-glass` → blur + opaque fallback). */
16
+ export type GlassIntensity = 'off' | 'subtle' | 'full';
17
+ /**
18
+ * A user-designed, saved theme. Reusable across every product (the storage key
19
+ * is shared across all shells). A custom theme inherits a light/dark base CSS
20
+ * block and redefines ONLY the action accent (which retints the whole UI via the
21
+ * existing `color-mix(... var(--color-action-primary-bg) ...)` tokens) plus the
22
+ * density / typography / glass / motion axes — no new token names.
23
+ */
24
+ export interface CustomTheme {
25
+ id: string;
26
+ name: string;
27
+ base: 'light' | 'dark';
28
+ /** single hex accent — feeds --color-action-primary-bg only */
29
+ accent: string;
30
+ density: Density;
31
+ typography: Typography;
32
+ glass: GlassIntensity;
33
+ reduceMotion: boolean;
34
+ }
15
35
  /** Metadata for the theme picker / Appearance settings UI. */
16
36
  export interface ThemeOption {
17
37
  value: ThemeName;
@@ -24,6 +44,8 @@ export interface ThemeContextValue {
24
44
  brand: Brand;
25
45
  density: Density;
26
46
  typography: Typography;
47
+ glass: GlassIntensity;
48
+ reduceMotion: boolean;
27
49
  /** light/dark family of the active theme */
28
50
  resolvedTheme: 'light' | 'dark';
29
51
  /** concrete theme written to data-theme (light|dark|forest|ocean|sunset|high-contrast) */
@@ -32,6 +54,15 @@ export interface ThemeContextValue {
32
54
  setBrand: (brand: Brand) => void;
33
55
  setDensity: (density: Density) => void;
34
56
  setTypography: (typography: Typography) => void;
57
+ setGlass: (glass: GlassIntensity) => void;
58
+ setReduceMotion: (reduce: boolean) => void;
59
+ customThemes: CustomTheme[];
60
+ activeCustomId: string | null;
61
+ createCustomTheme: (t: Omit<CustomTheme, 'id'>) => CustomTheme;
62
+ updateCustomTheme: (id: string, patch: Partial<Omit<CustomTheme, 'id'>>) => void;
63
+ deleteCustomTheme: (id: string) => void;
64
+ /** Activate a saved custom theme (sets mode='custom'). */
65
+ applyCustomTheme: (id: string) => void;
35
66
  colorMode: 'light' | 'dark';
36
67
  toggleColorMode: () => void;
37
68
  }
@@ -41,8 +72,9 @@ export interface ThemeProviderProps {
41
72
  defaultBrand?: Brand;
42
73
  defaultDensity?: Density;
43
74
  defaultTypography?: Typography;
75
+ defaultGlass?: GlassIntensity;
44
76
  storageKey?: string;
45
77
  }
46
- export declare function ThemeProvider({ children, defaultMode, defaultBrand, defaultDensity, defaultTypography, storageKey, }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
78
+ export declare function ThemeProvider({ children, defaultMode, defaultBrand, defaultDensity, defaultTypography, defaultGlass, storageKey, }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
47
79
  export declare function useTheme(): ThemeContextValue;
48
80
  //# sourceMappingURL=ThemeProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/shell/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GACjB,OAAO,GACP,MAAM,GACN,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,eAAe,GACf,QAAQ,CAAC;AACb,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AACrD,MAAM,MAAM,KAAK,GACb,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,QAAQ,GACR,cAAc,GACd,aAAa,GACb,SAAS,CAAC;AACd,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,aAAa,GAAG,UAAU,CAAC;AAC7D,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAYvD,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B;AACD,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,WAAW,CAOpD,CAAC;AAIF,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,4CAA4C;IAC5C,aAAa,EAAE,OAAO,GAAG,MAAM,CAAC;IAChC,0FAA0F;IAC1F,iBAAiB,EAAE,SAAS,CAAC;IAC7B,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAEhD,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,WAAsB,EACtB,YAAwB,EACxB,cAA8B,EAC9B,iBAA6B,EAC7B,UAA8B,GAC/B,EAAE,kBAAkB,2CA2IpB;AAED,wBAAgB,QAAQ,sBAMvB"}
1
+ {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/providers/shell/ThemeProvider.tsx"],"names":[],"mappings":"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"}
@@ -7,73 +7,184 @@ var s = new Set([
7
7
  "ocean",
8
8
  "sunset",
9
9
  "high-contrast"
10
- ]), c = (e) => s.has(e) ? "dark" : "light", l = e(null);
11
- function u({ children: e, defaultMode: t = "system", defaultBrand: s = "default", defaultDensity: u = "comfortable", defaultTypography: d = "default", storageKey: f = "burdenoff-theme" }) {
12
- let [p, m] = a(() => typeof window > "u" ? t : localStorage.getItem(`${f}-mode`) || t), [h, g] = a(() => typeof window > "u" ? s : localStorage.getItem(`${f}-brand`) || s), [_, v] = a(() => typeof window > "u" ? u : localStorage.getItem(`${f}-density`) || u), [y, b] = a(() => typeof window > "u" ? d : localStorage.getItem(`${f}-typography`) || d), [x, S] = a(() => p === "system" ? typeof window > "u" ? "light" : window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : p);
10
+ ]), c = [
11
+ {
12
+ value: "light",
13
+ label: "Light",
14
+ family: "light"
15
+ },
16
+ {
17
+ value: "dark",
18
+ label: "Dark",
19
+ family: "dark"
20
+ },
21
+ {
22
+ value: "forest",
23
+ label: "Forest",
24
+ family: "dark"
25
+ },
26
+ {
27
+ value: "ocean",
28
+ label: "Ocean",
29
+ family: "dark"
30
+ },
31
+ {
32
+ value: "sunset",
33
+ label: "Sunset",
34
+ family: "dark"
35
+ },
36
+ {
37
+ value: "high-contrast",
38
+ label: "High Contrast",
39
+ family: "dark"
40
+ }
41
+ ], l = (e) => s.has(e) ? "dark" : "light";
42
+ function u(e) {
43
+ let t = /^#?([0-9a-f]{6})$/i.exec(e.trim());
44
+ if (!t) return 0;
45
+ let n = parseInt(t[1], 16), r = [
46
+ n >> 16 & 255,
47
+ n >> 8 & 255,
48
+ n & 255
49
+ ].map((e) => {
50
+ let t = e / 255;
51
+ return t <= .03928 ? t / 12.92 : ((t + .055) / 1.055) ** 2.4;
52
+ });
53
+ return .2126 * r[0] + .7152 * r[1] + .0722 * r[2];
54
+ }
55
+ var d = (e) => u(e) > .45;
56
+ function f(e, t) {
57
+ if (typeof window > "u") return t;
58
+ try {
59
+ let n = localStorage.getItem(e);
60
+ return n ? JSON.parse(n) : t;
61
+ } catch {
62
+ return t;
63
+ }
64
+ }
65
+ var p = e(null);
66
+ function m({ children: e, defaultMode: t = "system", defaultBrand: s = "default", defaultDensity: c = "comfortable", defaultTypography: u = "default", defaultGlass: m = "full", storageKey: h = "burdenoff-theme" }) {
67
+ let g = (e, t) => typeof window > "u" ? t : localStorage.getItem(`${h}-${e}`) || t, [_, v] = a(() => g("mode", t)), [y, b] = a(() => g("brand", s)), [x, S] = a(() => g("density", c)), [C, w] = a(() => g("typography", u)), [T, E] = a(() => g("glass", m)), [D, O] = a(() => g("reduce-motion", "") === "1"), [k, A] = a(() => f(`${h}-custom-list`, [])), [j, M] = a(() => g("active-custom", "") || null), N = i(() => _ === "custom" ? k.find((e) => e.id === j) ?? null : null, [
68
+ _,
69
+ k,
70
+ j
71
+ ]), [P, F] = a(() => _ === "custom" ? "light" : _ === "system" ? typeof window > "u" ? "light" : window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : _);
13
72
  r(() => {
14
- if (p === "system") {
15
- let e = window.matchMedia("(prefers-color-scheme: dark)"), t = (e) => {
16
- S(e.matches ? "dark" : "light");
17
- };
18
- return e.addEventListener("change", t), S(e.matches ? "dark" : "light"), () => e.removeEventListener("change", t);
19
- } else S(p);
20
- }, [p]);
21
- let C = c(x);
73
+ if (_ === "system") {
74
+ let e = window.matchMedia("(prefers-color-scheme: dark)"), t = (e) => F(e.matches ? "dark" : "light");
75
+ return e.addEventListener("change", t), F(e.matches ? "dark" : "light"), () => e.removeEventListener("change", t);
76
+ }
77
+ F(_ === "custom" ? N?.base ?? "light" : _);
78
+ }, [_, N]);
79
+ let I = l(P), L = N?.density ?? x, R = N?.typography ?? C, z = N?.glass ?? T, B = N?.reduceMotion ?? D;
22
80
  r(() => {
23
81
  let e = document.documentElement;
24
- e.setAttribute("data-theme", x), e.setAttribute("data-brand", h), e.setAttribute("data-density", _), e.setAttribute("data-typography", y), C === "dark" ? e.classList.add("dark") : e.classList.remove("dark");
82
+ if (e.setAttribute("data-theme", P), e.setAttribute("data-brand", y), e.setAttribute("data-density", L), e.setAttribute("data-typography", R), e.setAttribute("data-glass", z), e.toggleAttribute("data-reduce-motion", B), I === "dark" ? e.classList.add("dark") : e.classList.remove("dark"), N) {
83
+ let t = N.accent;
84
+ e.style.setProperty("--color-action-primary-bg", t), e.style.setProperty("--color-action-primary-bgHover", `color-mix(in oklab, ${t} 84%, black)`), e.style.setProperty("--color-action-primary-bgActive", `color-mix(in oklab, ${t} 70%, black)`), d(t) ? e.style.setProperty("--color-action-primary-text", "#0a0a0a") : e.style.removeProperty("--color-action-primary-text");
85
+ } else e.style.removeProperty("--color-action-primary-bg"), e.style.removeProperty("--color-action-primary-bgHover"), e.style.removeProperty("--color-action-primary-bgActive"), e.style.removeProperty("--color-action-primary-text");
25
86
  }, [
26
- x,
27
- C,
28
- h,
29
- _,
30
- y
87
+ P,
88
+ I,
89
+ y,
90
+ L,
91
+ R,
92
+ z,
93
+ B,
94
+ N
31
95
  ]);
32
- let w = n((e) => {
33
- m(e), localStorage.setItem(`${f}-mode`, e);
34
- }, [f]), T = n((e) => {
35
- g(e), localStorage.setItem(`${f}-brand`, e);
36
- }, [f]), E = n((e) => {
37
- v(e), localStorage.setItem(`${f}-density`, e);
38
- }, [f]), D = n((e) => {
39
- b(e), localStorage.setItem(`${f}-typography`, e);
40
- }, [f]), O = n(() => {
41
- w(C === "light" ? "dark" : "light");
42
- }, [C, w]), k = i(() => ({
43
- mode: p,
44
- brand: h,
45
- density: _,
46
- typography: y,
47
- resolvedTheme: C,
48
- resolvedThemeName: x,
49
- setMode: w,
50
- setBrand: T,
51
- setDensity: E,
52
- setTypography: D,
53
- colorMode: C,
54
- toggleColorMode: O
96
+ let V = n((e, t) => localStorage.setItem(`${h}-${e}`, t), [h]), H = n((e) => {
97
+ v(e), V("mode", e);
98
+ }, [V]), U = n((e) => {
99
+ b(e), V("brand", e);
100
+ }, [V]), W = n((e) => {
101
+ S(e), V("density", e);
102
+ }, [V]), G = n((e) => {
103
+ w(e), V("typography", e);
104
+ }, [V]), K = n((e) => {
105
+ E(e), V("glass", e);
106
+ }, [V]), q = n((e) => {
107
+ O(e), V("reduce-motion", e ? "1" : "0");
108
+ }, [V]), J = n((e) => {
109
+ A(e), localStorage.setItem(`${h}-custom-list`, JSON.stringify(e));
110
+ }, [h]), Y = n((e) => {
111
+ let t = typeof crypto < "u" && crypto.randomUUID ? crypto.randomUUID() : `ct-${Date.now()}-${Math.floor(performance.now())}`, n = {
112
+ ...e,
113
+ id: t
114
+ };
115
+ return J([...k, n]), n;
116
+ }, [k, J]), X = n((e, t) => {
117
+ J(k.map((n) => n.id === e ? {
118
+ ...n,
119
+ ...t
120
+ } : n));
121
+ }, [k, J]), Z = n((e) => {
122
+ J(k.filter((t) => t.id !== e)), j === e && (M(null), V("active-custom", ""), H("system"));
123
+ }, [
124
+ k,
125
+ J,
126
+ j,
127
+ V,
128
+ H
129
+ ]), Q = n((e) => {
130
+ M(e), V("active-custom", e), H("custom");
131
+ }, [V, H]), $ = n(() => {
132
+ H(I === "light" ? "dark" : "light");
133
+ }, [I, H]), ee = i(() => ({
134
+ mode: _,
135
+ brand: y,
136
+ density: L,
137
+ typography: R,
138
+ glass: z,
139
+ reduceMotion: B,
140
+ resolvedTheme: I,
141
+ resolvedThemeName: P,
142
+ setMode: H,
143
+ setBrand: U,
144
+ setDensity: W,
145
+ setTypography: G,
146
+ setGlass: K,
147
+ setReduceMotion: q,
148
+ customThemes: k,
149
+ activeCustomId: j,
150
+ createCustomTheme: Y,
151
+ updateCustomTheme: X,
152
+ deleteCustomTheme: Z,
153
+ applyCustomTheme: Q,
154
+ colorMode: I,
155
+ toggleColorMode: $
55
156
  }), [
56
- p,
57
- h,
58
157
  _,
59
158
  y,
60
- C,
61
- x,
62
- w,
63
- T,
64
- E,
65
- D,
66
- O
159
+ L,
160
+ R,
161
+ z,
162
+ B,
163
+ I,
164
+ P,
165
+ H,
166
+ U,
167
+ W,
168
+ G,
169
+ K,
170
+ q,
171
+ k,
172
+ j,
173
+ Y,
174
+ X,
175
+ Z,
176
+ Q,
177
+ $
67
178
  ]);
68
- return /* @__PURE__ */ o(l.Provider, {
69
- value: k,
179
+ return /* @__PURE__ */ o(p.Provider, {
180
+ value: ee,
70
181
  children: e
71
182
  });
72
183
  }
73
- function d() {
74
- let e = t(l);
184
+ function h() {
185
+ let e = t(p);
75
186
  if (!e) throw Error("useTheme must be used within a ThemeProvider");
76
187
  return e;
77
188
  }
78
189
  //#endregion
79
- export { u as ThemeProvider, d as useTheme };
190
+ export { c as THEME_OPTIONS, m as ThemeProvider, h as useTheme };
@@ -0,0 +1,39 @@
1
+ import { ReactNode } from 'react';
2
+ export type CTAAction = {
3
+ label: string;
4
+ onSelect: () => void;
5
+ intent?: 'default' | 'destructive';
6
+ icon?: ReactNode;
7
+ disabled?: boolean;
8
+ };
9
+ export type CTAPrimaryAction = {
10
+ label: string;
11
+ onSelect: () => void;
12
+ disabled?: boolean;
13
+ icon?: ReactNode;
14
+ };
15
+ export type CTAOverflowMenuProps = {
16
+ /** Optional single primary call-to-action, rendered as a solid Button. */
17
+ primary?: CTAPrimaryAction;
18
+ /** Secondary actions, collapsed into the overflow ("More") menu. */
19
+ actions: CTAAction[];
20
+ /** Menu alignment relative to the trigger. Default 'end'. */
21
+ align?: 'start' | 'end';
22
+ /** Optional className for the wrapping flex row. */
23
+ className?: string;
24
+ };
25
+ /**
26
+ * CTAOverflowMenu — Boff UI 2.0 action-group primitive that enforces the
27
+ * "one primary CTA, everything else in a menu" rule. The primary action is a
28
+ * single solid Button; the remaining actions live behind an icon "More"
29
+ * dropdown. Destructive items are tinted with the status-error token.
30
+ *
31
+ * Fully keyboard accessible via the underlying Radix dropdown (the trigger is
32
+ * a real button with an accessible label).
33
+ */
34
+ declare function CTAOverflowMenu({ primary, actions, align, className }: CTAOverflowMenuProps): import("react/jsx-runtime").JSX.Element;
35
+ declare namespace CTAOverflowMenu {
36
+ var displayName: string;
37
+ }
38
+ export { CTAOverflowMenu };
39
+ //# sourceMappingURL=cta-overflow-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cta-overflow-menu.d.ts","sourceRoot":"","sources":["../../src/ui/cta-overflow-menu.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAWvC,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;IACnC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,0EAA0E;IAC1E,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,oEAAoE;IACpE,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACxB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;GAQG;AACH,iBAAS,eAAe,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,KAAa,EAAE,SAAS,EAAE,EAAE,oBAAoB,2CA2C5F;kBA3CQ,eAAe;;;AA8CxB,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { cn as e } from "../shared-utils.js";
2
+ import { Button as t } from "./button.js";
3
+ import { DropdownMenu as n, DropdownMenuContent as r, DropdownMenuItem as i, DropdownMenuTrigger as a } from "./dropdown-menu.js";
4
+ import { MoreHorizontal as o } from "lucide-react";
5
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
6
+ //#region src/ui/cta-overflow-menu.tsx
7
+ function l({ primary: l, actions: u, align: d = "end", className: f }) {
8
+ return /* @__PURE__ */ c("div", {
9
+ className: e("flex items-center gap-2", f),
10
+ children: [l ? /* @__PURE__ */ c(t, {
11
+ type: "button",
12
+ variant: "default",
13
+ onClick: l.onSelect,
14
+ disabled: l.disabled,
15
+ children: [l.icon, l.label]
16
+ }) : null, u.length > 0 ? /* @__PURE__ */ c(n, { children: [/* @__PURE__ */ s(a, {
17
+ asChild: !0,
18
+ children: /* @__PURE__ */ s(t, {
19
+ type: "button",
20
+ variant: "outline",
21
+ size: "icon",
22
+ "aria-label": "More actions",
23
+ children: /* @__PURE__ */ s(o, {})
24
+ })
25
+ }), /* @__PURE__ */ s(r, {
26
+ align: d,
27
+ children: u.map((t, n) => /* @__PURE__ */ c(i, {
28
+ disabled: t.disabled,
29
+ onSelect: t.onSelect,
30
+ className: e("gap-2", t.intent === "destructive" && "text-status-error-text focus:text-status-error-text focus:bg-status-error-bg-subtle"),
31
+ children: [t.icon, t.label]
32
+ }, `${t.label}-${n}`))
33
+ })] }) : null]
34
+ });
35
+ }
36
+ l.displayName = "CTAOverflowMenu";
37
+ //#endregion
38
+ export { l as CTAOverflowMenu };
@@ -0,0 +1,18 @@
1
+ import { HTMLAttributes } from 'react';
2
+ /**
3
+ * EmphasisPanel — Boff UI 2.0 hero / summary wrapper used to draw attention to
4
+ * exactly ONE zone per page (e.g. a primary summary, a featured callout). Uses
5
+ * the accent wash + seam border tokens so it reads as elevated-but-quiet.
6
+ *
7
+ * Restraint guideline: use at most one EmphasisPanel per page. For ordinary
8
+ * content surfaces, reach for `Card` / `GlassCard` instead.
9
+ */
10
+ export type EmphasisPanelProps = HTMLAttributes<HTMLDivElement> & {
11
+ ref?: React.Ref<HTMLDivElement>;
12
+ };
13
+ declare function EmphasisPanel({ ref, className, children, ...props }: EmphasisPanelProps): import("react/jsx-runtime").JSX.Element;
14
+ declare namespace EmphasisPanel {
15
+ var displayName: string;
16
+ }
17
+ export { EmphasisPanel };
18
+ //# sourceMappingURL=emphasis-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emphasis-panel.d.ts","sourceRoot":"","sources":["../../src/ui/emphasis-panel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAI5C;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,cAAc,CAAC,GAAG;IAChE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACjC,CAAC;AAEF,iBAAS,aAAa,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,2CAahF;kBAbQ,aAAa;;;AAgBtB,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { cn as e } from "../shared-utils.js";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ //#region src/ui/emphasis-panel.tsx
4
+ function n({ ref: n, className: r, children: i, ...a }) {
5
+ return /* @__PURE__ */ t("div", {
6
+ ref: n,
7
+ className: e("rounded-card border border-border-seam bg-accent-wash p-6 text-text-primary", r),
8
+ ...a,
9
+ children: i
10
+ });
11
+ }
12
+ n.displayName = "EmphasisPanel";
13
+ //#endregion
14
+ export { n as EmphasisPanel };
@@ -0,0 +1,24 @@
1
+ import { HTMLAttributes } from 'react';
2
+ import { VariantProps } from 'class-variance-authority';
3
+ /**
4
+ * GlassCard — Boff UI 2.0 surface primitive composed over the base Card visual
5
+ * language. It does NOT fork `Card`; it provides additional "treatments" for
6
+ * hero/metric/insight surfaces while staying on semantic tokens only.
7
+ *
8
+ * No-movement policy: cards NEVER shift position on hover. Hover only
9
+ * intensifies the shadow/border (a calm highlight) — it never translates,
10
+ * scales, or removes the resting shadow. Reduced-motion / high-contrast
11
+ * collapse the glass + glow via the underlying tokens.
12
+ */
13
+ declare const glassCardVariants: (props?: ({
14
+ treatment?: "glass" | "plain" | "metric" | "insight" | null | undefined;
15
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
16
+ export type GlassCardProps = HTMLAttributes<HTMLDivElement> & VariantProps<typeof glassCardVariants> & {
17
+ ref?: React.Ref<HTMLDivElement>;
18
+ };
19
+ declare function GlassCard({ ref, className, treatment, children, ...props }: GlassCardProps): import("react/jsx-runtime").JSX.Element;
20
+ declare namespace GlassCard {
21
+ var displayName: string;
22
+ }
23
+ export { GlassCard, glassCardVariants };
24
+ //# sourceMappingURL=glass-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glass-card.d.ts","sourceRoot":"","sources":["../../src/ui/glass-card.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE;;;;;;;;;GASG;AACH,QAAA,MAAM,iBAAiB;;8EAuBtB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC,cAAc,CAAC,GACzD,YAAY,CAAC,OAAO,iBAAiB,CAAC,GAAG;IACvC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACjC,CAAC;AAEJ,iBAAS,SAAS,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,SAAmB,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,2CAM7F;kBANQ,SAAS;;;AASlB,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { cn as e } from "../shared-utils.js";
2
+ import { jsx as t } from "react/jsx-runtime";
3
+ import { cva as n } from "class-variance-authority";
4
+ //#region src/ui/glass-card.tsx
5
+ var r = n("relative rounded-card text-text-primary transition-[box-shadow,border-color] duration-200 ease-[var(--motion-easing-out)]", {
6
+ variants: { treatment: {
7
+ plain: "border border-border-subtle bg-bg-surface shadow-elevation-1 hover:border-border-strong hover:shadow-elevation-2",
8
+ glass: "border border-border-seam bg-[var(--color-surface-glass)] backdrop-blur-[var(--blur-glass)] shadow-[var(--shadow-pop)] before:absolute before:inset-0 before:rounded-card before:bg-gloss-card before:pointer-events-none hover:border-border-strong hover:shadow-[var(--shadow-pop-hover)]",
9
+ metric: "border border-border-seam bg-bg-surface bg-accent-wash shadow-elevation-1 hover:border-border-strong hover:shadow-elevation-2",
10
+ insight: "border border-border-seam bg-bg-surface shadow-[var(--shadow-pop)] hover:border-border-strong hover:shadow-[var(--shadow-pop-hover)]"
11
+ } },
12
+ defaultVariants: { treatment: "plain" }
13
+ });
14
+ function i({ ref: n, className: i, treatment: a = "plain", children: o, ...s }) {
15
+ return /* @__PURE__ */ t("div", {
16
+ ref: n,
17
+ className: e(r({ treatment: a }), i),
18
+ ...s,
19
+ children: /* @__PURE__ */ t("div", {
20
+ className: "relative z-[1]",
21
+ children: o
22
+ })
23
+ });
24
+ }
25
+ i.displayName = "GlassCard";
26
+ //#endregion
27
+ export { i as GlassCard, r as glassCardVariants };
@@ -32,4 +32,8 @@ export { Tabs, TabsList, TabsTrigger, TabsContent } from './tabs';
32
32
  export { Textarea, type TextareaProps } from './textarea';
33
33
  export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './tooltip';
34
34
  export { PageContainer, type PageContainerProps, type PageContainerVariant, } from './page-container';
35
+ export { GlassCard, glassCardVariants, type GlassCardProps } from './glass-card';
36
+ export { EmphasisPanel, type EmphasisPanelProps } from './emphasis-panel';
37
+ export { ShowMore, type ShowMoreProps } from './show-more';
38
+ export { CTAOverflowMenu, type CTAOverflowMenuProps, type CTAAction, type CTAPrimaryAction, } from './cta-overflow-menu';
35
39
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { ReactNode } from 'react';
2
+ export type ShowMoreProps = {
3
+ children: ReactNode;
4
+ /** Clipped height (px) shown while collapsed. Default 120. */
5
+ collapsedHeight?: number;
6
+ /** Optional className for the outer wrapper. */
7
+ className?: string;
8
+ /** Label used for the toggle. Defaults to "Show more" / "Show less". */
9
+ label?: string;
10
+ };
11
+ /**
12
+ * ShowMore — Boff UI 2.0 progressive-disclosure primitive. Collapsed, the
13
+ * content is clipped to `collapsedHeight` with a bottom fade mask and a ghost
14
+ * toggle button. Expanded, the full content is revealed.
15
+ *
16
+ * Height is animated via a max-height transition. Reduced-motion is honoured
17
+ * globally (the `data-reduce-motion` CSS neutralises transitions), so no
18
+ * per-component motion guard is required here.
19
+ *
20
+ * Accessibility: the toggle exposes `aria-expanded` and `aria-controls`, and
21
+ * the disclosed content region is labelled by the button via `id`.
22
+ */
23
+ declare function ShowMore({ children, collapsedHeight, className, label }: ShowMoreProps): import("react/jsx-runtime").JSX.Element;
24
+ declare namespace ShowMore {
25
+ var displayName: string;
26
+ }
27
+ export { ShowMore };
28
+ //# sourceMappingURL=show-more.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show-more.d.ts","sourceRoot":"","sources":["../../src/ui/show-more.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKxD,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,iBAAS,QAAQ,CAAC,EAAE,QAAQ,EAAE,eAAqB,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,aAAa,2CAiCrF;kBAjCQ,QAAQ;;;AAoCjB,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { cn as e } from "../shared-utils.js";
2
+ import { Button as t } from "./button.js";
3
+ import { useId as n, useState as r } from "react";
4
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
+ //#region src/ui/show-more.tsx
6
+ function o({ children: o, collapsedHeight: s = 120, className: c, label: l }) {
7
+ let [u, d] = r(!1), f = n(), p = l ?? (u ? "Show less" : "Show more");
8
+ return /* @__PURE__ */ a("div", {
9
+ className: e("flex flex-col", c),
10
+ children: [/* @__PURE__ */ i("div", {
11
+ id: f,
12
+ className: e("relative overflow-hidden transition-[max-height] duration-300 ease-[var(--motion-easing-out)]", !u && "[mask-image:linear-gradient(to_bottom,black_calc(100%-3rem),transparent)] [-webkit-mask-image:linear-gradient(to_bottom,black_calc(100%-3rem),transparent)]"),
13
+ style: { maxHeight: u ? "100000px" : s },
14
+ children: o
15
+ }), /* @__PURE__ */ i("div", {
16
+ className: "mt-2 flex justify-center",
17
+ children: /* @__PURE__ */ i(t, {
18
+ type: "button",
19
+ variant: "ghost",
20
+ size: "sm",
21
+ "aria-expanded": u,
22
+ "aria-controls": f,
23
+ onClick: () => d((e) => !e),
24
+ children: p
25
+ })
26
+ })]
27
+ });
28
+ }
29
+ o.displayName = "ShowMore";
30
+ //#endregion
31
+ export { o as ShowMore };
package/dist/ui.js CHANGED
@@ -32,4 +32,8 @@ import { Tabs as ht, TabsContent as gt, TabsList as _t, TabsTrigger as vt } from
32
32
  import { Textarea as yt } from "./ui/textarea.js";
33
33
  import { Tooltip as bt, TooltipContent as xt, TooltipProvider as St, TooltipTrigger as Ct } from "./ui/tooltip.js";
34
34
  import { PageContainer as wt } from "./ui/page-container.js";
35
- export { e as Accordion, t as AccordionContent, n as AccordionItem, r as AccordionTrigger, ie as AlertDialog, ae as AlertDialogAction, oe as AlertDialogCancel, se as AlertDialogContent, ce as AlertDialogDescription, le as AlertDialogFooter, ue as AlertDialogHeader, de as AlertDialogOverlay, fe as AlertDialogPortal, pe as AlertDialogTitle, me as AlertDialogTrigger, he as Badge, _ as BottomSheet, v as BottomSheetClose, y as BottomSheetContent, b as BottomSheetDescription, x as BottomSheetFooter, S as BottomSheetHeader, C as BottomSheetTitle, w as BottomSheetTrigger, H as Button, _e as Card, ve as CardContent, ye as CardDescription, be as CardFooter, xe as CardHeader, Se as CardTitle, Ce as Checkbox, we as Command, Te as CommandDialog, Ee as CommandEmpty, De as CommandGroup, Oe as CommandInput, ke as CommandItem, Ae as CommandList, je as CommandSeparator, Me as CommandShortcut, i as Dialog, a as DialogClose, o as DialogContent, s as DialogDescription, c as DialogFooter, l as DialogHeader, u as DialogOverlay, d as DialogPortal, f as DialogTitle, p as DialogTrigger, Ne as DropdownMenu, Pe as DropdownMenuCheckboxItem, Fe as DropdownMenuContent, Ie as DropdownMenuGroup, Le as DropdownMenuItem, Re as DropdownMenuLabel, ze as DropdownMenuPortal, Be as DropdownMenuRadioGroup, Ve as DropdownMenuRadioItem, He as DropdownMenuSeparator, Ue as DropdownMenuShortcut, We as DropdownMenuSub, Ge as DropdownMenuSubContent, Ke as DropdownMenuSubTrigger, qe as DropdownMenuTrigger, re as EmptyState, m as EntityIdModal, Je as Input, Ye as Label, g as OptionalFields, wt as PageContainer, ee as Pagination, Xe as Popover, Ze as PopoverAnchor, Qe as PopoverContent, $e as PopoverTrigger, T as ResponsiveDialog, E as ResponsiveDialogClose, D as ResponsiveDialogContent, O as ResponsiveDialogDescription, k as ResponsiveDialogFooter, A as ResponsiveDialogHeader, j as ResponsiveDialogTitle, M as ResponsiveDialogTrigger, ne as ResponsiveStack, V as ResponsiveTable, et as ScrollArea, tt as ScrollBar, W as Select, G as SelectContent, K as SelectGroup, q as SelectItem, J as SelectLabel, Y as SelectScrollDownButton, X as SelectScrollUpButton, Z as SelectSeparator, Q as SelectTrigger, $ as SelectValue, nt as Separator, rt as Sheet, it as SheetClose, at as SheetContent, ot as SheetDescription, st as SheetFooter, ct as SheetHeader, lt as SheetTitle, ut as SheetTrigger, dt as Skeleton, pt as Spinner, te as Stepper, mt as Switch, N as Table, P as TableBody, F as TableCaption, I as TableCell, L as TableFooter, R as TableHead, z as TableHeader, B as TableRow, ht as Tabs, gt as TabsContent, _t as TabsList, vt as TabsTrigger, yt as Textarea, ft as Toaster, bt as Tooltip, xt as TooltipContent, St as TooltipProvider, Ct as TooltipTrigger, ge as badgeVariants, U as buttonVariants, h as useEntityIdModal };
35
+ import { GlassCard as Tt, glassCardVariants as Et } from "./ui/glass-card.js";
36
+ import { EmphasisPanel as Dt } from "./ui/emphasis-panel.js";
37
+ import { ShowMore as Ot } from "./ui/show-more.js";
38
+ import { CTAOverflowMenu as kt } from "./ui/cta-overflow-menu.js";
39
+ export { e as Accordion, t as AccordionContent, n as AccordionItem, r as AccordionTrigger, ie as AlertDialog, ae as AlertDialogAction, oe as AlertDialogCancel, se as AlertDialogContent, ce as AlertDialogDescription, le as AlertDialogFooter, ue as AlertDialogHeader, de as AlertDialogOverlay, fe as AlertDialogPortal, pe as AlertDialogTitle, me as AlertDialogTrigger, he as Badge, _ as BottomSheet, v as BottomSheetClose, y as BottomSheetContent, b as BottomSheetDescription, x as BottomSheetFooter, S as BottomSheetHeader, C as BottomSheetTitle, w as BottomSheetTrigger, H as Button, kt as CTAOverflowMenu, _e as Card, ve as CardContent, ye as CardDescription, be as CardFooter, xe as CardHeader, Se as CardTitle, Ce as Checkbox, we as Command, Te as CommandDialog, Ee as CommandEmpty, De as CommandGroup, Oe as CommandInput, ke as CommandItem, Ae as CommandList, je as CommandSeparator, Me as CommandShortcut, i as Dialog, a as DialogClose, o as DialogContent, s as DialogDescription, c as DialogFooter, l as DialogHeader, u as DialogOverlay, d as DialogPortal, f as DialogTitle, p as DialogTrigger, Ne as DropdownMenu, Pe as DropdownMenuCheckboxItem, Fe as DropdownMenuContent, Ie as DropdownMenuGroup, Le as DropdownMenuItem, Re as DropdownMenuLabel, ze as DropdownMenuPortal, Be as DropdownMenuRadioGroup, Ve as DropdownMenuRadioItem, He as DropdownMenuSeparator, Ue as DropdownMenuShortcut, We as DropdownMenuSub, Ge as DropdownMenuSubContent, Ke as DropdownMenuSubTrigger, qe as DropdownMenuTrigger, Dt as EmphasisPanel, re as EmptyState, m as EntityIdModal, Tt as GlassCard, Je as Input, Ye as Label, g as OptionalFields, wt as PageContainer, ee as Pagination, Xe as Popover, Ze as PopoverAnchor, Qe as PopoverContent, $e as PopoverTrigger, T as ResponsiveDialog, E as ResponsiveDialogClose, D as ResponsiveDialogContent, O as ResponsiveDialogDescription, k as ResponsiveDialogFooter, A as ResponsiveDialogHeader, j as ResponsiveDialogTitle, M as ResponsiveDialogTrigger, ne as ResponsiveStack, V as ResponsiveTable, et as ScrollArea, tt as ScrollBar, W as Select, G as SelectContent, K as SelectGroup, q as SelectItem, J as SelectLabel, Y as SelectScrollDownButton, X as SelectScrollUpButton, Z as SelectSeparator, Q as SelectTrigger, $ as SelectValue, nt as Separator, rt as Sheet, it as SheetClose, at as SheetContent, ot as SheetDescription, st as SheetFooter, ct as SheetHeader, lt as SheetTitle, ut as SheetTrigger, Ot as ShowMore, dt as Skeleton, pt as Spinner, te as Stepper, mt as Switch, N as Table, P as TableBody, F as TableCaption, I as TableCell, L as TableFooter, R as TableHead, z as TableHeader, B as TableRow, ht as Tabs, gt as TabsContent, _t as TabsList, vt as TabsTrigger, yt as Textarea, ft as Toaster, bt as Tooltip, xt as TooltipContent, St as TooltipProvider, Ct as TooltipTrigger, ge as badgeVariants, U as buttonVariants, Et as glassCardVariants, h as useEntityIdModal };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.624.2",
3
+ "version": "2026.625.2",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "imports": {