@base316/react 0.5.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -325,6 +325,23 @@ var STYLESHEET_EXTRA = `
325
325
  border-bottom: 2px solid transparent; margin-bottom: -1px;
326
326
  }
327
327
  .b316-tab-on { color: var(--b316-color-text); border-bottom-color: var(--b316-color-primary); }
328
+ .b316-social { display: flex; flex-direction: column; gap: 8px; }
329
+ .b316-social-button {
330
+ display: flex; align-items: center; justify-content: center; gap: 10px;
331
+ width: 100%; min-height: 40px; padding: 9px 14px;
332
+ border: 1px solid; border-radius: calc(var(--b316-radius) / 1.6);
333
+ font: inherit; font-weight: 500; cursor: pointer;
334
+ }
335
+ .b316-social-button:hover:not([disabled]) { filter: brightness(.96); }
336
+ .b316-social-button:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }
337
+ .b316-social-button[disabled] { opacity: .55; cursor: not-allowed; }
338
+ .b316-social-icon { display: inline-flex; width: 18px; height: 18px; flex: none; }
339
+ .b316-social-icon svg { width: 18px; height: 18px; }
340
+ .b316-divider {
341
+ display: flex; align-items: center; gap: 10px; margin: 14px 0;
342
+ color: var(--b316-color-muted); font-size: .87em;
343
+ }
344
+ .b316-divider::before, .b316-divider::after { content: ""; flex: 1; border-top: 1px solid var(--b316-color-border); }
328
345
  .b316-branding { display: flex; flex-direction: column; gap: 4px; }
329
346
  .b316-branding-logo { max-height: 40px; width: auto; align-self: flex-start; }
330
347
  .b316-branding-name { font-size: 1.5em; font-weight: 650; letter-spacing: -.01em; }
@@ -642,12 +659,13 @@ function Base316Provider({
642
659
  onTokenChange,
643
660
  appearance: appearance2,
644
661
  tenant,
662
+ organizationId,
645
663
  className,
646
664
  children
647
665
  }) {
648
666
  const client = useMemo(
649
- () => new Base316Browser({ publishableKey, baseUrl }),
650
- [publishableKey, baseUrl]
667
+ () => new Base316Browser({ publishableKey, baseUrl, organizationId: organizationId ?? void 0 }),
668
+ [publishableKey, baseUrl, organizationId]
651
669
  );
652
670
  useEffect(() => {
653
671
  if (document.getElementById(STYLE_ELEMENT_ID)) {
@@ -1606,7 +1624,7 @@ import {
1606
1624
  isPasskeySupported,
1607
1625
  needsSecondFactor
1608
1626
  } from "@base316/sdk";
1609
- import { useEffect as useEffect7, useRef as useRef2, useState as useState7 } from "react";
1627
+ import { useEffect as useEffect8, useRef as useRef2, useState as useState8 } from "react";
1610
1628
 
1611
1629
  // src/SecondFactorStep.tsx
1612
1630
  import {
@@ -1997,33 +2015,233 @@ function SecondFactorStep({
1997
2015
  return /* @__PURE__ */ jsx7("div", { className: cls("b316-mfa", className), style, children: body });
1998
2016
  }
1999
2017
 
2018
+ // src/sign-in-methods.ts
2019
+ import {
2020
+ OAUTH_STATE_COOKIE,
2021
+ createOAuthState
2022
+ } from "@base316/sdk";
2023
+ import { useEffect as useEffect7, useState as useState7 } from "react";
2024
+ var cache = /* @__PURE__ */ new WeakMap();
2025
+ function loadSignInMethods(client) {
2026
+ let pending = cache.get(client);
2027
+ if (!pending) {
2028
+ pending = client.auth.methods();
2029
+ cache.set(client, pending);
2030
+ pending.catch(() => cache.delete(client));
2031
+ }
2032
+ return pending;
2033
+ }
2034
+ function useSignInMethods(client) {
2035
+ const [state, setState] = useState7({ status: "loading", methods: null });
2036
+ useEffect7(() => {
2037
+ let cancelled = false;
2038
+ loadSignInMethods(client).then((methods) => {
2039
+ if (!cancelled) setState({ status: "ready", methods });
2040
+ }).catch(() => {
2041
+ if (!cancelled) setState({ status: "unavailable", methods: null });
2042
+ });
2043
+ return () => {
2044
+ cancelled = true;
2045
+ };
2046
+ }, [client]);
2047
+ return state;
2048
+ }
2049
+ function resolveMethods(methods, props, currentPage) {
2050
+ if (!methods) {
2051
+ return {
2052
+ password: props.password !== false,
2053
+ passkeys: props.passkeys !== false,
2054
+ magicLink: props.magicLink !== false ? props.magicLinkRedirectUrl ?? null : null,
2055
+ phone: props.phone === true,
2056
+ social: [],
2057
+ sso: false,
2058
+ signUp: true,
2059
+ hostedUrl: void 0
2060
+ };
2061
+ }
2062
+ const redirect = props.socialRedirectUrl;
2063
+ const only = Array.isArray(props.social) ? new Set(props.social.map((entry) => entry.toLowerCase())) : null;
2064
+ return {
2065
+ password: methods.password && props.password !== false,
2066
+ passkeys: methods.passkeys && props.passkeys !== false,
2067
+ magicLink: methods.magicLink && props.magicLink !== false ? props.magicLinkRedirectUrl ?? currentPage : null,
2068
+ phone: methods.phone && props.phone !== false,
2069
+ social: redirect && props.social !== false ? methods.social.filter(
2070
+ (option) => !only || only.has(option.slug.toLowerCase()) || only.has(option.provider.toLowerCase())
2071
+ ) : [],
2072
+ sso: Boolean(redirect) && methods.sso && props.sso !== false,
2073
+ signUp: methods.signUp,
2074
+ hostedUrl: methods.hostedUrl
2075
+ };
2076
+ }
2077
+ function beginRedirect(build, appState) {
2078
+ const { state, nonce } = createOAuthState(appState);
2079
+ const secure = window.location.protocol === "https:" ? "; Secure" : "";
2080
+ document.cookie = `${OAUTH_STATE_COOKIE}=${nonce}; Path=/; Max-Age=600; SameSite=Lax${secure}`;
2081
+ window.location.assign(build(state));
2082
+ }
2083
+ function currentPageUrl() {
2084
+ if (typeof window === "undefined") {
2085
+ return null;
2086
+ }
2087
+ return `${window.location.origin}${window.location.pathname}`;
2088
+ }
2089
+
2090
+ // src/social-icons.ts
2091
+ var PROVIDER_ICON = {
2092
+ GOOGLE: `<svg viewBox="0 0 18 18" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62Z"/><path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18Z"/><path fill="#FBBC05" d="M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33Z"/><path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58C13.46.9 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58Z"/></svg>`,
2093
+ FACEBOOK: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M24 12.07C24 5.4 18.63 0 12 0S0 5.4 0 12.07C0 18.1 4.39 23.1 10.13 24v-8.44H7.08v-3.49h3.05V9.41c0-3.02 1.79-4.69 4.53-4.69 1.31 0 2.68.24 2.68.24v2.96h-1.51c-1.49 0-1.96.93-1.96 1.89v2.26h3.33l-.53 3.49h-2.8V24C19.61 23.1 24 18.1 24 12.07Z"/></svg>`,
2094
+ APPLE: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.05 12.54c-.03-2.74 2.24-4.06 2.34-4.12-1.28-1.86-3.26-2.12-3.96-2.15-1.69-.17-3.29 1-4.14 1-.85 0-2.17-.98-3.57-.95-1.83.03-3.53 1.07-4.47 2.71-1.91 3.31-.49 8.2 1.37 10.88.91 1.31 1.99 2.78 3.42 2.73 1.37-.06 1.89-.89 3.55-.89 1.66 0 2.13.89 3.58.86 1.48-.03 2.41-1.34 3.31-2.65 1.04-1.52 1.47-2.99 1.5-3.07-.03-.01-2.88-1.1-2.91-4.37ZM14.3 4.44c.75-.92 1.26-2.19 1.12-3.44-1.08.04-2.4.72-3.18 1.63-.7.81-1.31 2.11-1.15 3.35 1.21.09 2.45-.61 3.21-1.54Z"/></svg>`,
2095
+ MICROSOFT: `<svg viewBox="0 0 23 23" aria-hidden="true"><path fill="#f25022" d="M1 1h10v10H1z"/><path fill="#7fba00" d="M12 1h10v10H12z"/><path fill="#00a4ef" d="M1 12h10v10H1z"/><path fill="#ffb900" d="M12 12h10v10H12z"/></svg>`,
2096
+ GITHUB: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M12 .3a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2c-3.3.7-4-1.6-4-1.6-.6-1.4-1.4-1.8-1.4-1.8-1-.7.1-.7.1-.7 1.2.1 1.8 1.2 1.8 1.2 1 1.8 2.8 1.3 3.5 1 0-.8.4-1.3.7-1.6-2.7-.3-5.5-1.3-5.5-5.9 0-1.3.5-2.4 1.2-3.2 0-.4-.5-1.6.2-3.2 0 0 1-.3 3.3 1.2a11.5 11.5 0 0 1 6 0C17.4 4.6 18.4 5 18.4 5c.7 1.6.2 2.8.1 3.2.8.8 1.2 1.9 1.2 3.2 0 4.6-2.8 5.6-5.5 5.9.5.4.9 1.1.9 2.2v3.3c0 .3.2.7.8.6A12 12 0 0 0 12 .3Z"/></svg>`,
2097
+ GITLAB: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#e24329" d="m12 22.5-3.7-11.3h7.4L12 22.5Z"/><path fill="#fc6d26" d="M12 22.5 8.3 11.2H3.1L12 22.5Z"/><path fill="#fca326" d="M3.1 11.2 2 14.7a.8.8 0 0 0 .3.8l9.7 7-8.9-11.3Z"/><path fill="#e24329" d="M3.1 11.2h5.2L6.1 4.3a.4.4 0 0 0-.8 0l-2.2 6.9Z"/><path fill="#fc6d26" d="M12 22.5l3.7-11.3h5.2L12 22.5Z"/><path fill="#fca326" d="m20.9 11.2 1.1 3.5a.8.8 0 0 1-.3.8l-9.7 7 8.9-11.3Z"/><path fill="#e24329" d="M20.9 11.2h-5.2l2.2-6.9a.4.4 0 0 1 .8 0l2.2 6.9Z"/></svg>`,
2098
+ LINKEDIN: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M20.45 20.45h-3.56v-5.57c0-1.33-.02-3.04-1.85-3.04-1.85 0-2.14 1.45-2.14 2.94v5.67H9.35V9h3.41v1.56h.05a3.74 3.74 0 0 1 3.37-1.85c3.6 0 4.27 2.37 4.27 5.46v6.28ZM5.34 7.43a2.07 2.07 0 1 1 0-4.13 2.07 2.07 0 0 1 0 4.13Zm1.78 13.02H3.55V9h3.57v11.45ZM22.22 0H1.77C.79 0 0 .77 0 1.72v20.56C0 23.23.79 24 1.77 24h20.45c.98 0 1.78-.77 1.78-1.72V1.72C24 .77 23.2 0 22.22 0Z"/></svg>`,
2099
+ // The four below are the Simple Icons marks (CC0), https://simpleicons.org.
2100
+ DISCORD: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/></svg>`,
2101
+ TWITTER: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"/></svg>`,
2102
+ TWITCH: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/></svg>`,
2103
+ ROBLOX: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M18.926 23.998 0 18.892 5.075.002 24 5.108ZM15.348 10.09l-5.282-1.453-1.414 5.273 5.282 1.453z"/></svg>`,
2104
+ SLACK: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#e01e5a" d="M5.04 15.17a2.53 2.53 0 1 1-2.52-2.53h2.52v2.53Zm1.27 0a2.53 2.53 0 1 1 5.05 0v6.31a2.53 2.53 0 1 1-5.05 0v-6.31Z"/><path fill="#36c5f0" d="M8.83 5.04a2.53 2.53 0 1 1 2.53-2.52v2.52H8.83Zm0 1.28a2.53 2.53 0 1 1 0 5.05H2.52a2.53 2.53 0 1 1 0-5.05h6.31Z"/><path fill="#2eb67d" d="M18.96 8.83a2.53 2.53 0 1 1 2.52 2.53h-2.52V8.83Zm-1.27 0a2.53 2.53 0 1 1-5.05 0V2.52a2.53 2.53 0 1 1 5.05 0v6.31Z"/><path fill="#ecb22e" d="M15.17 18.96a2.53 2.53 0 1 1-2.53 2.52v-2.52h2.53Zm0-1.27a2.53 2.53 0 1 1 0-5.05h6.31a2.53 2.53 0 1 1 0 5.05h-6.31Z"/></svg>`
2105
+ };
2106
+
2107
+ // src/SocialButtons.tsx
2108
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2109
+ function SocialButtons({
2110
+ options,
2111
+ continueWith,
2112
+ disabled,
2113
+ onChoose
2114
+ }) {
2115
+ if (options.length === 0) {
2116
+ return null;
2117
+ }
2118
+ return /* @__PURE__ */ jsx8("div", { className: "b316-social", children: options.map((option) => {
2119
+ const icon = PROVIDER_ICON[option.provider];
2120
+ const light = /^#f{3}(f{3})?$/i.test(option.buttonColor);
2121
+ return /* @__PURE__ */ jsxs7(
2122
+ "button",
2123
+ {
2124
+ type: "button",
2125
+ className: "b316-social-button",
2126
+ "data-provider": option.slug,
2127
+ disabled,
2128
+ style: {
2129
+ background: option.buttonColor,
2130
+ color: option.buttonTextColor,
2131
+ borderColor: light ? "#747775" : option.buttonColor
2132
+ },
2133
+ onClick: () => onChoose(option),
2134
+ children: [
2135
+ icon ? /* @__PURE__ */ jsx8(
2136
+ "span",
2137
+ {
2138
+ className: "b316-social-icon",
2139
+ "aria-hidden": "true",
2140
+ dangerouslySetInnerHTML: { __html: icon }
2141
+ }
2142
+ ) : null,
2143
+ /* @__PURE__ */ jsx8("span", { children: continueWith(option.name, option.provider) })
2144
+ ]
2145
+ },
2146
+ option.slug
2147
+ );
2148
+ }) });
2149
+ }
2150
+
2000
2151
  // src/SignIn.tsx
