@businessdash/sdk 0.9.80 → 0.9.90

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 (264) hide show
  1. package/README.md +133 -949
  2. package/assets/{biab-sw.js → bd-sw.js} +2 -2
  3. package/dist/account-core/index.d.ts +1 -1
  4. package/dist/account-core/index.d.ts.map +1 -1
  5. package/dist/adapters-revalidate.d.ts +2 -2
  6. package/dist/adapters-revalidate.js +2 -2
  7. package/dist/adapters-revalidate.js.map +1 -1
  8. package/dist/analytics-core.d.ts +6 -6
  9. package/dist/analytics-core.d.ts.map +1 -1
  10. package/dist/analytics-core.js +4 -4
  11. package/dist/analytics-core.js.map +1 -1
  12. package/dist/analytics-server.d.ts +6 -6
  13. package/dist/analytics-server.d.ts.map +1 -1
  14. package/dist/analytics-server.js +5 -5
  15. package/dist/auth-handler.d.ts +14 -14
  16. package/dist/auth-handler.d.ts.map +1 -1
  17. package/dist/auth-handler.js +16 -16
  18. package/dist/auth-handler.js.map +1 -1
  19. package/dist/auth-links.d.ts +2 -2
  20. package/dist/auth-links.d.ts.map +1 -1
  21. package/dist/auth-links.js +2 -2
  22. package/dist/auth-links.js.map +1 -1
  23. package/dist/{biab-forms.css → bd-forms.css} +158 -158
  24. package/dist/cli.d.ts +4 -4
  25. package/dist/cli.js +78 -78
  26. package/dist/cli.js.map +1 -1
  27. package/dist/client.d.ts +158 -147
  28. package/dist/client.d.ts.map +1 -1
  29. package/dist/client.js +156 -137
  30. package/dist/client.js.map +1 -1
  31. package/dist/consent-core/index.cjs +2 -2
  32. package/dist/consent-core/index.d.ts +2 -2
  33. package/dist/consent-core/index.d.ts.map +1 -1
  34. package/dist/consent-core/index.js +10 -8
  35. package/dist/consent-core/index.js.map +1 -1
  36. package/dist/contracts.d.ts +411 -52
  37. package/dist/contracts.d.ts.map +1 -1
  38. package/dist/contracts.js +89 -15
  39. package/dist/contracts.js.map +1 -1
  40. package/dist/data-model-schema.d.ts +15 -15
  41. package/dist/data-model-schema.d.ts.map +1 -1
  42. package/dist/data-model-schema.js +19 -17
  43. package/dist/data-model-schema.js.map +1 -1
  44. package/dist/distribution.d.ts +5 -5
  45. package/dist/distribution.d.ts.map +1 -1
  46. package/dist/distribution.js +4 -4
  47. package/dist/element.d.ts +36 -36
  48. package/dist/element.d.ts.map +1 -1
  49. package/dist/element.js +43 -43
  50. package/dist/element.js.map +1 -1
  51. package/dist/embed-protocol.d.ts +11 -11
  52. package/dist/embed-protocol.d.ts.map +1 -1
  53. package/dist/embed-protocol.js +1 -1
  54. package/dist/embed-protocol.js.map +1 -1
  55. package/dist/errors.d.ts +15 -15
  56. package/dist/errors.d.ts.map +1 -1
  57. package/dist/errors.js +18 -18
  58. package/dist/errors.js.map +1 -1
  59. package/dist/forms-core/autocomplete.d.ts +3 -3
  60. package/dist/forms-core/autocomplete.d.ts.map +1 -1
  61. package/dist/forms-core/autocomplete.js +2 -2
  62. package/dist/forms-core/controller.d.ts +10 -10
  63. package/dist/forms-core/controller.d.ts.map +1 -1
  64. package/dist/forms-core/controller.js +4 -4
  65. package/dist/forms-core/controller.js.map +1 -1
  66. package/dist/forms-core/elements.d.ts +4 -4
  67. package/dist/forms-core/elements.d.ts.map +1 -1
  68. package/dist/forms-core/elements.js +7 -7
  69. package/dist/forms-core/elements.js.map +1 -1
  70. package/dist/forms-core/formula.d.ts +1 -1
  71. package/dist/forms-core/formula.js +1 -1
  72. package/dist/forms-core/index.d.ts +6 -6
  73. package/dist/forms-core/index.d.ts.map +1 -1
  74. package/dist/forms-core/index.js +5 -5
  75. package/dist/forms-core/index.js.map +1 -1
  76. package/dist/forms-core/units.d.ts +1 -1
  77. package/dist/forms-core/units.js +1 -1
  78. package/dist/forms-core/us-states.d.ts +1 -1
  79. package/dist/forms-core/us-states.js +1 -1
  80. package/dist/forms-core/validation.d.ts +12 -3
  81. package/dist/forms-core/validation.d.ts.map +1 -1
  82. package/dist/forms-core/validation.js +152 -17
  83. package/dist/forms-core/validation.js.map +1 -1
  84. package/dist/forms.d.ts +2 -2
  85. package/dist/forms.d.ts.map +1 -1
  86. package/dist/forms.js +2 -2
  87. package/dist/forms.js.map +1 -1
  88. package/dist/framework-support.js +1 -1
  89. package/dist/framework-support.js.map +1 -1
  90. package/dist/gallery-types.d.ts +1 -1
  91. package/dist/graphql.d.ts +3 -3
  92. package/dist/graphql.d.ts.map +1 -1
  93. package/dist/graphql.js +3 -3
  94. package/dist/graphql.js.map +1 -1
  95. package/dist/index.cjs +351 -272
  96. package/dist/index.d.cts +5 -5
  97. package/dist/index.d.mts +5 -5
  98. package/dist/index.d.ts +5 -5
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +5 -5
  101. package/dist/index.js.map +1 -1
  102. package/dist/legal-core/index.cjs +8 -8
  103. package/dist/legal-core/index.d.ts +3 -3
  104. package/dist/legal-core/index.d.ts.map +1 -1
  105. package/dist/legal-core/index.js +11 -11
  106. package/dist/legal-core/index.js.map +1 -1
  107. package/dist/marketing-core/index.d.ts +51 -1
  108. package/dist/marketing-core/index.d.ts.map +1 -1
  109. package/dist/marketing-core/index.js +35 -0
  110. package/dist/marketing-core/index.js.map +1 -1
  111. package/dist/marketing-schema.d.ts +9 -9
  112. package/dist/marketing-schema.d.ts.map +1 -1
  113. package/dist/marketing-schema.js +1 -1
  114. package/dist/mcp.d.ts +4 -4
  115. package/dist/mcp.js +4 -4
  116. package/dist/native.d.ts +6 -6
  117. package/dist/native.d.ts.map +1 -1
  118. package/dist/native.js +4 -4
  119. package/dist/native.js.map +1 -1
  120. package/dist/next-revalidate.d.ts +8 -8
  121. package/dist/next-revalidate.d.ts.map +1 -1
  122. package/dist/next-revalidate.js +7 -7
  123. package/dist/next-revalidate.js.map +1 -1
  124. package/dist/notifications-core/index.d.ts +1 -1
  125. package/dist/notifications-core/index.js +1 -1
  126. package/dist/parallel-pages.d.ts +4 -4
  127. package/dist/parallel-pages.d.ts.map +1 -1
  128. package/dist/parallel-pages.js +5 -5
  129. package/dist/parallel-pages.js.map +1 -1
  130. package/dist/portal-core/index.d.ts +1 -1
  131. package/dist/portal-core/index.js +1 -1
  132. package/dist/proxy.d.ts +18 -18
  133. package/dist/proxy.d.ts.map +1 -1
  134. package/dist/proxy.js +10 -10
  135. package/dist/proxy.js.map +1 -1
  136. package/dist/push-core/index.cjs +6 -2
  137. package/dist/push-core/index.d.ts +1 -1
  138. package/dist/push-core/index.d.ts.map +1 -1
  139. package/dist/push-core/index.js +6 -2
  140. package/dist/push-core/index.js.map +1 -1
  141. package/dist/react-analytics.d.ts +14 -14
  142. package/dist/react-analytics.d.ts.map +1 -1
  143. package/dist/react-analytics.js +15 -15
  144. package/dist/react-analytics.js.map +1 -1
  145. package/dist/react-attribution.d.ts +2 -2
  146. package/dist/react-attribution.d.ts.map +1 -1
  147. package/dist/react-attribution.js +1 -1
  148. package/dist/react-marketing.js +5 -5
  149. package/dist/react-marketing.js.map +1 -1
  150. package/dist/react.d.ts +38 -61
  151. package/dist/react.d.ts.map +1 -1
  152. package/dist/react.js +247 -261
  153. package/dist/react.js.map +1 -1
  154. package/dist/reserved-paths.d.ts +2 -2
  155. package/dist/reserved-paths.js +3 -3
  156. package/dist/reserved-paths.js.map +1 -1
  157. package/dist/revalidate-verify.d.ts +3 -3
  158. package/dist/revalidate-verify.d.ts.map +1 -1
  159. package/dist/revalidate-verify.js +1 -1
  160. package/dist/revalidate-verify.js.map +1 -1
  161. package/dist/sdk.d.ts +51 -45
  162. package/dist/sdk.d.ts.map +1 -1
  163. package/dist/sdk.js +48 -50
  164. package/dist/sdk.js.map +1 -1
  165. package/dist/seed-core/index.js +8 -8
  166. package/dist/seed-core/index.js.map +1 -1
  167. package/dist/seo-core/blog.d.ts +1 -1
  168. package/dist/seo-core/blog.js +1 -1
  169. package/dist/seo-core/blog.js.map +1 -1
  170. package/dist/seo-core/index.cjs +2 -2
  171. package/dist/seo-core/index.js +1 -1
  172. package/dist/seo-core/index.js.map +1 -1
  173. package/dist/seo.d.ts +1 -1
  174. package/dist/seo.d.ts.map +1 -1
  175. package/dist/seo.js +1 -1
  176. package/dist/seo.js.map +1 -1
  177. package/dist/sitemap-core/index.cjs +5 -5
  178. package/dist/sitemap-core/index.d.ts +13 -5
  179. package/dist/sitemap-core/index.d.ts.map +1 -1
  180. package/dist/sitemap-core/index.js +4 -4
  181. package/dist/sitemap-core/index.js.map +1 -1
  182. package/dist/socials.d.ts +6 -6
  183. package/dist/socials.d.ts.map +1 -1
  184. package/dist/socials.js +5 -5
  185. package/dist/socials.js.map +1 -1
  186. package/dist/solid-compat.d.ts +1 -1
  187. package/dist/solid-compat.js +4 -4
  188. package/dist/solid-compat.js.map +1 -1
  189. package/dist/store-core/index.d.ts +1 -1
  190. package/dist/vanilla.d.ts +12 -12
  191. package/dist/vanilla.d.ts.map +1 -1
  192. package/dist/vanilla.js +192 -145
  193. package/dist/vanilla.js.map +1 -1
  194. package/openapi.json +264 -1
  195. package/package.json +8 -8
  196. package/src/account-core/index.ts +1 -1
  197. package/src/adapters-revalidate.ts +3 -3
  198. package/src/analytics-core.ts +8 -8
  199. package/src/analytics-server.ts +6 -6
  200. package/src/angular/{biab-form.component.ts → bd-form.component.ts} +269 -161
  201. package/src/angular/headless.ts +12 -12
  202. package/src/angular/index.ts +9 -9
  203. package/src/auth-handler.ts +22 -22
  204. package/src/auth-links.ts +2 -2
  205. package/src/cli.ts +81 -81
  206. package/src/client.ts +218 -193
  207. package/src/consent-core/index.ts +10 -8
  208. package/src/contracts.ts +99 -15
  209. package/src/data-model-schema.ts +29 -26
  210. package/src/distribution.ts +5 -5
  211. package/src/element.ts +54 -54
  212. package/src/embed-protocol.ts +14 -14
  213. package/src/errors.ts +27 -27
  214. package/src/forms-core/autocomplete.ts +3 -3
  215. package/src/forms-core/controller.ts +12 -12
  216. package/src/forms-core/elements.ts +7 -7
  217. package/src/forms-core/formula.ts +1 -1
  218. package/src/forms-core/index.ts +8 -8
  219. package/src/forms-core/units.ts +1 -1
  220. package/src/forms-core/us-states.ts +1 -1
  221. package/src/forms-core/validation.ts +158 -14
  222. package/src/forms.ts +2 -2
  223. package/src/framework-support.ts +1 -1
  224. package/src/gallery-types.ts +1 -1
  225. package/src/graphql.ts +4 -4
  226. package/src/index.ts +38 -38
  227. package/src/legal-core/index.ts +12 -12
  228. package/src/marketing-core/index.ts +62 -0
  229. package/src/marketing-schema.ts +9 -9
  230. package/src/mcp.ts +4 -4
  231. package/src/native.ts +14 -14
  232. package/src/next-revalidate.ts +10 -10
  233. package/src/notifications-core/index.ts +1 -1
  234. package/src/parallel-pages.ts +6 -6
  235. package/src/portal-core/index.ts +1 -1
  236. package/src/proxy.ts +28 -28
  237. package/src/push-core/index.ts +11 -5
  238. package/src/qwik.tsx +262 -166
  239. package/src/react-analytics.tsx +17 -17
  240. package/src/react-attribution.tsx +2 -2
  241. package/src/react-marketing.tsx +5 -5
  242. package/src/react.tsx +541 -500
  243. package/src/reserved-paths.ts +3 -3
  244. package/src/revalidate-verify.ts +5 -5
  245. package/src/sdk.ts +131 -101
  246. package/src/seed-core/index.ts +8 -8
  247. package/src/seo-core/blog.ts +2 -2
  248. package/src/seo-core/index.ts +1 -1
  249. package/src/seo.ts +1 -1
  250. package/src/sitemap-core/index.ts +17 -9
  251. package/src/socials.ts +6 -6
  252. package/src/solid-compat.tsx +5 -5
  253. package/src/solid-surfaces.tsx +28 -28
  254. package/src/solid.tsx +264 -175
  255. package/src/store-core/index.ts +1 -1
  256. package/src/styles/{biab-forms.css → bd-forms.css} +158 -158
  257. package/src/svelte/{BiabForm.svelte → BdForm.svelte} +240 -173
  258. package/src/svelte/context.ts +16 -16
  259. package/src/svelte/headless.ts +10 -10
  260. package/src/svelte/index.ts +16 -16
  261. package/src/vanilla.ts +250 -169
  262. package/src/vue/{BiabForm.vue → BdForm.vue} +270 -157
  263. package/src/vue/headless.ts +11 -11
  264. package/src/vue/index.ts +26 -26
package/dist/react.js CHANGED
@@ -10,7 +10,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
10
10
  * WHY THE DIRECTIVE IS HERE
11
11
  *
12
12
  * Without it, a React Server Components framework treats this module as server
13
- * code by default, and importing `<BiabForm>` into a page throws "you're
13
+ * code by default, and importing `<BdForm>` into a page throws "you're
14
14
  * importing a component that needs useState". The only way out is for every
15
15
  * consumer to hand-write a `"use client"` wrapper per component — which is
16
16
  * exactly what the Next App Router starter had to do, sixteen times, for
@@ -24,24 +24,24 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
24
24
  */
25
25
  import { createContext, Fragment, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore, } from "react";
26
26
  import { createFollowersController, createUserController, } from "./account-core/index.js";
27
- import { buildAuthHref, clearLocalFollow, DEFAULT_AUTH_BASE_PATH, followerStoreKey, readLocalFollow, writeLocalFollow, } from "./auth-links.js";
27
+ import { buildAuthHref, DEFAULT_AUTH_BASE_PATH } from "./auth-links.js";
28
28
  import { createBlogController } from "./blog-core/index.js";
29
29
  import { createChatController } from "./chat-core/index.js";
30
30
  import { createCheckoutController } from "./checkout-core/index.js";
31
- import { BiabDevClient } from "./client.js";
31
+ import { BdApiClient } from "./client.js";
32
32
  import { DEFAULT_EMBED_SANDBOX, DEFAULT_REFRESH_LEAD_MS, refreshDelayMs, subscribeToEmbedMessages, } from "./embed-protocol.js";
33
33
  import { buildAcceptAttr, concurrentRevealCount, createFormController, evalCondition, fetchIconNames, filterIconNames, flattenValueFields, formatCalcValue, iconUrl, isPendingFileValue, resolveFieldAutocomplete, shouldSearchOptions, validateFile, } from "./forms-core/index.js";
34
34
  import { baseUnitFor, convertToBase, formatMeasurement, isMeasurementCategory, unitsForCategory, } from "./forms-core/units.js";
35
35
  import { US_STATES } from "./forms-core/us-states.js";
36
- import { createMarketingController } from "./marketing-core/index.js";
36
+ import { createMarketingController, marketingListView, marketingPageView, } from "./marketing-core/index.js";
37
37
  import { createPortalController } from "./portal-core/index.js";
38
- import { createBiabClient } from "./sdk.js";
38
+ import { createBdClient } from "./sdk.js";
39
39
  import { resolveSocialLinks, SOCIAL_FALLBACK_GLYPH, SOCIAL_LIST_STYLE, } from "./social-core/index.js";
40
40
  import { createStoreController } from "./store-core/index.js";
41
41
  import { createVerifyController, } from "./verify-core/index.js";