2001
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2152
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2153
+ var DEFAULT_SIGN_IN_LABELS = {
2154
+ email: "Email",
2155
+ password: "Password",
2156
+ mobileNumber: "Mobile number",
2157
+ code: "Code",
2158
+ tabPassword: "Password",
2159
+ tabMagicLink: "Magic link",
2160
+ tabPhone: "Text message",
2161
+ submit: "Sign in",
2162
+ working: "Working\u2026",
2163
+ emailMeALink: "Email me a link",
2164
+ textMeACode: "Text me a code",
2165
+ includeCountryCode: "Include the country code.",
2166
+ codeSent: (destination) => `We sent a code to ${destination}. It expires in ten minutes.`,
2167
+ useDifferentNumber: "Use a different number",
2168
+ or: "or",
2169
+ passkey: "Sign in with a passkey",
2170
+ continueWith: (name) => `Continue with ${name}`,
2171
+ sso: "Sign in with SSO",
2172
+ ssoEmail: "Work email",
2173
+ ssoContinue: "Continue",
2174
+ back: "Back",
2175
+ checkEmailTitle: "Check your email",
2176
+ checkEmail: (email) => `If an account exists for ${email}, a sign-in link is on its way. It expires shortly and can be used once.`,
2177
+ backToSignIn: "Back to sign in",
2178
+ wrongPassword: "That email and password did not match.",
2179
+ passkeyFailed: "That passkey did not work.",
2180
+ linkInvalid: "That sign-in link is no longer valid. Ask for a new one.",
2181
+ linkFailed: "We could not send that link. Try again.",
2182
+ wrongCode: "That code did not work. Check it, or ask for a new one.",
2183
+ codeFailed: "We could not send a code. Try again.",
2184
+ noMethods: "Signing in is not available right now."
2185
+ };
2002
2186
  function SignIn({
2003
2187
  onSignedIn,
2004
- passkeys = true,
2188
+ password: passwordProp,
2189
+ passkeys: passkeysProp,
2190
+ magicLink: magicLinkProp,
2005
2191
  magicLinkRedirectUrl,
2006
- phone = false,
2192
+ phone: phoneProp,
2193
+ social: socialProp,
2194
+ sso: ssoProp,
2195
+ socialRedirectUrl,
2196
+ socialState,
2197
+ labels: overrides,
2007
2198
  secondFactorLabels,
2008
2199
  className,
2009
2200
  style
2010
2201
  }) {
2202
+ const labels = { ...DEFAULT_SIGN_IN_LABELS, ...overrides };
2011
2203
  const { client, setToken } = useBase316();
2012
- const [email, setEmail] = useState7("");
2013
- const [password, setPassword] = useState7("");
2014
- const [code, setCode] = useState7("");
2015
- const [pending, setPending] = useState7(null);
2204
+ const loaded = useSignInMethods(client);
2205
+ const [currentPage, setCurrentPage] = useState8(null);
2206
+ const [email, setEmail] = useState8("");
2207
+ const [password, setPassword] = useState8("");
2208
+ const [code, setCode] = useState8("");
2209
+ const [pending, setPending] = useState8(null);
2016
2210
  const pendingChallenge = pending?.challengeToken ?? null;
2017
- const [phoneNumber, setPhoneNumber] = useState7("");
2018
- const [phoneChallenge, setPhoneChallenge] = useState7(
2211
+ const [phoneNumber, setPhoneNumber] = useState8("");
2212
+ const [phoneChallenge, setPhoneChallenge] = useState8(
2019
2213
  null
2020
2214
  );
2021
- const [error, setError] = useState7(null);
2022
- const [busy, setBusy] = useState7(false);
2023
- const [passkeyReady, setPasskeyReady] = useState7(false);
2024
- const [mode, setMode] = useState7("password");
2025
- const [linkSent, setLinkSent] = useState7(false);
2215
+ const [error, setError] = useState8(null);
2216
+ const [busy, setBusy] = useState8(false);
2217
+ const [passkeyReady, setPasskeyReady] = useState8(false);
2218
+ const [chosenMode, setMode] = useState8(null);
2219
+ const [linkSent, setLinkSent] = useState8(false);
2026
2220
  const abortRef = useRef2(null);
2221
+ useEffect8(() => {
2222
+ setCurrentPage(currentPageUrl());
2223
+ }, []);
2224
+ const offered = resolveMethods(
2225
+ loaded.methods,
2226
+ {
2227
+ password: passwordProp,
2228
+ passkeys: passkeysProp,
2229
+ magicLink: magicLinkProp,
2230
+ magicLinkRedirectUrl,
2231
+ phone: phoneProp,
2232
+ social: socialProp,
2233
+ sso: ssoProp,
2234
+ socialRedirectUrl
2235
+ },
2236
+ currentPage
2237
+ );
2238
+ const tabs = [
2239
+ ...offered.password ? ["password"] : [],
2240
+ ...offered.magicLink ? ["magic"] : [],
2241
+ ...offered.phone ? ["phone"] : []
2242
+ ];
2243
+ const mode = chosenMode && (chosenMode === "sso" ? offered.sso : tabs.includes(chosenMode)) ? chosenMode : tabs[0] ?? null;
2244
+ const passkeysWanted = loaded.status !== "loading" && offered.passkeys;
2027
2245
  const signInWithPasskey = async (conditional, signal) => {
2028
2246
  if (!conditional) {
2029
2247
  setBusy(true);
@@ -2041,7 +2259,7 @@ function SignIn({
2041
2259
  setError(cause.message);
2042
2260
  } else if (!conditional) {
2043
2261
  console.error("[base316] passkey sign-in failed", cause);
2044
- setError("That passkey did not work.");
2262
+ setError(labels.passkeyFailed);
2045
2263
  }
2046
2264
  } finally {
2047
2265
  if (!conditional) {
@@ -2049,8 +2267,9 @@ function SignIn({
2049
2267
  }
2050
2268
  }
2051
2269
  };
2052
- useEffect7(() => {
2053
- if (!passkeys || !isPasskeySupported() || pendingChallenge) {
2270
+ useEffect8(() => {
2271
+ if (!passkeysWanted || !isPasskeySupported() || pendingChallenge) {
2272
+ setPasskeyReady(false);
2054
2273
  return;
2055
2274
  }
2056
2275
  setPasskeyReady(true);
@@ -2064,8 +2283,8 @@ function SignIn({
2064
2283
  return () => {
2065
2284
  controller.abort();
2066
2285
  };
2067
- }, [passkeys, pendingChallenge]);
2068
- useEffect7(() => {
2286
+ }, [passkeysWanted, pendingChallenge]);
2287
+ useEffect8(() => {
2069
2288
  if (typeof window === "undefined") {
2070
2289
  return;
2071
2290
  }
@@ -2089,7 +2308,7 @@ function SignIn({
2089
2308
  onSignedIn?.();
2090
2309
  }).catch(() => {
2091
2310
  if (!cancelled) {
2092
- setError("That sign-in link is no longer valid. Ask for a new one.");
2311
+ setError(labels.linkInvalid);
2093
2312
  }
2094
2313
  });
2095
2314
  return () => {
@@ -2097,23 +2316,44 @@ function SignIn({
2097
2316
  };
2098
2317
  }, []);
2099
2318
  async function sendLink() {
2100
- if (!magicLinkRedirectUrl) {
2319
+ if (!offered.magicLink) {
2101
2320
  return;
2102
2321
  }
2103
2322
  setBusy(true);
2104
2323
  setError(null);
2105
2324
  try {
2106
- await client.auth.magicLink.request({ email, redirectUrl: magicLinkRedirectUrl });
2325
+ await client.auth.magicLink.request({ email, redirectUrl: offered.magicLink });
2107
2326
  setLinkSent(true);
2108
2327
  } catch (cause) {
2109
2328
  console.error("[base316] magic link request failed", cause);
2110
- setError("We could not send that link. Try again.");
2329
+ setError(
2330
+ cause instanceof Base316Error2 && cause.code === "INVALID_REQUEST" && cause.message ? cause.message : labels.linkFailed
2331
+ );
2111
2332
  } finally {
2112
2333
  setBusy(false);
2113
2334
  }
2114
2335
  }
2336
+ function leaveForSso() {
2337
+ if (!socialRedirectUrl) {
2338
+ return;
2339
+ }
2340
+ setBusy(true);
2341
+ beginRedirect(
2342
+ (state) => client.ssoSignInUrl({
2343
+ email,
2344
+ redirectUri: socialRedirectUrl,
2345
+ state,
2346
+ hostedUrl: offered.hostedUrl
2347
+ }),
2348
+ socialState
2349
+ );
2350
+ }
2115
2351
  async function submit(event) {
2116
2352
  event.preventDefault();
2353
+ if (mode === "sso") {
2354
+ leaveForSso();
2355
+ return;
2356
+ }
2117
2357
  setBusy(true);
2118
2358
  setError(null);
2119
2359
  try {
@@ -2150,25 +2390,23 @@ function SignIn({
2150
2390
  } catch (cause) {
2151
2391
  console.error("[base316] sign-in failed", cause);
2152
2392
  setError(
2153
- mode === "phone" ? phoneChallenge ? "That code did not work. Check it, or ask for a new one." : (
2393
+ mode === "phone" ? phoneChallenge ? labels.wrongCode : (
2154
2394
  // Why a text could not be sent is worth saying — a number in the
2155
2395
  // wrong format, or too many requests — and the server words it
2156
2396
  // without saying anything about accounts.
2157
- cause instanceof Error && cause.message ? cause.message : "We could not send a code. Try again."
2397
+ cause instanceof Error && cause.message ? cause.message : labels.codeFailed
2158
2398
  ) : (
2159
2399
  // An unconfirmed address and a throttle are worth naming; the
2160
2400
  // server words both without saying whether an account exists.
2161
- cause instanceof Base316Error2 && (cause.reason === "EMAIL_NOT_VERIFIED" || cause.code === "RATE_LIMITED") ? cause.message : "That email and password did not match."
2401
+ cause instanceof Base316Error2 && (cause.reason === "EMAIL_NOT_VERIFIED" || cause.code === "RATE_LIMITED") ? cause.message : labels.wrongPassword
2162
2402
  )
2163
2403
  );
2164
2404
  } finally {
2165
2405
  setBusy(false);
2166
2406
  }
2167
2407
  }
2168
- const magicAvailable = Boolean(magicLinkRedirectUrl) && !pendingChallenge;
2169
- const tabsShown = (magicAvailable || phone) && !pendingChallenge;
2170
2408
  if (pending) {
2171
- return /* @__PURE__ */ jsx8("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx8(
2409
+ return /* @__PURE__ */ jsx9("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx9(
2172
2410
  SecondFactorStep,
2173
2411
  {
2174
2412
  pending,
@@ -2184,59 +2422,68 @@ function SignIn({
2184
2422
  ) });
2185
2423
  }
2186
2424
  if (linkSent) {
2187
- return /* @__PURE__ */ jsxs7("div", { className: cls("b316-card", className), style, children: [
2188
- /* @__PURE__ */ jsx8("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "Check your email" }),
2189
- /* @__PURE__ */ jsxs7("div", { className: "b316-muted", children: [
2190
- "If an account exists for ",
2191
- email,
2192
- ", a sign-in link is on its way. It expires shortly and can be used once."
2193
- ] }),
2194
- /* @__PURE__ */ jsx8(
2425
+ return /* @__PURE__ */ jsxs8("div", { className: cls("b316-card", className), style, children: [
2426
+ /* @__PURE__ */ jsx9("div", { style: { fontWeight: 600, marginBottom: 6 }, children: labels.checkEmailTitle }),
2427
+ /* @__PURE__ */ jsx9("div", { className: "b316-muted", children: labels.checkEmail(email) }),
2428
+ /* @__PURE__ */ jsx9(
2195
2429
  "button",
2196
2430
  {
2197
2431
  type: "button",
2198
2432
  className: "b316-button b316-button-secondary",
2199
2433
  style: { marginTop: 16 },
2200
2434
  onClick: () => setLinkSent(false),
2201
- children: "Back to sign in"
2435
+ children: labels.backToSignIn
2202
2436
  }
2203
2437
  )
2204
2438
  ] });
2205
2439
  }
2206
- return /* @__PURE__ */ jsxs7("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2207
- error ? /* @__PURE__ */ jsx8("div", { className: "b316-error", role: "alert", children: error }) : null,
2208
- tabsShown ? /* @__PURE__ */ jsxs7("div", { className: "b316-tabs", children: [
2209
- /* @__PURE__ */ jsx8(
2210
- "button",
2440
+ const hasForm = mode !== null;
2441
+ const hasButtons = offered.social.length > 0 || passkeyReady || offered.sso && mode !== "sso";
2442
+ if (!hasForm && !hasButtons) {
2443
+ return /* @__PURE__ */ jsx9("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx9("div", { className: "b316-error", role: "alert", children: error ?? labels.noMethods }) });
2444
+ }
2445
+ const tabsShown = tabs.length > 1 && mode !== "sso";
2446
+ return /* @__PURE__ */ jsxs8("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2447
+ error ? /* @__PURE__ */ jsx9("div", { className: "b316-error", role: "alert", children: error }) : null,
2448
+ offered.social.length > 0 && mode !== "sso" ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
2449
+ /* @__PURE__ */ jsx9(
2450
+ SocialButtons,
2211
2451
  {
2212
- type: "button",
2213
- className: cls("b316-tab", mode === "password" ? "b316-tab-on" : void 0),
2214
- onClick: () => setMode("password"),
2215
- children: "Password"
2452
+ options: offered.social,
2453
+ continueWith: labels.continueWith,
2454
+ disabled: busy,
2455
+ onChoose: (option) => {
2456
+ if (!socialRedirectUrl) {
2457
+ return;
2458
+ }
2459
+ setBusy(true);
2460
+ beginRedirect(
2461
+ (state) => client.socialSignInUrl({
2462
+ provider: option.slug,
2463
+ redirectUri: socialRedirectUrl,
2464
+ state,
2465
+ hostedUrl: offered.hostedUrl
2466
+ }),
2467
+ socialState
2468
+ );
2469
+ }
2216
2470
  }
2217
2471
  ),
2218
- magicAvailable ? /* @__PURE__ */ jsx8(
2219
- "button",
2220
- {
2221
- type: "button",
2222
- className: cls("b316-tab", mode === "magic" ? "b316-tab-on" : void 0),
2223
- onClick: () => setMode("magic"),
2224
- children: "Magic link"
2225
- }
2226
- ) : null,
2227
- phone ? /* @__PURE__ */ jsx8(
2228
- "button",
2229
- {
2230
- type: "button",
2231
- className: cls("b316-tab", mode === "phone" ? "b316-tab-on" : void 0),
2232
- onClick: () => setMode("phone"),
2233
- children: "Text message"
2234
- }
2235
- ) : null
2472
+ hasForm ? /* @__PURE__ */ jsx9("div", { className: "b316-divider", children: labels.or }) : null
2236
2473
  ] }) : null,
2237
- mode === "phone" ? phoneChallenge ? /* @__PURE__ */ jsxs7("div", { className: "b316-field", children: [
2238
- /* @__PURE__ */ jsx8("label", { className: "b316-label", htmlFor: "b316-phone-code", children: "Code" }),
2239
- /* @__PURE__ */ jsx8(
2474
+ tabsShown ? /* @__PURE__ */ jsx9("div", { className: "b316-tabs", children: tabs.map((tab) => /* @__PURE__ */ jsx9(
2475
+ "button",
2476
+ {
2477
+ type: "button",
2478
+ className: cls("b316-tab", mode === tab ? "b316-tab-on" : void 0),
2479
+ onClick: () => setMode(tab),
2480
+ children: tab === "password" ? labels.tabPassword : tab === "magic" ? labels.tabMagicLink : labels.tabPhone
2481
+ },
2482
+ tab
2483
+ )) }) : null,
2484
+ mode === "phone" ? phoneChallenge ? /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2485
+ /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-phone-code", children: labels.code }),
2486
+ /* @__PURE__ */ jsx9(
2240
2487
  "input",
2241
2488
  {
2242
2489
  id: "b316-phone-code",
@@ -2248,12 +2495,10 @@ function SignIn({
2248
2495
  required: true
2249
2496
  }
2250
2497
  ),
2251
- /* @__PURE__ */ jsxs7("span", { className: "b316-muted", children: [
2252
- "We sent a code to ",
2253
- phoneChallenge.hint,
2254
- ". It expires in ten minutes.",
2498
+ /* @__PURE__ */ jsxs8("span", { className: "b316-muted", children: [
2499
+ labels.codeSent(phoneChallenge.hint),
2255
2500
  " ",
2256
- /* @__PURE__ */ jsx8(
2501
+ /* @__PURE__ */ jsx9(
2257
2502
  "button",
2258
2503
  {
2259
2504
  type: "button",
@@ -2262,13 +2507,13 @@ function SignIn({
2262
2507
  setPhoneChallenge(null);
2263
2508
  setCode("");
2264
2509
  },
2265
- children: "Use a different number"
2510
+ children: labels.useDifferentNumber
2266
2511
  }
2267
2512
  )
2268
2513
  ] })
2269
- ] }) : /* @__PURE__ */ jsxs7("div", { className: "b316-field", children: [
2270
- /* @__PURE__ */ jsx8("label", { className: "b316-label", htmlFor: "b316-phone", children: "Mobile number" }),
2271
- /* @__PURE__ */ jsx8(
2514
+ ] }) : /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2515
+ /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-phone", children: labels.mobileNumber }),
2516
+ /* @__PURE__ */ jsx9(
2272
2517
  "input",
2273
2518
  {
2274
2519
  id: "b316-phone",
@@ -2281,11 +2526,11 @@ function SignIn({
2281
2526
  required: true
2282
2527
  }
2283
2528
  ),
2284
- /* @__PURE__ */ jsx8("span", { className: "b316-muted", children: "Include the country code." })
2285
- ] }) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
2286
- /* @__PURE__ */ jsxs7("div", { className: "b316-field", children: [
2287
- /* @__PURE__ */ jsx8("label", { className: "b316-label", htmlFor: "b316-email", children: "Email" }),
2288
- /* @__PURE__ */ jsx8(
2529
+ /* @__PURE__ */ jsx9("span", { className: "b316-muted", children: labels.includeCountryCode })
2530
+ ] }) : mode !== null ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
2531
+ /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2532
+ /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-email", children: mode === "sso" ? labels.ssoEmail : labels.email }),
2533
+ /* @__PURE__ */ jsx9(
2289
2534
  "input",
2290
2535
  {
2291
2536
  id: "b316-email",
@@ -2293,14 +2538,14 @@ function SignIn({
2293
2538
  type: "email",
2294
2539
  value: email,
2295
2540
  onChange: (event) => setEmail(event.target.value),
2296
- autoComplete: passkeyReady ? "email webauthn" : "email",
2541
+ autoComplete: passkeyReady && mode !== "sso" ? "email webauthn" : "email",
2297
2542
  required: true
2298
2543
  }
2299
2544
  )
2300
2545
  ] }),
2301
- mode === "password" ? /* @__PURE__ */ jsxs7("div", { className: "b316-field", children: [
2302
- /* @__PURE__ */ jsx8("label", { className: "b316-label", htmlFor: "b316-password", children: "Password" }),
2303
- /* @__PURE__ */ jsx8(
2546
+ mode === "password" ? /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2547
+ /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-password", children: labels.password }),
2548
+ /* @__PURE__ */ jsx9(
2304
2549
  "input",
2305
2550
  {
2306
2551
  id: "b316-password",
@@ -2313,34 +2558,101 @@ function SignIn({
2313
2558
  }
2314
2559
  )
2315
2560
  ] }) : null
2316
- ] }),
2317
- /* @__PURE__ */ jsx8("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? "Working\u2026" : mode === "magic" ? "Email me a link" : mode === "phone" && !phoneChallenge ? "Text me a code" : "Sign in" }),
2318
- passkeyReady && !pendingChallenge ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
2319
- /* @__PURE__ */ jsx8("div", { className: "b316-muted", style: { textAlign: "center", margin: "10px 0" }, children: "or" }),
2320
- /* @__PURE__ */ jsx8(
2561
+ ] }) : null,
2562
+ mode !== null ? /* @__PURE__ */ jsx9("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : mode === "magic" ? labels.emailMeALink : mode === "phone" && !phoneChallenge ? labels.textMeACode : mode === "sso" ? labels.ssoContinue : labels.submit }) : null,
2563
+ mode === "sso" ? /* @__PURE__ */ jsx9(
2564
+ "button",
2565
+ {
2566
+ type: "button",
2567
+ className: "b316-button b316-button-secondary",
2568
+ style: { marginTop: 10, width: "100%" },
2569
+ disabled: busy,
2570
+ onClick: () => setMode(null),
2571
+ children: labels.back
2572
+ }
2573
+ ) : null,
2574
+ (passkeyReady || offered.sso) && mode !== "sso" ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
2575
+ hasForm ? /* @__PURE__ */ jsx9("div", { className: "b316-divider", children: labels.or }) : null,
2576
+ passkeyReady ? /* @__PURE__ */ jsx9(
2321
2577
  "button",
2322
2578
  {
2323
2579
  type: "button",
2324
2580
  className: "b316-button b316-button-secondary",
2581
+ style: { width: "100%" },
2325
2582
  disabled: busy,
2326
2583
  onClick: () => {
2327
2584
  abortRef.current?.abort();
2328
2585
  void signInWithPasskey(false);
2329
2586
  },
2330
- children: "Sign in with a passkey"
2587
+ children: labels.passkey
2331
2588
  }
2332
- )
2589
+ ) : null,
2590
+ offered.sso ? /* @__PURE__ */ jsx9(
2591
+ "button",
2592
+ {
2593
+ type: "button",
2594
+ className: "b316-button b316-button-secondary",
2595
+ style: { width: "100%", marginTop: passkeyReady ? 8 : 0 },
2596
+ disabled: busy,
2597
+ onClick: () => {
2598
+ abortRef.current?.abort();
2599
+ setError(null);
2600
+ setMode("sso");
2601
+ },
2602
+ children: labels.sso
2603
+ }
2604
+ ) : null
2333
2605
  ] }) : null
2334
2606
  ] });
2335
2607
  }
2336
2608
 
2609
+ // src/SocialSignIn.tsx
2610
+ import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2611
+ function SocialSignIn({
2612
+ socialRedirectUrl,
2613
+ socialState,
2614
+ social,
2615
+ intent = "sign-in",
2616
+ divider = false,
2617
+ labels
2618
+ }) {
2619
+ const { client } = useBase316();
2620
+ const loaded = useSignInMethods(client);
2621
+ if (!loaded.methods || intent === "sign-up" && !loaded.methods.signUp) {
2622
+ return null;
2623
+ }
2624
+ const offered = resolveMethods(loaded.methods, { social, socialRedirectUrl }, null);
2625
+ if (!socialRedirectUrl || offered.social.length === 0) {
2626
+ return null;
2627
+ }
2628
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
2629
+ /* @__PURE__ */ jsx10(
2630
+ SocialButtons,
2631
+ {
2632
+ options: offered.social,
2633
+ continueWith: labels?.continueWith ?? ((name) => `Continue with ${name}`),
2634
+ onChoose: (option) => beginRedirect(
2635
+ (state) => client.socialSignInUrl({
2636
+ provider: option.slug,
2637
+ redirectUri: socialRedirectUrl,
2638
+ state,
2639
+ hostedUrl: offered.hostedUrl
2640
+ }),
2641
+ socialState
2642
+ )
2643
+ }
2644
+ ),
2645
+ divider ? /* @__PURE__ */ jsx10("div", { className: "b316-divider", children: labels?.or ?? "or" }) : null
2646
+ ] });
2647
+ }
2648
+
2337
2649
  // src/SignUp.tsx
2338
2650
  import {
2339
2651
  Base316Error as Base316Error3,
2340
2652
  needsSecondFactor as needsSecondFactor2
2341
2653
  } from "@base316/sdk";
2342
- import { useEffect as useEffect8, useState as useState8 } from "react";
2343
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2654
+ import { useEffect as useEffect9, useState as useState9 } from "react";
2655
+ import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2344
2656
  var DEFAULT_SIGN_UP_LABELS = {
2345
2657
  name: "Name",
2346
2658
  email: "Email",
@@ -2357,7 +2669,10 @@ var DEFAULT_SIGN_UP_LABELS = {
2357
2669
  confirmEmail: (email) => `Your account is ready. We sent a confirmation link to ${email} \u2014 open it, then sign in.`,
2358
2670
  createdSignInFailed: (reason) => `Your account was created, but we could not sign you in: ${reason}`,
2359
2671
  genericError: "We could not create that account. Try again.",
2360
- joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`
2672
+ joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`,
2673
+ continueWith: (name) => `Continue with ${name}`,
2674
+ or: "or",
2675
+ closed: "This application is not accepting new accounts right now."
2361
2676
  };
2362
2677
  function describeRules(policy, labels) {
2363
2678
  const extras = [
@@ -2376,30 +2691,35 @@ function SignUp({
2376
2691
  onJoined,
2377
2692
  labels: overrides,
2378
2693
  secondFactorLabels,
2694
+ social,
2695
+ socialRedirectUrl,
2696
+ socialState,
2379
2697
  className,
2380
2698
  style
2381
2699
  }) {
2382
2700
  const labels = { ...DEFAULT_SIGN_UP_LABELS, ...overrides };
2383
2701
  const { client, setToken } = useBase316();
2384
- const [name, setName] = useState8("");
2385
- const [email, setEmail] = useState8("");
2386
- const [password, setPassword] = useState8("");
2387
- const [error, setError] = useState8(null);
2388
- const [busy, setBusy] = useState8(false);
2389
- const [policy, setPolicy] = useState8(null);
2390
- const [pending, setPending] = useState8(null);
2391
- const [confirmEmail, setConfirmEmail] = useState8(false);
2392
- const [urlInvitation, setUrlInvitation] = useState8(null);
2393
- const [loaded, setLoaded] = useState8(null);
2702
+ const methodsState = useSignInMethods(client);
2703
+ const offered = resolveMethods(methodsState.methods, { social, socialRedirectUrl }, null);
2704
+ const [name, setName] = useState9("");
2705
+ const [email, setEmail] = useState9("");
2706
+ const [password, setPassword] = useState9("");
2707
+ const [error, setError] = useState9(null);
2708
+ const [busy, setBusy] = useState9(false);
2709
+ const [policy, setPolicy] = useState9(null);
2710
+ const [pending, setPending] = useState9(null);
2711
+ const [confirmEmail, setConfirmEmail] = useState9(false);
2712
+ const [urlInvitation, setUrlInvitation] = useState9(null);
2713
+ const [loaded, setLoaded] = useState9(null);
2394
2714
  const invitation = suppliedInvitation === void 0 ? urlInvitation : suppliedInvitation;
2395
2715
  const preview = loaded && loaded.token === invitation ? loaded.preview : null;
2396
- useEffect8(() => {
2716
+ useEffect9(() => {
2397
2717
  if (suppliedInvitation !== void 0 || typeof window === "undefined") {
2398
2718
  return;
2399
2719
  }
2400
2720
  setUrlInvitation(new URL(window.location.href).searchParams.get("invitation"));
2401
2721
  }, [suppliedInvitation]);
2402
- useEffect8(() => {
2722
+ useEffect9(() => {
2403
2723
  if (!invitation) {
2404
2724
  return;
2405
2725
  }
@@ -2414,7 +2734,7 @@ function SignUp({
2414
2734
  cancelled = true;
2415
2735
  };
2416
2736
  }, [client, invitation]);
2417
- useEffect8(() => {
2737
+ useEffect9(() => {
2418
2738
  let cancelled = false;
2419
2739
  client.auth.passwordPolicy().then((loaded2) => {
2420
2740
  if (!cancelled) {
@@ -2472,86 +2792,118 @@ function SignUp({
2472
2792
  }
2473
2793
  }
2474
2794
  if (pending) {
2475
- return /* @__PURE__ */ jsx9("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx9(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
2795
+ return /* @__PURE__ */ jsx11("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx11(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
2476
2796
  }
2477
2797
  if (confirmEmail) {
2478
- return /* @__PURE__ */ jsxs8("div", { className: cls("b316-card", className), style, children: [
2479
- /* @__PURE__ */ jsx9("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
2480
- /* @__PURE__ */ jsx9("output", { className: "b316-muted", children: labels.confirmEmail(email) })
2798
+ return /* @__PURE__ */ jsxs10("div", { className: cls("b316-card", className), style, children: [
2799
+ /* @__PURE__ */ jsx11("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
2800
+ /* @__PURE__ */ jsx11("output", { className: "b316-muted", children: labels.confirmEmail(email) })
2481
2801
  ] });
2482
2802
  }
2483
- return /* @__PURE__ */ jsxs8("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2484
- preview ? /* @__PURE__ */ jsx9("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
2485
- error ? /* @__PURE__ */ jsx9("div", { className: "b316-error", role: "alert", children: error }) : null,
2486
- /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2487
- /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
2488
- /* @__PURE__ */ jsx9(
2489
- "input",
2490
- {
2491
- id: "b316-name",
2492
- className: "b316-input",
2493
- value: name,
2494
- onChange: (event) => setName(event.target.value),
2495
- autoComplete: "name"
2496
- }
2497
- )
2498
- ] }),
2499
- /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2500
- /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
2501
- /* @__PURE__ */ jsx9(
2502
- "input",
2503
- {
2504
- id: "b316-signup-email",
2505
- className: "b316-input",
2506
- type: "email",
2507
- value: email,
2508
- onChange: (event) => setEmail(event.target.value),
2509
- autoComplete: "email",
2510
- required: true
2511
- }
2512
- )
2513
- ] }),
2514
- /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2515
- /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
2516
- /* @__PURE__ */ jsx9(
2517
- "input",
2803
+ if (!offered.signUp && !invitation) {
2804
+ return /* @__PURE__ */ jsx11("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx11("output", { className: "b316-muted", children: labels.closed }) });
2805
+ }
2806
+ const socialOptions = invitation ? [] : offered.social;
2807
+ return /* @__PURE__ */ jsxs10("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2808
+ socialOptions.length > 0 ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
2809
+ /* @__PURE__ */ jsx11(
2810
+ SocialButtons,
2518
2811
  {
2519
- id: "b316-signup-password",
2520
- className: "b316-input",
2521
- type: "password",
2522
- value: password,
2523
- onChange: (event) => setPassword(event.target.value),
2524
- autoComplete: "new-password",
2525
- minLength: policy?.minLength,
2526
- maxLength: policy?.maxLength,
2527
- "aria-describedby": policy ? "b316-signup-password-rules" : void 0,
2528
- required: true
2812
+ options: socialOptions,
2813
+ continueWith: labels.continueWith,
2814
+ disabled: busy,
2815
+ onChoose: (option) => {
2816
+ if (!socialRedirectUrl) {
2817
+ return;
2818
+ }
2819
+ setBusy(true);
2820
+ beginRedirect(
2821
+ (state) => client.socialSignInUrl({
2822
+ provider: option.slug,
2823
+ redirectUri: socialRedirectUrl,
2824
+ state,
2825
+ hostedUrl: offered.hostedUrl
2826
+ }),
2827
+ socialState
2828
+ );
2829
+ }
2529
2830
  }
2530
2831
  ),
2531
- policy ? /* @__PURE__ */ jsx9("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
2532
- ] }),
2533
- /* @__PURE__ */ jsx9("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
2832
+ offered.password ? /* @__PURE__ */ jsx11("div", { className: "b316-divider", children: labels.or }) : null
2833
+ ] }) : null,
2834
+ preview ? /* @__PURE__ */ jsx11("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
2835
+ error ? /* @__PURE__ */ jsx11("div", { className: "b316-error", role: "alert", children: error }) : null,
2836
+ offered.password || socialOptions.length === 0 ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
2837
+ /* @__PURE__ */ jsxs10("div", { className: "b316-field", children: [
2838
+ /* @__PURE__ */ jsx11("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
2839
+ /* @__PURE__ */ jsx11(
2840
+ "input",
2841
+ {
2842
+ id: "b316-name",
2843
+ className: "b316-input",
2844
+ value: name,
2845
+ onChange: (event) => setName(event.target.value),
2846
+ autoComplete: "name"
2847
+ }
2848
+ )
2849
+ ] }),
2850
+ /* @__PURE__ */ jsxs10("div", { className: "b316-field", children: [
2851
+ /* @__PURE__ */ jsx11("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
2852
+ /* @__PURE__ */ jsx11(
2853
+ "input",
2854
+ {
2855
+ id: "b316-signup-email",
2856
+ className: "b316-input",
2857
+ type: "email",
2858
+ value: email,
2859
+ onChange: (event) => setEmail(event.target.value),
2860
+ autoComplete: "email",
2861
+ required: true
2862
+ }
2863
+ )
2864
+ ] }),
2865
+ /* @__PURE__ */ jsxs10("div", { className: "b316-field", children: [
2866
+ /* @__PURE__ */ jsx11("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
2867
+ /* @__PURE__ */ jsx11(
2868
+ "input",
2869
+ {
2870
+ id: "b316-signup-password",
2871
+ className: "b316-input",
2872
+ type: "password",
2873
+ value: password,
2874
+ onChange: (event) => setPassword(event.target.value),
2875
+ autoComplete: "new-password",
2876
+ minLength: policy?.minLength,
2877
+ maxLength: policy?.maxLength,
2878
+ "aria-describedby": policy ? "b316-signup-password-rules" : void 0,
2879
+ required: true
2880
+ }
2881
+ ),
2882
+ policy ? /* @__PURE__ */ jsx11("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
2883
+ ] }),
2884
+ /* @__PURE__ */ jsx11("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
2885
+ ] }) : null
2534
2886
  ] });
2535
2887
  }
2536
2888
 
2537
2889
  // src/UserProfile.tsx
2538
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2890
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
2539
2891
  function UserProfile({ className, style }) {
2540
2892
  const { session, loading, signOut } = useBase316();
2541
2893
  if (loading) {
2542
- return /* @__PURE__ */ jsx10("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2894
+ return /* @__PURE__ */ jsx12("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2543
2895
  }
2544
2896
  if (!session) {
2545
- return /* @__PURE__ */ jsx10("div", { className: cls("b316-card", className), style, children: "Not signed in." });
2897
+ return /* @__PURE__ */ jsx12("div", { className: cls("b316-card", className), style, children: "Not signed in." });
2546
2898
  }
2547
2899
  const user = session.user ?? {};
2548
- return /* @__PURE__ */ jsx10("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs9("div", { className: "b316-row", children: [
2549
- /* @__PURE__ */ jsxs9("div", { children: [
2550
- /* @__PURE__ */ jsx10("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
2551
- user.name && user.email ? /* @__PURE__ */ jsx10("div", { className: "b316-muted", children: user.email }) : null,
2552
- user.emailVerified === false ? /* @__PURE__ */ jsx10("div", { className: "b316-muted", children: "Email not verified" }) : null
2900
+ return /* @__PURE__ */ jsx12("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs11("div", { className: "b316-row", children: [
2901
+ /* @__PURE__ */ jsxs11("div", { children: [
2902
+ /* @__PURE__ */ jsx12("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
2903
+ user.name && user.email ? /* @__PURE__ */ jsx12("div", { className: "b316-muted", children: user.email }) : null,
2904
+ user.emailVerified === false ? /* @__PURE__ */ jsx12("div", { className: "b316-muted", children: "Email not verified" }) : null
2553
2905
  ] }),
2554
- /* @__PURE__ */ jsx10(
2906
+ /* @__PURE__ */ jsx12(
2555
2907
  "button",
2556
2908
  {
2557
2909
  type: "button",
@@ -2565,11 +2917,11 @@ function UserProfile({ className, style }) {
2565
2917
 
2566
2918
  // src/PasskeyManager.tsx
2567
2919
  import { isPasskeySupported as isPasskeySupported2 } from "@base316/sdk";
2568
- import { useCallback as useCallback5, useEffect as useEffect10, useState as useState10 } from "react";
2920
+ import { useCallback as useCallback5, useEffect as useEffect11, useState as useState11 } from "react";
2569
2921
 
2570
2922
  // src/confirm.tsx
2571
- import { useEffect as useEffect9, useRef as useRef3, useState as useState9 } from "react";
2572
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2923
+ import { useEffect as useEffect10, useRef as useRef3, useState as useState10 } from "react";
2924
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
2573
2925
  var DEFAULT_TIMEOUT_MS = 5e3;
2574
2926
  function ConfirmButton({
2575
2927
  children,
@@ -2579,9 +2931,9 @@ function ConfirmButton({
2579
2931
  disabled,
2580
2932
  timeoutMs = DEFAULT_TIMEOUT_MS
2581
2933
  }) {
2582
- const [armed, setArmed] = useState9(false);
2934
+ const [armed, setArmed] = useState10(false);
2583
2935
  const confirmRef = useRef3(null);
2584
- useEffect9(() => {
2936
+ useEffect10(() => {
2585
2937
  if (!armed) {
2586
2938
  return;
2587
2939
  }
@@ -2590,7 +2942,7 @@ function ConfirmButton({
2590
2942
  return () => clearTimeout(timer);
2591
2943
  }, [armed, timeoutMs]);
2592
2944
  if (!armed) {
2593
- return /* @__PURE__ */ jsx11(
2945
+ return /* @__PURE__ */ jsx13(
2594
2946
  "button",
2595
2947
  {
2596
2948
  type: "button",
@@ -2604,8 +2956,8 @@ function ConfirmButton({
2604
2956
  return (
2605
2957
  // No `role="group"`: both buttons already say what they do, and the
2606
2958
  // grouping would only repeat the question a screen reader has just read.
2607
- /* @__PURE__ */ jsxs10("span", { className: "b316-confirm", children: [
2608
- /* @__PURE__ */ jsx11(
2959
+ /* @__PURE__ */ jsxs12("span", { className: "b316-confirm", children: [
2960
+ /* @__PURE__ */ jsx13(
2609
2961
  "button",
2610
2962
  {
2611
2963
  ref: confirmRef,
@@ -2619,7 +2971,7 @@ function ConfirmButton({
2619
2971
  children: confirmLabel
2620
2972
  }
2621
2973
  ),
2622
- /* @__PURE__ */ jsx11(
2974
+ /* @__PURE__ */ jsx13(
2623
2975
  "button",
2624
2976
  {
2625
2977
  type: "button",
@@ -2633,18 +2985,18 @@ function ConfirmButton({
2633
2985
  }
2634
2986
 
2635
2987
  // src/PasskeyManager.tsx
2636
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
2988
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
2637
2989
  function PasskeyManager({
2638
2990
  className,
2639
2991
  style,
2640
2992
  title = "Passkeys"
2641
2993
  }) {
2642
2994
  const { client, token, session } = useBase316();
2643
- const [passkeys, setPasskeys] = useState10(null);
2644
- const [busy, setBusy] = useState10(false);
2645
- const [error, setError] = useState10(null);
2646
- const [name, setName] = useState10("");
2647
- const [supported, setSupported] = useState10(false);
2995
+ const [passkeys, setPasskeys] = useState11(null);
2996
+ const [busy, setBusy] = useState11(false);
2997
+ const [error, setError] = useState11(null);
2998
+ const [name, setName] = useState11("");
2999
+ const [supported, setSupported] = useState11(false);
2648
3000
  const load = useCallback5(async () => {
2649
3001
  if (!token) {
2650
3002
  return;
@@ -2658,7 +3010,7 @@ function PasskeyManager({
2658
3010
  setPasskeys(null);
2659
3011
  }
2660
3012
  }, [client, token]);
2661
- useEffect10(() => {
3013
+ useEffect11(() => {
2662
3014
  if (!isPasskeySupported2()) {
2663
3015
  return;
2664
3016
  }
@@ -2694,18 +3046,18 @@ function PasskeyManager({
2694
3046
  setError(caught instanceof Error ? caught.message : "That did not work.");
2695
3047
  }
2696
3048
  };
2697
- return /* @__PURE__ */ jsxs11("div", { className: cls("b316-card", className), style, children: [
2698
- /* @__PURE__ */ jsx12("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
2699
- /* @__PURE__ */ jsx12("div", { className: "b316-muted", style: { marginBottom: 12 }, children: "Sign in with your fingerprint, face or a security key \u2014 nothing to type and nothing to remember." }),
2700
- passkeys === null ? /* @__PURE__ */ jsx12("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ jsx12("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ jsxs11("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
2701
- /* @__PURE__ */ jsxs11("div", { children: [
2702
- /* @__PURE__ */ jsx12("div", { children: passkey.name || "Passkey" }),
2703
- /* @__PURE__ */ jsxs11("div", { className: "b316-muted", children: [
3049
+ return /* @__PURE__ */ jsxs13("div", { className: cls("b316-card", className), style, children: [
3050
+ /* @__PURE__ */ jsx14("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
3051
+ /* @__PURE__ */ jsx14("div", { className: "b316-muted", style: { marginBottom: 12 }, children: "Sign in with your fingerprint, face or a security key \u2014 nothing to type and nothing to remember." }),
3052
+ passkeys === null ? /* @__PURE__ */ jsx14("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ jsx14("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ jsx14("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ jsxs13("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
3053
+ /* @__PURE__ */ jsxs13("div", { children: [
3054
+ /* @__PURE__ */ jsx14("div", { children: passkey.name || "Passkey" }),
3055
+ /* @__PURE__ */ jsxs13("div", { className: "b316-muted", children: [
2704
3056
  passkey.lastUsedAt ? `Last used ${formatDate(passkey.lastUsedAt)}` : `Added ${formatDate(passkey.createdAt)}`,
2705
3057
  passkey.backedUp ? "" : " \xB7 this device only"
2706
3058
  ] })
2707
3059
  ] }),
2708
- /* @__PURE__ */ jsx12(
3060
+ /* @__PURE__ */ jsx14(
2709
3061
  ConfirmButton,
2710
3062
  {
2711
3063
  className: "b316-button b316-button-secondary",
@@ -2715,9 +3067,9 @@ function PasskeyManager({
2715
3067
  }
2716
3068
  )
2717
3069
  ] }, passkey.id)) }),
2718
- error ? /* @__PURE__ */ jsx12("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
2719
- /* @__PURE__ */ jsxs11("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
2720
- /* @__PURE__ */ jsx12(
3070
+ error ? /* @__PURE__ */ jsx14("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
3071
+ /* @__PURE__ */ jsxs13("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
3072
+ /* @__PURE__ */ jsx14(
2721
3073
  "input",
2722
3074
  {
2723
3075
  className: "b316-input",
@@ -2726,7 +3078,7 @@ function PasskeyManager({
2726
3078
  onChange: (event) => setName(event.target.value)
2727
3079
  }
2728
3080
  ),
2729
- /* @__PURE__ */ jsx12("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
3081
+ /* @__PURE__ */ jsx14("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
2730
3082
  ] })
2731
3083
  ] });
2732
3084
  }
@@ -2736,8 +3088,8 @@ function formatDate(value) {
2736
3088
  }
2737
3089
 
2738
3090
  // src/ActiveSessions.tsx
2739
- import { useCallback as useCallback6, useEffect as useEffect11, useState as useState11 } from "react";
2740
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
3091
+ import { useCallback as useCallback6, useEffect as useEffect12, useState as useState12 } from "react";
3092
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
2741
3093
  function describeDevice(userAgent) {
2742
3094
  if (!userAgent) {
2743
3095
  return null;
@@ -2755,9 +3107,9 @@ function when(value) {
2755
3107
  }
2756
3108
  function ActiveSessions({ onRevoked, className, style }) {
2757
3109
  const { client, token } = useBase316();
2758
- const [sessions, setSessions] = useState11(null);
2759
- const [error, setError] = useState11(null);
2760
- const [busy, setBusy] = useState11(false);
3110
+ const [sessions, setSessions] = useState12(null);
3111
+ const [error, setError] = useState12(null);
3112
+ const [busy, setBusy] = useState12(false);
2761
3113
  const load = useCallback6(() => {
2762
3114
  if (!token) {
2763
3115
  return;
@@ -2769,15 +3121,15 @@ function ActiveSessions({ onRevoked, className, style }) {
2769
3121
  setError(cause instanceof Error ? cause.message : "Could not load your sessions.");
2770
3122
  });
2771
3123
  }, [client, token]);
2772
- useEffect11(load, [load]);
3124
+ useEffect12(load, [load]);
2773
3125
  if (!token) {
2774
3126
  return null;
2775
3127
  }
2776
3128
  if (error) {
2777
- return /* @__PURE__ */ jsx13("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx13("div", { className: "b316-error", role: "alert", children: error }) });
3129
+ return /* @__PURE__ */ jsx15("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx15("div", { className: "b316-error", role: "alert", children: error }) });
2778
3130
  }
2779
3131
  if (!sessions) {
2780
- return /* @__PURE__ */ jsx13("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3132
+ return /* @__PURE__ */ jsx15("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2781
3133
  }
2782
3134
  async function revokeOthers() {
2783
3135
  setBusy(true);
@@ -2791,32 +3143,32 @@ function ActiveSessions({ onRevoked, className, style }) {
2791
3143
  setBusy(false);
2792
3144
  }
2793
3145
  }
2794
- return /* @__PURE__ */ jsxs12("div", { className: cls("b316-card b316-sessions", className), style, children: [
2795
- /* @__PURE__ */ jsxs12("div", { className: "b316-sessions-head", children: [
2796
- /* @__PURE__ */ jsx13("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
2797
- sessions.length > 1 ? /* @__PURE__ */ jsx13("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
3146
+ return /* @__PURE__ */ jsxs14("div", { className: cls("b316-card b316-sessions", className), style, children: [
3147
+ /* @__PURE__ */ jsxs14("div", { className: "b316-sessions-head", children: [
3148
+ /* @__PURE__ */ jsx15("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
3149
+ sessions.length > 1 ? /* @__PURE__ */ jsx15("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
2798
3150
  ] }),
2799
- /* @__PURE__ */ jsx13("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ jsxs12("li", { className: "b316-session", children: [
2800
- /* @__PURE__ */ jsxs12("div", { className: "b316-session-device", children: [
3151
+ /* @__PURE__ */ jsx15("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ jsxs14("li", { className: "b316-session", children: [
3152
+ /* @__PURE__ */ jsxs14("div", { className: "b316-session-device", children: [
2801
3153
  describeDevice(session.userAgent) ?? "Unknown device",
2802
3154
  session.impersonatedBy ? (
2803
3155
  // Worth saying loudly: somebody is acting as this account.
2804
- /* @__PURE__ */ jsx13("span", { className: "b316-chip", children: " Support access" })
3156
+ /* @__PURE__ */ jsx15("span", { className: "b316-chip", children: " Support access" })
2805
3157
  ) : null
2806
3158
  ] }),
2807
- /* @__PURE__ */ jsxs12("div", { className: "b316-muted", children: [
3159
+ /* @__PURE__ */ jsxs14("div", { className: "b316-muted", children: [
2808
3160
  session.ipAddress ? `${session.ipAddress} \xB7 ` : "",
2809
3161
  "last used ",
2810
3162
  when(session.lastSeenAt)
2811
3163
  ] })
2812
3164
  ] }, session.id)) }),
2813
- sessions.length === 0 ? /* @__PURE__ */ jsx13("div", { className: "b316-muted", children: "No active sessions." }) : null
3165
+ sessions.length === 0 ? /* @__PURE__ */ jsx15("div", { className: "b316-muted", children: "No active sessions." }) : null
2814
3166
  ] });
2815
3167
  }
2816
3168
 
2817
3169
  // src/DeviceApproval.tsx
2818
- import { useState as useState12 } from "react";
2819
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
3170
+ import { useState as useState13 } from "react";
3171
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
2820
3172
  function DeviceApproval({
2821
3173
  userCode = "",
2822
3174
  onDecided,
@@ -2824,11 +3176,11 @@ function DeviceApproval({
2824
3176
  style
2825
3177
  }) {
2826
3178
  const { client, token } = useBase316();
2827
- const [code, setCode] = useState12(userCode);
2828
- const [request, setRequest] = useState12(null);
2829
- const [decided, setDecided] = useState12(null);
2830
- const [error, setError] = useState12(null);
2831
- const [busy, setBusy] = useState12(false);
3179
+ const [code, setCode] = useState13(userCode);
3180
+ const [request, setRequest] = useState13(null);
3181
+ const [decided, setDecided] = useState13(null);
3182
+ const [error, setError] = useState13(null);
3183
+ const [busy, setBusy] = useState13(false);
2832
3184
  if (!token) {
2833
3185
  return null;
2834
3186
  }
@@ -2861,25 +3213,25 @@ function DeviceApproval({
2861
3213
  }
2862
3214
  }
2863
3215
  if (decided !== null) {
2864
- return /* @__PURE__ */ jsxs13("div", { className: cls("b316-card b316-device", className), style, children: [
2865
- /* @__PURE__ */ jsx14("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
2866
- /* @__PURE__ */ jsx14("p", { className: "b316-muted", children: decided ? "You can close this page and go back to your device." : "Nothing was granted. You can close this page." })
3216
+ return /* @__PURE__ */ jsxs15("div", { className: cls("b316-card b316-device", className), style, children: [
3217
+ /* @__PURE__ */ jsx16("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
3218
+ /* @__PURE__ */ jsx16("p", { className: "b316-muted", children: decided ? "You can close this page and go back to your device." : "Nothing was granted. You can close this page." })
2867
3219
  ] });
2868
3220
  }
2869
3221
  if (request) {
2870
- return /* @__PURE__ */ jsxs13("div", { className: cls("b316-card b316-device", className), style, children: [
2871
- /* @__PURE__ */ jsxs13("h3", { className: "b316-device-title", children: [
3222
+ return /* @__PURE__ */ jsxs15("div", { className: cls("b316-card b316-device", className), style, children: [
3223
+ /* @__PURE__ */ jsxs15("h3", { className: "b316-device-title", children: [
2872
3224
  "Sign in to ",
2873
3225
  request.clientName
2874
3226
  ] }),
2875
- /* @__PURE__ */ jsxs13("p", { className: "b316-muted", children: [
3227
+ /* @__PURE__ */ jsxs15("p", { className: "b316-muted", children: [
2876
3228
  request.clientName,
2877
3229
  " is asking to sign in as you."
2878
3230
  ] }),
2879
- request.scopes.length > 0 ? /* @__PURE__ */ jsx14("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ jsx14("li", { children: scope }, scope)) }) : null,
2880
- error ? /* @__PURE__ */ jsx14("div", { className: "b316-error", role: "alert", children: error }) : null,
2881
- /* @__PURE__ */ jsxs13("div", { className: "b316-device-actions", children: [
2882
- /* @__PURE__ */ jsx14(
3231
+ request.scopes.length > 0 ? /* @__PURE__ */ jsx16("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ jsx16("li", { children: scope }, scope)) }) : null,
3232
+ error ? /* @__PURE__ */ jsx16("div", { className: "b316-error", role: "alert", children: error }) : null,
3233
+ /* @__PURE__ */ jsxs15("div", { className: "b316-device-actions", children: [
3234
+ /* @__PURE__ */ jsx16(
2883
3235
  "button",
2884
3236
  {
2885
3237
  type: "button",
@@ -2889,7 +3241,7 @@ function DeviceApproval({
2889
3241
  children: busy ? "Approving\u2026" : "Approve"
2890
3242
  }
2891
3243
  ),
2892
- /* @__PURE__ */ jsx14(
3244
+ /* @__PURE__ */ jsx16(
2893
3245
  "button",
2894
3246
  {
2895
3247
  type: "button",
@@ -2902,11 +3254,11 @@ function DeviceApproval({
2902
3254
  ] })
2903
3255
  ] });
2904
3256
  }
2905
- return /* @__PURE__ */ jsxs13("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
2906
- /* @__PURE__ */ jsx14("h3", { className: "b316-device-title", children: "Connect your device" }),
2907
- /* @__PURE__ */ jsx14("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
2908
- error ? /* @__PURE__ */ jsx14("div", { className: "b316-error", role: "alert", children: error }) : null,
2909
- /* @__PURE__ */ jsx14(
3257
+ return /* @__PURE__ */ jsxs15("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
3258
+ /* @__PURE__ */ jsx16("h3", { className: "b316-device-title", children: "Connect your device" }),
3259
+ /* @__PURE__ */ jsx16("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
3260
+ error ? /* @__PURE__ */ jsx16("div", { className: "b316-error", role: "alert", children: error }) : null,
3261
+ /* @__PURE__ */ jsx16(
2910
3262
  "input",
2911
3263
  {
2912
3264
  className: "b316-input",
@@ -2919,13 +3271,13 @@ function DeviceApproval({
2919
3271
  "aria-label": "Device code"
2920
3272
  }
2921
3273
  ),
2922
- /* @__PURE__ */ jsx14("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
3274
+ /* @__PURE__ */ jsx16("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
2923
3275
  ] });
2924
3276
  }
2925
3277
 
2926
3278
  // src/PrivacyControls.tsx
2927
- import { useState as useState13 } from "react";
2928
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
3279
+ import { useState as useState14 } from "react";
3280
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
2929
3281
  function PrivacyControls({
2930
3282
  confirmWord = "DELETE",
2931
3283
  onErased,
@@ -2933,10 +3285,10 @@ function PrivacyControls({
2933
3285
  style
2934
3286
  }) {
2935
3287
  const { client, token } = useBase316();
2936
- const [confirming, setConfirming] = useState13(false);
2937
- const [typed, setTyped] = useState13("");
2938
- const [error, setError] = useState13(null);
2939
- const [busy, setBusy] = useState13(false);
3288
+ const [confirming, setConfirming] = useState14(false);
3289
+ const [typed, setTyped] = useState14("");
3290
+ const [error, setError] = useState14(null);
3291
+ const [busy, setBusy] = useState14(false);
2940
3292
  if (!token) {
2941
3293
  return null;
2942
3294
  }
@@ -2971,22 +3323,22 @@ function PrivacyControls({
2971
3323
  setBusy(false);
2972
3324
  }
2973
3325
  }
2974
- return /* @__PURE__ */ jsxs14("div", { className: cls("b316-card b316-privacy", className), style, children: [
2975
- /* @__PURE__ */ jsx15("h3", { className: "b316-privacy-title", children: "Your data" }),
2976
- error ? /* @__PURE__ */ jsx15("div", { className: "b316-error", role: "alert", children: error }) : null,
2977
- /* @__PURE__ */ jsxs14("div", { className: "b316-privacy-row", children: [
2978
- /* @__PURE__ */ jsxs14("div", { children: [
2979
- /* @__PURE__ */ jsx15("p", { children: "Download a copy" }),
2980
- /* @__PURE__ */ jsx15("p", { className: "b316-muted", children: "Everything we hold about you, as a file. Passwords and security keys are not included \u2014 they are what protect the account rather than anything you can use." })
3326
+ return /* @__PURE__ */ jsxs16("div", { className: cls("b316-card b316-privacy", className), style, children: [
3327
+ /* @__PURE__ */ jsx17("h3", { className: "b316-privacy-title", children: "Your data" }),
3328
+ error ? /* @__PURE__ */ jsx17("div", { className: "b316-error", role: "alert", children: error }) : null,
3329
+ /* @__PURE__ */ jsxs16("div", { className: "b316-privacy-row", children: [
3330
+ /* @__PURE__ */ jsxs16("div", { children: [
3331
+ /* @__PURE__ */ jsx17("p", { children: "Download a copy" }),
3332
+ /* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "Everything we hold about you, as a file. Passwords and security keys are not included \u2014 they are what protect the account rather than anything you can use." })
2981
3333
  ] }),
2982
- /* @__PURE__ */ jsx15("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
3334
+ /* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
2983
3335
  ] }),
2984
- /* @__PURE__ */ jsxs14("div", { className: "b316-privacy-row", children: [
2985
- /* @__PURE__ */ jsxs14("div", { children: [
2986
- /* @__PURE__ */ jsx15("p", { children: "Delete your account" }),
2987
- /* @__PURE__ */ jsx15("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
3336
+ /* @__PURE__ */ jsxs16("div", { className: "b316-privacy-row", children: [
3337
+ /* @__PURE__ */ jsxs16("div", { children: [
3338
+ /* @__PURE__ */ jsx17("p", { children: "Delete your account" }),
3339
+ /* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
2988
3340
  ] }),
2989
- confirming ? null : /* @__PURE__ */ jsx15(
3341
+ confirming ? null : /* @__PURE__ */ jsx17(
2990
3342
  "button",
2991
3343
  {
2992
3344
  type: "button",
@@ -2997,13 +3349,13 @@ function PrivacyControls({
2997
3349
  }
2998
3350
  )
2999
3351
  ] }),
3000
- confirming ? /* @__PURE__ */ jsxs14("div", { className: "b316-privacy-confirm", children: [
3001
- /* @__PURE__ */ jsxs14("label", { className: "b316-label", htmlFor: "b316-privacy-confirm", children: [
3352
+ confirming ? /* @__PURE__ */ jsxs16("div", { className: "b316-privacy-confirm", children: [
3353
+ /* @__PURE__ */ jsxs16("label", { className: "b316-label", htmlFor: "b316-privacy-confirm", children: [
3002
3354
  "Type ",
3003
3355
  confirmWord,
3004
3356
  " to confirm"
3005
3357
  ] }),
3006
- /* @__PURE__ */ jsx15(
3358
+ /* @__PURE__ */ jsx17(
3007
3359
  "input",
3008
3360
  {
3009
3361
  id: "b316-privacy-confirm",
@@ -3013,8 +3365,8 @@ function PrivacyControls({
3013
3365
  onChange: (event) => setTyped(event.target.value)
3014
3366
  }
3015
3367
  ),
3016
- /* @__PURE__ */ jsxs14("div", { className: "b316-privacy-actions", children: [
3017
- /* @__PURE__ */ jsx15(
3368
+ /* @__PURE__ */ jsxs16("div", { className: "b316-privacy-actions", children: [
3369
+ /* @__PURE__ */ jsx17(
3018
3370
  "button",
3019
3371
  {
3020
3372
  type: "button",
@@ -3026,7 +3378,7 @@ function PrivacyControls({
3026
3378
  children: "Cancel"
3027
3379
  }
3028
3380
  ),
3029
- /* @__PURE__ */ jsx15(
3381
+ /* @__PURE__ */ jsx17(
3030
3382
  "button",
3031
3383
  {
3032
3384
  type: "button",
@@ -3042,12 +3394,12 @@ function PrivacyControls({
3042
3394
  }
3043
3395
 
3044
3396
  // src/TwoFactorManager.tsx
3045
- import { useState as useState14 } from "react";
3397
+ import { useState as useState15 } from "react";
3046
3398
 
3047
3399
  // src/QrCode.tsx
3048
3400
  import qrcode from "qrcode-generator";
3049
3401
  import { useMemo as useMemo2 } from "react";
3050
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
3402
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
3051
3403
  var QUIET_ZONE = 4;
3052
3404
  function utf8Binary(value) {
3053
3405
  let binary = "";
@@ -3074,7 +3426,7 @@ function qrPath(value) {
3074
3426
  function QrCode({ value, label, size = 180, className }) {
3075
3427
  const { path, modules } = useMemo2(() => qrPath(value), [value]);
3076
3428
  const extent = modules + QUIET_ZONE * 2;
3077
- return /* @__PURE__ */ jsxs15(
3429
+ return /* @__PURE__ */ jsxs17(
3078
3430
  "svg",
3079
3431
  {
3080
3432
  className,
@@ -3086,15 +3438,15 @@ function QrCode({ value, label, size = 180, className }) {
3086
3438
  shapeRendering: "crispEdges",
3087
3439
  xmlns: "http://www.w3.org/2000/svg",
3088
3440
  children: [
3089
- /* @__PURE__ */ jsx16("rect", { width: extent, height: extent, fill: "#ffffff" }),
3090
- /* @__PURE__ */ jsx16("path", { d: path, fill: "#000000" })
3441
+ /* @__PURE__ */ jsx18("rect", { width: extent, height: extent, fill: "#ffffff" }),
3442
+ /* @__PURE__ */ jsx18("path", { d: path, fill: "#000000" })
3091
3443
  ]
3092
3444
  }
3093
3445
  );
3094
3446
  }
3095
3447
 
3096
3448
  // src/TwoFactorManager.tsx
3097
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
3449
+ import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
3098
3450
  function groupKey(secret) {
3099
3451
  return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
3100
3452
  }
@@ -3107,12 +3459,12 @@ function TwoFactorManager({
3107
3459
  style
3108
3460
  }) {
3109
3461
  const { client, token } = useBase316();
3110
- const [stage, setStage] = useState14({ name: "idle" });
3111
- const [on, setOn] = useState14(enabled);
3112
- const [code, setCode] = useState14("");
3113
- const [phone, setPhone] = useState14("");
3114
- const [error, setError] = useState14(null);
3115
- const [busy, setBusy] = useState14(false);
3462
+ const [stage, setStage] = useState15({ name: "idle" });
3463
+ const [on, setOn] = useState15(enabled);
3464
+ const [code, setCode] = useState15("");
3465
+ const [phone, setPhone] = useState15("");
3466
+ const [error, setError] = useState15(null);
3467
+ const [busy, setBusy] = useState15(false);
3116
3468
  if (!token) {
3117
3469
  return null;
3118
3470
  }
@@ -3190,17 +3542,17 @@ function TwoFactorManager({
3190
3542
  setBusy(false);
3191
3543
  }
3192
3544
  }
3193
- return /* @__PURE__ */ jsxs16("div", { className: cls("b316-card b316-mfa", className), style, children: [
3194
- /* @__PURE__ */ jsx17("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3195
- error ? /* @__PURE__ */ jsx17("div", { className: "b316-error", role: "alert", children: error }) : null,
3196
- stage.name === "saved" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-codes", children: [
3197
- /* @__PURE__ */ jsx17("p", { children: "Save these recovery codes somewhere safe. Each one signs you in once if you lose your authenticator, and they are not shown again." }),
3198
- /* @__PURE__ */ jsx17("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ jsx17("li", { children: /* @__PURE__ */ jsx17("code", { children: recovery }) }, recovery)) }),
3199
- /* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3200
- ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-enrol", children: [
3201
- /* @__PURE__ */ jsx17("p", { children: "We will text a code to this number now, and each time you sign in." }),
3202
- /* @__PURE__ */ jsx17("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3203
- /* @__PURE__ */ jsx17(
3545
+ return /* @__PURE__ */ jsxs18("div", { className: cls("b316-card b316-mfa", className), style, children: [
3546
+ /* @__PURE__ */ jsx19("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3547
+ error ? /* @__PURE__ */ jsx19("div", { className: "b316-error", role: "alert", children: error }) : null,
3548
+ stage.name === "saved" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-codes", children: [
3549
+ /* @__PURE__ */ jsx19("p", { children: "Save these recovery codes somewhere safe. Each one signs you in once if you lose your authenticator, and they are not shown again." }),
3550
+ /* @__PURE__ */ jsx19("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ jsx19("li", { children: /* @__PURE__ */ jsx19("code", { children: recovery }) }, recovery)) }),
3551
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3552
+ ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-enrol", children: [
3553
+ /* @__PURE__ */ jsx19("p", { children: "We will text a code to this number now, and each time you sign in." }),
3554
+ /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3555
+ /* @__PURE__ */ jsx19(
3204
3556
  "input",
3205
3557
  {
3206
3558
  id: "b316-mfa-phone",
@@ -3212,8 +3564,8 @@ function TwoFactorManager({
3212
3564
  onChange: (event) => setPhone(event.target.value)
3213
3565
  }
3214
3566
  ),
3215
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
3216
- /* @__PURE__ */ jsx17(
3567
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
3568
+ /* @__PURE__ */ jsx19(
3217
3569
  "button",
3218
3570
  {
3219
3571
  type: "button",
@@ -3222,16 +3574,16 @@ function TwoFactorManager({
3222
3574
  children: "Cancel"
3223
3575
  }
3224
3576
  ),
3225
- /* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3577
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3226
3578
  ] })
3227
- ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-enrol", children: [
3228
- /* @__PURE__ */ jsxs16("p", { children: [
3579
+ ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-enrol", children: [
3580
+ /* @__PURE__ */ jsxs18("p", { children: [
3229
3581
  "We sent a code to ",
3230
3582
  stage.destinationHint,
3231
3583
  ". Enter it below to turn this on."
3232
3584
  ] }),
3233
- /* @__PURE__ */ jsx17("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3234
- /* @__PURE__ */ jsx17(
3585
+ /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3586
+ /* @__PURE__ */ jsx19(
3235
3587
  "input",
3236
3588
  {
3237
3589
  id: "b316-mfa-code",
@@ -3242,8 +3594,8 @@ function TwoFactorManager({
3242
3594
  onChange: (event) => setCode(event.target.value)
3243
3595
  }
3244
3596
  ),
3245
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
3246
- /* @__PURE__ */ jsx17(
3597
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
3598
+ /* @__PURE__ */ jsx19(
3247
3599
  "button",
3248
3600
  {
3249
3601
  type: "button",
@@ -3252,7 +3604,7 @@ function TwoFactorManager({
3252
3604
  children: "Cancel"
3253
3605
  }
3254
3606
  ),
3255
- /* @__PURE__ */ jsx17(
3607
+ /* @__PURE__ */ jsx19(
3256
3608
  "button",
3257
3609
  {
3258
3610
  type: "button",
@@ -3263,9 +3615,9 @@ function TwoFactorManager({
3263
3615
  }
3264
3616
  )
3265
3617
  ] })
3266
- ] }) : stage.name === "enrolling" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-enrol", children: [
3267
- /* @__PURE__ */ jsx17("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
3268
- /* @__PURE__ */ jsx17(
3618
+ ] }) : stage.name === "enrolling" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-enrol", children: [
3619
+ /* @__PURE__ */ jsx19("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
3620
+ /* @__PURE__ */ jsx19(
3269
3621
  QrCode,
3270
3622
  {
3271
3623
  className: "b316-mfa-qr",
@@ -3273,13 +3625,13 @@ function TwoFactorManager({
3273
3625
  label: "QR code for your authenticator app"
3274
3626
  }
3275
3627
  ),
3276
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-secret", children: [
3277
- /* @__PURE__ */ jsx17("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3278
- /* @__PURE__ */ jsx17("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
3628
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-secret", children: [
3629
+ /* @__PURE__ */ jsx19("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3630
+ /* @__PURE__ */ jsx19("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
3279
3631
  ] }),
3280
- /* @__PURE__ */ jsx17("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3281
- /* @__PURE__ */ jsx17("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3282
- /* @__PURE__ */ jsx17(
3632
+ /* @__PURE__ */ jsx19("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3633
+ /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3634
+ /* @__PURE__ */ jsx19(
3283
3635
  "input",
3284
3636
  {
3285
3637
  id: "b316-mfa-code",
@@ -3290,8 +3642,8 @@ function TwoFactorManager({
3290
3642
  onChange: (event) => setCode(event.target.value)
3291
3643
  }
3292
3644
  ),
3293
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
3294
- /* @__PURE__ */ jsx17(
3645
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
3646
+ /* @__PURE__ */ jsx19(
3295
3647
  "button",
3296
3648
  {
3297
3649
  type: "button",
@@ -3300,7 +3652,7 @@ function TwoFactorManager({
3300
3652
  children: "Cancel"
3301
3653
  }
3302
3654
  ),
3303
- /* @__PURE__ */ jsx17(
3655
+ /* @__PURE__ */ jsx19(
3304
3656
  "button",
3305
3657
  {
3306
3658
  type: "button",
@@ -3311,9 +3663,9 @@ function TwoFactorManager({
3311
3663
  }
3312
3664
  )
3313
3665
  ] })
3314
- ] }) : on ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-on", children: [
3315
- /* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3316
- /* @__PURE__ */ jsx17(
3666
+ ] }) : on ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-on", children: [
3667
+ /* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3668
+ /* @__PURE__ */ jsx19(
3317
3669
  ConfirmButton,
3318
3670
  {
3319
3671
  className: "b316-button-quiet b316-danger",
@@ -3323,11 +3675,11 @@ function TwoFactorManager({
3323
3675
  children: "Turn off"
3324
3676
  }
3325
3677
  )
3326
- ] }) : /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-off", children: [
3327
- /* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3328
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
3329
- /* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3330
- /* @__PURE__ */ jsx17(
3678
+ ] }) : /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-off", children: [
3679
+ /* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3680
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
3681
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3682
+ /* @__PURE__ */ jsx19(
3331
3683
  "button",
3332
3684
  {
3333
3685
  type: "button",
@@ -3337,7 +3689,7 @@ function TwoFactorManager({
3337
3689
  children: "Email me a code"
3338
3690
  }
3339
3691
  ),
3340
- allowSms ? /* @__PURE__ */ jsx17(
3692
+ allowSms ? /* @__PURE__ */ jsx19(
3341
3693
  "button",
3342
3694
  {
3343
3695
  type: "button",
@@ -3353,14 +3705,14 @@ function TwoFactorManager({
3353
3705
  }
3354
3706
 
3355
3707
  // src/ForgotPassword.tsx
3356
- import { useState as useState15 } from "react";
3357
- import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
3708
+ import { useState as useState16 } from "react";
3709
+ import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
3358
3710
  function ForgotPassword({ onSent, signInUrl, className, style }) {
3359
3711
  const { client } = useBase316();
3360
- const [email, setEmail] = useState15("");
3361
- const [sent, setSent] = useState15(false);
3362
- const [busy, setBusy] = useState15(false);
3363
- const [error, setError] = useState15(null);
3712
+ const [email, setEmail] = useState16("");
3713
+ const [sent, setSent] = useState16(false);
3714
+ const [busy, setBusy] = useState16(false);
3715
+ const [error, setError] = useState16(null);
3364
3716
  async function submit(event) {
3365
3717
  event.preventDefault();
3366
3718
  setBusy(true);
@@ -3376,22 +3728,22 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3376
3728
  }
3377
3729
  }
3378
3730
  if (sent) {
3379
- return /* @__PURE__ */ jsxs17("div", { className: cls("b316-card", className), style, children: [
3380
- /* @__PURE__ */ jsx18("h3", { className: "b316-form-title", children: "Check your email" }),
3381
- /* @__PURE__ */ jsxs17("p", { className: "b316-muted", children: [
3731
+ return /* @__PURE__ */ jsxs19("div", { className: cls("b316-card", className), style, children: [
3732
+ /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Check your email" }),
3733
+ /* @__PURE__ */ jsxs19("p", { className: "b316-muted", children: [
3382
3734
  "If there is an account for ",
3383
3735
  email.trim(),
3384
3736
  ", a link to set a new password is on its way."
3385
3737
  ] }),
3386
- signInUrl ? /* @__PURE__ */ jsx18("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3738
+ signInUrl ? /* @__PURE__ */ jsx20("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3387
3739
  ] });
3388
3740
  }
3389
- return /* @__PURE__ */ jsxs17("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3390
- /* @__PURE__ */ jsx18("h3", { className: "b316-form-title", children: "Reset your password" }),
3391
- error ? /* @__PURE__ */ jsx18("div", { className: "b316-error", role: "alert", children: error }) : null,
3392
- /* @__PURE__ */ jsxs17("div", { className: "b316-field", children: [
3393
- /* @__PURE__ */ jsx18("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3394
- /* @__PURE__ */ jsx18(
3741
+ return /* @__PURE__ */ jsxs19("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3742
+ /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Reset your password" }),
3743
+ error ? /* @__PURE__ */ jsx20("div", { className: "b316-error", role: "alert", children: error }) : null,
3744
+ /* @__PURE__ */ jsxs19("div", { className: "b316-field", children: [
3745
+ /* @__PURE__ */ jsx20("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3746
+ /* @__PURE__ */ jsx20(
3395
3747
  "input",
3396
3748
  {
3397
3749
  id: "b316-forgot-email",
@@ -3404,14 +3756,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3404
3756
  }
3405
3757
  )
3406
3758
  ] }),
3407
- /* @__PURE__ */ jsx18("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3408
- signInUrl ? /* @__PURE__ */ jsx18("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3759
+ /* @__PURE__ */ jsx20("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3760
+ signInUrl ? /* @__PURE__ */ jsx20("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3409
3761
  ] });
3410
3762
  }
3411
3763
 
3412
3764
  // src/ResetPassword.tsx
3413
- import { useEffect as useEffect12, useState as useState16 } from "react";
3414
- import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
3765
+ import { useEffect as useEffect13, useState as useState17 } from "react";
3766
+ import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
3415
3767
  function ResetPassword({
3416
3768
  token: supplied,
3417
3769
  onReset,
@@ -3420,13 +3772,13 @@ function ResetPassword({
3420
3772
  style
3421
3773
  }) {
3422
3774
  const { client } = useBase316();
3423
- const [token, setToken] = useState16(supplied ?? null);
3424
- const [password, setPassword] = useState16("");
3425
- const [confirmation, setConfirmation] = useState16("");
3426
- const [done, setDone] = useState16(false);
3427
- const [busy, setBusy] = useState16(false);
3428
- const [error, setError] = useState16(null);
3429
- useEffect12(() => {
3775
+ const [token, setToken] = useState17(supplied ?? null);
3776
+ const [password, setPassword] = useState17("");
3777
+ const [confirmation, setConfirmation] = useState17("");
3778
+ const [done, setDone] = useState17(false);
3779
+ const [busy, setBusy] = useState17(false);
3780
+ const [error, setError] = useState17(null);
3781
+ useEffect13(() => {
3430
3782
  if (supplied || typeof window === "undefined") {
3431
3783
  return;
3432
3784
  }
@@ -3461,24 +3813,24 @@ function ResetPassword({
3461
3813
  }
3462
3814
  }
3463
3815
  if (done) {
3464
- return /* @__PURE__ */ jsxs18("div", { className: cls("b316-card", className), style, children: [
3465
- /* @__PURE__ */ jsx19("h3", { className: "b316-form-title", children: "Password changed" }),
3466
- /* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3467
- signInUrl ? /* @__PURE__ */ jsx19("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3816
+ return /* @__PURE__ */ jsxs20("div", { className: cls("b316-card", className), style, children: [
3817
+ /* @__PURE__ */ jsx21("h3", { className: "b316-form-title", children: "Password changed" }),
3818
+ /* @__PURE__ */ jsx21("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3819
+ signInUrl ? /* @__PURE__ */ jsx21("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3468
3820
  ] });
3469
3821
  }
3470
3822
  if (!token) {
3471
- return /* @__PURE__ */ jsxs18("div", { className: cls("b316-card", className), style, children: [
3472
- /* @__PURE__ */ jsx19("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3473
- /* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3823
+ return /* @__PURE__ */ jsxs20("div", { className: cls("b316-card", className), style, children: [
3824
+ /* @__PURE__ */ jsx21("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3825
+ /* @__PURE__ */ jsx21("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3474
3826
  ] });
3475
3827
  }
3476
- return /* @__PURE__ */ jsxs18("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3477
- /* @__PURE__ */ jsx19("h3", { className: "b316-form-title", children: "Choose a new password" }),
3478
- error ? /* @__PURE__ */ jsx19("div", { className: "b316-error", role: "alert", children: error }) : null,
3479
- /* @__PURE__ */ jsxs18("div", { className: "b316-field", children: [
3480
- /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3481
- /* @__PURE__ */ jsx19(
3828
+ return /* @__PURE__ */ jsxs20("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3829
+ /* @__PURE__ */ jsx21("h3", { className: "b316-form-title", children: "Choose a new password" }),
3830
+ error ? /* @__PURE__ */ jsx21("div", { className: "b316-error", role: "alert", children: error }) : null,
3831
+ /* @__PURE__ */ jsxs20("div", { className: "b316-field", children: [
3832
+ /* @__PURE__ */ jsx21("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3833
+ /* @__PURE__ */ jsx21(
3482
3834
  "input",
3483
3835
  {
3484
3836
  id: "b316-reset-password",
@@ -3491,9 +3843,9 @@ function ResetPassword({
3491
3843
  }
3492
3844
  )
3493
3845
  ] }),
3494
- /* @__PURE__ */ jsxs18("div", { className: "b316-field", children: [
3495
- /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3496
- /* @__PURE__ */ jsx19(
3846
+ /* @__PURE__ */ jsxs20("div", { className: "b316-field", children: [
3847
+ /* @__PURE__ */ jsx21("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3848
+ /* @__PURE__ */ jsx21(
3497
3849
  "input",
3498
3850
  {
3499
3851
  id: "b316-reset-confirm",
@@ -3506,13 +3858,13 @@ function ResetPassword({
3506
3858
  }
3507
3859
  )
3508
3860
  ] }),
3509
- /* @__PURE__ */ jsx19("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
3861
+ /* @__PURE__ */ jsx21("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
3510
3862
  ] });
3511
3863
  }
3512
3864
 
3513
3865
  // src/VerifyEmail.tsx
3514
- import { useEffect as useEffect13, useRef as useRef4, useState as useState17 } from "react";
3515
- import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
3866
+ import { useEffect as useEffect14, useRef as useRef4, useState as useState18 } from "react";
3867
+ import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
3516
3868
  function VerifyEmail({
3517
3869
  token: supplied,
3518
3870
  onVerified,
@@ -3521,9 +3873,9 @@ function VerifyEmail({
3521
3873
  style
3522
3874
  }) {
3523
3875
  const { client } = useBase316();
3524
- const [state, setState] = useState17("waiting");
3876
+ const [state, setState] = useState18("waiting");
3525
3877
  const spent = useRef4(false);
3526
- useEffect13(() => {
3878
+ useEffect14(() => {
3527
3879
  if (spent.current) {
3528
3880
  return;
3529
3881
  }
@@ -3549,22 +3901,22 @@ function VerifyEmail({
3549
3901
  setState("failed");
3550
3902
  });
3551
3903
  }, [client, supplied, onVerified]);
3552
- return /* @__PURE__ */ jsx20("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
3553
- /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Email confirmed" }),
3554
- /* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3555
- continueUrl ? /* @__PURE__ */ jsx20("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3556
- ] }) : state === "failed" ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
3557
- /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "That link did not work" }),
3558
- /* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
3559
- ] }) : state === "missing" ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
3560
- /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3561
- /* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "This page needs the link from your email." })
3562
- ] }) : /* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
3904
+ return /* @__PURE__ */ jsx22("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
3905
+ /* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "Email confirmed" }),
3906
+ /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3907
+ continueUrl ? /* @__PURE__ */ jsx22("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3908
+ ] }) : state === "failed" ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
3909
+ /* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "That link did not work" }),
3910
+ /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
3911
+ ] }) : state === "missing" ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
3912
+ /* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3913
+ /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "This page needs the link from your email." })
3914
+ ] }) : /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
3563
3915
  }
3564
3916
 
3565
3917
  // src/TeamMembers.tsx
3566
- import { useCallback as useCallback7, useEffect as useEffect14, useState as useState18 } from "react";
3567
- import { Fragment as Fragment6, jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
3918
+ import { useCallback as useCallback7, useEffect as useEffect15, useState as useState19 } from "react";
3919
+ import { Fragment as Fragment8, jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
3568
3920
  function TeamMembers({
3569
3921
  organizationId,
3570
3922
  onInvited,
@@ -3574,13 +3926,13 @@ function TeamMembers({
3574
3926
  style
3575
3927
  }) {
3576
3928
  const { client, token, session } = useBase316();
3577
- const [teams, setTeams] = useState18(null);
3578
- const [members, setMembers] = useState18(null);
3579
- const [invitations, setInvitations] = useState18(null);
3580
- const [email, setEmail] = useState18("");
3581
- const [busy, setBusy] = useState18(false);
3582
- const [error, setError] = useState18(null);
3583
- const [copied, setCopied] = useState18(null);
3929
+ const [teams, setTeams] = useState19(null);
3930
+ const [members, setMembers] = useState19(null);
3931
+ const [invitations, setInvitations] = useState19(null);
3932
+ const [email, setEmail] = useState19("");
3933
+ const [busy, setBusy] = useState19(false);
3934
+ const [error, setError] = useState19(null);
3935
+ const [copied, setCopied] = useState19(null);
3584
3936
  const chosen = organizationId ?? (teams?.length === 1 ? teams[0].id : null);
3585
3937
  const team = teams?.find((candidate) => candidate.id === chosen) ?? null;
3586
3938
  const load = useCallback7(() => {
@@ -3591,8 +3943,8 @@ function TeamMembers({
3591
3943
  (cause) => setError(cause instanceof Error ? cause.message : "Could not load your teams.")
3592
3944
  );
3593
3945
  }, [client, token]);
3594
- useEffect14(load, [load]);
3595
- useEffect14(() => {
3946
+ useEffect15(load, [load]);
3947
+ useEffect15(() => {
3596
3948
  if (!token || !chosen) {
3597
3949
  return;
3598
3950
  }
@@ -3623,10 +3975,10 @@ function TeamMembers({
3623
3975
  return null;
3624
3976
  }
3625
3977
  if (!teams) {
3626
- return /* @__PURE__ */ jsx21("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
3978
+ return /* @__PURE__ */ jsx23("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
3627
3979
  }
3628
3980
  if (!chosen) {
3629
- return /* @__PURE__ */ jsx21("div", { className: cls("b316-card", className), style, children: teams.length === 0 ? "You are not in a team yet." : "You are in more than one team. Name which with the organizationId prop." });
3981
+ return /* @__PURE__ */ jsx23("div", { className: cls("b316-card", className), style, children: teams.length === 0 ? "You are not in a team yet." : "You are in more than one team. Name which with the organizationId prop." });
3630
3982
  }
3631
3983
  const canManage = invitations !== null;
3632
3984
  async function invite(event) {
@@ -3676,30 +4028,30 @@ function TeamMembers({
3676
4028
  setError(cause instanceof Error ? cause.message : "That invitation could not be withdrawn.");
3677
4029
  }
3678
4030
  }
3679
- return /* @__PURE__ */ jsxs20("div", { className: cls("b316-card b316-team", className), style, children: [
3680
- /* @__PURE__ */ jsx21("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
4031
+ return /* @__PURE__ */ jsxs22("div", { className: cls("b316-card b316-team", className), style, children: [
4032
+ /* @__PURE__ */ jsx23("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
3681
4033
  team?.inherited ? (
3682
4034
  // Not a member of this team, so not in the list below and with nothing
3683
4035
  // to leave: access comes from the team that manages it, and ends there.
3684
- /* @__PURE__ */ jsxs20("div", { className: "b316-muted", children: [
4036
+ /* @__PURE__ */ jsxs22("div", { className: "b316-muted", children: [
3685
4037
  "You have access through",
3686
4038
  " ",
3687
4039
  teams.find((candidate) => candidate.id === team.via)?.name ?? "the organization that manages this team",
3688
4040
  "."
3689
4041
  ] })
3690
4042
  ) : null,
3691
- error ? /* @__PURE__ */ jsx21("div", { className: "b316-error", role: "alert", children: error }) : null,
3692
- /* @__PURE__ */ jsx21("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ jsxs20("li", { className: "b316-team-member", children: [
3693
- /* @__PURE__ */ jsxs20("div", { children: [
3694
- /* @__PURE__ */ jsx21("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
3695
- /* @__PURE__ */ jsxs20("div", { className: "b316-muted", children: [
4043
+ error ? /* @__PURE__ */ jsx23("div", { className: "b316-error", role: "alert", children: error }) : null,
4044
+ /* @__PURE__ */ jsx23("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ jsxs22("li", { className: "b316-team-member", children: [
4045
+ /* @__PURE__ */ jsxs22("div", { children: [
4046
+ /* @__PURE__ */ jsx23("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
4047
+ /* @__PURE__ */ jsxs22("div", { className: "b316-muted", children: [
3696
4048
  member.user.email,
3697
4049
  member.user.id === session?.userId ? " \xB7 you" : ""
3698
4050
  ] })
3699
4051
  ] }),
3700
- /* @__PURE__ */ jsxs20("div", { className: "b316-team-member-side", children: [
3701
- /* @__PURE__ */ jsx21("span", { className: "b316-chip", children: member.role.name }),
3702
- canManage || member.user.id === session?.userId ? /* @__PURE__ */ jsx21(
4052
+ /* @__PURE__ */ jsxs22("div", { className: "b316-team-member-side", children: [
4053
+ /* @__PURE__ */ jsx23("span", { className: "b316-chip", children: member.role.name }),
4054
+ canManage || member.user.id === session?.userId ? /* @__PURE__ */ jsx23(
3703
4055
  ConfirmButton,
3704
4056
  {
3705
4057
  className: "b316-button-quiet b316-danger",
@@ -3711,19 +4063,19 @@ function TeamMembers({
3711
4063
  ) : null
3712
4064
  ] })
3713
4065
  ] }, member.id)) }),
3714
- canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ jsxs20(Fragment6, { children: [
3715
- /* @__PURE__ */ jsx21("h4", { className: "b316-team-subtitle", children: "Invited" }),
3716
- /* @__PURE__ */ jsx21("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ jsxs20("li", { className: "b316-team-member", children: [
3717
- /* @__PURE__ */ jsxs20("div", { children: [
3718
- /* @__PURE__ */ jsx21("div", { children: invitation.email }),
3719
- /* @__PURE__ */ jsxs20("div", { className: "b316-muted", children: [
4066
+ canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ jsxs22(Fragment8, { children: [
4067
+ /* @__PURE__ */ jsx23("h4", { className: "b316-team-subtitle", children: "Invited" }),
4068
+ /* @__PURE__ */ jsx23("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ jsxs22("li", { className: "b316-team-member", children: [
4069
+ /* @__PURE__ */ jsxs22("div", { children: [
4070
+ /* @__PURE__ */ jsx23("div", { children: invitation.email }),
4071
+ /* @__PURE__ */ jsxs22("div", { className: "b316-muted", children: [
3720
4072
  invitation.role.name,
3721
4073
  " \xB7 expires",
3722
4074
  " ",
3723
4075
  new Date(invitation.expiresAt).toLocaleDateString()
3724
4076
  ] })
3725
4077
  ] }),
3726
- /* @__PURE__ */ jsx21(
4078
+ /* @__PURE__ */ jsx23(
3727
4079
  "button",
3728
4080
  {
3729
4081
  type: "button",
@@ -3734,10 +4086,10 @@ function TeamMembers({
3734
4086
  )
3735
4087
  ] }, invitation.id)) })
3736
4088
  ] }) : null,
3737
- canManage ? /* @__PURE__ */ jsxs20("form", { className: "b316-team-invite", onSubmit: invite, children: [
3738
- /* @__PURE__ */ jsx21("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
3739
- /* @__PURE__ */ jsxs20("div", { className: "b316-team-invite-row", children: [
3740
- /* @__PURE__ */ jsx21(
4089
+ canManage ? /* @__PURE__ */ jsxs22("form", { className: "b316-team-invite", onSubmit: invite, children: [
4090
+ /* @__PURE__ */ jsx23("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
4091
+ /* @__PURE__ */ jsxs22("div", { className: "b316-team-invite-row", children: [
4092
+ /* @__PURE__ */ jsx23(
3741
4093
  "input",
3742
4094
  {
3743
4095
  id: "b316-invite-email",
@@ -3749,19 +4101,19 @@ function TeamMembers({
3749
4101
  onChange: (event) => setEmail(event.target.value)
3750
4102
  }
3751
4103
  ),
3752
- /* @__PURE__ */ jsx21("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
4104
+ /* @__PURE__ */ jsx23("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
3753
4105
  ] })
3754
4106
  ] }) : null,
3755
- copied ? /* @__PURE__ */ jsxs20("div", { className: "b316-team-link", children: [
3756
- /* @__PURE__ */ jsx21("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
3757
- /* @__PURE__ */ jsx21("code", { children: copied })
4107
+ copied ? /* @__PURE__ */ jsxs22("div", { className: "b316-team-link", children: [
4108
+ /* @__PURE__ */ jsx23("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
4109
+ /* @__PURE__ */ jsx23("code", { children: copied })
3758
4110
  ] }) : null
3759
4111
  ] });
3760
4112
  }
3761
4113
 
3762
4114
  // src/AcceptInvitation.tsx
3763
- import { useEffect as useEffect15, useState as useState19 } from "react";
3764
- import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
4115
+ import { useEffect as useEffect16, useState as useState20 } from "react";
4116
+ import { Fragment as Fragment9, jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
3765
4117
  function signUpUrlWithInvitation(url, token) {
3766
4118
  const [beforeHash, ...hash] = url.split("#");
3767
4119
  const base = beforeHash ?? "";
@@ -3780,18 +4132,18 @@ function AcceptInvitation({
3780
4132
  style
3781
4133
  }) {
3782
4134
  const { client, token: session, session: user } = useBase316();
3783
- const [invitationToken, setInvitationToken] = useState19(supplied ?? null);
3784
- const [preview, setPreview] = useState19(null);
3785
- const [state, setState] = useState19("loading");
3786
- const [error, setError] = useState19(null);
3787
- const [busy, setBusy] = useState19(false);
3788
- useEffect15(() => {
4135
+ const [invitationToken, setInvitationToken] = useState20(supplied ?? null);
4136
+ const [preview, setPreview] = useState20(null);
4137
+ const [state, setState] = useState20("loading");
4138
+ const [error, setError] = useState20(null);
4139
+ const [busy, setBusy] = useState20(false);
4140
+ useEffect16(() => {
3789
4141
  if (supplied || typeof window === "undefined") {
3790
4142
  return;
3791
4143
  }
3792
4144
  setInvitationToken(new URL(window.location.href).searchParams.get("invitation"));
3793
4145
  }, [supplied]);
3794
- useEffect15(() => {
4146
+ useEffect16(() => {
3795
4147
  if (!invitationToken) {
3796
4148
  setState(supplied === void 0 ? "loading" : "invalid");
3797
4149
  return;
@@ -3828,42 +4180,42 @@ function AcceptInvitation({
3828
4180
  }
3829
4181
  }
3830
4182
  if (state === "loading") {
3831
- return /* @__PURE__ */ jsx22("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
4183
+ return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3832
4184
  }
3833
4185
  if (state === "invalid") {
3834
- return /* @__PURE__ */ jsxs21("div", { className: cls("b316-card", className), style, children: [
3835
- /* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
3836
- /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
4186
+ return /* @__PURE__ */ jsxs23("div", { className: cls("b316-card", className), style, children: [
4187
+ /* @__PURE__ */ jsx24("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
4188
+ /* @__PURE__ */ jsx24("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
3837
4189
  ] });
3838
4190
  }
3839
4191
  if (state === "accepted") {
3840
- return /* @__PURE__ */ jsx22("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs21("h3", { className: "b316-form-title", children: [
4192
+ return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs23("h3", { className: "b316-form-title", children: [
3841
4193
  "You have joined ",
3842
4194
  preview?.organizationName
3843
4195
  ] }) });
3844
4196
  }
3845
4197
  const matches = !user || (user.user.email ?? "").toLowerCase() === preview?.email.toLowerCase();
3846
- return /* @__PURE__ */ jsxs21("div", { className: cls("b316-card b316-invitation", className), style, children: [
3847
- /* @__PURE__ */ jsxs21("h3", { className: "b316-form-title", children: [
4198
+ return /* @__PURE__ */ jsxs23("div", { className: cls("b316-card b316-invitation", className), style, children: [
4199
+ /* @__PURE__ */ jsxs23("h3", { className: "b316-form-title", children: [
3848
4200
  "Join ",
3849
4201
  preview?.organizationName
3850
4202
  ] }),
3851
- /* @__PURE__ */ jsxs21("p", { className: "b316-muted", children: [
4203
+ /* @__PURE__ */ jsxs23("p", { className: "b316-muted", children: [
3852
4204
  "Invited as ",
3853
4205
  preview?.email,
3854
4206
  " \xB7 ",
3855
4207
  preview?.roleName
3856
4208
  ] }),
3857
- error ? /* @__PURE__ */ jsx22("div", { className: "b316-error", role: "alert", children: error }) : null,
3858
- !session ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
3859
- /* @__PURE__ */ jsxs21("p", { children: [
4209
+ error ? /* @__PURE__ */ jsx24("div", { className: "b316-error", role: "alert", children: error }) : null,
4210
+ !session ? /* @__PURE__ */ jsxs23(Fragment9, { children: [
4211
+ /* @__PURE__ */ jsxs23("p", { children: [
3860
4212
  "Sign in as ",
3861
4213
  preview?.email,
3862
4214
  " to accept."
3863
4215
  ] }),
3864
- /* @__PURE__ */ jsxs21("div", { className: "b316-invitation-actions", children: [
3865
- signInUrl ? /* @__PURE__ */ jsx22("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
3866
- signUpUrl ? /* @__PURE__ */ jsx22(
4216
+ /* @__PURE__ */ jsxs23("div", { className: "b316-invitation-actions", children: [
4217
+ signInUrl ? /* @__PURE__ */ jsx24("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
4218
+ signUpUrl ? /* @__PURE__ */ jsx24(
3867
4219
  "a",
3868
4220
  {
3869
4221
  className: "b316-button-link",
@@ -3876,20 +4228,20 @@ function AcceptInvitation({
3876
4228
  // Said before they press anything. The server refuses this, but
3877
4229
  // finding out after a click reads as a broken invitation rather than
3878
4230
  // as being signed in as the wrong person.
3879
- /* @__PURE__ */ jsxs21("p", { children: [
4231
+ /* @__PURE__ */ jsxs23("p", { children: [
3880
4232
  "You are signed in as ",
3881
4233
  user?.user.email,
3882
4234
  ". This invitation was sent to ",
3883
4235
  preview?.email,
3884
4236
  " \u2014 sign in as that address to accept it."
3885
4237
  ] })
3886
- ) : /* @__PURE__ */ jsx22("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
4238
+ ) : /* @__PURE__ */ jsx24("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
3887
4239
  ] });
3888
4240
  }
3889
4241
 
3890
4242
  // src/PayInvoice.tsx
3891
- import { useEffect as useEffect16, useRef as useRef5, useState as useState20 } from "react";
3892
- import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
4243
+ import { useEffect as useEffect17, useRef as useRef5, useState as useState21 } from "react";
4244
+ import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3893
4245
  var STRIPE_SRC = "https://js.stripe.com/v3/";
3894
4246
  function loadStripeScript() {
3895
4247
  if (typeof window === "undefined") {
@@ -3924,11 +4276,11 @@ function PayInvoice({
3924
4276
  const mountRef = useRef5(null);
3925
4277
  const stripeRef = useRef5(null);
3926
4278
  const elementsRef = useRef5(null);
3927
- const [ready, setReady] = useState20(false);
3928
- const [paying, setPaying] = useState20(false);
3929
- const [done, setDone] = useState20(false);
3930
- const [error, setError] = useState20(null);
3931
- useEffect16(() => {
4279
+ const [ready, setReady] = useState21(false);
4280
+ const [paying, setPaying] = useState21(false);
4281
+ const [done, setDone] = useState21(false);
4282
+ const [error, setError] = useState21(null);
4283
+ useEffect17(() => {
3932
4284
  let cancelled = false;
3933
4285
  async function start() {
3934
4286
  const base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;
@@ -3981,17 +4333,17 @@ function PayInvoice({
3981
4333
  onPaid?.();
3982
4334
  };
3983
4335
  if (done) {
3984
- return /* @__PURE__ */ jsx23("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ jsx23("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
4336
+ return /* @__PURE__ */ jsx25("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ jsx25("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
3985
4337
  }
3986
- return /* @__PURE__ */ jsxs22("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
3987
- error ? /* @__PURE__ */ jsx23("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
3988
- /* @__PURE__ */ jsx23("div", { ref: mountRef, className: "b316-pay__element" }),
3989
- /* @__PURE__ */ jsx23("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
4338
+ return /* @__PURE__ */ jsxs24("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
4339
+ error ? /* @__PURE__ */ jsx25("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
4340
+ /* @__PURE__ */ jsx25("div", { ref: mountRef, className: "b316-pay__element" }),
4341
+ /* @__PURE__ */ jsx25("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
3990
4342
  ] });
3991
4343
  }
3992
4344
 
3993
4345
  // src/usePaymentLink.ts
3994
- import { useEffect as useEffect17, useRef as useRef6, useState as useState21 } from "react";
4346
+ import { useEffect as useEffect18, useRef as useRef6, useState as useState22 } from "react";
3995
4347
  function usePaymentLink({
3996
4348
  token,
3997
4349
  environmentId,
@@ -3999,10 +4351,10 @@ function usePaymentLink({
3999
4351
  onPaid
4000
4352
  }) {
4001
4353
  const { client } = useBase316();
4002
- const [status2, setStatus] = useState21({ state: "loading" });
4354
+ const [status2, setStatus] = useState22({ state: "loading" });
4003
4355
  const onPaidRef = useRef6(onPaid);
4004
4356
  onPaidRef.current = onPaid;
4005
- useEffect17(() => {
4357
+ useEffect18(() => {
4006
4358
  let stopped = false;
4007
4359
  let timer;
4008
4360
  const statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;
@@ -4051,23 +4403,23 @@ function usePaymentLink({
4051
4403
  }
4052
4404
 
4053
4405
  // src/PricingTable.tsx
4054
- import { useState as useState23 } from "react";
4406
+ import { useState as useState24 } from "react";
4055
4407
 
4056
4408
  // src/usePlans.ts
4057
- import { useCallback as useCallback8, useEffect as useEffect18, useState as useState22 } from "react";
4409
+ import { useCallback as useCallback8, useEffect as useEffect19, useState as useState23 } from "react";
4058
4410
  var CHECKOUT_STATUSES = /* @__PURE__ */ new Set([402, 409]);
4059
4411
  function usePlans(options = {}) {
4060
4412
  const { client, token } = useBase316();
4061
- const [plans, setPlans] = useState22(null);
4062
- const [error, setError] = useState22(false);
4063
- const [busyPlanVersionId, setBusy] = useState22(null);
4064
- const [lastError, setLastError] = useState22(null);
4065
- const [ownPlanVersionId, setOwnPlanVersionId] = useState22(null);
4066
- const [managedBy, setManagedBy] = useState22(null);
4067
- const [reloadCount, setReloadCount] = useState22(0);
4413
+ const [plans, setPlans] = useState23(null);
4414
+ const [error, setError] = useState23(false);
4415
+ const [busyPlanVersionId, setBusy] = useState23(null);
4416
+ const [lastError, setLastError] = useState23(null);
4417
+ const [ownPlanVersionId, setOwnPlanVersionId] = useState23(null);
4418
+ const [managedBy, setManagedBy] = useState23(null);
4419
+ const [reloadCount, setReloadCount] = useState23(0);
4068
4420
  const supplied = options.currentPlanVersionId;
4069
4421
  const discover = supplied === void 0;
4070
- useEffect18(() => {
4422
+ useEffect19(() => {
4071
4423
  let cancelled = false;
4072
4424
  client.billing.plans().then((result) => {
4073
4425
  if (!cancelled) {
@@ -4083,7 +4435,7 @@ function usePlans(options = {}) {
4083
4435
  cancelled = true;
4084
4436
  };
4085
4437
  }, [client, reloadCount]);
4086
- useEffect18(() => {
4438
+ useEffect19(() => {
4087
4439
  if (!token) {
4088
4440
  return;
4089
4441
  }
@@ -4172,7 +4524,7 @@ function usePlans(options = {}) {
4172
4524
  }
4173
4525
 
4174
4526
  // src/PricingTable.tsx
4175
- import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
4527
+ import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
4176
4528
  function formatAmount(amount, currency) {
4177
4529
  if (amount === null) return "Free";
4178
4530
  const value = Number(amount);
@@ -4221,7 +4573,7 @@ function PricingTable({
4221
4573
  managedBy,
4222
4574
  selectPlan
4223
4575
  } = usePlans({ currentPlanVersionId });
4224
- const [scheduled, setScheduled] = useState23(null);
4576
+ const [scheduled, setScheduled] = useState24(null);
4225
4577
  async function choose(plan) {
4226
4578
  if (onSelectPlan) {
4227
4579
  await onSelectPlan(plan.planVersionId, plan);
@@ -4238,50 +4590,50 @@ function PricingTable({
4238
4590
  }
4239
4591
  }
4240
4592
  if (error) {
4241
- return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4593
+ return /* @__PURE__ */ jsx26("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4242
4594
  }
4243
4595
  if (!plans) {
4244
- return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4596
+ return /* @__PURE__ */ jsx26("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4245
4597
  }
4246
4598
  if (plans.length === 0) {
4247
- return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4599
+ return /* @__PURE__ */ jsx26("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4248
4600
  }
4249
4601
  const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
4250
4602
  const anyDescription = plans.some((plan) => Boolean(plan.description));
4251
4603
  const anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);
4252
- return /* @__PURE__ */ jsxs23("div", { className: cls("b316-plans", className), style, children: [
4604
+ return /* @__PURE__ */ jsxs25("div", { className: cls("b316-plans", className), style, children: [
4253
4605
  managedBy ? (
4254
4606
  // A client company's plan comes from the firm that runs it. The table
4255
4607
  // still shows what is on offer, with the current plan marked, but
4256
4608
  // nothing here can be bought: it would grant this account nothing.
4257
- /* @__PURE__ */ jsxs23("div", { className: "b316-plans-managed b316-muted", children: [
4609
+ /* @__PURE__ */ jsxs25("div", { className: "b316-plans-managed b316-muted", children: [
4258
4610
  "Your plan is provided by ",
4259
4611
  managedBy.name ?? "the organization that manages your account",
4260
4612
  ". Ask them to change it."
4261
4613
  ] })
4262
- ) : lastError ? /* @__PURE__ */ jsx24("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ jsx24("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4614
+ ) : lastError ? /* @__PURE__ */ jsx26("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ jsx26("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4263
4615
  plans.map((plan) => {
4264
4616
  const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
4265
4617
  const isCurrent = current === plan.planVersionId;
4266
4618
  const featured = featuredPlanKey === plan.key;
4267
- return /* @__PURE__ */ jsxs23(
4619
+ return /* @__PURE__ */ jsxs25(
4268
4620
  "div",
4269
4621
  {
4270
4622
  className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
4271
4623
  children: [
4272
- /* @__PURE__ */ jsxs23("div", { className: "b316-plan-head", children: [
4273
- anyFeatured ? /* @__PURE__ */ jsx24("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4274
- /* @__PURE__ */ jsx24("div", { className: "b316-plan-name", children: plan.name }),
4275
- anyDescription ? /* @__PURE__ */ jsx24("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4624
+ /* @__PURE__ */ jsxs25("div", { className: "b316-plan-head", children: [
4625
+ anyFeatured ? /* @__PURE__ */ jsx26("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4626
+ /* @__PURE__ */ jsx26("div", { className: "b316-plan-name", children: plan.name }),
4627
+ anyDescription ? /* @__PURE__ */ jsx26("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4276
4628
  ] }),
4277
- /* @__PURE__ */ jsxs23("div", { className: "b316-plan-pricing", children: [
4278
- /* @__PURE__ */ jsx24("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4279
- /* @__PURE__ */ jsx24("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4280
- anyTrial ? /* @__PURE__ */ jsx24("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4629
+ /* @__PURE__ */ jsxs25("div", { className: "b316-plan-pricing", children: [
4630
+ /* @__PURE__ */ jsx26("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4631
+ /* @__PURE__ */ jsx26("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4632
+ anyTrial ? /* @__PURE__ */ jsx26("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4281
4633
  ] }),
4282
- /* @__PURE__ */ jsx24("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ jsxs23("li", { className: "b316-plan-feature", children: [
4283
- /* @__PURE__ */ jsx24("span", { children: entitlement.featureName }),
4284
- /* @__PURE__ */ jsx24("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4634
+ /* @__PURE__ */ jsx26("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ jsxs25("li", { className: "b316-plan-feature", children: [
4635
+ /* @__PURE__ */ jsx26("span", { children: entitlement.featureName }),
4636
+ /* @__PURE__ */ jsx26("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4285
4637
  // A usage price on the feature makes the limit an
4286
4638
  // allowance billed past, not a ceiling — the same
4287
4639
  // rule `check()` applies (any non-FLAT price).
@@ -4290,7 +4642,7 @@ function PricingTable({
4290
4642
  ) ? `${entitlement.limit} included` : entitlement.limit
4291
4643
  ) })
4292
4644
  ] }, entitlement.featureId)) }),
4293
- /* @__PURE__ */ jsx24("div", { className: "b316-plan-action", children: /* @__PURE__ */ jsx24(
4645
+ /* @__PURE__ */ jsx26("div", { className: "b316-plan-action", children: /* @__PURE__ */ jsx26(
4294
4646
  "button",
4295
4647
  {
4296
4648
  type: "button",
@@ -4312,14 +4664,14 @@ function PricingTable({
4312
4664
 
4313
4665
  // src/DataTable.tsx
4314
4666
  import { specFor as specFor3 } from "@base316/sdk";
4315
- import { useState as useState27 } from "react";
4667
+ import { useState as useState28 } from "react";
4316
4668
 
4317
4669
  // src/fields.tsx
4318
4670
  import {
4319
4671
  formatAddress,
4320
4672
  specFor
4321
4673
  } from "@base316/sdk";
4322
- import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
4674
+ import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
4323
4675
  function formatNumber(value, fraction = 0) {
4324
4676
  const number = Number(value);
4325
4677
  return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
@@ -4341,10 +4693,10 @@ function formatDuration(value) {
4341
4693
  }
4342
4694
  function FieldCell({ value, field, related }) {
4343
4695
  if (field.type === "RELATION") {
4344
- return related?.title ?? (related?.id ? /* @__PURE__ */ jsx25("code", { className: "b316-muted", children: related.id }) : "\u2014");
4696
+ return related?.title ?? (related?.id ? /* @__PURE__ */ jsx27("code", { className: "b316-muted", children: related.id }) : "\u2014");
4345
4697
  }
4346
4698
  if (value === null || value === void 0 || value === "") {
4347
- return /* @__PURE__ */ jsx25("span", { className: "b316-muted", children: "\u2014" });
4699
+ return /* @__PURE__ */ jsx27("span", { className: "b316-muted", children: "\u2014" });
4348
4700
  }
4349
4701
  switch (field.type) {
4350
4702
  case "BOOLEAN":
@@ -4357,9 +4709,9 @@ function FieldCell({ value, field, related }) {
4357
4709
  return formatDuration(value);
4358
4710
  case "RATING": {
4359
4711
  const stars = Math.round(Number(value));
4360
- return /* @__PURE__ */ jsxs24("span", { "aria-label": `${stars} out of 5`, children: [
4712
+ return /* @__PURE__ */ jsxs26("span", { "aria-label": `${stars} out of 5`, children: [
4361
4713
  "\u2605".repeat(stars),
4362
- /* @__PURE__ */ jsx25("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4714
+ /* @__PURE__ */ jsx27("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4363
4715
  ] });
4364
4716
  }
4365
4717
  case "DATE":
@@ -4367,15 +4719,15 @@ function FieldCell({ value, field, related }) {
4367
4719
  case "DATETIME":
4368
4720
  return new Date(String(value)).toLocaleString();
4369
4721
  case "SELECT":
4370
- return /* @__PURE__ */ jsx25("span", { className: "b316-chip", children: String(value) });
4722
+ return /* @__PURE__ */ jsx27("span", { className: "b316-chip", children: String(value) });
4371
4723
  case "MULTISELECT":
4372
- return /* @__PURE__ */ jsx25("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ jsx25("span", { className: "b316-chip", children: String(item) }, String(item))) });
4724
+ return /* @__PURE__ */ jsx27("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ jsx27("span", { className: "b316-chip", children: String(item) }, String(item))) });
4373
4725
  case "URL":
4374
- return /* @__PURE__ */ jsx25("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4726
+ return /* @__PURE__ */ jsx27("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4375
4727
  case "EMAIL":
4376
- return /* @__PURE__ */ jsx25("a", { href: `mailto:${String(value)}`, children: String(value) });
4728
+ return /* @__PURE__ */ jsx27("a", { href: `mailto:${String(value)}`, children: String(value) });
4377
4729
  case "PHONE":
4378
- return /* @__PURE__ */ jsx25("a", { href: `tel:${String(value)}`, children: String(value) });
4730
+ return /* @__PURE__ */ jsx27("a", { href: `tel:${String(value)}`, children: String(value) });
4379
4731
  case "ADDRESS":
4380
4732
  return formatAddress(value);
4381
4733
  case "ATTACHMENT": {
@@ -4387,7 +4739,7 @@ function FieldCell({ value, field, related }) {
4387
4739
  return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
4388
4740
  }
4389
4741
  case "JSON":
4390
- return /* @__PURE__ */ jsx25("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4742
+ return /* @__PURE__ */ jsx27("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4391
4743
  default:
4392
4744
  return String(value);
4393
4745
  }
@@ -4408,7 +4760,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4408
4760
  function control() {
4409
4761
  switch (field.type) {
4410
4762
  case "LONGTEXT":
4411
- return /* @__PURE__ */ jsx25(
4763
+ return /* @__PURE__ */ jsx27(
4412
4764
  "textarea",
4413
4765
  {
4414
4766
  ...common,
@@ -4418,7 +4770,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4418
4770
  }
4419
4771
  );
4420
4772
  case "BOOLEAN":
4421
- return /* @__PURE__ */ jsx25(
4773
+ return /* @__PURE__ */ jsx27(
4422
4774
  "input",
4423
4775
  {
4424
4776
  ...common,
@@ -4429,22 +4781,22 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4429
4781
  }
4430
4782
  );
4431
4783
  case "SELECT":
4432
- return /* @__PURE__ */ jsxs24(
4784
+ return /* @__PURE__ */ jsxs26(
4433
4785
  "select",
4434
4786
  {
4435
4787
  ...common,
4436
4788
  value: value === null || value === void 0 ? "" : String(value),
4437
4789
  onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
4438
4790
  children: [
4439
- field.required ? null : /* @__PURE__ */ jsx25("option", { value: "", children: "\u2014" }),
4440
- (field.options ?? []).map((option) => /* @__PURE__ */ jsx25("option", { value: option, children: option }, option))
4791
+ field.required ? null : /* @__PURE__ */ jsx27("option", { value: "", children: "\u2014" }),
4792
+ (field.options ?? []).map((option) => /* @__PURE__ */ jsx27("option", { value: option, children: option }, option))
4441
4793
  ]
4442
4794
  }
4443
4795
  );
4444
4796
  case "MULTISELECT": {
4445
4797
  const selected = new Set(Array.isArray(value) ? value.map(String) : []);
4446
- return /* @__PURE__ */ jsx25("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ jsxs24("label", { className: "b316-choice", children: [
4447
- /* @__PURE__ */ jsx25(
4798
+ return /* @__PURE__ */ jsx27("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ jsxs26("label", { className: "b316-choice", children: [
4799
+ /* @__PURE__ */ jsx27(
4448
4800
  "input",
4449
4801
  {
4450
4802
  type: "checkbox",
@@ -4467,7 +4819,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4467
4819
  case "NUMBER":
4468
4820
  case "MONEY":
4469
4821
  case "PERCENT":
4470
- return /* @__PURE__ */ jsx25(
4822
+ return /* @__PURE__ */ jsx27(
4471
4823
  "input",
4472
4824
  {
4473
4825
  ...common,
@@ -4478,7 +4830,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4478
4830
  }
4479
4831
  );
4480
4832
  case "RATING":
4481
- return /* @__PURE__ */ jsx25(
4833
+ return /* @__PURE__ */ jsx27(
4482
4834
  "input",
4483
4835
  {
4484
4836
  ...common,
@@ -4492,8 +4844,8 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4492
4844
  );
4493
4845
  case "DURATION": {
4494
4846
  const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
4495
- return /* @__PURE__ */ jsxs24("div", { className: "b316-suffixed", children: [
4496
- /* @__PURE__ */ jsx25(
4847
+ return /* @__PURE__ */ jsxs26("div", { className: "b316-suffixed", children: [
4848
+ /* @__PURE__ */ jsx27(
4497
4849
  "input",
4498
4850
  {
4499
4851
  ...common,
@@ -4503,11 +4855,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4503
4855
  onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
4504
4856
  }
4505
4857
  ),
4506
- /* @__PURE__ */ jsx25("span", { className: "b316-muted", children: "minutes" })
4858
+ /* @__PURE__ */ jsx27("span", { className: "b316-muted", children: "minutes" })
4507
4859
  ] });
4508
4860
  }
4509
4861
  case "DATE":
4510
- return /* @__PURE__ */ jsx25(
4862
+ return /* @__PURE__ */ jsx27(
4511
4863
  "input",
4512
4864
  {
4513
4865
  ...common,
@@ -4517,7 +4869,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4517
4869
  }
4518
4870
  );
4519
4871
  case "DATETIME":
4520
- return /* @__PURE__ */ jsx25(
4872
+ return /* @__PURE__ */ jsx27(
4521
4873
  "input",
4522
4874
  {
4523
4875
  ...common,
@@ -4530,7 +4882,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4530
4882
  );
4531
4883
  case "ADDRESS": {
4532
4884
  const address = value ?? {};
4533
- const part = (key, label) => /* @__PURE__ */ jsx25(
4885
+ const part = (key, label) => /* @__PURE__ */ jsx27(
4534
4886
  "input",
4535
4887
  {
4536
4888
  className: "b316-input",
@@ -4542,7 +4894,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4542
4894
  },
4543
4895
  key
4544
4896
  );
4545
- return /* @__PURE__ */ jsxs24("div", { className: "b316-address", children: [
4897
+ return /* @__PURE__ */ jsxs26("div", { className: "b316-address", children: [
4546
4898
  part("line1", "Address line 1"),
4547
4899
  part("line2", "Address line 2"),
4548
4900
  part("city", "City"),
@@ -4552,7 +4904,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4552
4904
  ] });
4553
4905
  }
4554
4906
  case "EMAIL":
4555
- return /* @__PURE__ */ jsx25(
4907
+ return /* @__PURE__ */ jsx27(
4556
4908
  "input",
4557
4909
  {
4558
4910
  ...common,
@@ -4562,7 +4914,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4562
4914
  }
4563
4915
  );
4564
4916
  case "URL":
4565
- return /* @__PURE__ */ jsx25(
4917
+ return /* @__PURE__ */ jsx27(
4566
4918
  "input",
4567
4919
  {
4568
4920
  ...common,
@@ -4572,7 +4924,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4572
4924
  }
4573
4925
  );
4574
4926
  case "PHONE":
4575
- return /* @__PURE__ */ jsx25(
4927
+ return /* @__PURE__ */ jsx27(
4576
4928
  "input",
4577
4929
  {
4578
4930
  ...common,
@@ -4582,7 +4934,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4582
4934
  }
4583
4935
  );
4584
4936
  default:
4585
- return /* @__PURE__ */ jsx25(
4937
+ return /* @__PURE__ */ jsx27(
4586
4938
  "input",
4587
4939
  {
4588
4940
  ...common,
@@ -4593,24 +4945,24 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4593
4945
  );
4594
4946
  }
4595
4947
  }
4596
- return /* @__PURE__ */ jsxs24("div", { className: "b316-field", children: [
4597
- /* @__PURE__ */ jsxs24("label", { className: "b316-label", htmlFor: id, children: [
4948
+ return /* @__PURE__ */ jsxs26("div", { className: "b316-field", children: [
4949
+ /* @__PURE__ */ jsxs26("label", { className: "b316-label", htmlFor: id, children: [
4598
4950
  field.label,
4599
- field.required ? /* @__PURE__ */ jsx25("span", { "aria-hidden": "true", children: " *" }) : null
4951
+ field.required ? /* @__PURE__ */ jsx27("span", { "aria-hidden": "true", children: " *" }) : null
4600
4952
  ] }),
4601
4953
  control(),
4602
- field.description ? /* @__PURE__ */ jsx25("div", { className: "b316-hint", children: field.description }) : null,
4603
- error ? /* @__PURE__ */ jsx25("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
4954
+ field.description ? /* @__PURE__ */ jsx27("div", { className: "b316-hint", children: field.description }) : null,
4955
+ error ? /* @__PURE__ */ jsx27("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
4604
4956
  ] });
4605
4957
  }
4606
4958
 
4607
4959
  // src/RecordForm.tsx
4608
4960
  import { specFor as specFor2 } from "@base316/sdk";
4609
- import { useEffect as useEffect21, useState as useState26 } from "react";
4961
+ import { useEffect as useEffect22, useState as useState27 } from "react";
4610
4962
 
4611
4963
  // src/RelationPicker.tsx
4612
- import { useEffect as useEffect19, useRef as useRef7, useState as useState24 } from "react";
4613
- import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
4964
+ import { useEffect as useEffect20, useRef as useRef7, useState as useState25 } from "react";
4965
+ import { Fragment as Fragment10, jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
4614
4966
  function RelationPicker({
4615
4967
  field,
4616
4968
  value,
@@ -4620,13 +4972,13 @@ function RelationPicker({
4620
4972
  tenant
4621
4973
  }) {
4622
4974
  const { client, token } = useBase316();
4623
- const [query, setQuery] = useState24("");
4624
- const [results, setResults] = useState24([]);
4625
- const [chosenTitle, setChosenTitle] = useState24(null);
4626
- const [open, setOpen] = useState24(false);
4975
+ const [query, setQuery] = useState25("");
4976
+ const [results, setResults] = useState25([]);
4977
+ const [chosenTitle, setChosenTitle] = useState25(null);
4978
+ const [open, setOpen] = useState25(false);
4627
4979
  const id = `b316-field-${field.key}`;
4628
4980
  const box = useRef7(null);
4629
- useEffect19(() => {
4981
+ useEffect20(() => {
4630
4982
  if (!token || !value || !field.relationTo) {
4631
4983
  setChosenTitle(null);
4632
4984
  return;
@@ -4641,7 +4993,7 @@ function RelationPicker({
4641
4993
  cancelled = true;
4642
4994
  };
4643
4995
  }, [client, token, value, field.relationTo, tenant]);
4644
- useEffect19(() => {
4996
+ useEffect20(() => {
4645
4997
  if (!token || !field.relationTo || !open) {
4646
4998
  return;
4647
4999
  }
@@ -4667,7 +5019,7 @@ function RelationPicker({
4667
5019
  clearTimeout(timer);
4668
5020
  };
4669
5021
  }, [client, token, field.relationTo, query, open, tenant]);
4670
- useEffect19(() => {
5022
+ useEffect20(() => {
4671
5023
  if (!open || typeof document === "undefined") {
4672
5024
  return;
4673
5025
  }
@@ -4681,14 +5033,14 @@ function RelationPicker({
4681
5033
  document.removeEventListener("mousedown", onDocumentClick);
4682
5034
  };
4683
5035
  }, [open]);
4684
- return /* @__PURE__ */ jsxs25("div", { className: "b316-field", ref: box, children: [
4685
- /* @__PURE__ */ jsxs25("label", { className: "b316-label", htmlFor: id, children: [
5036
+ return /* @__PURE__ */ jsxs27("div", { className: "b316-field", ref: box, children: [
5037
+ /* @__PURE__ */ jsxs27("label", { className: "b316-label", htmlFor: id, children: [
4686
5038
  field.label,
4687
- field.required ? /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", children: " *" }) : null
5039
+ field.required ? /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: " *" }) : null
4688
5040
  ] }),
4689
- value && !open ? /* @__PURE__ */ jsxs25("div", { className: "b316-relation-chosen", children: [
4690
- /* @__PURE__ */ jsx26("span", { children: chosenTitle ?? value }),
4691
- disabled ? null : /* @__PURE__ */ jsx26(
5041
+ value && !open ? /* @__PURE__ */ jsxs27("div", { className: "b316-relation-chosen", children: [
5042
+ /* @__PURE__ */ jsx28("span", { children: chosenTitle ?? value }),
5043
+ disabled ? null : /* @__PURE__ */ jsx28(
4692
5044
  "button",
4693
5045
  {
4694
5046
  type: "button",
@@ -4700,7 +5052,7 @@ function RelationPicker({
4700
5052
  children: "Change"
4701
5053
  }
4702
5054
  ),
4703
- disabled || field.required ? null : /* @__PURE__ */ jsx26(
5055
+ disabled || field.required ? null : /* @__PURE__ */ jsx28(
4704
5056
  "button",
4705
5057
  {
4706
5058
  type: "button",
@@ -4710,8 +5062,8 @@ function RelationPicker({
4710
5062
  children: "Clear"
4711
5063
  }
4712
5064
  )
4713
- ] }) : /* @__PURE__ */ jsxs25(Fragment8, { children: [
4714
- /* @__PURE__ */ jsx26(
5065
+ ] }) : /* @__PURE__ */ jsxs27(Fragment10, { children: [
5066
+ /* @__PURE__ */ jsx28(
4715
5067
  "input",
4716
5068
  {
4717
5069
  id,
@@ -4732,7 +5084,7 @@ function RelationPicker({
4732
5084
  }
4733
5085
  }
4734
5086
  ),
4735
- open ? /* @__PURE__ */ jsx26("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ jsx26("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsx26(
5087
+ open ? /* @__PURE__ */ jsx28("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ jsx28("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ jsx28("li", { children: /* @__PURE__ */ jsx28(
4736
5088
  "button",
4737
5089
  {
4738
5090
  type: "button",
@@ -4748,13 +5100,13 @@ function RelationPicker({
4748
5100
  }
4749
5101
  ) }, result.id)) }) : null
4750
5102
  ] }),
4751
- field.description ? /* @__PURE__ */ jsx26("div", { className: "b316-hint", children: field.description }) : null,
4752
- error ? /* @__PURE__ */ jsx26("div", { className: "b316-error", role: "alert", children: error }) : null
5103
+ field.description ? /* @__PURE__ */ jsx28("div", { className: "b316-hint", children: field.description }) : null,
5104
+ error ? /* @__PURE__ */ jsx28("div", { className: "b316-error", role: "alert", children: error }) : null
4753
5105
  ] });
4754
5106
  }
4755
5107
 
4756
5108
  // src/useCollection.ts
4757
- import { useCallback as useCallback9, useEffect as useEffect20, useMemo as useMemo3, useState as useState25 } from "react";
5109
+ import { useCallback as useCallback9, useEffect as useEffect21, useMemo as useMemo3, useState as useState26 } from "react";
4758
5110
  function fieldErrorFrom(cause) {
4759
5111
  const param = cause?.param;
4760
5112
  const message = cause instanceof Error ? cause.message : "That value was not accepted.";
@@ -4762,24 +5114,24 @@ function fieldErrorFrom(cause) {
4762
5114
  }
4763
5115
  function useCollection(collection, options = {}) {
4764
5116
  const { client, token } = useBase316();
4765
- const [schema, setSchema] = useState25(null);
4766
- const [records, setRecords] = useState25([]);
4767
- const [error, setError] = useState25(null);
4768
- const [loading, setLoading] = useState25(true);
4769
- const [total, setTotal] = useState25(0);
4770
- const [cursor, setCursor] = useState25(null);
4771
- const [reloadCount, setReloadCount] = useState25(0);
4772
- const [search, setSearch] = useState25("");
4773
- const [filters, setFilters] = useState25([]);
4774
- const [sort, setSort] = useState25(
5117
+ const [schema, setSchema] = useState26(null);
5118
+ const [records, setRecords] = useState26([]);
5119
+ const [error, setError] = useState26(null);
5120
+ const [loading, setLoading] = useState26(true);
5121
+ const [total, setTotal] = useState26(0);
5122
+ const [cursor, setCursor] = useState26(null);
5123
+ const [reloadCount, setReloadCount] = useState26(0);
5124
+ const [search, setSearch] = useState26("");
5125
+ const [filters, setFilters] = useState26([]);
5126
+ const [sort, setSort] = useState26(
4775
5127
  options.sort ?? null
4776
5128
  );
4777
- const [fieldErrors, setFieldErrors] = useState25({});
4778
- const [saving, setSaving] = useState25(false);
5129
+ const [fieldErrors, setFieldErrors] = useState26({});
5130
+ const [saving, setSaving] = useState26(false);
4779
5131
  const { tenant, limit, recordId } = options;
4780
5132
  const fixedFilters = JSON.stringify(options.filters ?? []);
4781
5133
  const scope = useMemo3(() => tenant ? { tenant } : void 0, [tenant]);
4782
- useEffect20(() => {
5134
+ useEffect21(() => {
4783
5135
  if (!token) {
4784
5136
  return;
4785
5137
  }
@@ -4798,7 +5150,7 @@ function useCollection(collection, options = {}) {
4798
5150
  cancelled = true;
4799
5151
  };
4800
5152
  }, [client, token, collection, scope]);
4801
- useEffect20(() => {
5153
+ useEffect21(() => {
4802
5154
  if (!token || !schema) {
4803
5155
  return;
4804
5156
  }
@@ -4990,7 +5342,7 @@ function useCollection(collection, options = {}) {
4990
5342
  }
4991
5343
 
4992
5344
  // src/RecordForm.tsx
4993
- import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
5345
+ import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
4994
5346
  function RecordForm({
4995
5347
  collection,
4996
5348
  recordId,
@@ -5011,20 +5363,20 @@ function RecordForm({
5011
5363
  recordId
5012
5364
  }
5013
5365
  );
5014
- const [values, setValues] = useState26(defaults ?? {});
5015
- const [loaded, setLoaded] = useState26(!recordId);
5366
+ const [values, setValues] = useState27(defaults ?? {});
5367
+ const [loaded, setLoaded] = useState27(!recordId);
5016
5368
  const existing = recordId ? records.find((record) => record.id === recordId) : void 0;
5017
- useEffect21(() => {
5369
+ useEffect22(() => {
5018
5370
  if (existing && !loaded) {
5019
5371
  setValues(existing.fields);
5020
5372
  setLoaded(true);
5021
5373
  }
5022
5374
  }, [existing, loaded]);
5023
5375
  if (error) {
5024
- return /* @__PURE__ */ jsx27("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx27("div", { className: "b316-error", role: "alert", children: error }) });
5376
+ return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx29("div", { className: "b316-error", role: "alert", children: error }) });
5025
5377
  }
5026
5378
  if (!schema || !loaded) {
5027
- return /* @__PURE__ */ jsx27("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5379
+ return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5028
5380
  }
5029
5381
  const editable = schema.fields.filter((field) => !specFor2(field).computed);
5030
5382
  async function submit(event) {
@@ -5034,11 +5386,11 @@ function RecordForm({
5034
5386
  onSaved?.(saved.id);
5035
5387
  }
5036
5388
  }
5037
- return /* @__PURE__ */ jsxs26("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5038
- /* @__PURE__ */ jsx27("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5039
- fieldErrors._ ? /* @__PURE__ */ jsx27("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5389
+ return /* @__PURE__ */ jsxs28("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5390
+ /* @__PURE__ */ jsx29("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5391
+ fieldErrors._ ? /* @__PURE__ */ jsx29("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5040
5392
  editable.map(
5041
- (field) => field.type === "RELATION" ? /* @__PURE__ */ jsx27(
5393
+ (field) => field.type === "RELATION" ? /* @__PURE__ */ jsx29(
5042
5394
  RelationPicker,
5043
5395
  {
5044
5396
  field,
@@ -5049,7 +5401,7 @@ function RecordForm({
5049
5401
  onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
5050
5402
  },
5051
5403
  field.key
5052
- ) : /* @__PURE__ */ jsx27(
5404
+ ) : /* @__PURE__ */ jsx29(
5053
5405
  FieldInput,
5054
5406
  {
5055
5407
  field,
@@ -5061,15 +5413,15 @@ function RecordForm({
5061
5413
  field.key
5062
5414
  )
5063
5415
  ),
5064
- /* @__PURE__ */ jsxs26("div", { className: "b316-form-actions", children: [
5065
- onCancel ? /* @__PURE__ */ jsx27("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5066
- /* @__PURE__ */ jsx27("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5416
+ /* @__PURE__ */ jsxs28("div", { className: "b316-form-actions", children: [
5417
+ onCancel ? /* @__PURE__ */ jsx29("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5418
+ /* @__PURE__ */ jsx29("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5067
5419
  ] })
5068
5420
  ] });
5069
5421
  }
5070
5422
 
5071
5423
  // src/DataTable.tsx
5072
- import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
5424
+ import { jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
5073
5425
  function DataTable({
5074
5426
  collection,
5075
5427
  columns,
@@ -5098,13 +5450,13 @@ function DataTable({
5098
5450
  loadMore,
5099
5451
  remove
5100
5452
  } = useCollection(collection, options);
5101
- const [editing, setEditing] = useState27(null);
5102
- const [removeFailed, setRemoveFailed] = useState27(null);
5453
+ const [editing, setEditing] = useState28(null);
5454
+ const [removeFailed, setRemoveFailed] = useState28(null);
5103
5455
  if (error) {
5104
- return /* @__PURE__ */ jsx28("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx28("div", { className: "b316-error", role: "alert", children: error }) });
5456
+ return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx30("div", { className: "b316-error", role: "alert", children: error }) });
5105
5457
  }
5106
5458
  if (!schema) {
5107
- return /* @__PURE__ */ jsx28("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5459
+ return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5108
5460
  }
5109
5461
  const shown = columns ? (
5110
5462
  // Ordered by what was asked for, not by the schema: a caller naming
@@ -5113,10 +5465,10 @@ function DataTable({
5113
5465
  ) : schema.fields;
5114
5466
  const searchable = schema.fields.some((field) => specFor3(field).capabilities.searchable);
5115
5467
  const writable = canWrite && !readOnly;
5116
- return /* @__PURE__ */ jsxs27("div", { className: cls("b316-table-wrap", className), style, children: [
5117
- removeFailed ? /* @__PURE__ */ jsx28("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5118
- /* @__PURE__ */ jsxs27("div", { className: "b316-table-bar", children: [
5119
- searchable && !hideSearch ? /* @__PURE__ */ jsx28(
5468
+ return /* @__PURE__ */ jsxs29("div", { className: cls("b316-table-wrap", className), style, children: [
5469
+ removeFailed ? /* @__PURE__ */ jsx30("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5470
+ /* @__PURE__ */ jsxs29("div", { className: "b316-table-bar", children: [
5471
+ searchable && !hideSearch ? /* @__PURE__ */ jsx30(
5120
5472
  "input",
5121
5473
  {
5122
5474
  type: "search",
@@ -5126,25 +5478,25 @@ function DataTable({
5126
5478
  value: search,
5127
5479
  onChange: (event) => setSearch(event.target.value)
5128
5480
  }
5129
- ) : /* @__PURE__ */ jsx28("span", {}),
5130
- /* @__PURE__ */ jsxs27("div", { className: "b316-table-actions", children: [
5131
- /* @__PURE__ */ jsxs27("span", { className: "b316-muted", children: [
5481
+ ) : /* @__PURE__ */ jsx30("span", {}),
5482
+ /* @__PURE__ */ jsxs29("div", { className: "b316-table-actions", children: [
5483
+ /* @__PURE__ */ jsxs29("span", { className: "b316-muted", children: [
5132
5484
  total,
5133
5485
  " ",
5134
5486
  total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()
5135
5487
  ] }),
5136
- writable ? /* @__PURE__ */ jsxs27("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5488
+ writable ? /* @__PURE__ */ jsxs29("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5137
5489
  "New ",
5138
5490
  schema.name.toLowerCase()
5139
5491
  ] }) : null
5140
5492
  ] })
5141
5493
  ] }),
5142
- /* @__PURE__ */ jsx28("div", { className: "b316-table-scroll", children: /* @__PURE__ */ jsxs27("table", { className: "b316-table", children: [
5143
- /* @__PURE__ */ jsx28("thead", { children: /* @__PURE__ */ jsxs27("tr", { children: [
5494
+ /* @__PURE__ */ jsx30("div", { className: "b316-table-scroll", children: /* @__PURE__ */ jsxs29("table", { className: "b316-table", children: [
5495
+ /* @__PURE__ */ jsx30("thead", { children: /* @__PURE__ */ jsxs29("tr", { children: [
5144
5496
  shown.map((field) => {
5145
5497
  const sortable = specFor3(field).capabilities.sortable;
5146
5498
  const active = sort?.field === field.key;
5147
- return /* @__PURE__ */ jsx28("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ jsxs27(
5499
+ return /* @__PURE__ */ jsx30("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ jsxs29(
5148
5500
  "button",
5149
5501
  {
5150
5502
  type: "button",
@@ -5152,20 +5504,20 @@ function DataTable({
5152
5504
  onClick: () => toggleSort(field.key),
5153
5505
  children: [
5154
5506
  field.label,
5155
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5507
+ /* @__PURE__ */ jsx30("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5156
5508
  ]
5157
5509
  }
5158
5510
  ) : field.label }, field.key);
5159
5511
  }),
5160
- writable ? /* @__PURE__ */ jsx28("th", { scope: "col", className: "b316-table-rowactions" }) : null
5512
+ writable ? /* @__PURE__ */ jsx30("th", { scope: "col", className: "b316-table-rowactions" }) : null
5161
5513
  ] }) }),
5162
- /* @__PURE__ */ jsx28("tbody", { children: records.map((record) => /* @__PURE__ */ jsxs27(
5514
+ /* @__PURE__ */ jsx30("tbody", { children: records.map((record) => /* @__PURE__ */ jsxs29(
5163
5515
  "tr",
5164
5516
  {
5165
5517
  className: onSelect ? "b316-row-clickable" : void 0,
5166
5518
  onClick: onSelect ? () => onSelect(record) : void 0,
5167
5519
  children: [
5168
- shown.map((field) => /* @__PURE__ */ jsx28("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ jsx28(
5520
+ shown.map((field) => /* @__PURE__ */ jsx30("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ jsx30(
5169
5521
  FieldCell,
5170
5522
  {
5171
5523
  value: record.fields[field.key] ?? null,
@@ -5173,8 +5525,8 @@ function DataTable({
5173
5525
  related: record.related[field.key]
5174
5526
  }
5175
5527
  ) }, field.key)),
5176
- writable ? /* @__PURE__ */ jsxs27("td", { className: "b316-table-rowactions", children: [
5177
- /* @__PURE__ */ jsx28(
5528
+ writable ? /* @__PURE__ */ jsxs29("td", { className: "b316-table-rowactions", children: [
5529
+ /* @__PURE__ */ jsx30(
5178
5530
  "button",
5179
5531
  {
5180
5532
  type: "button",
@@ -5186,7 +5538,7 @@ function DataTable({
5186
5538
  children: "Edit"
5187
5539
  }
5188
5540
  ),
5189
- /* @__PURE__ */ jsx28(
5541
+ /* @__PURE__ */ jsx30(
5190
5542
  ConfirmButton,
5191
5543
  {
5192
5544
  className: "b316-button-quiet b316-danger",
@@ -5210,10 +5562,10 @@ function DataTable({
5210
5562
  record.id
5211
5563
  )) })
5212
5564
  ] }) }),
5213
- records.length === 0 && !loading ? /* @__PURE__ */ jsx28("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5214
- loading ? /* @__PURE__ */ jsx28("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5215
- hasMore ? /* @__PURE__ */ jsx28("div", { className: "b316-table-more", children: /* @__PURE__ */ jsx28("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
5216
- editing ? /* @__PURE__ */ jsx28(
5565
+ records.length === 0 && !loading ? /* @__PURE__ */ jsx30("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5566
+ loading ? /* @__PURE__ */ jsx30("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5567
+ hasMore ? /* @__PURE__ */ jsx30("div", { className: "b316-table-more", children: /* @__PURE__ */ jsx30("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
5568
+ editing ? /* @__PURE__ */ jsx30(
5217
5569
  RecordForm,
5218
5570
  {
5219
5571
  collection,
@@ -5241,8 +5593,8 @@ import {
5241
5593
  specFor as specFor4,
5242
5594
  titleFieldOf
5243
5595
  } from "@base316/sdk";
5244
- import { useState as useState28 } from "react";
5245
- import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
5596
+ import { useState as useState29 } from "react";
5597
+ import { jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
5246
5598
  function Kanban({
5247
5599
  collection,
5248
5600
  groupBy,
@@ -5259,17 +5611,17 @@ function Kanban({
5259
5611
  limit: options.limit ?? 100,
5260
5612
  ...options
5261
5613
  });
5262
- const [dragging, setDragging] = useState28(null);
5263
- const [over, setOver] = useState28(null);
5614
+ const [dragging, setDragging] = useState29(null);
5615
+ const [over, setOver] = useState29(null);
5264
5616
  if (error) {
5265
- return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx29("div", { className: "b316-error", role: "alert", children: error }) });
5617
+ return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx31("div", { className: "b316-error", role: "alert", children: error }) });
5266
5618
  }
5267
5619
  if (!schema) {
5268
- return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5620
+ return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5269
5621
  }
5270
5622
  const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : defaultGroupFieldOf(schema.fields);
5271
5623
  if (!field || !specFor4(field).capabilities.groupable) {
5272
- return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: groupBy ? `"${groupBy}" cannot make columns. A board groups by a choice, a yes/no or a date.` : `${schema.namePlural} have no field to group by. Add a choice field \u2014 a status or a stage \u2014 and this board will use it.` });
5624
+ return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: groupBy ? `"${groupBy}" cannot make columns. A board groups by a choice, a yes/no or a date.` : `${schema.namePlural} have no field to group by. Add a choice field \u2014 a status or a stage \u2014 and this board will use it.` });
5273
5625
  }
5274
5626
  const columns = columnsFor(field);
5275
5627
  const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
@@ -5286,12 +5638,12 @@ function Kanban({
5286
5638
  }
5287
5639
  await update(record.id, { [field.key]: value });
5288
5640
  }
5289
- return /* @__PURE__ */ jsxs28("div", { className: cls("b316-board-wrap", className), style, children: [
5290
- /* @__PURE__ */ jsx29("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5641
+ return /* @__PURE__ */ jsxs30("div", { className: cls("b316-board-wrap", className), style, children: [
5642
+ /* @__PURE__ */ jsx31("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5291
5643
  const inColumn = records.filter(
5292
5644
  (record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
5293
5645
  );
5294
- return /* @__PURE__ */ jsxs28(
5646
+ return /* @__PURE__ */ jsxs30(
5295
5647
  "section",
5296
5648
  {
5297
5649
  className: over === String(column.value) ? "b316-board-column b316-board-over" : "b316-board-column",
@@ -5315,12 +5667,12 @@ function Kanban({
5315
5667
  setDragging(null);
5316
5668
  },
5317
5669
  children: [
5318
- /* @__PURE__ */ jsxs28("header", { className: "b316-board-head", children: [
5319
- /* @__PURE__ */ jsx29("span", { className: "b316-board-title", children: column.label }),
5320
- /* @__PURE__ */ jsx29("span", { className: "b316-muted", children: inColumn.length })
5670
+ /* @__PURE__ */ jsxs30("header", { className: "b316-board-head", children: [
5671
+ /* @__PURE__ */ jsx31("span", { className: "b316-board-title", children: column.label }),
5672
+ /* @__PURE__ */ jsx31("span", { className: "b316-muted", children: inColumn.length })
5321
5673
  ] }),
5322
- /* @__PURE__ */ jsxs28("div", { className: "b316-board-cards", children: [
5323
- inColumn.map((record) => /* @__PURE__ */ jsxs28(
5674
+ /* @__PURE__ */ jsxs30("div", { className: "b316-board-cards", children: [
5675
+ inColumn.map((record) => /* @__PURE__ */ jsxs30(
5324
5676
  "article",
5325
5677
  {
5326
5678
  className: "b316-board-card",
@@ -5332,10 +5684,10 @@ function Kanban({
5332
5684
  },
5333
5685
  onClick: onSelect ? () => onSelect(record) : void 0,
5334
5686
  children: [
5335
- /* @__PURE__ */ jsx29("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5336
- shown.map((candidate) => /* @__PURE__ */ jsxs28("div", { className: "b316-board-card-field", children: [
5337
- /* @__PURE__ */ jsx29("span", { className: "b316-muted", children: candidate.label }),
5338
- /* @__PURE__ */ jsx29(
5687
+ /* @__PURE__ */ jsx31("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5688
+ shown.map((candidate) => /* @__PURE__ */ jsxs30("div", { className: "b316-board-card-field", children: [
5689
+ /* @__PURE__ */ jsx31("span", { className: "b316-muted", children: candidate.label }),
5690
+ /* @__PURE__ */ jsx31(
5339
5691
  FieldCell,
5340
5692
  {
5341
5693
  value: record.fields[candidate.key] ?? null,
@@ -5348,9 +5700,9 @@ function Kanban({
5348
5700
  // Dragging is not reachable by keyboard and is awkward on a
5349
5701
  // phone. This is the same action by other means, not a
5350
5702
  // lesser fallback.
5351
- /* @__PURE__ */ jsxs28("label", { className: "b316-board-move", children: [
5352
- /* @__PURE__ */ jsx29("span", { className: "b316-muted", children: "Move to" }),
5353
- /* @__PURE__ */ jsx29(
5703
+ /* @__PURE__ */ jsxs30("label", { className: "b316-board-move", children: [
5704
+ /* @__PURE__ */ jsx31("span", { className: "b316-muted", children: "Move to" }),
5705
+ /* @__PURE__ */ jsx31(
5354
5706
  "select",
5355
5707
  {
5356
5708
  className: "b316-input",
@@ -5362,7 +5714,7 @@ function Kanban({
5362
5714
  );
5363
5715
  void move(record, chosen?.value ?? null);
5364
5716
  },
5365
- children: columns.map((candidate) => /* @__PURE__ */ jsx29("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5717
+ children: columns.map((candidate) => /* @__PURE__ */ jsx31("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5366
5718
  }
5367
5719
  )
5368
5720
  ] })
@@ -5371,14 +5723,14 @@ function Kanban({
5371
5723
  },
5372
5724
  record.id
5373
5725
  )),
5374
- inColumn.length === 0 ? /* @__PURE__ */ jsx29("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5726
+ inColumn.length === 0 ? /* @__PURE__ */ jsx31("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5375
5727
  ] })
5376
5728
  ]
5377
5729
  },
5378
5730
  String(column.value)
5379
5731
  );
5380
5732
  }) }),
5381
- hasMore ? /* @__PURE__ */ jsx29("div", { className: "b316-table-more", children: /* @__PURE__ */ jsxs28("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
5733
+ hasMore ? /* @__PURE__ */ jsx31("div", { className: "b316-table-more", children: /* @__PURE__ */ jsxs30("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
5382
5734
  "Showing ",
5383
5735
  records.length,
5384
5736
  " of ",
@@ -5405,7 +5757,7 @@ import {
5405
5757
  specFor as specFor5
5406
5758
  } from "@base316/sdk";
5407
5759
  import { useMemo as useMemo4 } from "react";
5408
- import { jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
5760
+ import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
5409
5761
  function Chart({
5410
5762
  collection,
5411
5763
  x,
@@ -5444,23 +5796,23 @@ function Chart({
5444
5796
  [records, axis, measure, aggregate, bucket, y]
5445
5797
  );
5446
5798
  if (error) {
5447
- return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx30("div", { className: "b316-error", role: "alert", children: error }) });
5799
+ return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx32("div", { className: "b316-error", role: "alert", children: error }) });
5448
5800
  }
5449
5801
  if (!schema || loading) {
5450
- return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5802
+ return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5451
5803
  }
5452
5804
  if (!axis) {
5453
- return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: x ? `"${x}" is not a date, so it cannot be a time axis.` : `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.` });
5805
+ return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: x ? `"${x}" is not a date, so it cannot be a time axis.` : `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.` });
5454
5806
  }
5455
5807
  if (y && !measure) {
5456
- return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
5808
+ return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
5457
5809
  }
5458
5810
  const peak = Math.max(...buckets.map((entry) => entry.value), 0);
5459
5811
  const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
5460
- return /* @__PURE__ */ jsxs29("figure", { className: cls("b316-card b316-chart", className), style, children: [
5461
- /* @__PURE__ */ jsx30("figcaption", { className: "b316-chart-title", children: heading }),
5462
- buckets.length === 0 || peak === 0 ? /* @__PURE__ */ jsx30("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ jsx30("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ jsxs29("div", { className: "b316-chart-col", children: [
5463
- /* @__PURE__ */ jsx30(
5812
+ return /* @__PURE__ */ jsxs31("figure", { className: cls("b316-card b316-chart", className), style, children: [
5813
+ /* @__PURE__ */ jsx32("figcaption", { className: "b316-chart-title", children: heading }),
5814
+ buckets.length === 0 || peak === 0 ? /* @__PURE__ */ jsx32("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ jsx32("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ jsxs31("div", { className: "b316-chart-col", children: [
5815
+ /* @__PURE__ */ jsx32(
5464
5816
  "div",
5465
5817
  {
5466
5818
  className: "b316-chart-bar",
@@ -5468,18 +5820,18 @@ function Chart({
5468
5820
  title: `${entry.label}: ${format(entry.value)}`
5469
5821
  }
5470
5822
  ),
5471
- /* @__PURE__ */ jsx30("span", { className: "b316-chart-label", children: entry.label })
5823
+ /* @__PURE__ */ jsx32("span", { className: "b316-chart-label", children: entry.label })
5472
5824
  ] }, entry.key)) }),
5473
- /* @__PURE__ */ jsxs29("details", { className: "b316-chart-data", children: [
5474
- /* @__PURE__ */ jsx30("summary", { children: "Values" }),
5475
- /* @__PURE__ */ jsxs29("table", { className: "b316-table", children: [
5476
- /* @__PURE__ */ jsx30("thead", { children: /* @__PURE__ */ jsxs29("tr", { children: [
5477
- /* @__PURE__ */ jsx30("th", { scope: "col", children: axis.label }),
5478
- /* @__PURE__ */ jsx30("th", { scope: "col", children: measure ? measure.label : "Count" })
5825
+ /* @__PURE__ */ jsxs31("details", { className: "b316-chart-data", children: [
5826
+ /* @__PURE__ */ jsx32("summary", { children: "Values" }),
5827
+ /* @__PURE__ */ jsxs31("table", { className: "b316-table", children: [
5828
+ /* @__PURE__ */ jsx32("thead", { children: /* @__PURE__ */ jsxs31("tr", { children: [
5829
+ /* @__PURE__ */ jsx32("th", { scope: "col", children: axis.label }),
5830
+ /* @__PURE__ */ jsx32("th", { scope: "col", children: measure ? measure.label : "Count" })
5479
5831
  ] }) }),
5480
- /* @__PURE__ */ jsx30("tbody", { children: buckets.map((entry) => /* @__PURE__ */ jsxs29("tr", { children: [
5481
- /* @__PURE__ */ jsx30("td", { children: entry.label }),
5482
- /* @__PURE__ */ jsx30("td", { children: format(entry.value) })
5832
+ /* @__PURE__ */ jsx32("tbody", { children: buckets.map((entry) => /* @__PURE__ */ jsxs31("tr", { children: [
5833
+ /* @__PURE__ */ jsx32("td", { children: entry.label }),
5834
+ /* @__PURE__ */ jsx32("td", { children: format(entry.value) })
5483
5835
  ] }, entry.key)) })
5484
5836
  ] })
5485
5837
  ] })
@@ -5538,8 +5890,8 @@ function combine(values, aggregate) {
5538
5890
 
5539
5891
  // src/RecordDetail.tsx
5540
5892
  import { specFor as specFor6 } from "@base316/sdk";
5541
- import { useState as useState29 } from "react";
5542
- import { jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
5893
+ import { useState as useState30 } from "react";
5894
+ import { jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
5543
5895
  function RecordDetail({
5544
5896
  collection,
5545
5897
  recordId,
@@ -5555,23 +5907,23 @@ function RecordDetail({
5555
5907
  tenant,
5556
5908
  recordId
5557
5909
  });
5558
- const [editing, setEditing] = useState29(false);
5910
+ const [editing, setEditing] = useState30(false);
5559
5911
  const record = records.find((candidate) => candidate.id === recordId);
5560
5912
  if (error) {
5561
- return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx31("div", { className: "b316-error", role: "alert", children: error }) });
5913
+ return /* @__PURE__ */ jsx33("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: error }) });
5562
5914
  }
5563
5915
  if (!schema || loading) {
5564
- return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5916
+ return /* @__PURE__ */ jsx33("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5565
5917
  }
5566
5918
  if (!record) {
5567
- return /* @__PURE__ */ jsxs30("div", { className: cls("b316-card", className), style, children: [
5919
+ return /* @__PURE__ */ jsxs32("div", { className: cls("b316-card", className), style, children: [
5568
5920
  "That ",
5569
5921
  schema.name.toLowerCase(),
5570
5922
  " is not available."
5571
5923
  ] });
5572
5924
  }
5573
5925
  if (editing) {
5574
- return /* @__PURE__ */ jsx31(
5926
+ return /* @__PURE__ */ jsx33(
5575
5927
  RecordForm,
5576
5928
  {
5577
5929
  collection,
@@ -5585,12 +5937,12 @@ function RecordDetail({
5585
5937
  );
5586
5938
  }
5587
5939
  const writable = canWrite && !readOnly;
5588
- return /* @__PURE__ */ jsxs30("div", { className: cls("b316-card b316-detail", className), style, children: [
5589
- /* @__PURE__ */ jsxs30("div", { className: "b316-detail-head", children: [
5590
- /* @__PURE__ */ jsx31("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5591
- /* @__PURE__ */ jsxs30("div", { className: "b316-detail-actions", children: [
5592
- writable ? /* @__PURE__ */ jsx31("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5593
- writable ? /* @__PURE__ */ jsx31(
5940
+ return /* @__PURE__ */ jsxs32("div", { className: cls("b316-card b316-detail", className), style, children: [
5941
+ /* @__PURE__ */ jsxs32("div", { className: "b316-detail-head", children: [
5942
+ /* @__PURE__ */ jsx33("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5943
+ /* @__PURE__ */ jsxs32("div", { className: "b316-detail-actions", children: [
5944
+ writable ? /* @__PURE__ */ jsx33("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5945
+ writable ? /* @__PURE__ */ jsx33(
5594
5946
  ConfirmButton,
5595
5947
  {
5596
5948
  className: "b316-button-quiet b316-danger",
@@ -5603,15 +5955,15 @@ function RecordDetail({
5603
5955
  children: "Delete"
5604
5956
  }
5605
5957
  ) : null,
5606
- onClose ? /* @__PURE__ */ jsx31("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
5958
+ onClose ? /* @__PURE__ */ jsx33("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
5607
5959
  ] })
5608
5960
  ] }),
5609
- /* @__PURE__ */ jsx31("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ jsxs30("div", { className: "b316-detail-row", children: [
5610
- /* @__PURE__ */ jsxs30("dt", { className: "b316-label", children: [
5961
+ /* @__PURE__ */ jsx33("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ jsxs32("div", { className: "b316-detail-row", children: [
5962
+ /* @__PURE__ */ jsxs32("dt", { className: "b316-label", children: [
5611
5963
  field.label,
5612
- specFor6(field).computed ? /* @__PURE__ */ jsx31("span", { className: "b316-muted", children: " (calculated)" }) : null
5964
+ specFor6(field).computed ? /* @__PURE__ */ jsx33("span", { className: "b316-muted", children: " (calculated)" }) : null
5613
5965
  ] }),
5614
- /* @__PURE__ */ jsx31("dd", { children: /* @__PURE__ */ jsx31(
5966
+ /* @__PURE__ */ jsx33("dd", { children: /* @__PURE__ */ jsx33(
5615
5967
  FieldCell,
5616
5968
  {
5617
5969
  value: record.fields[field.key] ?? null,
@@ -5625,8 +5977,8 @@ function RecordDetail({
5625
5977
  }
5626
5978
 
5627
5979
  // src/SubscriptionManager.tsx
5628
- import { useCallback as useCallback10, useEffect as useEffect22, useState as useState30 } from "react";
5629
- import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
5980
+ import { useCallback as useCallback10, useEffect as useEffect23, useState as useState31 } from "react";
5981
+ import { jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
5630
5982
  function statusLabel(status2) {
5631
5983
  const words = status2.toLowerCase().split("_");
5632
5984
  return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
@@ -5666,15 +6018,15 @@ function SubscriptionManager({
5666
6018
  style
5667
6019
  }) {
5668
6020
  const { client, token, loading: sessionLoading } = useBase316();
5669
- const [subscription, setSubscription] = useState30(null);
5670
- const [loading, setLoading] = useState30(true);
5671
- const [managedBy, setManagedBy] = useState30(null);
5672
- const [schedule, setSchedule] = useState30([]);
5673
- const [busy, setBusy] = useState30(false);
5674
- const [error, setError] = useState30(null);
5675
- const [step, setStep] = useState30({ kind: "idle" });
5676
- const [reason, setReason] = useState30(null);
5677
- const [comment, setComment] = useState30("");
6021
+ const [subscription, setSubscription] = useState31(null);
6022
+ const [loading, setLoading] = useState31(true);
6023
+ const [managedBy, setManagedBy] = useState31(null);
6024
+ const [schedule, setSchedule] = useState31([]);
6025
+ const [busy, setBusy] = useState31(false);
6026
+ const [error, setError] = useState31(null);
6027
+ const [step, setStep] = useState31({ kind: "idle" });
6028
+ const [reason, setReason] = useState31(null);
6029
+ const [comment, setComment] = useState31("");
5678
6030
  const load = useCallback10(async () => {
5679
6031
  if (!token) {
5680
6032
  setSubscription(null);
@@ -5693,7 +6045,7 @@ function SubscriptionManager({
5693
6045
  setLoading(false);
5694
6046
  }
5695
6047
  }, [client, token]);
5696
- useEffect22(() => {
6048
+ useEffect23(() => {
5697
6049
  void load();
5698
6050
  }, [load]);
5699
6051
  const act = async (change, failure) => {
@@ -5711,29 +6063,29 @@ function SubscriptionManager({
5711
6063
  }
5712
6064
  };
5713
6065
  if (sessionLoading || loading) {
5714
- return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6066
+ return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5715
6067
  }
5716
6068
  if (!token) {
5717
- return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
6069
+ return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
5718
6070
  }
5719
6071
  if (error) {
5720
- return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx32("div", { className: "b316-error", role: "alert", children: error }) });
6072
+ return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: error }) });
5721
6073
  }
5722
6074
  if (!subscription) {
5723
- return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
6075
+ return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
5724
6076
  }
5725
6077
  const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
5726
6078
  const next = schedule[0] ?? null;
5727
6079
  const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
5728
- return /* @__PURE__ */ jsxs31("div", { className: cls("b316-card", className), style, children: [
5729
- error ? /* @__PURE__ */ jsx32("div", { className: "b316-error", role: "alert", children: error }) : null,
5730
- /* @__PURE__ */ jsx32("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
5731
- /* @__PURE__ */ jsxs31("div", { className: "b316-muted", children: [
6080
+ return /* @__PURE__ */ jsxs33("div", { className: cls("b316-card", className), style, children: [
6081
+ error ? /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: error }) : null,
6082
+ /* @__PURE__ */ jsx34("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
6083
+ /* @__PURE__ */ jsxs33("div", { className: "b316-muted", children: [
5732
6084
  statusLabel(subscription.status),
5733
6085
  " \xB7 ",
5734
6086
  subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`
5735
6087
  ] }),
5736
- next && !managedBy ? /* @__PURE__ */ jsxs31("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
6088
+ next && !managedBy ? /* @__PURE__ */ jsxs33("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
5737
6089
  "Moves to ",
5738
6090
  next.plan.name,
5739
6091
  " on ",
@@ -5741,7 +6093,7 @@ function SubscriptionManager({
5741
6093
  ". You keep ",
5742
6094
  subscription.planVersion.plan.name,
5743
6095
  " until then.",
5744
- /* @__PURE__ */ jsx32("div", { children: /* @__PURE__ */ jsx32(
6096
+ /* @__PURE__ */ jsx34("div", { children: /* @__PURE__ */ jsx34(
5745
6097
  "button",
5746
6098
  {
5747
6099
  type: "button",
@@ -5766,17 +6118,17 @@ function SubscriptionManager({
5766
6118
  }
5767
6119
  ) })
5768
6120
  ] }) : null,
5769
- managedBy ? /* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
6121
+ managedBy ? /* @__PURE__ */ jsxs33("p", { className: "b316-muted", children: [
5770
6122
  "Provided by ",
5771
6123
  managedBy.name ?? "the organization that manages your account",
5772
6124
  ". Ask them to change or cancel it."
5773
- ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ jsxs31("div", { children: [
5774
- /* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
6125
+ ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ jsxs33("div", { children: [
6126
+ /* @__PURE__ */ jsxs33("p", { className: "b316-muted", children: [
5775
6127
  "This subscription will not renew. You keep access until ",
5776
6128
  renews,
5777
6129
  "."
5778
6130
  ] }),
5779
- /* @__PURE__ */ jsx32(
6131
+ /* @__PURE__ */ jsx34(
5780
6132
  "button",
5781
6133
  {
5782
6134
  type: "button",
@@ -5786,14 +6138,14 @@ function SubscriptionManager({
5786
6138
  children: busy ? "Working\u2026" : "Resume subscription"
5787
6139
  }
5788
6140
  )
5789
- ] }) : step.kind === "offer" ? /* @__PURE__ */ jsxs31("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
5790
- /* @__PURE__ */ jsx32("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
5791
- /* @__PURE__ */ jsx32("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
6141
+ ] }) : step.kind === "offer" ? /* @__PURE__ */ jsxs33("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
6142
+ /* @__PURE__ */ jsx34("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
6143
+ /* @__PURE__ */ jsx34("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
5792
6144
  step.cancellation.offer,
5793
6145
  step.cancellation.currency
5794
6146
  )}.` }),
5795
- /* @__PURE__ */ jsxs31("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5796
- /* @__PURE__ */ jsx32(
6147
+ /* @__PURE__ */ jsxs33("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6148
+ /* @__PURE__ */ jsx34(
5797
6149
  "button",
5798
6150
  {
5799
6151
  type: "button",
@@ -5806,7 +6158,7 @@ function SubscriptionManager({
5806
6158
  children: busy ? "Working\u2026" : "Accept offer and stay"
5807
6159
  }
5808
6160
  ),
5809
- /* @__PURE__ */ jsx32(
6161
+ /* @__PURE__ */ jsx34(
5810
6162
  "button",
5811
6163
  {
5812
6164
  type: "button",
@@ -5820,12 +6172,12 @@ function SubscriptionManager({
5820
6172
  }
5821
6173
  )
5822
6174
  ] }),
5823
- /* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
6175
+ /* @__PURE__ */ jsxs33("p", { className: "b316-muted", children: [
5824
6176
  "If you cancel, you keep access until ",
5825
6177
  renews,
5826
6178
  "."
5827
6179
  ] })
5828
- ] }) : step.kind === "survey" ? /* @__PURE__ */ jsxs31(
6180
+ ] }) : step.kind === "survey" ? /* @__PURE__ */ jsxs33(
5829
6181
  "form",
5830
6182
  {
5831
6183
  style: { marginTop: 14 },
@@ -5845,15 +6197,15 @@ function SubscriptionManager({
5845
6197
  }, "Could not cancel. Try again.");
5846
6198
  },
5847
6199
  children: [
5848
- /* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
6200
+ /* @__PURE__ */ jsxs33("p", { className: "b316-muted", children: [
5849
6201
  "You keep access until ",
5850
6202
  renews,
5851
6203
  ". It will not renew after that."
5852
6204
  ] }),
5853
- /* @__PURE__ */ jsxs31("fieldset", { className: "b316-fieldset", children: [
5854
- /* @__PURE__ */ jsx32("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
5855
- REASONS.map((option) => /* @__PURE__ */ jsxs31("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
5856
- /* @__PURE__ */ jsx32(
6205
+ /* @__PURE__ */ jsxs33("fieldset", { className: "b316-fieldset", children: [
6206
+ /* @__PURE__ */ jsx34("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
6207
+ REASONS.map((option) => /* @__PURE__ */ jsxs33("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
6208
+ /* @__PURE__ */ jsx34(
5857
6209
  "input",
5858
6210
  {
5859
6211
  type: "radio",
@@ -5863,12 +6215,12 @@ function SubscriptionManager({
5863
6215
  onChange: () => setReason(option.value)
5864
6216
  }
5865
6217
  ),
5866
- /* @__PURE__ */ jsx32("span", { children: option.label })
6218
+ /* @__PURE__ */ jsx34("span", { children: option.label })
5867
6219
  ] }, option.value))
5868
6220
  ] }),
5869
- /* @__PURE__ */ jsxs31("label", { className: "b316-field", children: [
5870
- /* @__PURE__ */ jsx32("span", { className: "b316-label", children: "Anything else? (optional)" }),
5871
- /* @__PURE__ */ jsx32(
6221
+ /* @__PURE__ */ jsxs33("label", { className: "b316-field", children: [
6222
+ /* @__PURE__ */ jsx34("span", { className: "b316-label", children: "Anything else? (optional)" }),
6223
+ /* @__PURE__ */ jsx34(
5872
6224
  "textarea",
5873
6225
  {
5874
6226
  className: "b316-input",
@@ -5879,9 +6231,9 @@ function SubscriptionManager({
5879
6231
  }
5880
6232
  )
5881
6233
  ] }),
5882
- /* @__PURE__ */ jsxs31("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5883
- /* @__PURE__ */ jsx32("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
5884
- /* @__PURE__ */ jsxs31(
6234
+ /* @__PURE__ */ jsxs33("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6235
+ /* @__PURE__ */ jsx34("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
6236
+ /* @__PURE__ */ jsxs33(
5885
6237
  "button",
5886
6238
  {
5887
6239
  type: "button",
@@ -5897,7 +6249,7 @@ function SubscriptionManager({
5897
6249
  ] })
5898
6250
  ]
5899
6251
  }
5900
- ) : /* @__PURE__ */ jsx32("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ jsx32(
6252
+ ) : /* @__PURE__ */ jsx34("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ jsx34(
5901
6253
  "button",
5902
6254
  {
5903
6255
  type: "button",
@@ -5915,11 +6267,11 @@ function SubscriptionManager({
5915
6267
  }
5916
6268
 
5917
6269
  // src/BillingPortal.tsx
5918
- import { useCallback as useCallback12, useEffect as useEffect26, useState as useState34 } from "react";
6270
+ import { useCallback as useCallback12, useEffect as useEffect27, useState as useState35 } from "react";
5919
6271
 
5920
6272
  // src/CreditBalances.tsx
5921
- import { useEffect as useEffect23, useState as useState31 } from "react";
5922
- import { Fragment as Fragment9, jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
6273
+ import { useEffect as useEffect24, useState as useState32 } from "react";
6274
+ import { Fragment as Fragment11, jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
5923
6275
  function units(value) {
5924
6276
  return value === null ? "Unlimited" : Number(value).toLocaleString("en");
5925
6277
  }
@@ -5954,10 +6306,10 @@ function Feature({
5954
6306
  }) {
5955
6307
  const { client, token } = useBase316();
5956
6308
  const setting = feature.autoRecharge;
5957
- const [busy, setBusy] = useState31(false);
5958
- const [error, setError] = useState31(null);
5959
- const [saved, setSaved] = useState31(null);
5960
- const [pack, setPack] = useState31(feature.packs[0]?.id ?? "");
6309
+ const [busy, setBusy] = useState32(false);
6310
+ const [error, setError] = useState32(null);
6311
+ const [saved, setSaved] = useState32(null);
6312
+ const [pack, setPack] = useState32(feature.packs[0]?.id ?? "");
5961
6313
  const unit = feature.unit ? ` ${feature.unit}` : "";
5962
6314
  const warning = status(feature);
5963
6315
  const buy = async () => {
@@ -6011,33 +6363,33 @@ function Feature({
6011
6363
  setBusy(false);
6012
6364
  }
6013
6365
  };
6014
- return /* @__PURE__ */ jsxs32("div", { className: "b316-card b316-credit-balance", children: [
6015
- /* @__PURE__ */ jsx33("div", { className: "b316-label", children: feature.featureName }),
6016
- /* @__PURE__ */ jsxs32("div", { children: [
6017
- /* @__PURE__ */ jsx33("strong", { children: units(feature.remaining) }),
6366
+ return /* @__PURE__ */ jsxs34("div", { className: "b316-card b316-credit-balance", children: [
6367
+ /* @__PURE__ */ jsx35("div", { className: "b316-label", children: feature.featureName }),
6368
+ /* @__PURE__ */ jsxs34("div", { children: [
6369
+ /* @__PURE__ */ jsx35("strong", { children: units(feature.remaining) }),
6018
6370
  unit,
6019
6371
  " left"
6020
6372
  ] }),
6021
- /* @__PURE__ */ jsxs32("div", { className: "b316-muted", children: [
6373
+ /* @__PURE__ */ jsxs34("div", { className: "b316-muted", children: [
6022
6374
  feature.allowance === null ? "Unlimited allowance" : `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`,
6023
6375
  " ",
6024
6376
  "\xB7 ",
6025
6377
  units(feature.purchasedRemaining),
6026
6378
  " purchased"
6027
6379
  ] }),
6028
- warning && !managed ? /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: warning }) : null,
6029
- error ? /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: error }) : null,
6030
- saved ? /* @__PURE__ */ jsx33("div", { className: "b316-notice", role: "status", children: saved }) : null,
6031
- managed || feature.packs.length === 0 ? null : /* @__PURE__ */ jsxs32(Fragment9, { children: [
6032
- /* @__PURE__ */ jsxs32("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6033
- /* @__PURE__ */ jsx33(
6380
+ warning && !managed ? /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: warning }) : null,
6381
+ error ? /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }) : null,
6382
+ saved ? /* @__PURE__ */ jsx35("div", { className: "b316-notice", role: "status", children: saved }) : null,
6383
+ managed || feature.packs.length === 0 ? null : /* @__PURE__ */ jsxs34(Fragment11, { children: [
6384
+ /* @__PURE__ */ jsxs34("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6385
+ /* @__PURE__ */ jsx35(
6034
6386
  "select",
6035
6387
  {
6036
6388
  className: "b316-input",
6037
6389
  "aria-label": "Pack to buy",
6038
6390
  value: pack,
6039
6391
  onChange: (event) => setPack(event.target.value),
6040
- children: feature.packs.map((option) => /* @__PURE__ */ jsxs32("option", { value: option.id, children: [
6392
+ children: feature.packs.map((option) => /* @__PURE__ */ jsxs34("option", { value: option.id, children: [
6041
6393
  option.name,
6042
6394
  " \u2014 ",
6043
6395
  units(option.units),
@@ -6046,7 +6398,7 @@ function Feature({
6046
6398
  ] }, option.id))
6047
6399
  }
6048
6400
  ),
6049
- /* @__PURE__ */ jsx33(
6401
+ /* @__PURE__ */ jsx35(
6050
6402
  "button",
6051
6403
  {
6052
6404
  type: "button",
@@ -6057,19 +6409,19 @@ function Feature({
6057
6409
  }
6058
6410
  )
6059
6411
  ] }),
6060
- /* @__PURE__ */ jsxs32("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6061
- /* @__PURE__ */ jsxs32("label", { className: "b316-checkbox", children: [
6062
- /* @__PURE__ */ jsx33("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
6412
+ /* @__PURE__ */ jsxs34("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6413
+ /* @__PURE__ */ jsxs34("label", { className: "b316-checkbox", children: [
6414
+ /* @__PURE__ */ jsx35("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
6063
6415
  " ",
6064
6416
  "Buy credits automatically when my balance runs low"
6065
6417
  ] }),
6066
- /* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
6067
- /* @__PURE__ */ jsxs32("span", { className: "b316-label", children: [
6418
+ /* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
6419
+ /* @__PURE__ */ jsxs34("span", { className: "b316-label", children: [
6068
6420
  "When fewer than this many",
6069
6421
  unit,
6070
6422
  " are left"
6071
6423
  ] }),
6072
- /* @__PURE__ */ jsx33(
6424
+ /* @__PURE__ */ jsx35(
6073
6425
  "input",
6074
6426
  {
6075
6427
  className: "b316-input",
@@ -6080,21 +6432,21 @@ function Feature({
6080
6432
  }
6081
6433
  )
6082
6434
  ] }),
6083
- /* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
6084
- /* @__PURE__ */ jsx33("span", { className: "b316-label", children: "Buy" }),
6085
- /* @__PURE__ */ jsx33(
6435
+ /* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
6436
+ /* @__PURE__ */ jsx35("span", { className: "b316-label", children: "Buy" }),
6437
+ /* @__PURE__ */ jsx35(
6086
6438
  "select",
6087
6439
  {
6088
6440
  className: "b316-input",
6089
6441
  name: "creditPackId",
6090
6442
  defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
6091
- children: feature.packs.map((option) => /* @__PURE__ */ jsx33("option", { value: option.id, children: option.name }, option.id))
6443
+ children: feature.packs.map((option) => /* @__PURE__ */ jsx35("option", { value: option.id, children: option.name }, option.id))
6092
6444
  }
6093
6445
  )
6094
6446
  ] }),
6095
- /* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
6096
- /* @__PURE__ */ jsx33("span", { className: "b316-label", children: "At most this many times a month" }),
6097
- /* @__PURE__ */ jsx33(
6447
+ /* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
6448
+ /* @__PURE__ */ jsx35("span", { className: "b316-label", children: "At most this many times a month" }),
6449
+ /* @__PURE__ */ jsx35(
6098
6450
  "input",
6099
6451
  {
6100
6452
  className: "b316-input",
@@ -6104,13 +6456,13 @@ function Feature({
6104
6456
  }
6105
6457
  )
6106
6458
  ] }),
6107
- /* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
6108
- /* @__PURE__ */ jsxs32("span", { className: "b316-label", children: [
6459
+ /* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
6460
+ /* @__PURE__ */ jsxs34("span", { className: "b316-label", children: [
6109
6461
  "Spending at most (",
6110
6462
  setting?.currency ?? feature.packs[0]?.currency ?? "USD",
6111
6463
  ") a month"
6112
6464
  ] }),
6113
- /* @__PURE__ */ jsx33(
6465
+ /* @__PURE__ */ jsx35(
6114
6466
  "input",
6115
6467
  {
6116
6468
  className: "b316-input",
@@ -6120,16 +6472,16 @@ function Feature({
6120
6472
  }
6121
6473
  )
6122
6474
  ] }),
6123
- /* @__PURE__ */ jsx33("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
6475
+ /* @__PURE__ */ jsx35("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
6124
6476
  ] })
6125
6477
  ] })
6126
6478
  ] });
6127
6479
  }
6128
6480
  function CreditBalances({ onChange, className, style }) {
6129
6481
  const { client, token, loading: sessionLoading } = useBase316();
6130
- const [state, setState] = useState31({ kind: "loading" });
6131
- const [version, setVersion] = useState31(0);
6132
- useEffect23(() => {
6482
+ const [state, setState] = useState32({ kind: "loading" });
6483
+ const [version, setVersion] = useState32(0);
6484
+ useEffect24(() => {
6133
6485
  if (!token) return;
6134
6486
  let cancelled = false;
6135
6487
  client.billing.credits(token).then((credits2) => {
@@ -6142,24 +6494,24 @@ function CreditBalances({ onChange, className, style }) {
6142
6494
  cancelled = true;
6143
6495
  };
6144
6496
  }, [client, token, version]);
6145
- const wrap = (content) => /* @__PURE__ */ jsx33("div", { className: cls("b316-credit-balances", className), style, children: content });
6497
+ const wrap = (content) => /* @__PURE__ */ jsx35("div", { className: cls("b316-credit-balances", className), style, children: content });
6146
6498
  if (sessionLoading || !token || state.kind === "loading") return null;
6147
6499
  if (state.kind === "error") {
6148
6500
  return wrap(
6149
- /* @__PURE__ */ jsx33("div", { className: "b316-card", children: /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
6501
+ /* @__PURE__ */ jsx35("div", { className: "b316-card", children: /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
6150
6502
  );
6151
6503
  }
6152
6504
  const { credits } = state;
6153
6505
  if (credits.features.length === 0) return null;
6154
6506
  return wrap(
6155
- /* @__PURE__ */ jsxs32(Fragment9, { children: [
6156
- credits.managedBy ? /* @__PURE__ */ jsxs32("p", { className: "b316-muted", children: [
6507
+ /* @__PURE__ */ jsxs34(Fragment11, { children: [
6508
+ credits.managedBy ? /* @__PURE__ */ jsxs34("p", { className: "b316-muted", children: [
6157
6509
  "Credits for this account come from",
6158
6510
  " ",
6159
6511
  credits.managedBy.name ?? "the organization that manages it",
6160
6512
  ", which manages them."
6161
6513
  ] }) : null,
6162
- credits.features.map((feature) => /* @__PURE__ */ jsx33(
6514
+ credits.features.map((feature) => /* @__PURE__ */ jsx35(
6163
6515
  Feature,
6164
6516
  {
6165
6517
  feature,
@@ -6176,19 +6528,19 @@ function CreditBalances({ onChange, className, style }) {
6176
6528
  }
6177
6529
 
6178
6530
  // src/PaymentMethod.tsx
6179
- import { useEffect as useEffect24, useState as useState32 } from "react";
6180
- import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
6531
+ import { useEffect as useEffect25, useState as useState33 } from "react";
6532
+ import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs35 } from "react/jsx-runtime";
6181
6533
  function brandName(brand) {
6182
6534
  if (!brand) return "Card";
6183
6535
  return brand.charAt(0).toUpperCase() + brand.slice(1);
6184
6536
  }
6185
6537
  function PaymentMethod({ returnUrl, className, style }) {
6186
6538
  const { client, token, loading: sessionLoading } = useBase316();
6187
- const [state, setState] = useState32({ kind: "loading" });
6188
- const [busy, setBusy] = useState32(false);
6189
- const [error, setError] = useState32(null);
6190
- const [version, setVersion] = useState32(0);
6191
- useEffect24(() => {
6539
+ const [state, setState] = useState33({ kind: "loading" });
6540
+ const [busy, setBusy] = useState33(false);
6541
+ const [error, setError] = useState33(null);
6542
+ const [version, setVersion] = useState33(0);
6543
+ useEffect25(() => {
6192
6544
  if (!token) return;
6193
6545
  let cancelled = false;
6194
6546
  client.billing.paymentMethods(token).then((result) => {
@@ -6204,7 +6556,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6204
6556
  cancelled = true;
6205
6557
  };
6206
6558
  }, [client, token, version]);
6207
- const wrap = (content) => /* @__PURE__ */ jsx34("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6559
+ const wrap = (content) => /* @__PURE__ */ jsx36("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6208
6560
  if (sessionLoading) return wrap("Loading\u2026");
6209
6561
  if (!token) return wrap("Sign in to manage your payment method.");
6210
6562
  switch (state.kind) {
@@ -6212,11 +6564,11 @@ function PaymentMethod({ returnUrl, className, style }) {
6212
6564
  return wrap("Loading\u2026");
6213
6565
  case "error":
6214
6566
  return wrap(
6215
- /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6567
+ /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6216
6568
  );
6217
6569
  case "managed":
6218
6570
  return wrap(
6219
- /* @__PURE__ */ jsx34("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6571
+ /* @__PURE__ */ jsx36("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6220
6572
  );
6221
6573
  }
6222
6574
  const card = state.cards.find((saved) => saved.isDefault) ?? null;
@@ -6235,31 +6587,31 @@ function PaymentMethod({ returnUrl, className, style }) {
6235
6587
  }
6236
6588
  };
6237
6589
  return wrap(
6238
- /* @__PURE__ */ jsxs33(Fragment10, { children: [
6239
- /* @__PURE__ */ jsx34("div", { className: "b316-label", children: "Payment method" }),
6240
- card ? /* @__PURE__ */ jsxs33("div", { children: [
6241
- /* @__PURE__ */ jsxs33("div", { children: [
6590
+ /* @__PURE__ */ jsxs35(Fragment12, { children: [
6591
+ /* @__PURE__ */ jsx36("div", { className: "b316-label", children: "Payment method" }),
6592
+ card ? /* @__PURE__ */ jsxs35("div", { children: [
6593
+ /* @__PURE__ */ jsxs35("div", { children: [
6242
6594
  brandName(card.brand),
6243
6595
  " ending ",
6244
6596
  card.last4 ?? "????"
6245
6597
  ] }),
6246
- card.expMonth && card.expYear ? /* @__PURE__ */ jsxs33("div", { className: "b316-muted", children: [
6598
+ card.expMonth && card.expYear ? /* @__PURE__ */ jsxs35("div", { className: "b316-muted", children: [
6247
6599
  "Expires ",
6248
6600
  String(card.expMonth).padStart(2, "0"),
6249
6601
  "/",
6250
6602
  card.expYear
6251
6603
  ] }) : null
6252
- ] }) : /* @__PURE__ */ jsx34("p", { className: "b316-muted", children: "No card on file." }),
6253
- others.length > 0 ? /* @__PURE__ */ jsxs33("div", { style: { marginTop: 12 }, children: [
6254
- /* @__PURE__ */ jsx34("div", { className: "b316-label", children: "Other saved cards" }),
6255
- others.map((saved) => /* @__PURE__ */ jsxs33("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6256
- /* @__PURE__ */ jsxs33("span", { children: [
6604
+ ] }) : /* @__PURE__ */ jsx36("p", { className: "b316-muted", children: "No card on file." }),
6605
+ others.length > 0 ? /* @__PURE__ */ jsxs35("div", { style: { marginTop: 12 }, children: [
6606
+ /* @__PURE__ */ jsx36("div", { className: "b316-label", children: "Other saved cards" }),
6607
+ others.map((saved) => /* @__PURE__ */ jsxs35("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6608
+ /* @__PURE__ */ jsxs35("span", { children: [
6257
6609
  brandName(saved.brand),
6258
6610
  " ending ",
6259
6611
  saved.last4 ?? "????"
6260
6612
  ] }),
6261
- /* @__PURE__ */ jsxs33("span", { children: [
6262
- /* @__PURE__ */ jsx34(
6613
+ /* @__PURE__ */ jsxs35("span", { children: [
6614
+ /* @__PURE__ */ jsx36(
6263
6615
  "button",
6264
6616
  {
6265
6617
  type: "button",
@@ -6273,7 +6625,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6273
6625
  }
6274
6626
  ),
6275
6627
  " ",
6276
- /* @__PURE__ */ jsx34(
6628
+ /* @__PURE__ */ jsx36(
6277
6629
  "button",
6278
6630
  {
6279
6631
  type: "button",
@@ -6289,8 +6641,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6289
6641
  ] })
6290
6642
  ] }, saved.id))
6291
6643
  ] }) : null,
6292
- error ? /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: error }) : null,
6293
- /* @__PURE__ */ jsx34(
6644
+ error ? /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: error }) : null,
6645
+ /* @__PURE__ */ jsx36(
6294
6646
  "button",
6295
6647
  {
6296
6648
  type: "button",
@@ -6319,8 +6671,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6319
6671
  }
6320
6672
 
6321
6673
  // src/PlanChangeReview.tsx
6322
- import { useCallback as useCallback11, useEffect as useEffect25, useState as useState33 } from "react";
6323
- import { Fragment as Fragment11, jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
6674
+ import { useCallback as useCallback11, useEffect as useEffect26, useState as useState34 } from "react";
6675
+ import { Fragment as Fragment13, jsx as jsx37, jsxs as jsxs36 } from "react/jsx-runtime";
6324
6676
  function money5(amount, currency) {
6325
6677
  if (amount === null) return "\u2014";
6326
6678
  const value = Number(amount);
@@ -6353,12 +6705,12 @@ function PlanChangeReview({
6353
6705
  style
6354
6706
  }) {
6355
6707
  const { client, token } = useBase316();
6356
- const [timing, setTiming] = useState33(void 0);
6357
- const [preview, setPreview] = useState33(null);
6358
- const [error, setError] = useState33(null);
6359
- const [needsCard, setNeedsCard] = useState33(false);
6360
- const [busy, setBusy] = useState33(false);
6361
- useEffect25(() => {
6708
+ const [timing, setTiming] = useState34(void 0);
6709
+ const [preview, setPreview] = useState34(null);
6710
+ const [error, setError] = useState34(null);
6711
+ const [needsCard, setNeedsCard] = useState34(false);
6712
+ const [busy, setBusy] = useState34(false);
6713
+ useEffect26(() => {
6362
6714
  if (!token) return;
6363
6715
  let cancelled = false;
6364
6716
  client.billing.previewPlanChange(token, planVersionId, timing).then((result) => {
@@ -6410,12 +6762,12 @@ function PlanChangeReview({
6410
6762
  setError("Cards cannot be added here right now.");
6411
6763
  }
6412
6764
  }, [client, token, onNeedsCard]);
6413
- const card = (content) => /* @__PURE__ */ jsx35("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6765
+ const card = (content) => /* @__PURE__ */ jsx37("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6414
6766
  if (error && !preview) {
6415
6767
  return card(
6416
- /* @__PURE__ */ jsxs34(Fragment11, { children: [
6417
- /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }),
6418
- onCancel ? /* @__PURE__ */ jsx35("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6768
+ /* @__PURE__ */ jsxs36(Fragment13, { children: [
6769
+ /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }),
6770
+ onCancel ? /* @__PURE__ */ jsx37("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6419
6771
  ] })
6420
6772
  );
6421
6773
  }
@@ -6428,26 +6780,26 @@ function PlanChangeReview({
6428
6780
  const otherReason = preview.timings[other]?.reason ?? null;
6429
6781
  const changes = preview.entitlements.filter((change) => change.change !== "UNCHANGED");
6430
6782
  return card(
6431
- /* @__PURE__ */ jsxs34(Fragment11, { children: [
6432
- /* @__PURE__ */ jsxs34("div", { className: "b316-plan-name", children: [
6783
+ /* @__PURE__ */ jsxs36(Fragment13, { children: [
6784
+ /* @__PURE__ */ jsxs36("div", { className: "b316-plan-name", children: [
6433
6785
  "Change to ",
6434
6786
  to.planName
6435
6787
  ] }),
6436
- /* @__PURE__ */ jsxs34("div", { className: "b316-muted", children: [
6788
+ /* @__PURE__ */ jsxs36("div", { className: "b316-muted", children: [
6437
6789
  "From ",
6438
6790
  from.planName
6439
6791
  ] }),
6440
- error ? /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }) : null,
6441
- changes.length === 0 ? /* @__PURE__ */ jsx35("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ jsxs34("table", { className: "b316-review-table", children: [
6442
- /* @__PURE__ */ jsx35("thead", { children: /* @__PURE__ */ jsxs34("tr", { children: [
6443
- /* @__PURE__ */ jsx35("th", { children: "Feature" }),
6444
- /* @__PURE__ */ jsx35("th", { children: from.planName }),
6445
- /* @__PURE__ */ jsx35("th", { children: to.planName })
6792
+ error ? /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }) : null,
6793
+ changes.length === 0 ? /* @__PURE__ */ jsx37("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ jsxs36("table", { className: "b316-review-table", children: [
6794
+ /* @__PURE__ */ jsx37("thead", { children: /* @__PURE__ */ jsxs36("tr", { children: [
6795
+ /* @__PURE__ */ jsx37("th", { children: "Feature" }),
6796
+ /* @__PURE__ */ jsx37("th", { children: from.planName }),
6797
+ /* @__PURE__ */ jsx37("th", { children: to.planName })
6446
6798
  ] }) }),
6447
- /* @__PURE__ */ jsx35("tbody", { children: changes.map((change) => /* @__PURE__ */ jsxs34("tr", { children: [
6448
- /* @__PURE__ */ jsx35("td", { children: change.featureName }),
6449
- /* @__PURE__ */ jsx35("td", { children: limitText(change.before, change.type) }),
6450
- /* @__PURE__ */ jsx35(
6799
+ /* @__PURE__ */ jsx37("tbody", { children: changes.map((change) => /* @__PURE__ */ jsxs36("tr", { children: [
6800
+ /* @__PURE__ */ jsx37("td", { children: change.featureName }),
6801
+ /* @__PURE__ */ jsx37("td", { children: limitText(change.before, change.type) }),
6802
+ /* @__PURE__ */ jsx37(
6451
6803
  "td",
6452
6804
  {
6453
6805
  className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
@@ -6456,40 +6808,40 @@ function PlanChangeReview({
6456
6808
  )
6457
6809
  ] }, change.featureId)) })
6458
6810
  ] }),
6459
- preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ jsxs34("p", { children: [
6811
+ preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ jsxs36("p", { children: [
6460
6812
  "The change happens now. Your trial carries on until ",
6461
6813
  day4(now.trialEndsAt),
6462
6814
  ", and nothing is charged before then."
6463
- ] }) : /* @__PURE__ */ jsxs34("div", { children: [
6464
- Number(now.credit) > 0 ? /* @__PURE__ */ jsxs34("div", { className: "b316-row", children: [
6465
- /* @__PURE__ */ jsxs34("span", { className: "b316-muted", children: [
6815
+ ] }) : /* @__PURE__ */ jsxs36("div", { children: [
6816
+ Number(now.credit) > 0 ? /* @__PURE__ */ jsxs36("div", { className: "b316-row", children: [
6817
+ /* @__PURE__ */ jsxs36("span", { className: "b316-muted", children: [
6466
6818
  "Credit for the unused part of ",
6467
6819
  from.planName
6468
6820
  ] }),
6469
- /* @__PURE__ */ jsxs34("span", { className: "b316-num", children: [
6821
+ /* @__PURE__ */ jsxs36("span", { className: "b316-num", children: [
6470
6822
  "\u2212",
6471
6823
  money5(now.credit, from.currency)
6472
6824
  ] })
6473
6825
  ] }) : null,
6474
- Number(now.closingUsage) > 0 ? /* @__PURE__ */ jsxs34("div", { className: "b316-row", children: [
6475
- /* @__PURE__ */ jsx35("span", { className: "b316-muted", children: "Usage so far this period" }),
6476
- /* @__PURE__ */ jsx35("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
6826
+ Number(now.closingUsage) > 0 ? /* @__PURE__ */ jsxs36("div", { className: "b316-row", children: [
6827
+ /* @__PURE__ */ jsx37("span", { className: "b316-muted", children: "Usage so far this period" }),
6828
+ /* @__PURE__ */ jsx37("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
6477
6829
  ] }) : null,
6478
- /* @__PURE__ */ jsxs34("div", { className: "b316-row", children: [
6479
- /* @__PURE__ */ jsxs34("span", { className: "b316-muted", children: [
6830
+ /* @__PURE__ */ jsxs36("div", { className: "b316-row", children: [
6831
+ /* @__PURE__ */ jsxs36("span", { className: "b316-muted", children: [
6480
6832
  to.planName,
6481
6833
  ", ",
6482
6834
  day4(now.newPeriod.start),
6483
6835
  " \u2013 ",
6484
6836
  day4(now.newPeriod.end)
6485
6837
  ] }),
6486
- /* @__PURE__ */ jsx35("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
6838
+ /* @__PURE__ */ jsx37("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
6487
6839
  ] }),
6488
- now.net !== null ? /* @__PURE__ */ jsxs34("div", { className: "b316-row b316-invoice-total", children: [
6489
- /* @__PURE__ */ jsx35("span", { children: "Due now" }),
6490
- /* @__PURE__ */ jsx35("span", { className: "b316-num", children: money5(now.net, to.currency) })
6840
+ now.net !== null ? /* @__PURE__ */ jsxs36("div", { className: "b316-row b316-invoice-total", children: [
6841
+ /* @__PURE__ */ jsx37("span", { children: "Due now" }),
6842
+ /* @__PURE__ */ jsx37("span", { className: "b316-num", children: money5(now.net, to.currency) })
6491
6843
  ] }) : null
6492
- ] }) : /* @__PURE__ */ jsxs34("p", { children: [
6844
+ ] }) : /* @__PURE__ */ jsxs36("p", { children: [
6493
6845
  "You keep ",
6494
6846
  from.planName,
6495
6847
  " until ",
@@ -6502,7 +6854,7 @@ function PlanChangeReview({
6502
6854
  preview.atPeriodEnd.nextInvoice.currency
6503
6855
  )}.` : ""
6504
6856
  ] }),
6505
- otherOpen ? /* @__PURE__ */ jsx35(
6857
+ otherOpen ? /* @__PURE__ */ jsx37(
6506
6858
  "button",
6507
6859
  {
6508
6860
  type: "button",
@@ -6513,12 +6865,12 @@ function PlanChangeReview({
6513
6865
  },
6514
6866
  children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
6515
6867
  }
6516
- ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ jsx35("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6517
- needsCard ? /* @__PURE__ */ jsxs34("div", { className: "b316-notice", role: "status", children: [
6868
+ ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ jsx37("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6869
+ needsCard ? /* @__PURE__ */ jsxs36("div", { className: "b316-notice", role: "status", children: [
6518
6870
  "A card is needed for a change that is charged now.",
6519
- /* @__PURE__ */ jsx35("div", { className: "b316-review-actions", children: /* @__PURE__ */ jsx35("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
6520
- ] }) : /* @__PURE__ */ jsxs34("div", { className: "b316-review-actions", children: [
6521
- /* @__PURE__ */ jsx35(
6871
+ /* @__PURE__ */ jsx37("div", { className: "b316-review-actions", children: /* @__PURE__ */ jsx37("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
6872
+ ] }) : /* @__PURE__ */ jsxs36("div", { className: "b316-review-actions", children: [
6873
+ /* @__PURE__ */ jsx37(
6522
6874
  "button",
6523
6875
  {
6524
6876
  type: "button",
@@ -6528,7 +6880,7 @@ function PlanChangeReview({
6528
6880
  children: busy ? "Working\u2026" : preview.timing === "NOW" ? `Change to ${to.planName} now` : `Schedule ${to.planName}`
6529
6881
  }
6530
6882
  ),
6531
- onCancel ? /* @__PURE__ */ jsxs34("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
6883
+ onCancel ? /* @__PURE__ */ jsxs36("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
6532
6884
  "Keep ",
6533
6885
  from.planName
6534
6886
  ] }) : null
@@ -6538,7 +6890,7 @@ function PlanChangeReview({
6538
6890
  }
6539
6891
 
6540
6892
  // src/BillingPortal.tsx
6541
- import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs35 } from "react/jsx-runtime";
6893
+ import { Fragment as Fragment14, jsx as jsx38, jsxs as jsxs37 } from "react/jsx-runtime";
6542
6894
  function BillingPortal({
6543
6895
  returnUrl,
6544
6896
  featuredPlanKey,
@@ -6548,12 +6900,12 @@ function BillingPortal({
6548
6900
  style
6549
6901
  }) {
6550
6902
  const { client, token, loading: sessionLoading } = useBase316();
6551
- const [overview, setOverview] = useState34(null);
6552
- const [failed, setFailed] = useState34(false);
6553
- const [version, setVersion] = useState34(0);
6554
- const [reviewing, setReviewing] = useState34(null);
6555
- const [notice, setNotice] = useState34(null);
6556
- useEffect26(() => {
6903
+ const [overview, setOverview] = useState35(null);
6904
+ const [failed, setFailed] = useState35(false);
6905
+ const [version, setVersion] = useState35(0);
6906
+ const [reviewing, setReviewing] = useState35(null);
6907
+ const [notice, setNotice] = useState35(null);
6908
+ useEffect27(() => {
6557
6909
  if (!token) return;
6558
6910
  let cancelled = false;
6559
6911
  client.billing.subscription(token).then((result) => {
@@ -6576,24 +6928,24 @@ function BillingPortal({
6576
6928
  setNotice(null);
6577
6929
  setVersion((value) => value + 1);
6578
6930
  }, []);
6579
- const shell = (content) => /* @__PURE__ */ jsx36("div", { className: cls("b316-billing-portal", className), style, children: content });
6580
- if (sessionLoading) return shell(/* @__PURE__ */ jsx36("div", { className: "b316-card", children: "Loading\u2026" }));
6581
- if (!token) return shell(/* @__PURE__ */ jsx36("div", { className: "b316-card", children: "Sign in to manage your billing." }));
6931
+ const shell = (content) => /* @__PURE__ */ jsx38("div", { className: cls("b316-billing-portal", className), style, children: content });
6932
+ if (sessionLoading) return shell(/* @__PURE__ */ jsx38("div", { className: "b316-card", children: "Loading\u2026" }));
6933
+ if (!token) return shell(/* @__PURE__ */ jsx38("div", { className: "b316-card", children: "Sign in to manage your billing." }));
6582
6934
  if (failed) {
6583
6935
  return shell(
6584
- /* @__PURE__ */ jsx36("div", { className: "b316-card", children: /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
6936
+ /* @__PURE__ */ jsx38("div", { className: "b316-card", children: /* @__PURE__ */ jsx38("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
6585
6937
  );
6586
6938
  }
6587
- if (!overview) return shell(/* @__PURE__ */ jsx36("div", { className: "b316-card", children: "Loading\u2026" }));
6939
+ if (!overview) return shell(/* @__PURE__ */ jsx38("div", { className: "b316-card", children: "Loading\u2026" }));
6588
6940
  const { subscription, managedBy, quantityPriced } = overview;
6589
6941
  const canChange = Boolean(subscription) && !managedBy;
6590
6942
  return shell(
6591
- /* @__PURE__ */ jsxs35(Fragment12, { children: [
6592
- notice ? /* @__PURE__ */ jsx36("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6593
- /* @__PURE__ */ jsx36(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6594
- canChange ? /* @__PURE__ */ jsx36(UpcomingInvoice, {}, `next-${version}`) : null,
6595
- canChange && quantityPriced ? /* @__PURE__ */ jsx36(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6596
- reviewing ? /* @__PURE__ */ jsx36(
6943
+ /* @__PURE__ */ jsxs37(Fragment14, { children: [
6944
+ notice ? /* @__PURE__ */ jsx38("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6945
+ /* @__PURE__ */ jsx38(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6946
+ canChange ? /* @__PURE__ */ jsx38(UpcomingInvoice, {}, `next-${version}`) : null,
6947
+ canChange && quantityPriced ? /* @__PURE__ */ jsx38(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6948
+ reviewing ? /* @__PURE__ */ jsx38(
6597
6949
  PlanChangeReview,
6598
6950
  {
6599
6951
  planVersionId: reviewing,
@@ -6606,9 +6958,9 @@ function BillingPortal({
6606
6958
  );
6607
6959
  }
6608
6960
  }
6609
- ) : /* @__PURE__ */ jsxs35("section", { children: [
6610
- /* @__PURE__ */ jsx36("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
6611
- /* @__PURE__ */ jsx36(
6961
+ ) : /* @__PURE__ */ jsxs37("section", { children: [
6962
+ /* @__PURE__ */ jsx38("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
6963
+ /* @__PURE__ */ jsx38(
6612
6964
  PricingTable,
6613
6965
  {
6614
6966
  featuredPlanKey,
@@ -6620,17 +6972,17 @@ function BillingPortal({
6620
6972
  `plans-${version}`
6621
6973
  )
6622
6974
  ] }),
6623
- /* @__PURE__ */ jsx36(CreditBalances, {}, `credits-${version}`),
6624
- managedBy ? null : /* @__PURE__ */ jsx36(PaymentMethod, { returnUrl }, `card-${version}`),
6625
- /* @__PURE__ */ jsx36(Invoices, {}, `invoices-${version}`),
6626
- billingDetails === void 0 ? /* @__PURE__ */ jsx36(BillingDetailsForm, {}, `details-${version}`) : billingDetails
6975
+ /* @__PURE__ */ jsx38(CreditBalances, {}, `credits-${version}`),
6976
+ managedBy ? null : /* @__PURE__ */ jsx38(PaymentMethod, { returnUrl }, `card-${version}`),
6977
+ /* @__PURE__ */ jsx38(Invoices, {}, `invoices-${version}`),
6978
+ billingDetails === void 0 ? /* @__PURE__ */ jsx38(BillingDetailsForm, {}, `details-${version}`) : billingDetails
6627
6979
  ] })
6628
6980
  );
6629
6981
  }
6630
6982
 
6631
6983
  // src/ApiKeyManager.tsx
6632
- import { useCallback as useCallback13, useEffect as useEffect27, useState as useState35 } from "react";
6633
- import { jsx as jsx37, jsxs as jsxs36 } from "react/jsx-runtime";
6984
+ import { useCallback as useCallback13, useEffect as useEffect28, useState as useState36 } from "react";
6985
+ import { jsx as jsx39, jsxs as jsxs38 } from "react/jsx-runtime";
6634
6986
  function duration(seconds) {
6635
6987
  if (seconds % 3600 === 0) {
6636
6988
  return `${seconds / 3600}h`;
@@ -6647,16 +6999,16 @@ function ApiKeyManager({
6647
6999
  audience
6648
7000
  }) {
6649
7001
  const { client, token, loading: sessionLoading } = useBase316();
6650
- const [resources, setResources] = useState35([]);
6651
- const [credentials, setCredentials] = useState35([]);
6652
- const [loading, setLoading] = useState35(true);
6653
- const [busy, setBusy] = useState35(false);
6654
- const [error, setError] = useState35(null);
6655
- const [creating, setCreating] = useState35(false);
6656
- const [name, setName] = useState35("");
6657
- const [chosen, setChosen] = useState35([]);
6658
- const [resourceId, setResourceId] = useState35(null);
6659
- const [issued, setIssued] = useState35(null);
7002
+ const [resources, setResources] = useState36([]);
7003
+ const [credentials, setCredentials] = useState36([]);
7004
+ const [loading, setLoading] = useState36(true);
7005
+ const [busy, setBusy] = useState36(false);
7006
+ const [error, setError] = useState36(null);
7007
+ const [creating, setCreating] = useState36(false);
7008
+ const [name, setName] = useState36("");
7009
+ const [chosen, setChosen] = useState36([]);
7010
+ const [resourceId, setResourceId] = useState36(null);
7011
+ const [issued, setIssued] = useState36(null);
6660
7012
  const load = useCallback13(async () => {
6661
7013
  if (!token) {
6662
7014
  setLoading(false);
@@ -6678,20 +7030,20 @@ function ApiKeyManager({
6678
7030
  setLoading(false);
6679
7031
  }
6680
7032
  }, [client, token, audience]);
6681
- useEffect27(() => {
7033
+ useEffect28(() => {
6682
7034
  void load();
6683
7035
  }, [load]);
6684
7036
  if (sessionLoading || loading) {
6685
- return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
7037
+ return /* @__PURE__ */ jsx39("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6686
7038
  }
6687
7039
  if (!token) {
6688
- return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
7040
+ return /* @__PURE__ */ jsx39("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
6689
7041
  }
6690
7042
  if (error) {
6691
- return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }) });
7043
+ return /* @__PURE__ */ jsx39("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx39("div", { className: "b316-error", role: "alert", children: error }) });
6692
7044
  }
6693
7045
  if (resources.length === 0) {
6694
- return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
7046
+ return /* @__PURE__ */ jsx39("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
6695
7047
  }
6696
7048
  const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
6697
7049
  const reset = () => {
@@ -6700,37 +7052,37 @@ function ApiKeyManager({
6700
7052
  setChosen([]);
6701
7053
  setIssued(null);
6702
7054
  };
6703
- return /* @__PURE__ */ jsxs36("div", { className: cls("b316-card", className), style, children: [
6704
- error ? /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }) : null,
6705
- resources.length > 1 ? /* @__PURE__ */ jsx37(
7055
+ return /* @__PURE__ */ jsxs38("div", { className: cls("b316-card", className), style, children: [
7056
+ error ? /* @__PURE__ */ jsx39("div", { className: "b316-error", role: "alert", children: error }) : null,
7057
+ resources.length > 1 ? /* @__PURE__ */ jsx39(
6706
7058
  "select",
6707
7059
  {
6708
7060
  className: "b316-input",
6709
7061
  value: resource.id,
6710
7062
  onChange: (event) => setResourceId(event.target.value),
6711
7063
  style: { marginBottom: 14 },
6712
- children: resources.map((item) => /* @__PURE__ */ jsx37("option", { value: item.id, children: item.name }, item.id))
7064
+ children: resources.map((item) => /* @__PURE__ */ jsx39("option", { value: item.id, children: item.name }, item.id))
6713
7065
  }
6714
- ) : /* @__PURE__ */ jsx37("div", { className: "b316-plan-name", children: resource.name }),
6715
- resource.rateLimit ? /* @__PURE__ */ jsxs36("div", { className: "b316-muted", children: [
7066
+ ) : /* @__PURE__ */ jsx39("div", { className: "b316-plan-name", children: resource.name }),
7067
+ resource.rateLimit ? /* @__PURE__ */ jsxs38("div", { className: "b316-muted", children: [
6716
7068
  resource.rateLimit.requestsPerWindow,
6717
7069
  " requests per",
6718
7070
  " ",
6719
7071
  duration(resource.rateLimit.windowSeconds),
6720
7072
  resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
6721
- ] }) : /* @__PURE__ */ jsx37("div", { className: "b316-muted", children: "No rate limit." }),
6722
- credentials.length === 0 ? /* @__PURE__ */ jsx37("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ jsx37("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ jsxs36("li", { className: "b316-list-item", children: [
6723
- /* @__PURE__ */ jsxs36("div", { children: [
6724
- /* @__PURE__ */ jsx37("div", { className: "b316-plan-name", children: credential.name }),
6725
- /* @__PURE__ */ jsxs36("div", { className: "b316-muted", children: [
6726
- /* @__PURE__ */ jsx37("code", { children: credential.clientId }),
7073
+ ] }) : /* @__PURE__ */ jsx39("div", { className: "b316-muted", children: "No rate limit." }),
7074
+ credentials.length === 0 ? /* @__PURE__ */ jsx39("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ jsx39("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ jsxs38("li", { className: "b316-list-item", children: [
7075
+ /* @__PURE__ */ jsxs38("div", { children: [
7076
+ /* @__PURE__ */ jsx39("div", { className: "b316-plan-name", children: credential.name }),
7077
+ /* @__PURE__ */ jsxs38("div", { className: "b316-muted", children: [
7078
+ /* @__PURE__ */ jsx39("code", { children: credential.clientId }),
6727
7079
  credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
6728
7080
  credential.disabled ? " \xB7 Disabled" : null
6729
7081
  ] }),
6730
- /* @__PURE__ */ jsx37("div", { className: "b316-muted", children: credential.scopes.join(", ") })
7082
+ /* @__PURE__ */ jsx39("div", { className: "b316-muted", children: credential.scopes.join(", ") })
6731
7083
  ] }),
6732
- /* @__PURE__ */ jsxs36("div", { style: { display: "flex", gap: 8 }, children: [
6733
- /* @__PURE__ */ jsx37(
7084
+ /* @__PURE__ */ jsxs38("div", { style: { display: "flex", gap: 8 }, children: [
7085
+ /* @__PURE__ */ jsx39(
6734
7086
  "button",
6735
7087
  {
6736
7088
  type: "button",
@@ -6759,7 +7111,7 @@ function ApiKeyManager({
6759
7111
  children: "Rotate"
6760
7112
  }
6761
7113
  ),
6762
- /* @__PURE__ */ jsx37(
7114
+ /* @__PURE__ */ jsx39(
6763
7115
  ConfirmButton,
6764
7116
  {
6765
7117
  className: "b316-button b316-button-secondary",
@@ -6783,11 +7135,11 @@ function ApiKeyManager({
6783
7135
  )
6784
7136
  ] })
6785
7137
  ] }, credential.clientId)) }),
6786
- issued ? /* @__PURE__ */ jsxs36("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
6787
- /* @__PURE__ */ jsx37("strong", { children: "Copy this now." }),
7138
+ issued ? /* @__PURE__ */ jsxs38("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
7139
+ /* @__PURE__ */ jsx39("strong", { children: "Copy this now." }),
6788
7140
  " It is shown once and cannot be retrieved again.",
6789
- /* @__PURE__ */ jsx37("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ jsx37("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
6790
- /* @__PURE__ */ jsx37(
7141
+ /* @__PURE__ */ jsx39("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ jsx39("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
7142
+ /* @__PURE__ */ jsx39(
6791
7143
  "button",
6792
7144
  {
6793
7145
  type: "button",
@@ -6800,7 +7152,7 @@ function ApiKeyManager({
6800
7152
  children: "Copy"
6801
7153
  }
6802
7154
  ),
6803
- /* @__PURE__ */ jsx37(
7155
+ /* @__PURE__ */ jsx39(
6804
7156
  "button",
6805
7157
  {
6806
7158
  type: "button",
@@ -6811,8 +7163,8 @@ function ApiKeyManager({
6811
7163
  }
6812
7164
  )
6813
7165
  ] }) : null,
6814
- creating && !issued ? /* @__PURE__ */ jsxs36("div", { style: { marginTop: 14 }, children: [
6815
- /* @__PURE__ */ jsx37(
7166
+ creating && !issued ? /* @__PURE__ */ jsxs38("div", { style: { marginTop: 14 }, children: [
7167
+ /* @__PURE__ */ jsx39(
6816
7168
  "input",
6817
7169
  {
6818
7170
  className: "b316-input",
@@ -6821,9 +7173,9 @@ function ApiKeyManager({
6821
7173
  onChange: (event) => setName(event.target.value)
6822
7174
  }
6823
7175
  ),
6824
- /* @__PURE__ */ jsxs36("div", { style: { marginTop: 10 }, children: [
6825
- resource.availableScopes.map((scope) => /* @__PURE__ */ jsxs36("label", { className: "b316-checkbox", children: [
6826
- /* @__PURE__ */ jsx37(
7176
+ /* @__PURE__ */ jsxs38("div", { style: { marginTop: 10 }, children: [
7177
+ resource.availableScopes.map((scope) => /* @__PURE__ */ jsxs38("label", { className: "b316-checkbox", children: [
7178
+ /* @__PURE__ */ jsx39(
6827
7179
  "input",
6828
7180
  {
6829
7181
  type: "checkbox",
@@ -6833,19 +7185,19 @@ function ApiKeyManager({
6833
7185
  )
6834
7186
  }
6835
7187
  ),
6836
- /* @__PURE__ */ jsx37("code", { children: scope.key }),
6837
- scope.description ? /* @__PURE__ */ jsxs36("span", { className: "b316-muted", children: [
7188
+ /* @__PURE__ */ jsx39("code", { children: scope.key }),
7189
+ scope.description ? /* @__PURE__ */ jsxs38("span", { className: "b316-muted", children: [
6838
7190
  " \u2014 ",
6839
7191
  scope.description
6840
7192
  ] }) : null
6841
7193
  ] }, scope.key)),
6842
- resource.lockedScopes.map((scope) => /* @__PURE__ */ jsxs36("label", { className: "b316-checkbox b316-muted", children: [
6843
- /* @__PURE__ */ jsx37("input", { type: "checkbox", disabled: true }),
6844
- /* @__PURE__ */ jsx37("code", { children: scope.key }),
6845
- /* @__PURE__ */ jsx37("span", { children: " \u2014 not included in your plan" })
7194
+ resource.lockedScopes.map((scope) => /* @__PURE__ */ jsxs38("label", { className: "b316-checkbox b316-muted", children: [
7195
+ /* @__PURE__ */ jsx39("input", { type: "checkbox", disabled: true }),
7196
+ /* @__PURE__ */ jsx39("code", { children: scope.key }),
7197
+ /* @__PURE__ */ jsx39("span", { children: " \u2014 not included in your plan" })
6846
7198
  ] }, scope.key))
6847
7199
  ] }),
6848
- /* @__PURE__ */ jsx37(
7200
+ /* @__PURE__ */ jsx39(
6849
7201
  "button",
6850
7202
  {
6851
7203
  type: "button",
@@ -6879,7 +7231,7 @@ function ApiKeyManager({
6879
7231
  children: "Create key"
6880
7232
  }
6881
7233
  ),
6882
- /* @__PURE__ */ jsx37(
7234
+ /* @__PURE__ */ jsx39(
6883
7235
  "button",
6884
7236
  {
6885
7237
  type: "button",
@@ -6890,7 +7242,7 @@ function ApiKeyManager({
6890
7242
  }
6891
7243
  )
6892
7244
  ] }) : null,
6893
- !creating && !issued ? /* @__PURE__ */ jsx37(
7245
+ !creating && !issued ? /* @__PURE__ */ jsx39(
6894
7246
  "button",
6895
7247
  {
6896
7248
  type: "button",
@@ -6965,26 +7317,45 @@ var MANIFEST = [
6965
7317
  {
6966
7318
  name: "SignIn",
6967
7319
  kind: "component",
6968
- summary: "Password, passkey, magic-link and text-message sign-in in one form.",
7320
+ summary: "Sign in the ways the environment offers \u2014 password, magic link, passkeys, text message, social providers and SSO, as switched on in the dashboard (`GET /v1/auth/methods`).",
6969
7321
  useWhen: "The application renders its own sign-in rather than redirecting to the hosted page.",
6970
7322
  requires: [],
6971
7323
  props: [
6972
7324
  { name: "onSignedIn", summary: "Called once a session exists.", required: false },
7325
+ {
7326
+ name: "password",
7327
+ summary: "`false` hides the password form. Every method prop can only turn a method off.",
7328
+ required: false
7329
+ },
6973
7330
  {
6974
7331
  name: "passkeys",
6975
- summary: "Offer passkeys where supported. On by default.",
7332
+ summary: "`false` hides passkeys; otherwise offered where the environment and browser allow.",
6976
7333
  required: false
6977
7334
  },
7335
+ { name: "magicLink", summary: "`false` hides the emailed sign-in link.", required: false },
6978
7336
  {
6979
7337
  name: "magicLinkRedirectUrl",
6980
- summary: "Where an emailed link lands, which must be registered on the environment. Without it, magic link is not offered at all.",
7338
+ summary: "Where an emailed link lands; defaults to the page rendering the form, which redeems `?token=`. Must be on the environment's redirect allow-list.",
7339
+ required: false
7340
+ },
7341
+ { name: "phone", summary: "`false` hides text-message codes.", required: false },
7342
+ {
7343
+ name: "social",
7344
+ summary: "`false` hides the social buttons; a list of slugs keeps only those providers.",
6981
7345
  required: false
6982
7346
  },
7347
+ { name: "sso", summary: '`false` hides "Sign in with SSO".', required: false },
6983
7348
  {
6984
- name: "phone",
6985
- summary: "Offer signing in with a code sent by text message. Needs text messages switched on for the environment, and its own Twilio account in production.",
7349
+ name: "socialRedirectUrl",
7350
+ summary: "Your server route a social or SSO sign-in returns to with `?code=&state=`: check `state` against the `b316_oauth_state` cookie (`readOAuthState`), then `base316.auth.exchangeCode` with the secret key. On the redirect allow-list. Without it no social or SSO button is shown.",
6986
7351
  required: false
6987
7352
  },
7353
+ {
7354
+ name: "socialState",
7355
+ summary: "A short value carried through a social or SSO sign-in, returned by `readOAuthState`.",
7356
+ required: false
7357
+ },
7358
+ { name: "labels", summary: "Wording for the form, for translation.", required: false },
6988
7359
  {
6989
7360
  name: "secondFactorLabels",
6990
7361
  summary: "Wording for the second-factor step (code box, or enrolment when the environment requires a factor and the user has none), for translation. English when omitted.",
@@ -6994,6 +7365,38 @@ var MANIFEST = [
6994
7365
  ],
6995
7366
  seeAlso: ["SignUp", "ForgotPassword", "SecondFactorStep"]
6996
7367
  },
7368
+ {
7369
+ name: "SocialSignIn",
7370
+ kind: "component",
7371
+ summary: `The environment's social sign-in buttons alone ("Continue with Google"), for a sign-in or sign-up form you draw yourself.`,
7372
+ useWhen: "Your own form needs the social providers switched on in the dashboard. SignIn and SignUp already include them.",
7373
+ requires: [],
7374
+ props: [
7375
+ {
7376
+ name: "socialRedirectUrl",
7377
+ summary: "Your server route the code lands on with `?code=&state=`; check with `readOAuthState`, redeem with `exchangeCode`. On the redirect allow-list. Without it nothing is drawn.",
7378
+ required: false
7379
+ },
7380
+ {
7381
+ name: "socialState",
7382
+ summary: "A short value carried through, returned by `readOAuthState`.",
7383
+ required: false
7384
+ },
7385
+ {
7386
+ name: "social",
7387
+ summary: "`false` hides every button; a list of slugs keeps only those providers.",
7388
+ required: false
7389
+ },
7390
+ {
7391
+ name: "intent",
7392
+ summary: "`sign-up` hides the buttons when the environment is closed to new accounts.",
7393
+ required: false
7394
+ },
7395
+ { name: "divider", summary: 'Draw an "or" rule under the buttons.', required: false },
7396
+ { name: "labels", summary: "`continueWith` and `or`, for translation.", required: false }
7397
+ ],
7398
+ seeAlso: ["SignIn", "SignUp"]
7399
+ },
6997
7400
  {
6998
7401
  name: "SignUp",
6999
7402
  kind: "component",
@@ -7022,6 +7425,21 @@ var MANIFEST = [
7022
7425
  summary: "Wording for the second-factor step, for translation.",
7023
7426
  required: false
7024
7427
  },
7428
+ {
7429
+ name: "social",
7430
+ summary: "`false` hides the social buttons; a list of slugs keeps only those providers.",
7431
+ required: false
7432
+ },
7433
+ {
7434
+ name: "socialRedirectUrl",
7435
+ summary: "Where a social sign-up returns with `?code=&state=`, as on SignIn. Without it no social button is shown.",
7436
+ required: false
7437
+ },
7438
+ {
7439
+ name: "socialState",
7440
+ summary: "A short value carried through a social sign-up, returned by `readOAuthState`.",
7441
+ required: false
7442
+ },
7025
7443
  ...appearance
7026
7444
  ],
7027
7445
  seeAlso: ["SignIn", "VerifyEmail", "SecondFactorStep"]
@@ -7793,6 +8211,7 @@ export {
7793
8211
  SecondFactorStep,
7794
8212
  SignIn,
7795
8213
  SignUp,
8214
+ SocialSignIn,
7796
8215
  SubscriptionManager,
7797
8216
  TeamMembers,
7798
8217
  TwoFactorManager,