42
42
  function useEmbedSession(loader, options) {
43
43
  const { apiKey, baseUrl, refreshLeadMs = DEFAULT_REFRESH_LEAD_MS } = options;
44
- const client = useMemo(() => new BiabDevClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
44
+ const client = useMemo(() => new BdApiClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
45
45
  const [state, setState] = useState({ status: "idle" });
46
46
  // `loader` is recreated per surface; depending on it would refetch on every
47
47
  // render, so it's intentionally omitted from the deps below.
@@ -152,7 +152,7 @@ export function Storefront({ apiKey, baseUrl, productId, className, style, title
152
152
  const { state, refresh } = useEmbedSession((client) => client.storefront.createSession(input), { apiKey, baseUrl, refreshLeadMs });
153
153
  const handleEvent = useCallback((event) => {
154
154
  onEvent?.(event);
155
- if (event.type === "biab:cart:update") {
155
+ if (event.type === "bd:cart:update") {
156
156
  onCartChange?.(event.count, event.subtotalCents);
157
157
  }
158
158
  }, [onEvent, onCartChange]);
@@ -162,7 +162,7 @@ export function Cart({ apiKey, baseUrl, className, style, title = "Cart", loadin
162
162
  const { state, refresh } = useEmbedSession((client) => client.cart.createSession(), { apiKey, baseUrl, refreshLeadMs });
163
163
  const handleEvent = useCallback((event) => {
164
164
  onEvent?.(event);
165
- if (event.type === "biab:cart:update") {
165
+ if (event.type === "bd:cart:update") {
166
166
  onCartChange?.(event.count, event.subtotalCents);
167
167
  }
168
168
  }, [onEvent, onCartChange]);
@@ -170,7 +170,7 @@ export function Cart({ apiKey, baseUrl, className, style, title = "Cart", loadin
170
170
  }
171
171
  export function Checkout(props) {
172
172
  const { apiKey, baseUrl, cart, mode = "redirect", className, style, title = "Checkout", children, loadingFallback, errorFallback, onEvent, onSuccess, onCancel, onError, } = props;
173
- const client = useMemo(() => new BiabDevClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
173
+ const client = useMemo(() => new BdApiClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
174
174
  const [state, setState] = useState({
175
175
  status: "idle",
176
176
  });
@@ -191,11 +191,11 @@ export function Checkout(props) {
191
191
  }, [client, cart, mode, onError]);
192
192
  const handleEvent = useCallback((event) => {
193
193
  onEvent?.(event);
194
- if (event.type === "biab:checkout:success")
194
+ if (event.type === "bd:checkout:success")
195
195
  onSuccess?.(event.sessionId);
196
- else if (event.type === "biab:checkout:cancel")
196
+ else if (event.type === "bd:checkout:cancel")
197
197
  onCancel?.(event.sessionId);
198
- else if (event.type === "biab:checkout:error")
198
+ else if (event.type === "bd:checkout:error")
199
199
  onError?.(new Error(event.message));
200
200
  }, [onEvent, onSuccess, onCancel, onError]);
201
201
  // Lazily create the session once it's idle (iframe mode). Declared BEFORE the
@@ -220,7 +220,7 @@ export function CheckoutResult(props) {
220
220
  setState({ status: "error", error: new Error("Missing session id.") });
221
221
  return;
222
222
  }
223
- const client = new BiabDevClient({ apiKey, baseUrl });
223
+ const client = new BdApiClient({ apiKey, baseUrl });
224
224
  // We hit the *public* tRPC endpoint via fetch — no API key required.
225
225
  const trpcUrl = baseUrl.replace(/\/api\/package\/v1\/?$/, "");
226
226
  const requestUrl = `${trpcUrl}/api/trpc/store.checkoutSessionStatus?input=${encodeURIComponent(JSON.stringify({ json: { orgSlug, sessionId } }))}`;
@@ -277,7 +277,7 @@ export function Chatbot({ apiKey, baseUrl, className, style, title = "Assistant"
277
277
  const { state, refresh } = useEmbedSession((client) => client.chatbot.createSession(), { apiKey, baseUrl, refreshLeadMs });
278
278
  const handleEvent = useCallback((event) => {
279
279
  onEvent?.(event);
280
- if (event.type === "biab:chatbot:assistant-message") {
280
+ if (event.type === "bd:chatbot:assistant-message") {
281
281
  onAssistantMessage?.(event.content, event.model);
282
282
  }
283
283
  }, [onEvent, onAssistantMessage]);
@@ -296,13 +296,13 @@ export function Chatbot({ apiKey, baseUrl, className, style, title = "Assistant"
296
296
  export function useChatbot(options) {
297
297
  const { apiKey, baseUrl } = options;
298
298
  const controller = useMemo(() => createChatController({
299
- client: new BiabDevClient({ apiKey, baseUrl }),
299
+ client: new BdApiClient({ apiKey, baseUrl }),
300
300
  }), [apiKey, baseUrl]);
301
301
  useEffect(() => () => controller.destroy(), [controller]);
302
302
  const subscribe = useCallback((onStoreChange) => controller.subscribe(() => onStoreChange()), [controller]);
303
303
  const getSnapshot = useCallback(() => controller.snapshot(), [controller]);
304
304
  const snap = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
305
- const uploadFile = useCallback((args) => new BiabDevClient({ apiKey, baseUrl }).chatbot.uploadFile(args), [apiKey, baseUrl]);
305
+ const uploadFile = useCallback((args) => new BdApiClient({ apiKey, baseUrl }).chatbot.uploadFile(args), [apiKey, baseUrl]);
306
306
  // The returned shape is unchanged from before this hook was moved onto
307
307
  // `chat-core`, so existing consumers keep working — only the implementation
308
308
  // moved, and it now backs every other framework's chat binding too.
@@ -335,7 +335,7 @@ export function useChatbot(options) {
335
335
  export function useStorefront(options) {
336
336
  const { apiKey, baseUrl, pageSize, categoryId } = options;
337
337
  const controller = useMemo(() => createStoreController({
338
- client: new BiabDevClient({ apiKey, baseUrl }),
338
+ client: new BdApiClient({ apiKey, baseUrl }),
339
339
  ...(pageSize ? { pageSize } : {}),
340
340
  ...(categoryId ? { categoryId } : {}),
341
341
  }), [apiKey, baseUrl, pageSize, categoryId]);
@@ -399,52 +399,52 @@ const inlineLayoutStyles = {
399
399
  * Opt-in default visual theme for {@link ChatbotInline}. Every rule is wrapped
400
400
  * in `:where(…)` so it has **zero specificity** — any class a consumer passes
401
401
  * via `classNames` (or their global CSS) overrides it without `!important`.
402
- * Scoped to the `[data-biab-chatbot]` root (set only when `unstyled` is false),
402
+ * Scoped to the `[data-bd-chatbot]` root (set only when `unstyled` is false),
403
403
  * and targets the per-slot `data-slot` attributes the component stamps on each
404
404
  * element. Injected once into `<head>` (id-guarded). This is what makes the
405
405
  * inline component a polished drop-in instead of bare divs, while preserving
406
406
  * the headless contract for anyone who wants to style it themselves.
407
407
  */
408
- const CHATBOT_INLINE_STYLE_ID = "biab-chatbot-inline-styles";
408
+ const CHATBOT_INLINE_STYLE_ID = "bd-chatbot-inline-styles";
409
409
  const CHATBOT_INLINE_CSS = `
410
- :where([data-biab-chatbot]){font-size:14px;color:inherit;background:var(--biab-chatbot-bg,Canvas);border:1px solid color-mix(in srgb,currentColor 12%,transparent);border-radius:16px;}
411
- :where([data-biab-chatbot] [data-slot="header"]){padding:12px 16px;border-bottom:1px solid color-mix(in srgb,currentColor 10%,transparent);}
412
- :where([data-biab-chatbot] [data-slot="header-title"]){font-weight:600;}
413
- :where([data-biab-chatbot] [data-slot="header-subtitle"]){font-size:12px;opacity:.6;margin-top:2px;}
414
- :where([data-biab-chatbot] [data-slot="presence-strip"]){display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 16px;font-size:12px;border-bottom:1px solid color-mix(in srgb,currentColor 8%,transparent);opacity:.85;}
415
- :where([data-biab-chatbot] [data-slot="message-list"]){padding:16px;gap:12px;}
416
- :where([data-biab-chatbot] [data-slot="message-row"]){max-width:85%;width:fit-content;padding:8px 12px;border-radius:16px;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere;box-shadow:0 1px 2px color-mix(in srgb,currentColor 8%,transparent);}
417
- :where([data-biab-chatbot] [data-slot="message-row"][data-role="user"]){align-self:flex-end;background:var(--biab-chatbot-accent,#0d9488);color:#fff;border-bottom-right-radius:4px;}
418
- :where([data-biab-chatbot] [data-slot="message-row"][data-role="assistant"]){align-self:flex-start;background:color-mix(in srgb,currentColor 8%,transparent);border-bottom-left-radius:4px;}
419
- :where([data-biab-chatbot] [data-slot="message-pending"]){align-self:flex-start;width:fit-content;padding:8px 12px;background-image:linear-gradient(90deg,currentColor 35%,color-mix(in srgb,currentColor 25%,transparent) 50%,currentColor 65%);background-size:200% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:biab-chatbot-shimmer 2s linear infinite;}
420
- :where([data-biab-chatbot] [data-slot="error-text"]){align-self:center;font-size:12px;color:#dc2626;}
421
- :where([data-biab-chatbot] [data-slot="input-bar"]){gap:8px;padding:12px;border-top:1px solid color-mix(in srgb,currentColor 10%,transparent);}
422
- :where([data-biab-chatbot] [data-slot="input-field"]){padding:8px 12px;border-radius:10px;border:1px solid color-mix(in srgb,currentColor 15%,transparent);background:transparent;color:inherit;font:inherit;outline:none;}
423
- :where([data-biab-chatbot] [data-slot="input-field"]:focus-visible){border-color:var(--biab-chatbot-accent,#0d9488);}
424
- :where([data-biab-chatbot] [data-slot="send-button"]){padding:8px 14px;border-radius:10px;border:none;background:var(--biab-chatbot-accent,#0d9488);color:#fff;font-weight:500;cursor:pointer;}
425
- :where([data-biab-chatbot] [data-slot="send-button"]:disabled){opacity:.5;cursor:default;}
426
- :where([data-biab-chatbot] [data-slot="upload-button"]){display:inline-flex;align-items:center;justify-content:center;padding:0 6px;border:none;background:transparent;color:inherit;font-size:18px;line-height:1;cursor:pointer;opacity:.7;}
427
- :where([data-biab-chatbot] [data-slot="upload-button"]:hover){opacity:1;}
428
- :where([data-biab-chatbot] [data-slot="upload-button"]:disabled){opacity:.4;cursor:default;}
429
- :where([data-biab-chatbot] [data-slot="message-file"]){align-self:flex-end;max-width:85%;padding:8px 12px;border-radius:16px;border-bottom-right-radius:4px;background:var(--biab-chatbot-accent,#0d9488);color:#fff;text-decoration:none;font-size:13px;word-break:break-all;}
430
- :where([data-biab-chatbot] [data-slot="message-image"]){align-self:flex-end;max-width:85%;border-radius:12px;overflow:hidden;}
431
- :where([data-biab-chatbot] [data-slot="jump-latest"]){position:absolute;left:50%;bottom:72px;transform:translateX(-50%);display:inline-flex;align-items:center;gap:4px;padding:6px 12px;border-radius:999px;border:1px solid color-mix(in srgb,currentColor 15%,transparent);background:var(--biab-chatbot-bg,Canvas);font-size:12px;font-weight:500;cursor:pointer;box-shadow:0 2px 10px color-mix(in srgb,currentColor 20%,transparent);}
432
- :where([data-biab-chatbot] [data-slot="form-card"]){display:flex;flex-direction:column;gap:10px;align-self:stretch;padding:14px;border-radius:14px;border:1px solid color-mix(in srgb,currentColor 14%,transparent);background:color-mix(in srgb,currentColor 4%,transparent);}
433
- :where([data-biab-chatbot] [data-slot="form-title"]){font-weight:600;}
434
- :where([data-biab-chatbot] [data-slot="form-description"]){font-size:12px;opacity:.7;}
435
- :where([data-biab-chatbot] [data-slot="form-field"]){gap:4px;}
436
- :where([data-biab-chatbot] [data-slot="form-label"]){font-size:12px;font-weight:500;opacity:.85;}
437
- :where([data-biab-chatbot] [data-slot="form-input"],[data-biab-chatbot] [data-slot="form-textarea"],[data-biab-chatbot] [data-slot="form-select"]){padding:8px 10px;border-radius:8px;border:1px solid color-mix(in srgb,currentColor 15%,transparent);background:transparent;color:inherit;font:inherit;outline:none;}
438
- :where([data-biab-chatbot] [data-slot="form-input"]:focus-visible,[data-biab-chatbot] [data-slot="form-textarea"]:focus-visible,[data-biab-chatbot] [data-slot="form-select"]:focus-visible){border-color:var(--biab-chatbot-accent,#0d9488);}
439
- :where([data-biab-chatbot] [data-slot="form-submit"]){padding:8px 14px;border-radius:8px;border:none;background:var(--biab-chatbot-accent,#0d9488);color:#fff;font-weight:500;cursor:pointer;}
440
- :where([data-biab-chatbot] [data-slot="form-submit"]:disabled){opacity:.5;cursor:default;}
441
- :where([data-biab-chatbot] [data-slot="form-error"]){font-size:12px;color:#dc2626;}
442
- :where([data-biab-chatbot] [data-slot="form-receipt"]){font-size:13px;opacity:.8;}
443
- @keyframes biab-chatbot-shimmer{from{background-position:100% 0;}to{background-position:0 0;}}
444
- @media (prefers-reduced-motion:reduce){:where([data-biab-chatbot] [data-slot="message-pending"]){animation:none;-webkit-text-fill-color:currentColor;}}
445
- @property --biab-chatbot-fade{syntax:"<length>";inherits:false;initial-value:0px;}
446
- @keyframes biab-chatbot-fade-b{from{--biab-chatbot-fade:24px;}to{--biab-chatbot-fade:0px;}}
447
- @supports (animation-timeline:scroll()){:where([data-biab-chatbot] [data-slot="message-list"]){-webkit-mask-image:linear-gradient(to bottom,#000 0,#000 calc(100% - var(--biab-chatbot-fade,0px)),transparent 100%);mask-image:linear-gradient(to bottom,#000 0,#000 calc(100% - var(--biab-chatbot-fade,0px)),transparent 100%);animation:biab-chatbot-fade-b 1ms linear both;animation-timeline:scroll(self y);animation-range:calc(100% - 96px) 100%;}}
410
+ :where([data-bd-chatbot]){font-size:14px;color:inherit;background:var(--bd-chatbot-bg,Canvas);border:1px solid color-mix(in srgb,currentColor 12%,transparent);border-radius:16px;}
411
+ :where([data-bd-chatbot] [data-slot="header"]){padding:12px 16px;border-bottom:1px solid color-mix(in srgb,currentColor 10%,transparent);}
412
+ :where([data-bd-chatbot] [data-slot="header-title"]){font-weight:600;}
413
+ :where([data-bd-chatbot] [data-slot="header-subtitle"]){font-size:12px;opacity:.6;margin-top:2px;}
414
+ :where([data-bd-chatbot] [data-slot="presence-strip"]){display:flex;align-items:center;justify-content:space-between;gap:8px;padding:8px 16px;font-size:12px;border-bottom:1px solid color-mix(in srgb,currentColor 8%,transparent);opacity:.85;}
415
+ :where([data-bd-chatbot] [data-slot="message-list"]){padding:16px;gap:12px;}
416
+ :where([data-bd-chatbot] [data-slot="message-row"]){max-width:85%;width:fit-content;padding:8px 12px;border-radius:16px;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere;box-shadow:0 1px 2px color-mix(in srgb,currentColor 8%,transparent);}
417
+ :where([data-bd-chatbot] [data-slot="message-row"][data-role="user"]){align-self:flex-end;background:var(--bd-chatbot-accent,#0d9488);color:#fff;border-bottom-right-radius:4px;}
418
+ :where([data-bd-chatbot] [data-slot="message-row"][data-role="assistant"]){align-self:flex-start;background:color-mix(in srgb,currentColor 8%,transparent);border-bottom-left-radius:4px;}
419
+ :where([data-bd-chatbot] [data-slot="message-pending"]){align-self:flex-start;width:fit-content;padding:8px 12px;background-image:linear-gradient(90deg,currentColor 35%,color-mix(in srgb,currentColor 25%,transparent) 50%,currentColor 65%);background-size:200% 100%;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;animation:bd-chatbot-shimmer 2s linear infinite;}
420
+ :where([data-bd-chatbot] [data-slot="error-text"]){align-self:center;font-size:12px;color:#dc2626;}
421
+ :where([data-bd-chatbot] [data-slot="input-bar"]){gap:8px;padding:12px;border-top:1px solid color-mix(in srgb,currentColor 10%,transparent);}
422
+ :where([data-bd-chatbot] [data-slot="input-field"]){padding:8px 12px;border-radius:10px;border:1px solid color-mix(in srgb,currentColor 15%,transparent);background:transparent;color:inherit;font:inherit;outline:none;}
423
+ :where([data-bd-chatbot] [data-slot="input-field"]:focus-visible){border-color:var(--bd-chatbot-accent,#0d9488);}
424
+ :where([data-bd-chatbot] [data-slot="send-button"]){padding:8px 14px;border-radius:10px;border:none;background:var(--bd-chatbot-accent,#0d9488);color:#fff;font-weight:500;cursor:pointer;}
425
+ :where([data-bd-chatbot] [data-slot="send-button"]:disabled){opacity:.5;cursor:default;}
426
+ :where([data-bd-chatbot] [data-slot="upload-button"]){display:inline-flex;align-items:center;justify-content:center;padding:0 6px;border:none;background:transparent;color:inherit;font-size:18px;line-height:1;cursor:pointer;opacity:.7;}
427
+ :where([data-bd-chatbot] [data-slot="upload-button"]:hover){opacity:1;}
428
+ :where([data-bd-chatbot] [data-slot="upload-button"]:disabled){opacity:.4;cursor:default;}
429
+ :where([data-bd-chatbot] [data-slot="message-file"]){align-self:flex-end;max-width:85%;padding:8px 12px;border-radius:16px;border-bottom-right-radius:4px;background:var(--bd-chatbot-accent,#0d9488);color:#fff;text-decoration:none;font-size:13px;word-break:break-all;}
430
+ :where([data-bd-chatbot] [data-slot="message-image"]){align-self:flex-end;max-width:85%;border-radius:12px;overflow:hidden;}
431
+ :where([data-bd-chatbot] [data-slot="jump-latest"]){position:absolute;left:50%;bottom:72px;transform:translateX(-50%);display:inline-flex;align-items:center;gap:4px;padding:6px 12px;border-radius:999px;border:1px solid color-mix(in srgb,currentColor 15%,transparent);background:var(--bd-chatbot-bg,Canvas);font-size:12px;font-weight:500;cursor:pointer;box-shadow:0 2px 10px color-mix(in srgb,currentColor 20%,transparent);}
432
+ :where([data-bd-chatbot] [data-slot="form-card"]){display:flex;flex-direction:column;gap:10px;align-self:stretch;padding:14px;border-radius:14px;border:1px solid color-mix(in srgb,currentColor 14%,transparent);background:color-mix(in srgb,currentColor 4%,transparent);}
433
+ :where([data-bd-chatbot] [data-slot="form-title"]){font-weight:600;}
434
+ :where([data-bd-chatbot] [data-slot="form-description"]){font-size:12px;opacity:.7;}
435
+ :where([data-bd-chatbot] [data-slot="form-field"]){gap:4px;}
436
+ :where([data-bd-chatbot] [data-slot="form-label"]){font-size:12px;font-weight:500;opacity:.85;}
437
+ :where([data-bd-chatbot] [data-slot="form-input"],[data-bd-chatbot] [data-slot="form-textarea"],[data-bd-chatbot] [data-slot="form-select"]){padding:8px 10px;border-radius:8px;border:1px solid color-mix(in srgb,currentColor 15%,transparent);background:transparent;color:inherit;font:inherit;outline:none;}
438
+ :where([data-bd-chatbot] [data-slot="form-input"]:focus-visible,[data-bd-chatbot] [data-slot="form-textarea"]:focus-visible,[data-bd-chatbot] [data-slot="form-select"]:focus-visible){border-color:var(--bd-chatbot-accent,#0d9488);}
439
+ :where([data-bd-chatbot] [data-slot="form-submit"]){padding:8px 14px;border-radius:8px;border:none;background:var(--bd-chatbot-accent,#0d9488);color:#fff;font-weight:500;cursor:pointer;}
440
+ :where([data-bd-chatbot] [data-slot="form-submit"]:disabled){opacity:.5;cursor:default;}
441
+ :where([data-bd-chatbot] [data-slot="form-error"]){font-size:12px;color:#dc2626;}
442
+ :where([data-bd-chatbot] [data-slot="form-receipt"]){font-size:13px;opacity:.8;}
443
+ @keyframes bd-chatbot-shimmer{from{background-position:100% 0;}to{background-position:0 0;}}
444
+ @media (prefers-reduced-motion:reduce){:where([data-bd-chatbot] [data-slot="message-pending"]){animation:none;-webkit-text-fill-color:currentColor;}}
445
+ @property --bd-chatbot-fade{syntax:"<length>";inherits:false;initial-value:0px;}
446
+ @keyframes bd-chatbot-fade-b{from{--bd-chatbot-fade:24px;}to{--bd-chatbot-fade:0px;}}
447
+ @supports (animation-timeline:scroll()){:where([data-bd-chatbot] [data-slot="message-list"]){-webkit-mask-image:linear-gradient(to bottom,#000 0,#000 calc(100% - var(--bd-chatbot-fade,0px)),transparent 100%);mask-image:linear-gradient(to bottom,#000 0,#000 calc(100% - var(--bd-chatbot-fade,0px)),transparent 100%);animation:bd-chatbot-fade-b 1ms linear both;animation-timeline:scroll(self y);animation-range:calc(100% - 96px) 100%;}}
448
448
  `;
449
449
  /**
450
450
  * In-tree React chatbot component. Same backend wiring as the iframe
@@ -744,7 +744,7 @@ export function ChatbotInline({ apiKey, baseUrl, welcomeMessage, title = "Assist
744
744
  URL.revokeObjectURL(stagedPreview);
745
745
  };
746
746
  }, [stagedPreview]);
747
- return (_jsxs("div", { className: [classNames.root, className].filter(Boolean).join(" ") || undefined, "data-biab-chatbot": unstyled ? undefined : "", style: { ...inlineLayoutStyles.root, ...style }, children: [title !== null ? (_jsxs("div", { className: classNames.header, "data-slot": "header", children: [_jsx("div", { className: classNames.headerTitle, "data-slot": "header-title", children: title }), subtitle !== null && subtitle !== undefined ? (_jsx("div", { className: classNames.headerSubtitle, "data-slot": "header-subtitle", children: subtitle })) : null] })) : null, availability?.frontDeskEnabled
747
+ return (_jsxs("div", { className: [classNames.root, className].filter(Boolean).join(" ") || undefined, "data-bd-chatbot": unstyled ? undefined : "", style: { ...inlineLayoutStyles.root, ...style }, children: [title !== null ? (_jsxs("div", { className: classNames.header, "data-slot": "header", children: [_jsx("div", { className: classNames.headerTitle, "data-slot": "header-title", children: title }), subtitle !== null && subtitle !== undefined ? (_jsx("div", { className: classNames.headerSubtitle, "data-slot": "header-subtitle", children: subtitle })) : null] })) : null, availability?.frontDeskEnabled
748
748
  ? renderPresenceStrip
749
749
  ? renderPresenceStrip(availability)
750
750
  : defaultPresenceStrip({ availability, classNames })
@@ -976,7 +976,7 @@ export async function signOut(options = {}) {
976
976
  }
977
977
  /**
978
978
  * Programmatic "forgot password" — POSTs to the auth handler's
979
- * `/password-reset` route, which the SDK forwards to BIAB. The server
979
+ * `/password-reset` route, which the SDK forwards to BD. The server
980
980
  * returns `{ ok: true }` regardless of whether an account matched
981
981
  * (intentional anti-leak), and emails the platform-hosted reset link
982
982
  * out-of-band when a match exists.
@@ -1047,7 +1047,7 @@ export function useUser(options) {
1047
1047
  export function useFollowers(options) {
1048
1048
  const { token, siteId, baseUrl } = options;
1049
1049
  const controller = useMemo(() => createFollowersController({
1050
- client: createBiabClient({
1050
+ client: createBdClient({
1051
1051
  apiKey: token,
1052
1052
  siteId,
1053
1053
  baseUrl: baseUrl ?? DEFAULT_PACKAGE_BASE_URL,
@@ -1077,7 +1077,7 @@ export function useFollowers(options) {
1077
1077
  export function useCheckout(options) {
1078
1078
  const { apiKey, baseUrl } = options;
1079
1079
  const controller = useMemo(() => createCheckoutController({
1080
- client: new BiabDevClient({ apiKey, baseUrl }),
1080
+ client: new BdApiClient({ apiKey, baseUrl }),
1081
1081
  }), [apiKey, baseUrl]);
1082
1082
  useEffect(() => () => controller.destroy(), [controller]);
1083
1083
  const subscribe = useCallback((onStoreChange) => controller.subscribe(() => onStoreChange()), [controller]);
@@ -1091,6 +1091,17 @@ export function useCheckout(options) {
1091
1091
  reset: controller.reset,
1092
1092
  };
1093
1093
  }
1094
+ /** One controller per hook instance. The cache they share lives a layer down
1095
+ * in the client, so this costs a subscriber set and nothing else. */
1096
+ function useMarketingController(apiKey, baseUrl, siteId) {
1097
+ const client = useMemo(() => new BdApiClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1098
+ const controller = useMemo(() => createMarketingController({ client: client.site(siteId) }), [client, siteId]);
1099
+ useEffect(() => () => controller.destroy(), [controller]);
1100
+ const subscribe = useCallback((onStoreChange) => controller.subscribe(() => onStoreChange()), [controller]);
1101
+ const getSnapshot = useCallback(() => controller.snapshot(), [controller]);
1102
+ const snap = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
1103
+ return { client, controller, snap };
1104
+ }
1094
1105
  /**
1095
1106
  * Lazy-fetch a single marketing page by `pageKey`. The hook reads from the
1096
1107
  * SDK's shared cache when present (warmed by `useMarketingPagePreloader` or
@@ -1103,44 +1114,17 @@ export function useCheckout(options) {
1103
1114
  */
1104
1115
  export function useMarketingPage(options) {
1105
1116
  const { apiKey, baseUrl, siteId, pageKey, enabled = true } = options;
1106
- const client = useMemo(() => new BiabDevClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1107
- const initial = client.site(siteId).marketingPages.getCached(pageKey);
1108
- const [state, setState] = useState(initial
1109
- ? { status: "ready", page: initial.page }
1110
- : { status: "idle", page: null });
1111
- const fetchOnce = useCallback(async (skipCache = false) => {
1112
- if (!enabled)
1113
- return;
1114
- setState({ status: "loading", page: null });
1115
- try {
1116
- const response = await client
1117
- .site(siteId)
1118
- .marketingPages.get(pageKey, { skipCache });
1119
- setState({ status: "ready", page: response.page });
1120
- }
1121
- catch (err) {
1122
- setState({
1123
- status: "error",
1124
- page: null,
1125
- error: err instanceof Error
1126
- ? err
1127
- : new Error("Marketing page load failed"),
1128
- });
1129
- }
1130
- }, [client, siteId, pageKey, enabled]);
1117
+ const { client, controller, snap } = useMarketingController(apiKey, baseUrl, siteId);
1131
1118
  useEffect(() => {
1132
1119
  if (!enabled)
1133
1120
  return;
1134
- // Cache hit: render synchronously, no fetch.
1135
- const hit = client.site(siteId).marketingPages.getCached(pageKey);
1136
- if (hit) {
1137
- setState({ status: "ready", page: hit.page });
1138
- return;
1139
- }
1140
- void fetchOnce(false);
1141
- }, [client, siteId, pageKey, enabled, fetchOnce]);
1142
- const refresh = useCallback(() => fetchOnce(true), [fetchOnce]);
1143
- return { ...state, refresh };
1121
+ void controller.open(pageKey);
1122
+ }, [controller, pageKey, enabled]);
1123
+ const refresh = useCallback(() => controller.open(pageKey, { skipCache: true }), [controller, pageKey]);
1124
+ // The synchronous cache read is React's to do — the controller cannot,
1125
+ // because the cache lives in the client. Everything after it is the core's.
1126
+ const cached = client.site(siteId).marketingPages.getCached(pageKey)?.page ?? null;
1127
+ return { ...marketingPageView(snap, pageKey, cached), refresh };
1144
1128
  }
1145
1129
  /**
1146
1130
  * Loads the payload-free directory of marketing pages for a site. Pair with
@@ -1148,33 +1132,16 @@ export function useMarketingPage(options) {
1148
1132
  */
1149
1133
  export function useMarketingPagesList(options) {
1150
1134
  const { apiKey, baseUrl, siteId, enabled = true } = options;
1151
- const client = useMemo(() => new BiabDevClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1152
- const [state, setState] = useState({
1153
- status: "idle",
1154
- pages: null,
1155
- });
1156
- const fetchOnce = useCallback(async () => {
1135
+ const { controller, snap } = useMarketingController(apiKey, baseUrl, siteId);
1136
+ // This hook only ever calls `load()`, so the controller's single `status`
1137
+ // is describing the index and nothing else.
1138
+ const refresh = useCallback(() => controller.load(), [controller]);
1139
+ useEffect(() => {
1157
1140
  if (!enabled)
1158
1141
  return;
1159
- setState({ status: "loading", pages: null });
1160
- try {
1161
- const response = await client
1162
- .site(siteId)
1163
- .marketingPages.list();
1164
- setState({ status: "ready", pages: response.pages });
1165
- }
1166
- catch (err) {
1167
- setState({
1168
- status: "error",
1169
- pages: null,
1170
- error: err instanceof Error ? err : new Error("Marketing pages list failed"),
1171
- });
1172
- }
1173
- }, [client, siteId, enabled]);
1174
- useEffect(() => {
1175
- void fetchOnce();
1176
- }, [fetchOnce]);
1177
- return { ...state, refresh: fetchOnce };
1142
+ void controller.load();
1143
+ }, [controller, enabled]);
1144
+ return { ...marketingListView(snap), refresh };
1178
1145
  }
1179
1146
  /**
1180
1147
  * Returns a stable `preload(pageKey)` function that warms the SDK cache for
@@ -1184,15 +1151,15 @@ export function useMarketingPagesList(options) {
1184
1151
  */
1185
1152
  export function useMarketingPagePreloader(options) {
1186
1153
  const { apiKey, baseUrl, siteId } = options;
1187
- const client = useMemo(() => new BiabDevClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1154
+ const { client, controller } = useMarketingController(apiKey, baseUrl, siteId);
1188
1155
  return useCallback(async (pageKey) => {
1189
- try {
1190
- return await client.site(siteId).marketingPages.prefetch(pageKey);
1191
- }
1192
- catch {
1193
- return null;
1194
- }
1195
- }, [client, siteId]);
1156
+ // The core swallows prefetch failures on purpose — a guess about
1157
+ // where the visitor is going must never surface as an error on the
1158
+ // page they are actually reading. Reading the cache afterwards is
1159
+ // how this keeps returning the response its signature promises.
1160
+ await controller.prefetch(pageKey);
1161
+ return client.site(siteId).marketingPages.getCached(pageKey) ?? null;
1162
+ }, [client, controller, siteId]);
1196
1163
  }
1197
1164
  // ── Marketing-flow hooks (schema-driven, see ./react-marketing.tsx) ────────
1198
1165
  export { useMarketingBundlePreloader, useMarketingLocales, useMarketingPageBundle, useMarketingPageSeo, useMarketingSection, usePublishedMarketingSchema, } from "./react-marketing.js";
@@ -1205,7 +1172,7 @@ export { useMarketingBundlePreloader, useMarketingLocales, useMarketingPageBundl
1205
1172
  */
1206
1173
  export function VerifyEmailFlow(props) {
1207
1174
  const { apiKey, baseUrl, sessionToken, currentEmail } = props;
1208
- const client = useMemo(() => new BiabDevClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1175
+ const client = useMemo(() => new BdApiClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1209
1176
  const [email, setEmail] = useState(currentEmail ?? "");
1210
1177
  const [sent, setSent] = useState(false);
1211
1178
  const [busy, setBusy] = useState(false);
@@ -1239,7 +1206,7 @@ export function VerifyEmailFlow(props) {
1239
1206
  */
1240
1207
  export function VerifyEmailConfirm(props) {
1241
1208
  const { apiKey, baseUrl, sessionToken, token, onVerified } = props;
1242
- const client = useMemo(() => new BiabDevClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1209
+ const client = useMemo(() => new BdApiClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1243
1210
  const [state, setState] = useState({ kind: "idle" });
1244
1211
  useEffect(() => {
1245
1212
  let cancelled = false;
@@ -1279,7 +1246,7 @@ export function VerifyEmailConfirm(props) {
1279
1246
  */
1280
1247
  export function VerifyPhoneFlow(props) {
1281
1248
  const { apiKey, baseUrl, sessionToken, currentPhone, onVerified } = props;
1282
- const client = useMemo(() => new BiabDevClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1249
+ const client = useMemo(() => new BdApiClient({ apiKey, baseUrl }), [apiKey, baseUrl]);
1283
1250
  const [phone, setPhone] = useState(currentPhone ?? "");
1284
1251
  const [phase, setPhase] = useState("enter");
1285
1252
  const [otp, setOtp] = useState("");
@@ -1342,7 +1309,7 @@ export function VerifyPhoneFlow(props) {
1342
1309
  * bundled: it's ~1,600 entries that change only when Lucide does. An author who
1343
1310
  * curated `allowedIcons` skips the fetch entirely.
1344
1311
  */
1345
- function BiabIconSelect({ field, value, set, }) {
1312
+ function BdIconSelect({ field, value, set, }) {
1346
1313
  const cfg = field
1347
1314
  .iconConfig ?? {};
1348
1315
  const curated = cfg.allowedIcons ?? [];
@@ -1364,7 +1331,7 @@ function BiabIconSelect({ field, value, set, }) {
1364
1331
  };
1365
1332
  }, [curated.length]);
1366
1333
  const results = useMemo(() => filterIconNames(all, query), [all, query]);
1367
- return (_jsxs("div", { className: "biab-iconselect", children: [_jsx("input", { className: "biab-input biab-iconselect__search", onChange: (e) => setQuery(e.target.value), placeholder: field.placeholder || "Search icons…", type: "text", value: query }), selected && (_jsxs("span", { className: "biab-iconselect__current", children: [_jsx("img", { alt: selected, height: 16, src: iconUrl(selected), width: 16 }), _jsx("button", { className: "biab-iconselect__clear", onClick: () => set(""), type: "button", children: "\u00D7" })] })), _jsx("div", { className: "biab-iconselect__grid", children: results.map((name) => (_jsx("button", { "aria-label": name, "aria-pressed": selected === name, className: `biab-iconselect__item${selected === name ? "is-selected" : ""}`, onClick: () => set(name), title: name, type: "button", children: _jsx("img", { alt: "", height: 16, src: iconUrl(name), width: 16 }) }, name))) })] }));
1334
+ return (_jsxs("div", { className: "bd-iconselect", children: [_jsx("input", { className: "bd-input bd-iconselect__search", onChange: (e) => setQuery(e.target.value), placeholder: field.placeholder || "Search icons…", type: "text", value: query }), selected && (_jsxs("span", { className: "bd-iconselect__current", children: [_jsx("img", { alt: selected, height: 16, src: iconUrl(selected), width: 16 }), _jsx("button", { className: "bd-iconselect__clear", onClick: () => set(""), type: "button", children: "\u00D7" })] })), _jsx("div", { className: "bd-iconselect__grid", children: results.map((name) => (_jsx("button", { "aria-label": name, "aria-pressed": selected === name, className: `bd-iconselect__item${selected === name ? "is-selected" : ""}`, onClick: () => set(name), title: name, type: "button", children: _jsx("img", { alt: "", height: 16, src: iconUrl(name), width: 16 }) }, name))) })] }));
1368
1335
  }
1369
1336
  /**
1370
1337
  * `image_input` — one image, from an upload OR a pasted URL.
@@ -1373,13 +1340,13 @@ function BiabIconSelect({ field, value, set, }) {
1373
1340
  * pending file and flushed by the controller at submit, exactly like
1374
1341
  * `file_upload`, then replaced by its stored URL.
1375
1342
  */
1376
- function BiabImageInput({ field, value, set, }) {
1343
+ function BdImageInput({ field, value, set, }) {
1377
1344
  const cfg = field.imageInputConfig ?? {};
1378
1345
  const sources = cfg.sources ?? "both";
1379
1346
  const [mode, setMode] = useState(sources === "url" ? "url" : "upload");
1380
1347
  const pending = isPendingFileValue(value) ? value : null;
1381
1348
  const url = typeof value === "string" ? value : "";
1382
- return (_jsxs("div", { className: "biab-imageinput", children: [sources === "both" && (_jsx("div", { className: "biab-imageinput__modes", children: ["upload", "url"].map((m) => (_jsx("button", { "aria-pressed": mode === m, className: `biab-imageinput__mode${mode === m ? "is-active" : ""}`, onClick: () => setMode(m), type: "button", children: m === "upload" ? "Upload" : "Paste URL" }, m))) })), mode === "upload" && sources !== "url" ? (_jsx("input", { accept: (cfg.allowedTypes ?? ["image/*"]).join(","), className: "biab-input biab-imageinput__file", onChange: (e) => {
1349
+ return (_jsxs("div", { className: "bd-imageinput", children: [sources === "both" && (_jsx("div", { className: "bd-imageinput__modes", children: ["upload", "url"].map((m) => (_jsx("button", { "aria-pressed": mode === m, className: `bd-imageinput__mode${mode === m ? "is-active" : ""}`, onClick: () => setMode(m), type: "button", children: m === "upload" ? "Upload" : "Paste URL" }, m))) })), mode === "upload" && sources !== "url" ? (_jsx("input", { accept: (cfg.allowedTypes ?? ["image/*"]).join(","), className: "bd-input bd-imageinput__file", onChange: (e) => {
1383
1350
  const file = e.target.files?.[0];
1384
1351
  if (!file)
1385
1352
  return;
@@ -1392,44 +1359,44 @@ function BiabImageInput({ field, value, set, }) {
1392
1359
  name: file.name,
1393
1360
  size: file.size,
1394
1361
  });
1395
- }, type: "file" })) : (_jsx("input", { className: "biab-input biab-imageinput__url", onChange: (e) => set(e.target.value), placeholder: field.placeholder || "https://example.com/image.png", type: "url", value: url })), cfg.showPreview !== false && (pending || url) ? (_jsx("img", { alt: "", className: "biab-imageinput__preview", src: pending ? "" : url })) : null, pending && (_jsxs("span", { className: "biab-imageinput__pending", children: [pending.name, " \u2014 uploads on submit."] }))] }));
1362
+ }, type: "file" })) : (_jsx("input", { className: "bd-input bd-imageinput__url", onChange: (e) => set(e.target.value), placeholder: field.placeholder || "https://example.com/image.png", type: "url", value: url })), cfg.showPreview !== false && (pending || url) ? (_jsx("img", { alt: "", className: "bd-imageinput__preview", src: pending ? "" : url })) : null, pending && (_jsxs("span", { className: "bd-imageinput__pending", children: [pending.name, " \u2014 uploads on submit."] }))] }));
1396
1363
  }
1397
- // A `BiabFormProvider` lets a consumer supply the client once at the root and
1398
- // drop `<BiabForm slug="…" />` anywhere below without threading the client prop.
1399
- const BiabFormClientContext = createContext(null);
1364
+ // A `BdFormProvider` lets a consumer supply the client once at the root and
1365
+ // drop `<BdForm slug="…" />` anywhere below without threading the client prop.
1366
+ const BdFormClientContext = createContext(null);
1400
1367
  /** Production package-API base URL — the default target for a publishable token
1401
1368
  * when no `baseUrl` is supplied. Override via the `baseUrl` prop for staging or
1402
1369
  * a custom host. Use the **apex** host: `www.biab.app` 307-redirects to the
1403
1370
  * apex, and a CORS preflight does not follow redirects (the browser fails the
1404
1371
  * request), so a browser publishable-token client must target the apex. */
1405
1372
  export const DEFAULT_PACKAGE_BASE_URL = "https://biab.app/api/package/v1";
1406
- /** Provide a BIAB forms client to every nested `<BiabForm>`. Pass a `client`, or
1373
+ /** Provide a BD forms client to every nested `<BdForm>`. Pass a `client`, or
1407
1374
  * a publishable `token` + `siteId` (+ optional `baseUrl`) to build a browser
1408
1375
  * client. */
1409
- export function BiabFormProvider({ client, token, siteId, baseUrl, children, }) {
1376
+ export function BdFormProvider({ client, token, siteId, baseUrl, children, }) {
1410
1377
  const resolved = useMemo(() => client ??
1411
1378
  (token && siteId
1412
- ? createBiabClient({
1379
+ ? createBdClient({
1413
1380
  apiKey: token,
1414
1381
  siteId,
1415
1382
  baseUrl: baseUrl ?? DEFAULT_PACKAGE_BASE_URL,
1416
1383
  })
1417
1384
  : null), [client, token, siteId, baseUrl]);
1418
- return (_jsx(BiabFormClientContext.Provider, { value: resolved, children: children }));
1385
+ return (_jsx(BdFormClientContext.Provider, { value: resolved, children: children }));
1419
1386
  }
1420
- /** Read the client from a surrounding `<BiabFormProvider>`, if any. */
1421
- export function useBiabFormsClient() {
1422
- return useContext(BiabFormClientContext);
1387
+ /** Read the client from a surrounding `<BdFormProvider>`, if any. */
1388
+ export function useBdFormsClient() {
1389
+ return useContext(BdFormClientContext);
1423
1390
  }
1424
1391
  const FetchScheduleSlotsContext = createContext(undefined);
1425
- /** Autofill (`autocomplete`) config for the field tree, provided by `<BiabForm>`.
1392
+ /** Autofill (`autocomplete`) config for the field tree, provided by `<BdForm>`.
1426
1393
  * Default `{}` → inference on, no overrides. */
1427
1394
  const AutocompleteContext = createContext({});
1428
- /** Auto-schedule (instant booking) picker for `<BiabForm>`: fetches the assigned
1395
+ /** Auto-schedule (instant booking) picker for `<BdForm>`: fetches the assigned
1429
1396
  * staff's open slots and lets the visitor pick one. Value `{ slotStartAt,
1430
1397
  * timezone }`; the server books the meeting on submit. Dependency-light (plain
1431
- * elements + `biab-field__schedule-*` classes). */
1432
- function BiabScheduleAuto({ field, value, onChange, }) {
1398
+ * elements + `bd-field__schedule-*` classes). */
1399
+ function BdScheduleAuto({ field, value, onChange, }) {
1433
1400
  const fetchSlots = useContext(FetchScheduleSlotsContext);
1434
1401
  const v = value && typeof value === "object" ? value : {};
1435
1402
  const tz = typeof Intl !== "undefined"
@@ -1460,16 +1427,16 @@ function BiabScheduleAuto({ field, value, onChange, }) {
1460
1427
  };
1461
1428
  }, [fetchSlots, field.id]);
1462
1429
  if (!fetchSlots) {
1463
- return (_jsx("p", { className: "biab-field__schedule-hint", children: "Booking isn't available here." }));
1430
+ return (_jsx("p", { className: "bd-field__schedule-hint", children: "Booking isn't available here." }));
1464
1431
  }
1465
1432
  if (phase === "loading" || phase === "idle") {
1466
- return (_jsx("p", { className: "biab-field__schedule-hint", children: "Loading available times\u2026" }));
1433
+ return _jsx("p", { className: "bd-field__schedule-hint", children: "Loading available times\u2026" });
1467
1434
  }
1468
1435
  if (phase === "error") {
1469
- return (_jsx("p", { className: "biab-field__schedule-hint", children: "Couldn't load times right now." }));
1436
+ return (_jsx("p", { className: "bd-field__schedule-hint", children: "Couldn't load times right now." }));
1470
1437
  }
1471
1438
  if (slots.length === 0) {
1472
- return (_jsx("p", { className: "biab-field__schedule-hint", children: "No open times in the next few weeks." }));
1439
+ return (_jsx("p", { className: "bd-field__schedule-hint", children: "No open times in the next few weeks." }));
1473
1440
  }
1474
1441
  const byDay = new Map();
1475
1442
  for (const s of slots) {
@@ -1487,7 +1454,7 @@ function BiabScheduleAuto({ field, value, onChange, }) {
1487
1454
  arr.push({ startAt: s.startAt, label });
1488
1455
  byDay.set(dayKey, arr);
1489
1456
  }
1490
- return (_jsx("div", { className: "biab-field__schedule-auto", children: [...byDay.entries()].map(([day, times]) => (_jsxs("div", { className: "biab-field__schedule-day", children: [_jsx("p", { className: "biab-field__schedule-day-label", children: day }), _jsx("div", { className: "biab-field__schedule-times", children: times.map((t) => (_jsx("button", { className: "biab-field__schedule-slot", "data-selected": v.slotStartAt === t.startAt ? "true" : undefined, onClick: () => onChange({ slotStartAt: t.startAt, timezone: tz }), type: "button", children: t.label }, t.startAt))) })] }, day))) }));
1457
+ return (_jsx("div", { className: "bd-field__schedule-auto", children: [...byDay.entries()].map(([day, times]) => (_jsxs("div", { className: "bd-field__schedule-day", children: [_jsx("p", { className: "bd-field__schedule-day-label", children: day }), _jsx("div", { className: "bd-field__schedule-times", children: times.map((t) => (_jsx("button", { className: "bd-field__schedule-slot", "data-selected": v.slotStartAt === t.startAt ? "true" : undefined, onClick: () => onChange({ slotStartAt: t.startAt, timezone: tz }), type: "button", children: t.label }, t.startAt))) })] }, day))) }));
1491
1458
  }
1492
1459
  /**
1493
1460
  * Subscribe a component to a `FormController` via React's official external-store
@@ -1500,7 +1467,7 @@ function useFormSnapshot(controller) {
1500
1467
  const getSnapshot = useCallback(() => controller.snapshot(), [controller]);
1501
1468
  return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
1502
1469
  }
1503
- // ── biab-* class helpers (mirrors FormPreview's `fieldCssKey`) ───────────────
1470
+ // ── bd-* class helpers (mirrors FormPreview's `fieldCssKey`) ───────────────
1504
1471
  function cx(...parts) {
1505
1472
  return parts.filter(Boolean).join(" ");
1506
1473
  }
@@ -1573,7 +1540,7 @@ function safeHttpHref(raw) {
1573
1540
  // ── Self-contained date-range picker (no external calendar dep) ─────────────
1574
1541
  // A popover trigger + a month grid with click-to-select range. Stored value is
1575
1542
  // `{ start, end }` as `yyyy-MM-dd` strings (identical to the app's contract).
1576
- // Styled via biab-* classes so consumers can theme it.
1543
+ // Styled via bd-* classes so consumers can theme it.
1577
1544
  function parseIsoDate(s) {
1578
1545
  if (!s)
1579
1546
  return null;
@@ -1586,7 +1553,7 @@ function toIsoDate(d) {
1586
1553
  const day = String(d.getDate()).padStart(2, "0");
1587
1554
  return `${y}-${m}-${day}`;
1588
1555
  }
1589
- const BIAB_MONTHS = [
1556
+ const BD_MONTHS = [
1590
1557
  "January",
1591
1558
  "February",
1592
1559
  "March",
@@ -1600,8 +1567,8 @@ const BIAB_MONTHS = [
1600
1567
  "November",
1601
1568
  "December",
1602
1569
  ];
1603
- const BIAB_WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
1604
- function BiabDateRange({ value, setValue, }) {
1570
+ const BD_WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
1571
+ function BdDateRange({ value, setValue, }) {
1605
1572
  const v = (value && typeof value === "object" ? value : {});
1606
1573
  const start = parseIsoDate(v.start);
1607
1574
  const end = parseIsoDate(v.end);
@@ -1658,48 +1625,48 @@ function BiabDateRange({ value, setValue, }) {
1658
1625
  : `${v.start} → …`
1659
1626
  : "Pick a date range";
1660
1627
  // Positioning is the only inline style (so the popover never overlaps content
1661
- // even before the CSS loads); everything visual lives in `biab-forms.css`,
1628
+ // even before the CSS loads); everything visual lives in `bd-forms.css`,
1662
1629
  // which mirrors the COSS/shadcn calendar (import it from the SDK).
1663
- return (_jsxs("div", { className: "biab-daterange", ref: ref, style: { position: "relative" }, children: [_jsx("button", { className: "biab-input biab-field__input biab-daterange__trigger", onClick: () => setOpen((o) => !o), type: "button", children: label }), open && (_jsxs("div", { className: "biab-daterange__popover", style: { position: "absolute", zIndex: 50 }, children: [_jsxs("div", { className: "biab-daterange__nav", children: [_jsx("button", { "aria-label": "Previous month", className: "biab-daterange__navbtn", onClick: () => setView((s) => s.m === 0 ? { y: s.y - 1, m: 11 } : { y: s.y, m: s.m - 1 }), type: "button", children: "\u2039" }), _jsxs("span", { className: "biab-daterange__title", children: [BIAB_MONTHS[view.m], " ", view.y] }), _jsx("button", { "aria-label": "Next month", className: "biab-daterange__navbtn", onClick: () => setView((s) => s.m === 11 ? { y: s.y + 1, m: 0 } : { y: s.y, m: s.m + 1 }), type: "button", children: "\u203A" })] }), _jsxs("div", { className: "biab-daterange__grid", children: [BIAB_WEEKDAYS.map((w) => (_jsx("span", { className: "biab-daterange__dow", children: w }, w))), cells.map((d, i) => {
1630
+ return (_jsxs("div", { className: "bd-daterange", ref: ref, style: { position: "relative" }, children: [_jsx("button", { className: "bd-input bd-field__input bd-daterange__trigger", onClick: () => setOpen((o) => !o), type: "button", children: label }), open && (_jsxs("div", { className: "bd-daterange__popover", style: { position: "absolute", zIndex: 50 }, children: [_jsxs("div", { className: "bd-daterange__nav", children: [_jsx("button", { "aria-label": "Previous month", className: "bd-daterange__navbtn", onClick: () => setView((s) => s.m === 0 ? { y: s.y - 1, m: 11 } : { y: s.y, m: s.m - 1 }), type: "button", children: "\u2039" }), _jsxs("span", { className: "bd-daterange__title", children: [BD_MONTHS[view.m], " ", view.y] }), _jsx("button", { "aria-label": "Next month", className: "bd-daterange__navbtn", onClick: () => setView((s) => s.m === 11 ? { y: s.y + 1, m: 0 } : { y: s.y, m: s.m + 1 }), type: "button", children: "\u203A" })] }), _jsxs("div", { className: "bd-daterange__grid", children: [BD_WEEKDAYS.map((w) => (_jsx("span", { className: "bd-daterange__dow", children: w }, w))), cells.map((d, i) => {
1664
1631
  if (!d) {
1665
- return (_jsx("span", { className: "biab-daterange__blank" }, `b-${i}`));
1632
+ return _jsx("span", { className: "bd-daterange__blank" }, `b-${i}`);
1666
1633
  }
1667
1634
  const st = dayState(d);
1668
- return (_jsx("button", { className: "biab-daterange__day", "data-range-end": st.end || undefined, "data-range-middle": st.middle || undefined, "data-range-start": st.start || undefined, "data-selected-single": st.single || undefined, "data-today": st.today || undefined, onClick: () => pick(d), type: "button", children: d.getDate() }, toIsoDate(d)));
1635
+ return (_jsx("button", { className: "bd-daterange__day", "data-range-end": st.end || undefined, "data-range-middle": st.middle || undefined, "data-range-start": st.start || undefined, "data-selected-single": st.single || undefined, "data-today": st.today || undefined, onClick: () => pick(d), type: "button", children: d.getDate() }, toIsoDate(d)));
1669
1636
  })] })] }))] }));
1670
1637
  }
1671
- // ── Per-type input renderer (light DOM, biab-* classes, no shadcn) ──────────
1672
- function BiabFieldInput({ field, value, setValue, }) {
1638
+ // ── Per-type input renderer (light DOM, bd-* classes, no shadcn) ──────────
1639
+ function BdFieldInput({ field, value, setValue, }) {
1673
1640
  const set = (v) => setValue(field.id, v);
1674
1641
  const ph = field.placeholder || "";
1675
1642
  // Resolved HTML autofill token for this field (or undefined to omit the
1676
- // attribute). Honors the global `<BiabForm autoComplete>` switch and per-field
1643
+ // attribute). Honors the global `<BdForm autoComplete>` switch and per-field
1677
1644
  // overrides; see forms-core/autocomplete.ts.
1678
1645
  const acConfig = useContext(AutocompleteContext);
1679
1646
  const autoComplete = resolveFieldAutocomplete(field, acConfig);
1680
1647
  switch (field.type) {
1681
1648
  case "title":
1682
- return _jsx("h2", { className: "biab-field__title", children: field.label || "Untitled" });
1649
+ return _jsx("h2", { className: "bd-field__title", children: field.label || "Untitled" });
1683
1650
  case "subtitle":
1684
- return _jsx("h3", { className: "biab-field__subtitle", children: field.label || "" });
1651
+ return _jsx("h3", { className: "bd-field__subtitle", children: field.label || "" });
1685
1652
  case "separator":
1686
- return _jsx("hr", { className: "biab-field__separator" });
1653
+ return _jsx("hr", { className: "bd-field__separator" });
1687
1654
  case "richtext":
1688
1655
  // `content` is server-sanitized HTML.
1689
- return field.content ? (_jsx("div", { className: "biab-field__richtext",
1656
+ return field.content ? (_jsx("div", { className: "bd-field__richtext",
1690
1657
  // biome-ignore lint/security/noDangerouslySetInnerHtml: server-sanitized
1691
1658
  dangerouslySetInnerHTML: { __html: field.content } })) : null;
1692
1659
  case "body_text":
1693
1660
  // Plain body paragraph (no HTML). Display only.
1694
- return field.content ? (_jsx("p", { className: "biab-field__body", children: field.content })) : null;
1661
+ return field.content ? (_jsx("p", { className: "bd-field__body", children: field.content })) : null;
1695
1662
  case "bullet_list": {
1696
1663
  const lc = field.listConfig ?? {};
1697
1664
  const variant = lc.variant ?? "bullets";
1698
1665
  const items = lc.items ?? [];
1699
1666
  if (variant === "details") {
1700
- return (_jsx("div", { className: "biab-field__points", children: items.map((it, i) => (_jsxs("div", { className: "biab-field__point", children: [it.icon && (_jsx("span", { "aria-hidden": "true", className: "biab-field__point-icon", "data-icon": it.icon })), _jsxs("span", { className: "biab-field__point-body", children: [_jsx("span", { className: "biab-field__point-title", children: it.text }), it.description && (_jsx("span", { className: "biab-field__point-desc", children: it.description }))] })] }, `${field.id}-li-${i}`))) }));
1667
+ return (_jsx("div", { className: "bd-field__points", children: items.map((it, i) => (_jsxs("div", { className: "bd-field__point", children: [it.icon && (_jsx("span", { "aria-hidden": "true", className: "bd-field__point-icon", "data-icon": it.icon })), _jsxs("span", { className: "bd-field__point-body", children: [_jsx("span", { className: "bd-field__point-title", children: it.text }), it.description && (_jsx("span", { className: "bd-field__point-desc", children: it.description }))] })] }, `${field.id}-li-${i}`))) }));
1701
1668
  }
1702
- return (_jsxs("div", { className: "biab-field__bullets", children: [lc.title && (_jsx("div", { className: "biab-field__bullets-title", children: lc.title })), _jsx("ul", { children: items.map((it, i) => (_jsx("li", { children: it.text }, `${field.id}-li-${i}`))) })] }));
1669
+ return (_jsxs("div", { className: "bd-field__bullets", children: [lc.title && (_jsx("div", { className: "bd-field__bullets-title", children: lc.title })), _jsx("ul", { children: items.map((it, i) => (_jsx("li", { children: it.text }, `${field.id}-li-${i}`))) })] }));
1703
1670
  }
1704
1671
  case "table": {
1705
1672
  const cfg = field.tableConfig ?? {};
@@ -1707,7 +1674,7 @@ function BiabFieldInput({ field, value, setValue, }) {
1707
1674
  const rows = cfg.rows ?? [];
1708
1675
  if (columns.length === 0)
1709
1676
  return null;
1710
- return (_jsx("div", { className: "biab-field__table", children: _jsxs("table", { children: [_jsx("thead", { children: _jsx("tr", { children: columns.map((col, ci) => (_jsx("th", { "data-align": col.align ?? "left", "data-highlight": cfg.highlightColumn === ci ? "" : undefined, children: col.header }, `${field.id}-col-${ci}`))) }) }), _jsx("tbody", { children: rows.map((row, ri) => (_jsx("tr", { children: columns.map((col, ci) => {
1677
+ return (_jsx("div", { className: "bd-field__table", children: _jsxs("table", { children: [_jsx("thead", { children: _jsx("tr", { children: columns.map((col, ci) => (_jsx("th", { "data-align": col.align ?? "left", "data-highlight": cfg.highlightColumn === ci ? "" : undefined, children: col.header }, `${field.id}-col-${ci}`))) }) }), _jsx("tbody", { children: rows.map((row, ri) => (_jsx("tr", { children: columns.map((col, ci) => {
1711
1678
  const cell = row.cells?.[ci] ?? "";
1712
1679
  const check = col.type === "check" ? tableCheckState(cell) : "text";
1713
1680
  return (_jsx("td", { "data-align": col.align ?? "left", "data-check": check === "text" ? undefined : check, "data-highlight": cfg.highlightColumn === ci ? "" : undefined, children: check === "yes" ? "✓" : check === "no" ? "–" : cell }, `${field.id}-cell-${ri}-${ci}`));
@@ -1720,13 +1687,13 @@ function BiabFieldInput({ field, value, setValue, }) {
1720
1687
  .calculationConfig;
1721
1688
  const hasVal = value !== null && value !== undefined && value !== "";
1722
1689
  if (cfg?.sensitive && !hasVal) {
1723
- return (_jsx("output", { className: "biab-field__calc biab-field__calc--pending", children: "Calculated on submit." }));
1690
+ return (_jsx("output", { className: "bd-field__calc bd-field__calc--pending", children: "Calculated on submit." }));
1724
1691
  }
1725
- return (_jsx("output", { className: "biab-field__calc", children: hasVal ? formatCalcValue(value, cfg?.display) : "—" }));
1692
+ return (_jsx("output", { className: "bd-field__calc", children: hasVal ? formatCalcValue(value, cfg?.display) : "—" }));
1726
1693
  }
1727
1694
  case "image": {
1728
1695
  const cfg = (field["imageConfig"] ?? {});
1729
- return cfg.src ? (_jsx("img", { alt: cfg.alt || "", className: "biab-field__image", src: cfg.src, style: {
1696
+ return cfg.src ? (_jsx("img", { alt: cfg.alt || "", className: "bd-field__image", src: cfg.src, style: {
1730
1697
  width: cfg.width ? `${cfg.width}px` : "auto",
1731
1698
  height: cfg.height ? `${cfg.height}px` : "auto",
1732
1699
  maxWidth: "100%",
@@ -1734,7 +1701,7 @@ function BiabFieldInput({ field, value, setValue, }) {
1734
1701
  }
1735
1702
  case "textarea": {
1736
1703
  const cfg = (field["textareaConfig"] ?? {});
1737
- return (_jsx("textarea", { autoComplete: autoComplete, className: "biab-textarea biab-field__input", onChange: (e) => set(e.target.value), placeholder: ph, rows: cfg.rows ?? 4, style: cfg.resizable
1704
+ return (_jsx("textarea", { autoComplete: autoComplete, className: "bd-textarea bd-field__input", onChange: (e) => set(e.target.value), placeholder: ph, rows: cfg.rows ?? 4, style: cfg.resizable
1738
1705
  ? { resize: "vertical", minHeight: "6rem", maxHeight: "30rem" }
1739
1706
  : { resize: "none" }, value: typeof value === "string" ? value : "" }));
1740
1707
  }
@@ -1745,27 +1712,27 @@ function BiabFieldInput({ field, value, setValue, }) {
1745
1712
  // gives native typeahead with no JS and no styling opinion — which is
1746
1713
  // exactly the SDK's contract.
1747
1714
  if (shouldSearchOptions(opts.length, field.display)) {
1748
- const listId = `biab-list-${field.id}`;
1749
- return (_jsxs(_Fragment, { children: [_jsx("input", { className: "biab-input biab-combobox biab-field__input", list: listId, onChange: (e) => set(e.target.value), placeholder: ph || "Search…", type: "text", value: typeof value === "string" ? value : "" }), _jsx("datalist", { id: listId, children: opts.map((opt) => (_jsx("option", { value: opt }, opt))) })] }));
1715
+ const listId = `bd-list-${field.id}`;
1716
+ return (_jsxs(_Fragment, { children: [_jsx("input", { className: "bd-input bd-combobox bd-field__input", list: listId, onChange: (e) => set(e.target.value), placeholder: ph || "Search…", type: "text", value: typeof value === "string" ? value : "" }), _jsx("datalist", { id: listId, children: opts.map((opt) => (_jsx("option", { value: opt }, opt))) })] }));
1750
1717
  }
1751
- return (_jsxs("select", { className: "biab-select biab-field__input", onChange: (e) => set(e.target.value), value: typeof value === "string" ? value : "", children: [_jsx("option", { value: "", children: ph || "Select…" }), opts.map((opt) => (_jsx("option", { value: opt, children: opt }, opt)))] }));
1718
+ return (_jsxs("select", { className: "bd-select bd-field__input", onChange: (e) => set(e.target.value), value: typeof value === "string" ? value : "", children: [_jsx("option", { value: "", children: ph || "Select…" }), opts.map((opt) => (_jsx("option", { value: opt, children: opt }, opt)))] }));
1752
1719
  }
1753
1720
  case "icon_select":
1754
- return _jsx(BiabIconSelect, { field: field, set: set, value: value });
1721
+ return _jsx(BdIconSelect, { field: field, set: set, value: value });
1755
1722
  case "image_input":
1756
- return _jsx(BiabImageInput, { field: field, set: set, value: value });
1723
+ return _jsx(BdImageInput, { field: field, set: set, value: value });
1757
1724
  case "radio":
1758
- return (_jsx("div", { className: "biab-field__radios", children: (field.options ?? []).map((opt) => (_jsxs("label", { className: "biab-field__radio", children: [_jsx("input", { checked: value === opt, name: field.id, onChange: () => set(opt), type: "radio", value: opt }), _jsx("span", { children: opt })] }, opt))) }));
1725
+ return (_jsx("div", { className: "bd-field__radios", children: (field.options ?? []).map((opt) => (_jsxs("label", { className: "bd-field__radio", children: [_jsx("input", { checked: value === opt, name: field.id, onChange: () => set(opt), type: "radio", value: opt }), _jsx("span", { children: opt })] }, opt))) }));
1759
1726
  case "checkbox": {
1760
1727
  const arr = Array.isArray(value) ? value : [];
1761
1728
  // Multi-Select element: a checkbox (value = string[]) rendered as a native
1762
1729
  // multiple-select. The SDK ships unstyled HTML; consumers style it.
1763
1730
  if (field.display === "dropdown") {
1764
- return (_jsx("select", { className: "biab-select biab-field__input", multiple: true, onChange: (e) => set(Array.from(e.target.selectedOptions).map((o) => o.value)), value: arr, children: (field.options ?? []).map((opt) => (_jsx("option", { value: opt, children: opt }, opt))) }));
1731
+ return (_jsx("select", { className: "bd-select bd-field__input", multiple: true, onChange: (e) => set(Array.from(e.target.selectedOptions).map((o) => o.value)), value: arr, children: (field.options ?? []).map((opt) => (_jsx("option", { value: opt, children: opt }, opt))) }));
1765
1732
  }
1766
- return (_jsx("div", { className: "biab-field__checkboxes", children: (field.options ?? []).map((opt) => {
1733
+ return (_jsx("div", { className: "bd-field__checkboxes", children: (field.options ?? []).map((opt) => {
1767
1734
  const checked = arr.includes(opt);
1768
- return (_jsxs("label", { className: "biab-field__checkbox", children: [_jsx("input", { checked: checked, onChange: (e) => set(e.target.checked
1735
+ return (_jsxs("label", { className: "bd-field__checkbox", children: [_jsx("input", { checked: checked, onChange: (e) => set(e.target.checked
1769
1736
  ? [...arr, opt]
1770
1737
  : arr.filter((x) => x !== opt)), type: "checkbox" }), _jsx("span", { children: opt })] }, opt));
1771
1738
  }) }));
@@ -1786,17 +1753,17 @@ function BiabFieldInput({ field, value, setValue, }) {
1786
1753
  set(single === label ? "" : label);
1787
1754
  }
1788
1755
  };
1789
- return (_jsx("div", { className: "biab-field__choice-cards", role: ccMulti ? "group" : "radiogroup", children: ccOptions.map((opt) => {
1756
+ return (_jsx("div", { className: "bd-field__choice-cards", role: ccMulti ? "group" : "radiogroup", children: ccOptions.map((opt) => {
1790
1757
  const active = ccMulti
1791
1758
  ? arr.includes(opt.label)
1792
1759
  : single === opt.label;
1793
- return (_jsxs("button", { "aria-pressed": active, className: "biab-field__choice-card", "data-active": active ? "" : undefined, "data-product-id": opt.productId || undefined, onClick: () => toggle(opt.label), role: ccMulti ? "checkbox" : "radio", type: "button", children: [opt.imageUrl ? (_jsx("img", { alt: opt.label, className: "biab-field__choice-card-image", src: opt.imageUrl })) : opt.icon ? (_jsx("span", { "aria-hidden": "true", className: "biab-field__choice-card-icon", "data-icon": opt.icon })) : null, _jsxs("span", { className: "biab-field__choice-card-body", children: [_jsxs("span", { className: "biab-field__choice-card-header", children: [_jsx("span", { className: "biab-field__choice-card-label", children: opt.label }), opt.price ? (_jsx("span", { className: "biab-field__choice-card-price", children: opt.price })) : null] }), opt.description ? (_jsx("span", { className: "biab-field__choice-card-description", children: opt.description })) : null, safeHttpHref(opt.href) ? (_jsx("a", { className: "biab-field__choice-card-link", href: safeHttpHref(opt.href), onClick: (e) => e.stopPropagation(), rel: "noopener noreferrer nofollow", target: "_blank", children: "View" })) : null] })] }, opt.label));
1760
+ return (_jsxs("button", { "aria-pressed": active, className: "bd-field__choice-card", "data-active": active ? "" : undefined, "data-product-id": opt.productId || undefined, onClick: () => toggle(opt.label), role: ccMulti ? "checkbox" : "radio", type: "button", children: [opt.imageUrl ? (_jsx("img", { alt: opt.label, className: "bd-field__choice-card-image", src: opt.imageUrl })) : opt.icon ? (_jsx("span", { "aria-hidden": "true", className: "bd-field__choice-card-icon", "data-icon": opt.icon })) : null, _jsxs("span", { className: "bd-field__choice-card-body", children: [_jsxs("span", { className: "bd-field__choice-card-header", children: [_jsx("span", { className: "bd-field__choice-card-label", children: opt.label }), opt.price ? (_jsx("span", { className: "bd-field__choice-card-price", children: opt.price })) : null] }), opt.description ? (_jsx("span", { className: "bd-field__choice-card-description", children: opt.description })) : null, safeHttpHref(opt.href) ? (_jsx("a", { className: "bd-field__choice-card-link", href: safeHttpHref(opt.href), onClick: (e) => e.stopPropagation(), rel: "noopener noreferrer nofollow", target: "_blank", children: "View" })) : null] })] }, opt.label));
1794
1761
  }) }));
1795
1762
  }
1796
1763
  case "boolean":
1797
- return (_jsxs("label", { className: "biab-field__switch", children: [_jsx("input", { checked: value === true, onChange: (e) => set(e.target.checked), type: "checkbox" }), _jsx("span", { children: field.placeholder || "Yes / No" })] }));
1764
+ return (_jsxs("label", { className: "bd-field__switch", children: [_jsx("input", { checked: value === true, onChange: (e) => set(e.target.checked), type: "checkbox" }), _jsx("span", { children: field.placeholder || "Yes / No" })] }));
1798
1765
  case "date":
1799
- return (_jsx("input", { className: "biab-input biab-field__input", onChange: (e) => set(e.target.value), type: "date", value: typeof value === "string" ? value : "" }));
1766
+ return (_jsx("input", { className: "bd-input bd-field__input", onChange: (e) => set(e.target.value), type: "date", value: typeof value === "string" ? value : "" }));
1800
1767
  case "time_picker": {
1801
1768
  const mode = field.timeConfig?.mode ?? "simple";
1802
1769
  if (mode === "simple") {
@@ -1817,7 +1784,7 @@ function BiabFieldInput({ field, value, setValue, }) {
1817
1784
  const h12 = h % 12 === 0 ? 12 : h % 12;
1818
1785
  return `${h12}:${mStr} ${ampm}`;
1819
1786
  };
1820
- return (_jsxs("select", { className: "biab-select biab-field__input", onChange: (e) => set(e.target.value), value: typeof value === "string" ? value : "", children: [_jsx("option", { value: "", children: ph || "Select time" }), opts.map((o) => (_jsx("option", { value: o, children: fmt(o) }, o)))] }));
1787
+ return (_jsxs("select", { className: "bd-select bd-field__input", onChange: (e) => set(e.target.value), value: typeof value === "string" ? value : "", children: [_jsx("option", { value: "", children: ph || "Select time" }), opts.map((o) => (_jsx("option", { value: o, children: fmt(o) }, o)))] }));
1821
1788
  }
1822
1789
  const pair = mode === "time_block"
1823
1790
  ? ["start", "end"]
@@ -1826,10 +1793,10 @@ function BiabFieldInput({ field, value, setValue, }) {
1826
1793
  ? value
1827
1794
  : {};
1828
1795
  const inputType = (k) => (k === "date" ? "date" : "time");
1829
- return (_jsx("div", { className: "biab-field__grid2", children: pair.map((k) => (_jsxs("label", { className: "biab-field__sub", children: [_jsxs("span", { className: "biab-field__sublabel", children: [k[0]?.toUpperCase(), k.slice(1)] }), _jsx("input", { className: "biab-input", onChange: (e) => set({ ...v, [k]: e.target.value }), type: inputType(k), value: v[k] ?? "" })] }, k))) }));
1796
+ return (_jsx("div", { className: "bd-field__grid2", children: pair.map((k) => (_jsxs("label", { className: "bd-field__sub", children: [_jsxs("span", { className: "bd-field__sublabel", children: [k[0]?.toUpperCase(), k.slice(1)] }), _jsx("input", { className: "bd-input", onChange: (e) => set({ ...v, [k]: e.target.value }), type: inputType(k), value: v[k] ?? "" })] }, k))) }));
1830
1797
  }
1831
1798
  case "date_range":
1832
- return _jsx(BiabDateRange, { setValue: (next) => set(next), value: value });
1799
+ return _jsx(BdDateRange, { setValue: (next) => set(next), value: value });
1833
1800
  case "slider": {
1834
1801
  const min = field.sliderConfig?.min ?? 0;
1835
1802
  const max = field.sliderConfig?.max ?? 100;
@@ -1837,23 +1804,41 @@ function BiabFieldInput({ field, value, setValue, }) {
1837
1804
  const unit = field.sliderConfig?.unit;
1838
1805
  const fmt = (n) => unit === "currency" ? `$${n}` : unit === "percent" ? `${n}%` : `${n}`;
1839
1806
  const v = typeof value === "number" ? value : min;
1840
- return (_jsxs("div", { className: "biab-field__slider", children: [_jsxs("div", { className: "biab-field__sliderscale", children: [_jsx("span", { children: fmt(min) }), _jsx("span", { className: "biab-field__slidervalue", children: fmt(v) }), _jsx("span", { children: fmt(max) })] }), _jsx("input", { max: max, min: min, onChange: (e) => set(Number(e.target.value)), step: step, type: "range", value: v })] }));
1807
+ return (_jsxs("div", { className: "bd-field__slider", children: [_jsxs("div", { className: "bd-field__sliderscale", children: [_jsx("span", { children: fmt(min) }), _jsx("span", { className: "bd-field__slidervalue", children: fmt(v) }), _jsx("span", { children: fmt(max) })] }), _jsx("input", { max: max, min: min, onChange: (e) => set(Number(e.target.value)), step: step, type: "range", value: v })] }));
1841
1808
  }
1842
1809
  case "star_rating": {
1843
1810
  const max = field.starRatingConfig?.maxStars ?? 5;
1844
1811
  const v = typeof value === "number" ? value : 0;
1845
- return (_jsx("div", { className: "biab-field__stars", children: Array.from({ length: max }).map((_, i) => (_jsx("button", { "aria-label": `${i + 1} star${i ? "s" : ""}`, className: cx("biab-field__star", i < v && "biab-field__star--on"), onClick: () => set(i + 1), type: "button", children: "\u2605" }, `${field.id}-star-${i}`))) }));
1812
+ return (_jsx("div", { className: "bd-field__stars", children: Array.from({ length: max }).map((_, i) => (_jsx("button", { "aria-label": `${i + 1} star${i ? "s" : ""}`, className: cx("bd-field__star", i < v && "bd-field__star--on"), onClick: () => set(i + 1), type: "button", children: "\u2605" }, `${field.id}-star-${i}`))) }));
1846
1813
  }
1847
1814
  case "happiness_rating": {
1848
1815
  const v = typeof value === "number" ? value : -1;
1849
- return (_jsx("div", { className: "biab-field__happiness", children: ["😞", "😕", "😐", "🙂", "😄"].map((emoji, i) => (_jsx("button", { className: cx("biab-field__emoji", i === v && "biab-field__emoji--on"), onClick: () => set(i), type: "button", children: emoji }, emoji))) }));
1816
+ return (_jsx("div", { className: "bd-field__happiness", children: ["😞", "😕", "😐", "🙂", "😄"].map((emoji, i) => (_jsx("button", { className: cx("bd-field__emoji", i === v && "bd-field__emoji--on"), onClick: () => set(i), type: "button", children: emoji }, emoji))) }));
1850
1817
  }
1851
1818
  case "stepper": {
1852
1819
  const v = typeof value === "number" ? value : 0;
1853
- return (_jsxs("div", { className: "biab-field__stepper", children: [_jsx("button", { className: "biab-btn biab-btn--ghost", onClick: () => set(v - 1), type: "button", children: "\u2212" }), _jsx("input", { className: "biab-field__steppervalue", inputMode: "numeric", onChange: (e) => {
1820
+ return (_jsxs("div", { className: "bd-field__stepper", children: [_jsx("button", { className: "bd-btn bd-btn--ghost", onClick: () => set(v - 1), type: "button", children: "\u2212" }), _jsx("input", { className: "bd-field__steppervalue", inputMode: "numeric", onChange: (e) => {
1854
1821
  const n = Number(e.target.value.replace(/[^\d-]/g, ""));
1855
1822
  set(Number.isFinite(n) ? n : 0);
1856
- }, value: String(v) }), _jsx("button", { className: "biab-btn biab-btn--ghost", onClick: () => set(v + 1), type: "button", children: "+" })] }));
1823
+ }, value: String(v) }), _jsx("button", { className: "bd-btn bd-btn--ghost", onClick: () => set(v + 1), type: "button", children: "+" })] }));
1824
+ }
1825
+ case "name": {
1826
+ const v = (value && typeof value === "object" ? value : {});
1827
+ const cfg = field.nameConfig ?? {};
1828
+ // Per-subfield autofill tokens (given/family/honorifics), suppressed when
1829
+ // autofill is off for this field (global switch or per-field override).
1830
+ const acOff = autoComplete === "off";
1831
+ const part = (k, label, ac, placeholder) => (_jsxs("label", { className: "bd-field__sub", children: [_jsx("span", { className: "bd-field__sublabel", children: label }), _jsx("input", { autoComplete: acOff ? "off" : ac, className: "bd-input", onChange: (e) => set({ ...v, [k]: e.target.value }), placeholder: placeholder, value: v[k] ?? "" })] }, k));
1832
+ // The nicknames input keeps the raw comma-separated string while the
1833
+ // visitor types; submit normalizes it into a string[] (and the server
1834
+ // re-normalizes authoritatively).
1835
+ const nicknamesText = Array.isArray(v.nicknames)
1836
+ ? v.nicknames.join(", ")
1837
+ : typeof v.nicknames === "string"
1838
+ ? v.nicknames
1839
+ : "";
1840
+ return (_jsxs("div", { className: "bd-field__name", children: [cfg.prefix && part("prefix", "Title", "honorific-prefix", "Dr."), cfg.middle ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "bd-field__grid2", children: [part("first", "First name", "given-name", "Jane"), part("middle", "Middle name", "additional-name", "Quinn")] }), cfg.suffix ? (_jsxs("div", { className: "bd-field__grid2", children: [part("last", "Last name", "family-name", "Doe"), part("suffix", "Suffix", "honorific-suffix", "Jr.")] })) : (part("last", "Last name", "family-name", "Doe"))] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "bd-field__grid2", children: [part("first", "First name", "given-name", "Jane"), part("last", "Last name", "family-name", "Doe")] }), cfg.suffix &&
1841
+ part("suffix", "Suffix", "honorific-suffix", "Jr.")] })), cfg.nicknames && (_jsxs("label", { className: "bd-field__sub", children: [_jsx("span", { className: "bd-field__sublabel", children: "Nicknames" }), _jsx("input", { autoComplete: acOff ? "off" : undefined, className: "bd-input", onChange: (e) => set({ ...v, nicknames: e.target.value }), placeholder: "Johnny, JM \u2014 separate with commas", value: nicknamesText })] }, "nicknames"))] }));
1857
1842
  }
1858
1843
  case "address": {
1859
1844
  const v = value && typeof value === "object"
@@ -1867,7 +1852,7 @@ function BiabFieldInput({ field, value, setValue, }) {
1867
1852
  { k: "line2", label: "Address Line 2", ac: "address-line2" },
1868
1853
  { k: "city", label: "City", ac: "address-level2" },
1869
1854
  ];
1870
- return (_jsxs("div", { className: "biab-field__address", children: [rows.map(({ k, label, ac }) => (_jsxs("label", { className: "biab-field__sub", children: [_jsx("span", { className: "biab-field__sublabel", children: label }), _jsx("input", { autoComplete: acOff ? "off" : ac, className: "biab-input", onChange: (e) => set({ ...v, [k]: e.target.value }), value: v[k] ?? "" })] }, k))), _jsxs("label", { className: "biab-field__sub", children: [_jsx("span", { className: "biab-field__sublabel", children: "State" }), _jsxs("select", { autoComplete: acOff ? "off" : "address-level1", className: "biab-select", onChange: (e) => set({ ...v, state: e.target.value }), value: v["state"] ?? "", children: [_jsx("option", { value: "", children: "Select state" }), US_STATES.map((s) => (_jsx("option", { value: s.abbr, children: s.name }, s.abbr)))] })] }, "state"), _jsxs("label", { className: "biab-field__sub", children: [_jsx("span", { className: "biab-field__sublabel", children: "Zip" }), _jsx("input", { autoComplete: acOff ? "off" : "postal-code", className: "biab-input", inputMode: "numeric", onChange: (e) =>
1855
+ return (_jsxs("div", { className: "bd-field__address", children: [rows.map(({ k, label, ac }) => (_jsxs("label", { className: "bd-field__sub", children: [_jsx("span", { className: "bd-field__sublabel", children: label }), _jsx("input", { autoComplete: acOff ? "off" : ac, className: "bd-input", onChange: (e) => set({ ...v, [k]: e.target.value }), value: v[k] ?? "" })] }, k))), _jsxs("label", { className: "bd-field__sub", children: [_jsx("span", { className: "bd-field__sublabel", children: "State" }), _jsxs("select", { autoComplete: acOff ? "off" : "address-level1", className: "bd-select", onChange: (e) => set({ ...v, state: e.target.value }), value: v["state"] ?? "", children: [_jsx("option", { value: "", children: "Select state" }), US_STATES.map((s) => (_jsx("option", { value: s.abbr, children: s.name }, s.abbr)))] })] }, "state"), _jsxs("label", { className: "bd-field__sub", children: [_jsx("span", { className: "bd-field__sublabel", children: "Zip" }), _jsx("input", { autoComplete: acOff ? "off" : "postal-code", className: "bd-input", inputMode: "numeric", onChange: (e) =>
1871
1856
  // Numbers only (allow a single hyphen for ZIP+4).
1872
1857
  set({ ...v, zip: e.target.value.replace(/[^\d-]/g, "") }), placeholder: "90210", value: v["zip"] ?? "" })] }, "zip")] }));
1873
1858
  }
@@ -1875,7 +1860,7 @@ function BiabFieldInput({ field, value, setValue, }) {
1875
1860
  const v = typeof value === "string" ? value : "";
1876
1861
  const presets = field.options ?? [];
1877
1862
  const isCustom = v !== "" && !presets.includes(v);
1878
- return (_jsxs("div", { className: "biab-field__colors", children: [presets.map((color) => (_jsx("button", { className: cx("biab-field__color", v === color && "biab-field__color--on"), onClick: () => set(color), style: { backgroundColor: color }, title: color, type: "button" }, color))), _jsx("label", { className: cx("biab-field__color biab-field__color--custom", isCustom && "biab-field__color--on"), style: isCustom
1863
+ return (_jsxs("div", { className: "bd-field__colors", children: [presets.map((color) => (_jsx("button", { className: cx("bd-field__color", v === color && "bd-field__color--on"), onClick: () => set(color), style: { backgroundColor: color }, title: color, type: "button" }, color))), _jsx("label", { className: cx("bd-field__color bd-field__color--custom", isCustom && "bd-field__color--on"), style: isCustom
1879
1864
  ? { backgroundColor: v }
1880
1865
  : {
1881
1866
  background: "conic-gradient(red, yellow, lime, cyan, blue, magenta, red)",
@@ -1891,7 +1876,7 @@ function BiabFieldInput({ field, value, setValue, }) {
1891
1876
  const cfg = field.fileConfig ?? {};
1892
1877
  const maxFiles = cfg.maxFiles ?? 1;
1893
1878
  const remaining = Math.max(maxFiles - files.length, 0);
1894
- return (_jsxs("div", { className: "biab-field__files", children: [_jsx("input", { accept: buildAcceptAttr(cfg.allowedTypes), className: "biab-field__fileinput", disabled: remaining === 0, multiple: maxFiles > 1, onChange: (e) => {
1879
+ return (_jsxs("div", { className: "bd-field__files", children: [_jsx("input", { accept: buildAcceptAttr(cfg.allowedTypes), className: "bd-field__fileinput", disabled: remaining === 0, multiple: maxFiles > 1, onChange: (e) => {
1895
1880
  const list = e.target.files;
1896
1881
  if (!list)
1897
1882
  return;
@@ -1913,7 +1898,7 @@ function BiabFieldInput({ field, value, setValue, }) {
1913
1898
  if (additions.length > 0)
1914
1899
  set([...files, ...additions]);
1915
1900
  e.target.value = "";
1916
- }, type: "file" }), files.length > 0 && (_jsx("ul", { className: "biab-field__filelist", children: files.map((f, i) => (_jsxs("li", { className: "biab-field__fileitem", children: [_jsx("span", { className: "biab-field__filename", children: f.name }), isPendingFileValue(f) ? (_jsxs("span", { className: "biab-field__filepending", children: [" ", "\u00B7 uploads on submit"] })) : null, _jsx("button", { "aria-label": "Remove file", className: "biab-field__fileremove", onClick: () => set(files.filter((_, idx) => idx !== i)), type: "button", children: "\u00D7" })] }, `${f.name}-${i}`))) }))] }));
1901
+ }, type: "file" }), files.length > 0 && (_jsx("ul", { className: "bd-field__filelist", children: files.map((f, i) => (_jsxs("li", { className: "bd-field__fileitem", children: [_jsx("span", { className: "bd-field__filename", children: f.name }), isPendingFileValue(f) ? (_jsxs("span", { className: "bd-field__filepending", children: [" ", "\u00B7 uploads on submit"] })) : null, _jsx("button", { "aria-label": "Remove file", className: "bd-field__fileremove", onClick: () => set(files.filter((_, idx) => idx !== i)), type: "button", children: "\u00D7" })] }, `${f.name}-${i}`))) }))] }));
1917
1902
  }
1918
1903
  case "credit_card": {
1919
1904
  const pc = field.paymentConfig;
@@ -1921,14 +1906,14 @@ function BiabFieldInput({ field, value, setValue, }) {
1921
1906
  const amount = deposit && pc?.amountCents
1922
1907
  ? `${(pc.amountCents / 100).toFixed(2)} ${(pc.currency ?? "usd").toUpperCase()}`
1923
1908
  : null;
1924
- return (_jsxs("div", { className: "biab-field__card", children: [_jsxs("div", { className: "biab-field__card-row", children: [_jsx("span", { className: "biab-field__card-brand", children: "CARD" }), _jsx("span", { className: "biab-field__card-dots", children: "\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022" }), _jsx("span", { className: "biab-field__card-mode", children: deposit
1909
+ return (_jsxs("div", { className: "bd-field__card", children: [_jsxs("div", { className: "bd-field__card-row", children: [_jsx("span", { className: "bd-field__card-brand", children: "CARD" }), _jsx("span", { className: "bd-field__card-dots", children: "\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022" }), _jsx("span", { className: "bd-field__card-mode", children: deposit
1925
1910
  ? `Deposit${amount ? ` · ${amount}` : ""}`
1926
- : "Card on file" })] }), pc?.description ? (_jsx("p", { className: "biab-field__card-desc", children: pc.description })) : null, _jsxs("p", { className: "biab-field__card-note", children: ["Secure card entry via Stripe. Initialize Elements with", " ", _jsxs("code", { children: ["biab.forms.paymentIntent(slug, \"", field.id, "\")"] }), " (returns the clientSecret + the org's connected account), confirm, then store the intent id on this field before submit."] })] }));
1911
+ : "Card on file" })] }), pc?.description ? (_jsx("p", { className: "bd-field__card-desc", children: pc.description })) : null, _jsxs("p", { className: "bd-field__card-note", children: ["Secure card entry via Stripe. Initialize Elements with", " ", _jsxs("code", { children: ["bd.forms.paymentIntent(slug, \"", field.id, "\")"] }), " (returns the clientSecret + the org's connected account), confirm, then store the intent id on this field before submit."] })] }));
1927
1912
  }
1928
1913
  case "schedule": {
1929
1914
  if (field.scheduleConfig
1930
1915
  ?.mode === "auto") {
1931
- return _jsx(BiabScheduleAuto, { field: field, onChange: set, value: value });
1916
+ return _jsx(BdScheduleAuto, { field: field, onChange: set, value: value });
1932
1917
  }
1933
1918
  const sc = field.scheduleConfig;
1934
1919
  const sv = (value && typeof value === "object" ? value : {});
@@ -1976,25 +1961,25 @@ function BiabFieldInput({ field, value, setValue, }) {
1976
1961
  : [...arr, item],
1977
1962
  });
1978
1963
  };
1979
- return (_jsxs("div", { className: "biab-field__schedule", children: [sc?.allowAsap !== false && (_jsxs("label", { className: "biab-field__schedule-asap", children: [_jsx("input", { checked: sv.asap === true, onChange: (e) => set({ ...sv, asap: e.target.checked }), type: "checkbox" }), " ", "As soon as possible"] })), _jsxs("div", { className: "biab-field__schedule-group", children: [_jsx("span", { className: "biab-field__schedule-label", children: "Preferred days" }), _jsx("div", { className: "biab-field__schedule-chips", children: days.map((d) => (_jsx("button", { className: cx("biab-field__chip", sv.days?.includes(d) && "biab-field__chip--on"), onClick: () => toggle("days", d), type: "button", children: DAY[d] ?? d }, d))) })] }), _jsxs("div", { className: "biab-field__schedule-group", children: [_jsx("span", { className: "biab-field__schedule-label", children: "Preferred times" }), _jsx("div", { className: "biab-field__schedule-chips", children: windows.map((w) => (_jsx("button", { className: cx("biab-field__chip", sv.times?.includes(w) && "biab-field__chip--on"), onClick: () => toggle("times", w), type: "button", children: TIME[w] ?? w }, w))) })] }), sc?.allowNotes !== false && (_jsx("textarea", { className: "biab-input biab-field__schedule-notes", onChange: (e) => set({ ...sv, notes: e.target.value }), placeholder: "Anything we should know about timing?", value: sv.notes ?? "" }))] }));
1964
+ return (_jsxs("div", { className: "bd-field__schedule", children: [sc?.allowAsap !== false && (_jsxs("label", { className: "bd-field__schedule-asap", children: [_jsx("input", { checked: sv.asap === true, onChange: (e) => set({ ...sv, asap: e.target.checked }), type: "checkbox" }), " ", "As soon as possible"] })), _jsxs("div", { className: "bd-field__schedule-group", children: [_jsx("span", { className: "bd-field__schedule-label", children: "Preferred days" }), _jsx("div", { className: "bd-field__schedule-chips", children: days.map((d) => (_jsx("button", { className: cx("bd-field__chip", sv.days?.includes(d) && "bd-field__chip--on"), onClick: () => toggle("days", d), type: "button", children: DAY[d] ?? d }, d))) })] }), _jsxs("div", { className: "bd-field__schedule-group", children: [_jsx("span", { className: "bd-field__schedule-label", children: "Preferred times" }), _jsx("div", { className: "bd-field__schedule-chips", children: windows.map((w) => (_jsx("button", { className: cx("bd-field__chip", sv.times?.includes(w) && "bd-field__chip--on"), onClick: () => toggle("times", w), type: "button", children: TIME[w] ?? w }, w))) })] }), sc?.allowNotes !== false && (_jsx("textarea", { className: "bd-input bd-field__schedule-notes", onChange: (e) => set({ ...sv, notes: e.target.value }), placeholder: "Anything we should know about timing?", value: sv.notes ?? "" }))] }));
1980
1965
  }
1981
1966
  case "phone": {
1982
1967
  const phoneIntl = field.phoneConfig?.international === true;
1983
1968
  const phoneShown = formatPhoneLocal(typeof value === "string" ? value : "", phoneIntl);
1984
- return (_jsxs("div", { className: "biab-field__phone", children: [field.phoneConfig?.showFlags && (_jsx("span", { "aria-hidden": true, className: "biab-field__flag", children: "\uD83C\uDDFA\uD83C\uDDF8" })), _jsx("input", { autoComplete: autoComplete, className: "biab-input biab-field__input", inputMode: "tel", maxLength: phoneIntl ? 20 : 14, onChange: (e) => set(formatPhoneLocal(e.target.value, phoneIntl)), placeholder: ph || (phoneIntl ? "+1 (555) 000-0000" : "(555) 000-0000"), type: "tel", value: phoneShown })] }));
1969
+ return (_jsxs("div", { className: "bd-field__phone", children: [field.phoneConfig?.showFlags && (_jsx("span", { "aria-hidden": true, className: "bd-field__flag", children: "\uD83C\uDDFA\uD83C\uDDF8" })), _jsx("input", { autoComplete: autoComplete, className: "bd-input bd-field__input", inputMode: "tel", maxLength: phoneIntl ? 20 : 14, onChange: (e) => set(formatPhoneLocal(e.target.value, phoneIntl)), placeholder: ph || (phoneIntl ? "+1 (555) 000-0000" : "(555) 000-0000"), type: "tel", value: phoneShown })] }));
1985
1970
  }
1986
1971
  case "email":
1987
- return (_jsx("input", { autoComplete: autoComplete, className: "biab-input biab-field__input", onChange: (e) => set(e.target.value), placeholder: ph || "you@example.com", type: "email", value: typeof value === "string" ? value : "" }));
1972
+ return (_jsx("input", { autoComplete: autoComplete, className: "bd-input bd-field__input", onChange: (e) => set(e.target.value), placeholder: ph || "you@example.com", type: "email", value: typeof value === "string" ? value : "" }));
1988
1973
  case "url": {
1989
1974
  // Value object: { url, verified }. Visitor edits `url`; server stamps
1990
1975
  // `verified` on submit.
1991
1976
  const uv = (value && typeof value === "object" ? value : {});
1992
- return (_jsx("input", { autoComplete: autoComplete, className: "biab-input biab-field__input", inputMode: "url", onChange: (e) => set({ ...uv, url: e.target.value }), placeholder: ph || "https://example.com", type: "url", value: typeof uv.url === "string" ? uv.url : "" }));
1977
+ return (_jsx("input", { autoComplete: autoComplete, className: "bd-input bd-field__input", inputMode: "url", onChange: (e) => set({ ...uv, url: e.target.value }), placeholder: ph || "https://example.com", type: "url", value: typeof uv.url === "string" ? uv.url : "" }));
1993
1978
  }
1994
1979
  case "number": {
1995
1980
  const allowDecimal = field.allowDecimal !== false;
1996
1981
  const noNegative = field.allowNegative === false;
1997
- return (_jsx("input", { className: "biab-input biab-field__input", inputMode: allowDecimal ? "decimal" : "numeric", min: noNegative ? 0 : undefined, onChange: (e) => {
1982
+ return (_jsx("input", { className: "bd-input bd-field__input", inputMode: allowDecimal ? "decimal" : "numeric", min: noNegative ? 0 : undefined, onChange: (e) => {
1998
1983
  const raw = e.target.value;
1999
1984
  if (raw === "")
2000
1985
  return set("");
@@ -2010,7 +1995,7 @@ function BiabFieldInput({ field, value, setValue, }) {
2010
1995
  const symbol = field.currencyConfig?.symbol || "$";
2011
1996
  const allowNeg = field.currencyConfig?.allowNegative === true;
2012
1997
  const allowDec = field.currencyConfig?.allowDecimal !== false;
2013
- return (_jsxs("div", { className: "biab-field__currency", children: [_jsx("span", { "aria-hidden": "true", className: "biab-field__currency-symbol", children: symbol }), _jsx("input", { className: "biab-input biab-field__input", inputMode: "decimal", min: allowNeg ? undefined : 0, onChange: (e) => {
1998
+ return (_jsxs("div", { className: "bd-field__currency", children: [_jsx("span", { "aria-hidden": "true", className: "bd-field__currency-symbol", children: symbol }), _jsx("input", { className: "bd-input bd-field__input", inputMode: "decimal", min: allowNeg ? undefined : 0, onChange: (e) => {
2014
1999
  const raw = e.target.value;
2015
2000
  if (raw === "")
2016
2001
  return set("");
@@ -2048,16 +2033,16 @@ function BiabFieldInput({ field, value, setValue, }) {
2048
2033
  });
2049
2034
  };
2050
2035
  const hint = typeof num === "number" ? formatMeasurement(num, unit, category) : "";
2051
- return (_jsxs("div", { className: "biab-field__measurement", children: [_jsx("input", { className: "biab-input biab-field__input", inputMode: "decimal", onChange: (e) => {
2036
+ return (_jsxs("div", { className: "bd-field__measurement", children: [_jsx("input", { className: "bd-input bd-field__input", inputMode: "decimal", onChange: (e) => {
2052
2037
  const raw = e.target.value;
2053
2038
  if (raw === "")
2054
2039
  return emit("", unit);
2055
2040
  const n = allowDec ? Number(raw) : Math.trunc(Number(raw));
2056
2041
  emit(Number.isNaN(n) ? "" : n, unit);
2057
- }, placeholder: ph || "0", step: allowDec ? "any" : 1, type: "number", value: num }), mode === "fixed" ? (_jsx("span", { "aria-hidden": "true", className: "biab-field__unit", children: unit })) : (_jsx("select", { className: "biab-select biab-field__unit-select", onChange: (e) => emit(num, e.target.value), value: unit, children: units.map((u) => (_jsx("option", { value: u, children: u }, u))) })), hint ? (_jsxs("span", { className: "biab-field__measurement-hint", children: ["\u2248 ", hint] })) : null] }));
2042
+ }, placeholder: ph || "0", step: allowDec ? "any" : 1, type: "number", value: num }), mode === "fixed" ? (_jsx("span", { "aria-hidden": "true", className: "bd-field__unit", children: unit })) : (_jsx("select", { className: "bd-select bd-field__unit-select", onChange: (e) => emit(num, e.target.value), value: unit, children: units.map((u) => (_jsx("option", { value: u, children: u }, u))) })), hint ? (_jsxs("span", { className: "bd-field__measurement-hint", children: ["\u2248 ", hint] })) : null] }));
2058
2043
  }
2059
2044
  default:
2060
- return (_jsx("input", { autoComplete: autoComplete, className: "biab-input biab-field__input", onChange: (e) => set(e.target.value), placeholder: ph, value: typeof value === "string" ? value : "" }));
2045
+ return (_jsx("input", { autoComplete: autoComplete, className: "bd-input bd-field__input", onChange: (e) => set(e.target.value), placeholder: ph, value: typeof value === "string" ? value : "" }));
2061
2046
  }
2062
2047
  }
2063
2048
  const NO_LABEL_TYPES = new Set([
@@ -2069,18 +2054,18 @@ const NO_LABEL_TYPES = new Set([
2069
2054
  "bullet_list",
2070
2055
  "table",
2071
2056
  ]);
2072
- function BiabFieldRow({ field, value, error, setValue, upload, }) {
2057
+ function BdFieldRow({ field, value, error, setValue, upload, }) {
2073
2058
  const showLabel = !NO_LABEL_TYPES.has(field.type);
2074
- return (_jsxs("div", { className: cx("biab-field", `biab-field--${field.type}`, field.required && "biab-field--required", error && "biab-field--error"), "data-biab-field": fieldCssKey(field), "data-biab-type": field.type, "data-field-id": field.id, children: [showLabel && (
2059
+ return (_jsxs("div", { className: cx("bd-field", `bd-field--${field.type}`, field.required && "bd-field--required", error && "bd-field--error"), "data-bd-field": fieldCssKey(field), "data-bd-type": field.type, "data-field-id": field.id, children: [showLabel && (
2075
2060
  // A visual field heading, not a control-associated <label> — the field's
2076
- // inputs render in BiabFieldInput below and carry no shared id to point a
2061
+ // inputs render in BdFieldInput below and carry no shared id to point a
2077
2062
  // `htmlFor` at, so a <label> here would be an orphan.
2078
- _jsxs("span", { className: "biab-field__label biab-label", children: [field.label || "", field.required && _jsx("span", { className: "biab-field__required", children: "*" })] })), _jsx(BiabFieldInput, { field: field, setValue: setValue, upload: upload, value: value }), error && _jsx("p", { className: "biab-field__error", children: error.message }), field.helpText && _jsx("p", { className: "biab-field__help", children: field.helpText })] }));
2063
+ _jsxs("span", { className: "bd-field__label bd-label", children: [field.label || "", field.required && _jsx("span", { className: "bd-field__required", children: "*" })] })), _jsx(BdFieldInput, { field: field, setValue: setValue, upload: upload, value: value }), error && _jsx("p", { className: "bd-field__error", children: error.message }), field.helpText && _jsx("p", { className: "bd-field__help", children: field.helpText })] }));
2079
2064
  }
2080
2065
  /** Recursively render a field subtree, mirroring FormPreview's `RenderTree`:
2081
2066
  * input_group (+ concurrent reveal), condition_block, or_condition, flex_row. */
2082
- function BiabRenderTree({ fields, values, errors, setValue, upload, flat, }) {
2083
- return (_jsx("div", { className: "biab-tree", children: fields.map((f) => {
2067
+ function BdRenderTree({ fields, values, errors, setValue, upload, flat, }) {
2068
+ return (_jsx("div", { className: "bd-tree", children: fields.map((f) => {
2084
2069
  if (f.type === "multi_populator") {
2085
2070
  const cfg = f.populatorConfig ?? {};
2086
2071
  const max = cfg.maxInstances ?? 10;
@@ -2090,14 +2075,14 @@ function BiabRenderTree({ fields, values, errors, setValue, upload, flat, }) {
2090
2075
  ? raw
2091
2076
  : [{}];
2092
2077
  const writeInstances = (next) => setValue(f.id, next);
2093
- return (_jsxs("div", { className: "biab-populator", "data-biab-field": fieldCssKey(f), "data-field-id": f.id, children: [instances.map((inst, idx) => {
2078
+ return (_jsxs("div", { className: "bd-populator", "data-bd-field": fieldCssKey(f), "data-field-id": f.id, children: [instances.map((inst, idx) => {
2094
2079
  const scopedSetValue = (childId, v) => {
2095
2080
  const nextArr = instances.map((x) => ({ ...x }));
2096
2081
  nextArr[idx] = { ...nextArr[idx], [childId]: v };
2097
2082
  writeInstances(nextArr);
2098
2083
  };
2099
- return (_jsxs("div", { className: "biab-populator__item", children: [_jsxs("div", { className: "biab-populator__item-head", children: [_jsxs("span", { className: "biab-populator__item-label", children: [cfg.itemLabel || f.label || "Entry", " ", idx + 1] }), instances.length > 1 && (_jsx("button", { "aria-label": "Remove entry", className: "biab-populator__remove", onClick: () => writeInstances(instances.filter((_, i) => i !== idx)), type: "button", children: "\u00D7" }))] }), _jsx(BiabRenderTree, { errors: errors, fields: children, setValue: scopedSetValue, upload: upload, values: inst })] }, `${f.id}-inst-${idx}`));
2100
- }), instances.length < max && (_jsxs("button", { className: "biab-populator__add", onClick: () => writeInstances([...instances, {}]), type: "button", children: ["+ ", cfg.addButtonLabel || "Add another"] }))] }, f.id));
2084
+ return (_jsxs("div", { className: "bd-populator__item", children: [_jsxs("div", { className: "bd-populator__item-head", children: [_jsxs("span", { className: "bd-populator__item-label", children: [cfg.itemLabel || f.label || "Entry", " ", idx + 1] }), instances.length > 1 && (_jsx("button", { "aria-label": "Remove entry", className: "bd-populator__remove", onClick: () => writeInstances(instances.filter((_, i) => i !== idx)), type: "button", children: "\u00D7" }))] }), _jsx(BdRenderTree, { errors: errors, fields: children, setValue: scopedSetValue, upload: upload, values: inst })] }, `${f.id}-inst-${idx}`));
2085
+ }), instances.length < max && (_jsxs("button", { className: "bd-populator__add", onClick: () => writeInstances([...instances, {}]), type: "button", children: ["+ ", cfg.addButtonLabel || "Add another"] }))] }, f.id));
2101
2086
  }
2102
2087
  if (f.type === "input_group") {
2103
2088
  const children = (f.children ?? []);
@@ -2107,12 +2092,12 @@ function BiabRenderTree({ fields, values, errors, setValue, upload, flat, }) {
2107
2092
  ? concurrentRevealCount(children, values)
2108
2093
  : children.length;
2109
2094
  const shown = concurrent ? children.slice(0, revealCount) : children;
2110
- return (_jsxs("div", { className: cx("biab-group", flat && "biab-group--flat"), "data-biab-group": fieldCssKey(f), children: [f.label && showGroupLabel && (_jsx("div", { className: "biab-group__label", children: f.label })), _jsx(BiabRenderTree, { errors: errors, fields: shown, setValue: setValue, upload: upload, values: values })] }, f.id));
2095
+ return (_jsxs("div", { className: cx("bd-group", flat && "bd-group--flat"), "data-bd-group": fieldCssKey(f), children: [f.label && showGroupLabel && (_jsx("div", { className: "bd-group__label", children: f.label })), _jsx(BdRenderTree, { errors: errors, fields: shown, setValue: setValue, upload: upload, values: values })] }, f.id));
2111
2096
  }
2112
2097
  if (f.type === "condition_block") {
2113
2098
  if (!evalCondition(f.conditionRule, values))
2114
2099
  return null;
2115
- return (_jsx(BiabRenderTree, { errors: errors, fields: (f.children ?? []), setValue: setValue, upload: upload, values: values }, f.id));
2100
+ return (_jsx(BdRenderTree, { errors: errors, fields: (f.children ?? []), setValue: setValue, upload: upload, values: values }, f.id));
2116
2101
  }
2117
2102
  if (f.type === "or_condition") {
2118
2103
  const branches = f.children ?? [];
@@ -2122,19 +2107,19 @@ function BiabRenderTree({ fields, values, errors, setValue, upload, flat, }) {
2122
2107
  branches[i]?.label ||
2123
2108
  ["Option A", "Option B", "Option C"][i] ||
2124
2109
  `Option ${i + 1}`;
2125
- return (_jsxs("div", { className: cx("biab-or", errored && "biab-or--error"), children: [f.label && (_jsxs("div", { className: "biab-or__label", children: [f.label, _jsx("span", { className: "biab-or__hint", children: "Fill at least one side" })] })), _jsx("div", { className: "biab-or__sides", children: branches.flatMap((child, i) => {
2126
- const side = (_jsxs("div", { className: "biab-or__side", children: [_jsx("div", { className: "biab-or__sidelabel", children: branchLabel(i) }), _jsx(BiabRenderTree, { errors: errors, fields: [child], setValue: setValue, upload: upload, values: values })] }, child.id));
2110
+ return (_jsxs("div", { className: cx("bd-or", errored && "bd-or--error"), children: [f.label && (_jsxs("div", { className: "bd-or__label", children: [f.label, _jsx("span", { className: "bd-or__hint", children: "Fill at least one side" })] })), _jsx("div", { className: "bd-or__sides", children: branches.flatMap((child, i) => {
2111
+ const side = (_jsxs("div", { className: "bd-or__side", children: [_jsx("div", { className: "bd-or__sidelabel", children: branchLabel(i) }), _jsx(BdRenderTree, { errors: errors, fields: [child], setValue: setValue, upload: upload, values: values })] }, child.id));
2127
2112
  if (i === 0)
2128
2113
  return [side];
2129
2114
  return [
2130
- _jsx("div", { className: "biab-or__divider", children: "OR" }, `or-${child.id}`),
2115
+ _jsx("div", { className: "bd-or__divider", children: "OR" }, `or-${child.id}`),
2131
2116
  side,
2132
2117
  ];
2133
- }) }), errored && (_jsx("p", { className: "biab-field__error", children: "Fill in at least one side to continue." }))] }, f.id));
2118
+ }) }), errored && (_jsx("p", { className: "bd-field__error", children: "Fill in at least one side to continue." }))] }, f.id));
2134
2119
  }
2135
2120
  if (f.type === "flex_row") {
2136
2121
  const cfg = (f["flexConfig"] ?? {});
2137
- return (_jsx("div", { className: "biab-flexrow", style: {
2122
+ return (_jsx("div", { className: "bd-flexrow", style: {
2138
2123
  display: "flex",
2139
2124
  justifyContent: cfg.justify === "center"
2140
2125
  ? "center"
@@ -2152,18 +2137,18 @@ function BiabRenderTree({ fields, values, errors, setValue, upload, flat, }) {
2152
2137
  : "center",
2153
2138
  gap: `${cfg.gap ?? 12}px`,
2154
2139
  flexWrap: "wrap",
2155
- }, children: (f.children ?? []).map((child) => (_jsx("div", { className: "biab-flexrow__cell", children: _jsx(BiabRenderTree, { errors: errors, fields: [child], setValue: setValue, upload: upload, values: values }) }, child.id))) }, f.id));
2140
+ }, children: (f.children ?? []).map((child) => (_jsx("div", { className: "bd-flexrow__cell", children: _jsx(BdRenderTree, { errors: errors, fields: [child], setValue: setValue, upload: upload, values: values }) }, child.id))) }, f.id));
2156
2141
  }
2157
- return (_jsx(BiabFieldRow, { error: errors[f.id], field: f, setValue: setValue, upload: upload, value: values[f.id] }, f.id));
2142
+ return (_jsx(BdFieldRow, { error: errors[f.id], field: f, setValue: setValue, upload: upload, value: values[f.id] }, f.id));
2158
2143
  }) }));
2159
2144
  }
2160
- export function BiabForm(props) {
2161
- const providerClient = useBiabFormsClient();
2162
- // A publishable token (`pk_…`) builds a browser client that calls BIAB
2145
+ export function BdForm(props) {
2146
+ const providerClient = useBdFormsClient();
2147
+ // A publishable token (`pk_…`) builds a browser client that calls BD
2163
2148
  // directly — the zero-backend path. Explicit `client` still wins, then the
2164
2149
  // token client, then a surrounding provider.
2165
2150
  const tokenClient = useMemo(() => props.token && props.siteId
2166
- ? createBiabClient({
2151
+ ? createBdClient({
2167
2152
  apiKey: props.token,
2168
2153
  siteId: props.siteId,
2169
2154
  baseUrl: props.baseUrl ?? DEFAULT_PACKAGE_BASE_URL,
@@ -2223,9 +2208,10 @@ export function BiabForm(props) {
2223
2208
  // Autofill config provided to the field tree. Keyed by the serialized
2224
2209
  // overrides so a fresh-but-equal `fieldAutoComplete` literal doesn't churn.
2225
2210
  const fieldAutoCompleteKey = JSON.stringify(props.fieldAutoComplete ?? null);
2226
- const autocompleteConfig = useMemo(
2227
- // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by fieldAutoCompleteKey
2228
- () => ({
2211
+ // The directive has to sit immediately above the flagged `useMemo`; inside
2212
+ // the call it attaches to the callback and does nothing.
2213
+ // biome-ignore lint/correctness/useExhaustiveDependencies: keyed by fieldAutoCompleteKey, so a fresh-but-equal literal does not churn
2214
+ const autocompleteConfig = useMemo(() => ({
2229
2215
  ...(props.autoComplete !== undefined
2230
2216
  ? { enabled: props.autoComplete }
2231
2217
  : {}),
@@ -2252,30 +2238,30 @@ export function BiabForm(props) {
2252
2238
  window.addEventListener("beforeunload", onBeforeUnload);
2253
2239
  return () => window.removeEventListener("beforeunload", onBeforeUnload);
2254
2240
  }, [exitConfirm?.enabled, exitConfirm?.message, snap.submitted, exitDirty]);
2255
- const rootClass = cx("biab-form", props.className, props.class);
2241
+ const rootClass = cx("bd-form", props.className, props.class);
2256
2242
  if (snap.status === "loading" || snap.status === "idle") {
2257
- return (_jsx("div", { className: rootClass, style: props.style, children: props.loadingFallback ?? (_jsx("div", { className: "biab-form__loading", children: "Loading\u2026" })) }));
2243
+ return (_jsx("div", { className: rootClass, style: props.style, children: props.loadingFallback ?? (_jsx("div", { className: "bd-form__loading", children: "Loading\u2026" })) }));
2258
2244
  }
2259
2245
  if (snap.status === "error") {
2260
2246
  const message = snap.loadError ?? "Failed to load the form.";
2261
- return (_jsx("div", { className: rootClass, style: props.style, children: props.errorFallback ? (props.errorFallback(message)) : (_jsx("div", { className: "biab-form__error", children: message })) }));
2247
+ return (_jsx("div", { className: rootClass, style: props.style, children: props.errorFallback ? (props.errorFallback(message)) : (_jsx("div", { className: "bd-form__error", children: message })) }));
2262
2248
  }
2263
2249
  if (snap.submitted && snap.result?.ok) {
2264
2250
  const ok = snap.result;
2265
- return (_jsx("div", { className: rootClass, style: props.style, children: props.successFallback ? (props.successFallback(ok)) : (_jsx("div", { className: "biab-form__success", children: "Thanks \u2014 your response was received." })) }));
2251
+ return (_jsx("div", { className: rootClass, style: props.style, children: props.successFallback ? (props.successFallback(ok)) : (_jsx("div", { className: "bd-form__success", children: "Thanks \u2014 your response was received." })) }));
2266
2252
  }
2267
2253
  const { settings } = snap;
2268
2254
  const consecutive = settings.isConsecutive && snap.stepCount > 1;
2269
2255
  const animClass = settings.animation === "fade"
2270
- ? "biab-anim--fade"
2256
+ ? "bd-anim--fade"
2271
2257
  : settings.animation === "scale"
2272
- ? "biab-anim--scale"
2258
+ ? "bd-anim--scale"
2273
2259
  : settings.animation === "slide"
2274
2260
  ? snap.forward
2275
- ? "biab-anim--slide-fwd"
2276
- : "biab-anim--slide-back"
2261
+ ? "bd-anim--slide-fwd"
2262
+ : "bd-anim--slide-back"
2277
2263
  : settings.animation === "scroll"
2278
- ? "biab-anim--scroll"
2264
+ ? "bd-anim--scroll"
2279
2265
  : "";
2280
2266
  const handleSubmit = async () => {
2281
2267
  const res = await controller.submit();
@@ -2303,17 +2289,17 @@ export function BiabForm(props) {
2303
2289
  }, delay);
2304
2290
  }
2305
2291
  };
2306
- return (_jsx(FetchScheduleSlotsContext.Provider, { value: fetchScheduleSlots, children: _jsx(AutocompleteContext.Provider, { value: autocompleteConfig, children: _jsxs("div", { className: rootClass, style: props.style, children: [snap.orgIcon && (_jsx("img", { alt: "", className: "biab-form__orgicon", src: snap.orgIcon })), (snap.title || snap.description) && (_jsxs("div", { className: "biab-form__head", children: [snap.title && _jsx("h2", { className: "biab-form__title", children: snap.title }), snap.description && (_jsx("p", { className: "biab-form__desc", children: snap.description }))] })), consecutive &&
2292
+ return (_jsx(FetchScheduleSlotsContext.Provider, { value: fetchScheduleSlots, children: _jsx(AutocompleteContext.Provider, { value: autocompleteConfig, children: _jsxs("div", { className: rootClass, style: props.style, children: [snap.orgIcon && (_jsx("img", { alt: "", className: "bd-form__orgicon", src: snap.orgIcon })), (snap.title || snap.description) && (_jsxs("div", { className: "bd-form__head", children: [snap.title && _jsx("h2", { className: "bd-form__title", children: snap.title }), snap.description && (_jsx("p", { className: "bd-form__desc", children: snap.description }))] })), consecutive &&
2307
2293
  settings.showProgress &&
2308
- settings.progressStyle !== "bar" && (_jsx("div", { className: "biab-progress biab-progress--steps", children: snap.steps.map((s, i) => {
2294
+ settings.progressStyle !== "bar" && (_jsx("div", { className: "bd-progress bd-progress--steps", children: snap.steps.map((s, i) => {
2309
2295
  const f = s[0];
2310
2296
  const title = f?.stepTitle || f?.label || `Step ${i + 1}`;
2311
2297
  const done = i < snap.step;
2312
2298
  const current = i === snap.step;
2313
- return (_jsxs(Fragment, { children: [i > 0 && (_jsx("span", { className: cx("biab-progress__line", i <= snap.step && "biab-progress__line--done") })), _jsxs("button", { className: cx("biab-progress__step", current && "biab-progress__step--current", done && "biab-progress__step--done"), onClick: () => controller.goToStep(i), type: "button", children: [_jsx("span", { className: "biab-progress__num", children: done ? "✓" : i + 1 }), _jsx("span", { className: "biab-progress__title", children: title })] })] }, `step-${i}`));
2299
+ return (_jsxs(Fragment, { children: [i > 0 && (_jsx("span", { className: cx("bd-progress__line", i <= snap.step && "bd-progress__line--done") })), _jsxs("button", { className: cx("bd-progress__step", current && "bd-progress__step--current", done && "bd-progress__step--done"), onClick: () => controller.goToStep(i), type: "button", children: [_jsx("span", { className: "bd-progress__num", children: done ? "✓" : i + 1 }), _jsx("span", { className: "bd-progress__title", children: title })] })] }, `step-${i}`));
2314
2300
  }) })), consecutive &&
2315
2301
  settings.showProgress &&
2316
- settings.progressStyle === "bar" && (_jsxs("div", { className: "biab-progress biab-progress--bar", children: [_jsxs("span", { className: "biab-progress__count", children: [snap.step + 1, " / ", snap.stepCount] }), _jsx("div", { className: "biab-progress__track", children: _jsx("div", { className: "biab-progress__fill", style: { width: `${snap.progressPercent}%` } }) })] })), snap.errorList.length > 0 && (_jsxs("div", { className: "biab-form__notice", role: "alert", children: [_jsxs("div", { className: "biab-form__notice-title", children: ["Please complete the highlighted field", snap.errorList.length === 1 ? "" : "s", "."] }), _jsx("div", { className: "biab-form__notice-list", children: snap.errorList.map((e) => e.label).join(", ") })] })), _jsx("div", { className: cx("biab-form__body", animClass), children: _jsx(BiabRenderTree, { errors: snap.errors, fields: snap.visibleFields, flat: consecutive, setValue: (id, v) => controller.setValue(id, v), upload: upload, values: snap.values }) }, `biab-step-${snap.step}`), (!consecutive || snap.isLastStep) &&
2302
+ settings.progressStyle === "bar" && (_jsxs("div", { className: "bd-progress bd-progress--bar", children: [_jsxs("span", { className: "bd-progress__count", children: [snap.step + 1, " / ", snap.stepCount] }), _jsx("div", { className: "bd-progress__track", children: _jsx("div", { className: "bd-progress__fill", style: { width: `${snap.progressPercent}%` } }) })] })), snap.errorList.length > 0 && (_jsxs("div", { className: "bd-form__notice", role: "alert", children: [_jsxs("div", { className: "bd-form__notice-title", children: ["Please complete the highlighted field", snap.errorList.length === 1 ? "" : "s", "."] }), _jsx("div", { className: "bd-form__notice-list", children: snap.errorList.map((e) => e.label).join(", ") })] })), _jsx("div", { className: cx("bd-form__body", animClass), children: _jsx(BdRenderTree, { errors: snap.errors, fields: snap.visibleFields, flat: consecutive, setValue: (id, v) => controller.setValue(id, v), upload: upload, values: snap.values }) }, `bd-step-${snap.step}`), (!consecutive || snap.isLastStep) &&
2317
2303
  (snap.schema?.actions ?? [])
2318
2304
  .filter((a) => a.type === "grant_coupon" &&
2319
2305
  (a.coupon?.notice || a.coupon?.code))
@@ -2322,8 +2308,8 @@ export function BiabForm(props) {
2322
2308
  const text = a.coupon?.notice
2323
2309
  ? a.coupon.notice.replace(/\{code\}/g, code)
2324
2310
  : `Coupon ${code} will be applied to this submission.`;
2325
- return (_jsxs("div", { className: "biab-coupon-notice", children: [_jsx("p", { className: "biab-coupon-notice__text", children: text }), a.coupon?.finePrint && (_jsx("p", { className: "biab-coupon-notice__fine", children: a.coupon.finePrint }))] }, `coupon-${i}`));
2326
- }), consecutive ? (_jsxs("div", { className: "biab-nav", children: [_jsx("button", { className: "biab-btn biab-btn--back biab-btn--ghost", disabled: snap.isFirstStep, onClick: () => controller.back(), type: "button", children: "Back" }), !snap.isLastStep ? (_jsx("button", { className: "biab-btn biab-btn--next", disabled: !snap.canAdvance, onClick: () => controller.next(), type: "button", children: "Next" })) : (_jsx("button", { className: "biab-btn biab-btn--submit", disabled: snap.submitting || snap.uploading, onClick: () => void handleSubmit(), type: "button", children: snap.submitting ? "Sending…" : submitLabel }))] })) : (_jsx("div", { className: "biab-nav", children: _jsx("button", { className: "biab-btn biab-btn--submit", disabled: snap.submitting || snap.uploading, onClick: () => void handleSubmit(), type: "button", children: snap.submitting ? "Sending…" : submitLabel }) })), snap.result && !snap.result.ok && snap.errorList.length === 0 && (_jsx("div", { className: "biab-form__error", role: "alert", children: snap.result.message }))] }) }) }));
2311
+ return (_jsxs("div", { className: "bd-coupon-notice", children: [_jsx("p", { className: "bd-coupon-notice__text", children: text }), a.coupon?.finePrint && (_jsx("p", { className: "bd-coupon-notice__fine", children: a.coupon.finePrint }))] }, `coupon-${i}`));
2312
+ }), consecutive ? (_jsxs("div", { className: "bd-nav", children: [_jsx("button", { className: "bd-btn bd-btn--back bd-btn--ghost", disabled: snap.isFirstStep, onClick: () => controller.back(), type: "button", children: "Back" }), !snap.isLastStep ? (_jsx("button", { className: "bd-btn bd-btn--next", disabled: !snap.canAdvance, onClick: () => controller.next(), type: "button", children: "Next" })) : (_jsx("button", { className: "bd-btn bd-btn--submit", disabled: snap.submitting || snap.uploading, onClick: () => void handleSubmit(), type: "button", children: snap.submitting ? "Sending…" : submitLabel }))] })) : (_jsx("div", { className: "bd-nav", children: _jsx("button", { className: "bd-btn bd-btn--submit", disabled: snap.submitting || snap.uploading, onClick: () => void handleSubmit(), type: "button", children: snap.submitting ? "Sending…" : submitLabel }) })), snap.result && !snap.result.ok && snap.errorList.length === 0 && (_jsx("div", { className: "bd-form__error", role: "alert", children: snap.result.message }))] }) }) }));
2327
2313
  }
2328
2314
  function SocialGlyph({ iconUrl, size, className, label, }) {
2329
2315
  if (iconUrl) {
@@ -2335,7 +2321,7 @@ function SocialGlyph({ iconUrl, size, className, label, }) {
2335
2321
  }
2336
2322
  /**
2337
2323
  * Render every social profile on the company as an icon + link, in canonical
2338
- * order, resolving BIAB's exact keys (`meta`, `twitterX`, …) for you. Branded
2324
+ * order, resolving BD's exact keys (`meta`, `twitterX`, …) for you. Branded
2339
2325
  * glyphs come from the simple-icons CDN; platforms without one fall back to a
2340
2326
  * globe. Returns `null` when no socials are set.
2341
2327
  */
@@ -2360,7 +2346,7 @@ export function SocialLinks({ socials, color, size = 20, className, linkClassNam
2360
2346
  export function useBlog(options) {
2361
2347
  const { apiKey, baseUrl, pageSize, categoryId } = options;
2362
2348
  const controller = useMemo(() => createBlogController({
2363
- client: new BiabDevClient({ apiKey, baseUrl }),
2349
+ client: new BdApiClient({ apiKey, baseUrl }),
2364
2350
  ...(pageSize ? { pageSize } : {}),
2365
2351
  ...(categoryId ? { categoryId } : {}),
2366
2352
  }), [apiKey, baseUrl, pageSize, categoryId]);
@@ -2392,7 +2378,7 @@ export function useBlog(options) {
2392
2378
  export function useVerify(options) {
2393
2379
  const { apiKey, baseUrl, kind, resendCooldownSeconds } = options;
2394
2380
  const controller = useMemo(() => createVerifyController({
2395
- client: new BiabDevClient({ apiKey, baseUrl }),
2381
+ client: new BdApiClient({ apiKey, baseUrl }),
2396
2382
  kind,
2397
2383
  ...(resendCooldownSeconds ? { resendCooldownSeconds } : {}),
2398
2384
  }), [apiKey, baseUrl, kind, resendCooldownSeconds]);
@@ -2427,7 +2413,7 @@ export function useVerify(options) {
2427
2413
  export function usePortal(options) {
2428
2414
  const { apiKey, baseUrl, sessionToken } = options;
2429
2415
  const controller = useMemo(() => createPortalController({
2430
- client: new BiabDevClient({ apiKey, baseUrl }),
2416
+ client: new BdApiClient({ apiKey, baseUrl }),
2431
2417
  sessionToken,
2432
2418
  }), [apiKey, baseUrl, sessionToken]);
2433
2419
  useEffect(() => {