@base316/react 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/provider.tsx","../src/appearance.ts","../src/Branding.tsx","../src/Invoices.tsx","../src/UpcomingInvoice.tsx","../src/SeatManager.tsx","../src/BillingDetailsForm.tsx","../src/SignIn.tsx","../src/SecondFactorStep.tsx","../src/SignUp.tsx","../src/UserProfile.tsx","../src/PasskeyManager.tsx","../src/confirm.tsx","../src/ActiveSessions.tsx","../src/DeviceApproval.tsx","../src/PrivacyControls.tsx","../src/TwoFactorManager.tsx","../src/ForgotPassword.tsx","../src/ResetPassword.tsx","../src/VerifyEmail.tsx","../src/TeamMembers.tsx","../src/AcceptInvitation.tsx","../src/PayInvoice.tsx","../src/usePaymentLink.ts","../src/PricingTable.tsx","../src/usePlans.ts","../src/DataTable.tsx","../src/fields.tsx","../src/RecordForm.tsx","../src/RelationPicker.tsx","../src/useCollection.ts","../src/Kanban.tsx","../src/Chart.tsx","../src/RecordDetail.tsx","../src/SubscriptionManager.tsx","../src/BillingPortal.tsx","../src/CreditBalances.tsx","../src/PaymentMethod.tsx","../src/PlanChangeReview.tsx","../src/ApiKeyManager.tsx","../src/manifest.ts"],"sourcesContent":["\"use client\";\n\nimport { Base316Browser } from \"@base316/sdk\";\nimport type { Branding as BrandingInfo, ResolvedSession } from \"@base316/sdk\";\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseState,\n\ttype ReactNode,\n} from \"react\";\n\nimport {\n\tappearanceToStyle,\n\tSTYLESHEET,\n\tSTYLESHEET_EXTRA,\n\tSTYLE_ELEMENT_ID,\n\ttype Base316Appearance,\n} from \"./appearance\";\n\n/**\n * Shared state for the Base316 components.\n *\n * Holds one browser client and the end user's session. The session token is the\n * credential these components send alongside the publishable key: the key says\n * which environment, the token says who, and billing answers need both.\n *\n * The token is kept in `localStorage` by default because that is what a\n * single-page app needs to survive a refresh. An application that would rather\n * hold it in an httpOnly cookie can pass `token` and `onTokenChange` and own\n * the storage itself — which is the better choice if the app has a server.\n */\n\ninterface Base316ContextValue {\n\tclient: Base316Browser;\n\t/** The environment's logo, name and colours. Null until it loads. */\n\tbranding: BrandingInfo | null;\n\ttoken: string | null;\n\tsetToken: (token: string | null) => void;\n\tsession: ResolvedSession | null;\n\tloading: boolean;\n\trefresh: () => Promise<void>;\n\tsignOut: () => Promise<void>;\n}\n\nconst Base316Context = createContext<Base316ContextValue | null>(null);\n\nconst STORAGE_KEY = \"base316.session\";\n\nfunction readStoredToken(): string | null {\n\ttry {\n\t\treturn window.localStorage.getItem(STORAGE_KEY);\n\t} catch {\n\t\t// Private browsing and blocked site data both throw here. A signed-out\n\t\t// render is correct in that case, not a crash.\n\t\treturn null;\n\t}\n}\n\nfunction writeStoredToken(token: string | null): void {\n\ttry {\n\t\tif (token === null) {\n\t\t\twindow.localStorage.removeItem(STORAGE_KEY);\n\t\t} else {\n\t\t\twindow.localStorage.setItem(STORAGE_KEY, token);\n\t\t}\n\t} catch {\n\t\t// Nothing to do: the session simply will not survive a refresh.\n\t}\n}\n\nexport function Base316Provider({\n\tpublishableKey,\n\tbaseUrl,\n\ttoken: controlledToken,\n\tonTokenChange,\n\tappearance,\n\ttenant,\n\tclassName,\n\tchildren,\n}: {\n\tpublishableKey: string;\n\tbaseUrl?: string;\n\t/** Supply this to own session storage yourself. */\n\ttoken?: string | null;\n\tonTokenChange?: (token: string | null) => void;\n\t/** Colours, radius and font, as tokens. See `Base316Appearance`. */\n\tappearance?: Base316Appearance;\n\t/**\n\t * White-label every component under this provider for one tenant: a firm's\n\t * name, logo and colours on the screens your application shows its clients.\n\t * Its own branding, then its parent's, then the environment's, field by\n\t * field. Change it — when the user switches team, say — and the components\n\t * restyle without a reload. Omit it for the environment's own branding.\n\t */\n\ttenant?: { organizationId: string } | { organizationExternalId: string } | null;\n\t/** Your own classes on the wrapper — a Tailwind scope, for instance. */\n\tclassName?: string;\n\tchildren: ReactNode;\n}) {\n\tconst client = useMemo(\n\t\t() => new Base316Browser({ publishableKey, baseUrl }),\n\t\t[publishableKey, baseUrl],\n\t);\n\n\t// Injected once per document rather than imported. The package ships as\n\t// source, and a bare `import \"./styles.css\"` would force every consumer to\n\t// have a CSS loader configured before anything would render at all.\n\tuseEffect(() => {\n\t\tif (document.getElementById(STYLE_ELEMENT_ID)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst element = document.createElement(\"style\");\n\t\telement.id = STYLE_ELEMENT_ID;\n\t\telement.textContent = STYLESHEET + STYLESHEET_EXTRA;\n\t\tdocument.head.appendChild(element);\n\t}, []);\n\n\tconst controlled = controlledToken !== undefined;\n\tconst [internalToken, setInternalToken] = useState<string | null>(null);\n\tconst [session, setSession] = useState<ResolvedSession | null>(null);\n\tconst [branding, setBranding] = useState<BrandingInfo | null>(null);\n\tconst [loading, setLoading] = useState(true);\n\n\tconst token = controlled ? controlledToken : internalToken;\n\n\t// Read storage after mount rather than in the initial state, so a server\n\t// render and the first client render agree and React does not warn.\n\tuseEffect(() => {\n\t\tif (controlled) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetInternalToken(readStoredToken());\n\t}, [controlled]);\n\n\t// Branding needs only the publishable key, so it loads independently of the\n\t// session and is available on a signed-out page too.\n\t// Keyed by value rather than identity, so an inline `tenant={{ … }}` does\n\t// not refetch on every render.\n\tconst tenantKey = tenant\n\t\t? \"organizationId\" in tenant\n\t\t\t? `id:${tenant.organizationId}`\n\t\t\t: `ext:${tenant.organizationExternalId}`\n\t\t: null;\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tconst request = tenantKey\n\t\t\t? client.billing.tenantBranding(\n\t\t\t\t\ttenantKey.startsWith(\"id:\")\n\t\t\t\t\t\t? { organizationId: tenantKey.slice(3) }\n\t\t\t\t\t\t: { organizationExternalId: tenantKey.slice(4) },\n\t\t\t\t)\n\t\t\t: client.billing.branding();\n\n\t\trequest\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) setBranding(result);\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t// A page without branding is still usable: the components that show\n\t\t\t\t// it render nothing rather than blocking everything else.\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, tenantKey]);\n\n\tconst setToken = useCallback(\n\t\t(next: string | null) => {\n\t\t\tif (controlled) {\n\t\t\t\tonTokenChange?.(next);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\twriteStoredToken(next);\n\t\t\tsetInternalToken(next);\n\t\t\tonTokenChange?.(next);\n\t\t},\n\t\t[controlled, onTokenChange],\n\t);\n\n\tconst refresh = useCallback(async () => {\n\t\tif (!token) {\n\t\t\tsetSession(null);\n\t\t\tsetLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tsetSession(await client.auth.session(token));\n\t\t} catch {\n\t\t\t// An expired or revoked token is indistinguishable from a bad one and\n\t\t\t// both mean the same thing here: this browser is signed out.\n\t\t\tsetSession(null);\n\t\t\tsetToken(null);\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, [client, token, setToken]);\n\n\tuseEffect(() => {\n\t\tsetLoading(true);\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\tconst signOut = useCallback(async () => {\n\t\tif (token) {\n\t\t\tawait client.auth.signOut(token).catch(() => {\n\t\t\t\t// The local session is cleared regardless: a failed revoke must not\n\t\t\t\t// leave someone apparently still signed in.\n\t\t\t});\n\t\t}\n\n\t\tsetToken(null);\n\t\tsetSession(null);\n\t}, [client, token, setToken]);\n\n\tconst value = useMemo(\n\t\t() => ({ client, branding, token, setToken, session, loading, refresh, signOut }),\n\t\t[client, branding, token, setToken, session, loading, refresh, signOut],\n\t);\n\n\treturn (\n\t\t<Base316Context.Provider value={value}>\n\t\t\t<div\n\t\t\t\tclassName={className ? `b316-root ${className}` : \"b316-root\"}\n\t\t\t\tstyle={appearanceToStyle({\n\t\t\t\t\t// Whatever was set in the sign-in designer arrives here, so a\n\t\t\t\t\t// customer styles their login once on Base316 and the embedded\n\t\t\t\t\t// components follow — rather than configuring the same colours\n\t\t\t\t\t// twice and watching them drift apart.\n\t\t\t\t\t//\n\t\t\t\t\t// An explicit `appearance` still wins, because a host that has\n\t\t\t\t\t// gone to the trouble of passing tokens means them.\n\t\t\t\t\t...(branding\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tcolorPrimary: branding.primaryColor,\n\t\t\t\t\t\t\t\tcolorBackground: branding.backgroundColor,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t...appearance,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</Base316Context.Provider>\n\t);\n}\n\nexport function useBase316(): Base316ContextValue {\n\tconst value = useContext(Base316Context);\n\n\tif (!value) {\n\t\tthrow new Error(\"Base316 components must be rendered inside <Base316Provider>.\");\n\t}\n\n\treturn value;\n}\n\n/** The signed-in user, or null. `loading` distinguishes \"no one\" from \"not yet\". */\nexport function useSession(): { session: ResolvedSession | null; loading: boolean } {\n\tconst { session, loading } = useBase316();\n\treturn { session, loading };\n}\n","import type { CSSProperties } from \"react\";\n\n/**\n * How these components are styled, and why it works this way.\n *\n * They drop into an application whose CSS we cannot see. Three approaches were\n * possible and only one of them is actually controllable by the host:\n *\n * - Inline styles are self-contained but *unoverridable* — they beat any\n * stylesheet short of `!important`, so a customer cannot restyle anything.\n * - A shipped stylesheet fights the host's cascade unpredictably.\n * - CSS custom properties, with every value read through a variable, let the\n * host restyle without either side guessing at specificity.\n *\n * So: one small stylesheet, injected once, with every colour, radius and font\n * behind a `--b316-*` variable. A customer can restyle in three ways, from\n * least to most invasive:\n *\n * 1. `appearance` on the provider — tokens, no CSS to write.\n * 2. Their own CSS targeting the `b316-*` class names.\n * 3. `className` on any component, to hand it their own utility classes.\n *\n * Nothing here inherits the host's design automatically. That is deliberate:\n * silently absorbing whatever `body { font }` and `button { }` rules exist\n * produces components that look broken in ways neither side can predict.\n */\n\nexport interface Base316Appearance {\n\t/** Buttons, links, focus rings. */\n\tcolorPrimary?: string;\n\t/** Text on primary-coloured surfaces. */\n\tcolorPrimaryText?: string;\n\tcolorText?: string;\n\tcolorMuted?: string;\n\tcolorBackground?: string;\n\tcolorBorder?: string;\n\tcolorDanger?: string;\n\tcolorDangerBackground?: string;\n\tcolorSuccess?: string;\n\tborderRadius?: string;\n\tfontFamily?: string;\n\tfontSize?: string;\n\tspacing?: string;\n}\n\nconst VARIABLES: Record<keyof Base316Appearance, string> = {\n\tcolorPrimary: \"--b316-color-primary\",\n\tcolorPrimaryText: \"--b316-color-primary-text\",\n\tcolorText: \"--b316-color-text\",\n\tcolorMuted: \"--b316-color-muted\",\n\tcolorBackground: \"--b316-color-background\",\n\tcolorBorder: \"--b316-color-border\",\n\tcolorDanger: \"--b316-color-danger\",\n\tcolorDangerBackground: \"--b316-color-danger-bg\",\n\tcolorSuccess: \"--b316-color-success\",\n\tborderRadius: \"--b316-radius\",\n\tfontFamily: \"--b316-font\",\n\tfontSize: \"--b316-font-size\",\n\tspacing: \"--b316-spacing\",\n};\n\n/** Turn the token object into inline custom properties for the root element. */\nexport function appearanceToStyle(appearance?: Base316Appearance): CSSProperties {\n\tif (!appearance) {\n\t\treturn {};\n\t}\n\n\tconst style: Record<string, string> = {};\n\n\tfor (const [key, variable] of Object.entries(VARIABLES)) {\n\t\tconst value = appearance[key as keyof Base316Appearance];\n\n\t\tif (value !== undefined) {\n\t\t\tstyle[variable] = value;\n\t\t}\n\t}\n\n\treturn style as CSSProperties;\n}\n\nexport const STYLE_ELEMENT_ID = \"base316-components\";\n\n/**\n * The stylesheet, injected once per document.\n *\n * Defaults live on `.b316-root` rather than `:root` so an application that\n * never sets a token still gets a coherent look, and one that sets tokens on a\n * parent still wins through normal inheritance.\n */\nexport const STYLESHEET = `\n.b316-root {\n --b316-color-primary: #111827;\n --b316-color-primary-text: #ffffff;\n --b316-color-text: #111827;\n --b316-color-muted: #6b7280;\n --b316-color-background: #ffffff;\n --b316-color-border: #e5e7eb;\n --b316-color-danger: #991b1b;\n --b316-color-danger-bg: #fef2f2;\n --b316-color-success: #166534;\n --b316-radius: 12px;\n --b316-font: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n --b316-font-size: 15px;\n --b316-spacing: 12px;\n\n font-family: var(--b316-font);\n font-size: var(--b316-font-size);\n line-height: 1.5;\n color: var(--b316-color-text);\n}\n\n.b316-card {\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n padding: calc(var(--b316-spacing) * 1.6);\n background: var(--b316-color-background);\n}\n\n.b316-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: var(--b316-spacing); }\n.b316-label { font-size: 0.87em; color: var(--b316-color-muted); }\n\n.b316-input {\n padding: 9px 11px;\n border: 1px solid var(--b316-color-border);\n border-radius: calc(var(--b316-radius) / 1.6);\n font: inherit;\n color: inherit;\n background: var(--b316-color-background);\n}\n.b316-input:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 1px; }\n\n.b316-button {\n width: 100%;\n padding: 10px 14px;\n border: 0;\n border-radius: calc(var(--b316-radius) / 1.6);\n background: var(--b316-color-primary);\n color: var(--b316-color-primary-text);\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n.b316-button:hover:not([disabled]) { filter: brightness(1.12); }\n.b316-button:active:not([disabled]) { transform: translateY(1px); }\n.b316-button:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }\n.b316-button[disabled] { opacity: .55; cursor: not-allowed; }\n\n.b316-button-secondary {\n width: auto;\n transition: background-color .12s ease;\n background: var(--b316-color-background);\n color: var(--b316-color-text);\n border: 1px solid var(--b316-color-border);\n font-weight: 500;\n}\n\n.b316-button-link {\n width: auto;\n background: none;\n border: 0;\n padding: 0;\n color: var(--b316-color-primary);\n font: inherit;\n cursor: pointer;\n text-decoration: underline;\n}\n\n/*\n * An armed confirmation: the question and its way out, side by side.\n *\n * Inline rather than a dialog, because a sandboxed iframe does not get dialogs\n * and these components are meant to be embedded in one.\n */\n.b316-confirm {\n display: inline-flex;\n gap: .4rem;\n align-items: center;\n}\n\n.b316-error {\n background: var(--b316-color-danger-bg);\n color: var(--b316-color-danger);\n padding: 8px 10px;\n border-radius: calc(var(--b316-radius) / 2);\n font-size: 0.9em;\n margin-bottom: var(--b316-spacing);\n}\n\n.b316-muted { color: var(--b316-color-muted); font-size: 0.87em; }\n.b316-success { color: var(--b316-color-success); }\n\n.b316-plans {\n display: grid;\n gap: calc(var(--b316-spacing) * 1.3);\n grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\n align-items: stretch;\n}\n\n/* Messages above the cards span the row rather than taking a card's column. */\n.b316-plans-error,\n.b316-plans-managed { grid-column: 1 / -1; }\n\n.b316-plan {\n display: flex;\n flex-direction: column;\n padding: 0;\n overflow: hidden;\n}\n\n/* The recommended plan. Lifted rather than merely tinted: on a pricing table\n the eye needs one obvious default, and colour alone does not survive being\n viewed in greyscale or by someone who cannot distinguish the accent. */\n.b316-plan-featured {\n border-color: var(--b316-color-primary);\n box-shadow: 0 0 0 1px var(--b316-color-primary);\n}\n\n.b316-plan-badge {\n display: inline-block;\n background: var(--b316-color-primary);\n color: var(--b316-color-primary-text);\n border-radius: 999px;\n padding: 2px 9px;\n font-size: 0.75em;\n font-weight: 600;\n letter-spacing: .02em;\n margin-bottom: 8px;\n}\n\n/* Occupies the badge's height without drawing anything, so a featured card\n does not push its own price and features out of line with the others. */\n.b316-plan-badge-spacer {\n display: inline-block;\n padding: 2px 9px;\n font-size: 0.75em;\n margin-bottom: 8px;\n visibility: hidden;\n}\n\n.b316-plan-head { padding: calc(var(--b316-spacing) * 1.6); padding-bottom: 0; }\n.b316-plan-name { font-weight: 600; font-size: 1.06em; }\n.b316-plan-desc { color: var(--b316-color-muted); font-size: 0.87em; margin-top: 2px; }\n\n.b316-plan-pricing { padding: 0 calc(var(--b316-spacing) * 1.6) calc(var(--b316-spacing) * 1.4); }\n\n.b316-plan-price {\n font-size: 2.1em;\n font-weight: 640;\n letter-spacing: -.02em;\n margin-top: calc(var(--b316-spacing) * 0.7);\n /* Lining figures of even width, so prices do not shimmer between cards. */\n font-variant-numeric: tabular-nums lining-nums;\n}\n\n.b316-plan-cadence { color: var(--b316-color-muted); font-size: 0.87em; min-height: 1.35em; }\n.b316-plan-trial { color: var(--b316-color-success); font-size: 0.87em; min-height: 1.35em; }\n\n.b316-plan-features {\n list-style: none;\n padding: calc(var(--b316-spacing) * 1.2) calc(var(--b316-spacing) * 1.6);\n margin: 0;\n flex: 1;\n border-top: 1px solid var(--b316-color-border);\n}\n.b316-plan-feature {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding: 5px 0;\n font-size: 0.94em;\n}\n.b316-plan-feature-value { color: var(--b316-color-muted); font-variant-numeric: tabular-nums; }\n\n.b316-plan-action {\n padding: calc(var(--b316-spacing) * 1.2) calc(var(--b316-spacing) * 1.6);\n border-top: 1px solid var(--b316-color-border);\n}\n\n/* The plan already held. A faded primary button reads as broken rather than\n as \"you are here\", so this is a flat, quiet, genuinely inert surface. */\n.b316-button-current,\n.b316-button-current[disabled] {\n background: transparent;\n color: var(--b316-color-muted);\n border: 1px solid var(--b316-color-border);\n font-weight: 500;\n opacity: 1;\n cursor: default;\n}\n\n.b316-row { display: flex; justify-content: space-between; gap: 16px; align-items: center; }\n\n/* Credential lists. A row is a thing plus the actions on it, and the actions\n stay put as names vary in length, so the eye tracks one column not two. */\n.b316-list { list-style: none; margin: 0; padding: 0; }\n\n.b316-list-item {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n padding: 12px 0;\n border-top: 1px solid var(--b316-color-border);\n}\n\n.b316-list-item:first-child { border-top: none; }\n\n/* Carries a secret shown exactly once, so it has to read as different from the\n rest of the card rather than as another paragraph. */\n.b316-notice {\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n background: var(--b316-color-subtle, rgba(0,0,0,0.03));\n padding: 12px;\n font-size: 0.93em;\n}\n\n.b316-checkbox {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 4px 0;\n cursor: pointer;\n}\n\n.b316-checkbox input[disabled] { cursor: default; }\n.b316-checkbox.b316-muted { cursor: default; }\n`;\n\n/** Join the component's own class with any the host passed in. */\nexport function cls(base: string, extra?: string): string {\n\treturn extra ? `${base} ${extra}` : base;\n}\n\n/**\n * Branding and invoice styles.\n *\n * Appended as a second block so the print rules stay next to the invoice they\n * apply to, rather than being buried in the middle of the component styles.\n */\nexport const STYLESHEET_EXTRA = `\n.b316-pay__element { margin-bottom: var(--b316-spacing); min-height: 40px; }\n\n.b316-pay__submit {\n width: 100%;\n padding: 11px 14px;\n border: 0;\n border-radius: calc(var(--b316-radius) / 1.6);\n background: var(--b316-color-primary);\n color: #fff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.b316-pay__submit[disabled] { opacity: 0.55; cursor: progress; }\n\n.b316-pay__error {\n background: var(--b316-color-danger-bg);\n color: var(--b316-color-danger);\n padding: 8px 10px;\n border-radius: calc(var(--b316-radius) / 2);\n font-size: 0.9em;\n margin-bottom: var(--b316-spacing);\n}\n\n.b316-pay__done {\n background: var(--b316-color-success-bg, #f0fdf4);\n color: var(--b316-color-success);\n padding: 12px 14px;\n border-radius: calc(var(--b316-radius) / 2);\n text-align: center;\n margin: 0;\n}\n\n.b316-tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--b316-color-border); }\n.b316-tab {\n flex: 1; padding: 8px 4px; background: none; border: 0; cursor: pointer;\n font: inherit; font-size: .95em; color: var(--b316-color-muted);\n border-bottom: 2px solid transparent; margin-bottom: -1px;\n}\n.b316-tab-on { color: var(--b316-color-text); border-bottom-color: var(--b316-color-primary); }\n.b316-branding { display: flex; flex-direction: column; gap: 4px; }\n.b316-branding-logo { max-height: 40px; width: auto; align-self: flex-start; }\n.b316-branding-name { font-size: 1.5em; font-weight: 650; letter-spacing: -.01em; }\n.b316-branding-tagline { color: var(--b316-color-muted); }\n\n.b316-invoice-table { width: 100%; border-collapse: collapse; font-size: 0.94em; }\n.b316-invoice-table th {\n text-align: left;\n font-weight: 500;\n color: var(--b316-color-muted);\n font-size: 0.85em;\n padding: 0 0 6px;\n border-bottom: 1px solid var(--b316-color-border);\n}\n.b316-invoice-table td { padding: 9px 0; border-bottom: 1px solid var(--b316-color-border); }\n/* Columns need breathing room or the amount runs straight into the action —\n \"$49.00View\" — which is what happens when only the row has padding. */\n.b316-invoice-table th + th,\n.b316-invoice-table td + td { padding-left: 16px; }\n.b316-invoice-table td:last-child,\n.b316-invoice-table th:last-child { text-align: right; width: 1%; white-space: nowrap; }\n.b316-invoice-table tr:last-child td { border-bottom: 0; }\n.b316-num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.b316-invoice-view {\n margin-top: calc(var(--b316-spacing) * 1.4);\n border-top: 1px solid var(--b316-color-border);\n padding-top: calc(var(--b316-spacing) * 1.4);\n}\n.b316-invoice-actions { display: flex; gap: 8px; justify-content: flex-end; margin-bottom: var(--b316-spacing); }\n.b316-invoice-doc { display: flex; flex-direction: column; gap: calc(var(--b316-spacing) * 1.4); }\n.b316-invoice-meta { display: grid; grid-template-columns: 1fr 1fr; gap: var(--b316-spacing); }\n.b316-invoice-totals { display: flex; flex-direction: column; gap: 6px; margin-left: auto; min-width: 240px; }\n.b316-invoice-total { font-weight: 650; border-top: 1px solid var(--b316-color-border); padding-top: 6px; }\n\n/* Printing an invoice emits the invoice alone, and printing anything else is\n none of this package's business.\n\n This used to start with a bare \"body * { visibility: hidden }\", which is the\n usual recipe for printing one element — and it is scoped to the document,\n not to us. The stylesheet is injected into the host page's head the first\n time any Base316 component mounts, so from that moment every print in the\n host application came out blank unless the content happened to sit inside\n .b316-invoice-doc. A customer printing their own page had no way to connect\n it back to us.\n\n Scoped to a root the invoice sets on <html> while it is being printed\n instead, so nothing applies unless an invoice asked for it. */\n@media print {\n [data-b316-printing] body * { visibility: hidden; }\n [data-b316-printing] .b316-invoice-doc,\n [data-b316-printing] .b316-invoice-doc * { visibility: visible; }\n [data-b316-printing] .b316-invoice-doc {\n position: absolute;\n inset: 0 auto auto 0;\n width: 100%;\n padding: 24px;\n }\n .b316-invoice-actions { display: none; }\n}\n\n/* --- Collections: tables, forms and detail views ------------------------- */\n\n.b316-table-wrap { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-table-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); flex-wrap: wrap; }\n.b316-table-actions { display: flex; align-items: center; gap: var(--b316-spacing); }\n\n/* The table scrolls inside its own box rather than pushing the page sideways:\n a collection with twenty fields is normal, and a horizontally scrolling page\n makes every other component on it unreachable. */\n.b316-table-scroll { overflow-x: auto; border: 1px solid var(--b316-color-border); border-radius: var(--b316-radius); }\n.b316-table { width: 100%; border-collapse: collapse; font-size: 0.95em; }\n.b316-table th, .b316-table td { padding: 10px 12px; text-align: left; vertical-align: top; white-space: nowrap; }\n.b316-table thead th { background: var(--b316-color-surface-muted, rgba(0,0,0,.03)); font-weight: 600; font-size: 0.87em; color: var(--b316-color-muted); border-bottom: 1px solid var(--b316-color-border); }\n.b316-table tbody tr + tr td { border-top: 1px solid var(--b316-color-border); }\n.b316-row-clickable { cursor: pointer; }\n.b316-row-clickable:hover td { background: var(--b316-color-surface-muted, rgba(0,0,0,.02)); }\n.b316-table-rowactions { text-align: right; white-space: nowrap; }\n.b316-table-more { display: flex; justify-content: center; }\n\n.b316-sort { background: none; border: 0; padding: 0; font: inherit; color: inherit; cursor: pointer; }\n.b316-sort:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }\n\n.b316-empty { padding: calc(var(--b316-spacing) * 2); text-align: center; color: var(--b316-color-muted); }\n\n.b316-button-quiet {\n background: none;\n border: 0;\n padding: 4px 6px;\n font: inherit;\n font-size: 0.9em;\n color: var(--b316-color-primary);\n cursor: pointer;\n border-radius: calc(var(--b316-radius) / 2);\n}\n.b316-button-quiet:hover:not([disabled]) { background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); }\n.b316-button-quiet:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 1px; }\n.b316-button-quiet[disabled] { opacity: .55; cursor: not-allowed; }\n.b316-danger { color: var(--b316-color-danger, #b42318); }\n\n.b316-chip {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--b316-color-surface-muted, rgba(0,0,0,.05));\n font-size: 0.87em;\n}\n.b316-chips { display: inline-flex; gap: 4px; flex-wrap: wrap; }\n\n.b316-form { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-form-title { margin: 0; font-size: 1.05em; }\n.b316-form-actions { display: flex; justify-content: flex-end; gap: 8px; }\n.b316-field { display: flex; flex-direction: column; gap: 4px; }\n.b316-hint { font-size: 0.82em; color: var(--b316-color-muted); }\n.b316-input-invalid { border-color: var(--b316-color-danger, #b42318); }\n.b316-choices { display: flex; flex-wrap: wrap; gap: 10px; }\n.b316-choice { display: inline-flex; align-items: center; gap: 6px; font-size: 0.95em; }\n.b316-suffixed { display: flex; align-items: center; gap: 8px; }\n.b316-address { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }\n\n.b316-relation-chosen { display: flex; align-items: center; gap: 8px; }\n.b316-relation-results {\n list-style: none;\n margin: 4px 0 0;\n padding: 4px;\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n max-height: 220px;\n overflow-y: auto;\n background: var(--b316-color-surface, #fff);\n}\n.b316-relation-result { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 6px 8px; font: inherit; cursor: pointer; border-radius: calc(var(--b316-radius) / 2); }\n.b316-relation-result:hover, .b316-relation-result:focus-visible { background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); outline: none; }\n.b316-relation-empty { padding: 6px 8px; }\n\n.b316-detail { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--b316-spacing); }\n.b316-detail-title { margin: 0; font-size: 1.1em; }\n.b316-detail-actions { display: flex; gap: 4px; }\n.b316-detail-fields { display: grid; grid-template-columns: minmax(120px, 200px) 1fr; gap: 8px var(--b316-spacing); margin: 0; }\n.b316-detail-row { display: contents; }\n.b316-detail-fields dd { margin: 0; }\n\n/* One column on a narrow screen. A label column of 200px beside a value leaves\n nothing for the value on a phone. */\n/* --- Teams --------------------------------------------------------------- */\n\n.b316-team { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-team-title { margin: 0; font-size: 1em; font-weight: 600; }\n.b316-team-subtitle { margin: 0; font-size: .9em; font-weight: 600; color: var(--b316-color-muted); }\n.b316-team-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }\n.b316-team-member { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); }\n.b316-team-member-side { display: flex; align-items: center; gap: 8px; }\n.b316-team-invite { display: flex; flex-direction: column; gap: 4px; }\n.b316-team-invite-row { display: flex; gap: 8px; }\n.b316-team-invite-row input { flex: 1; }\n/* Selectable and wrapping: this is copied by hand and pasted into an email. */\n.b316-team-link { display: flex; flex-direction: column; gap: 4px; }\n.b316-team-link code { word-break: break-all; user-select: all; padding: 8px; border: 1px solid var(--b316-color-border); border-radius: var(--b316-radius); }\n\n.b316-invitation { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-invitation-actions { display: flex; align-items: center; gap: var(--b316-spacing); }\n\n/* --- Sessions, two-factor and the password flows ------------------------- */\n\n.b316-sessions { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-sessions-head { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); flex-wrap: wrap; }\n.b316-sessions-title, .b316-mfa-title { margin: 0; font-size: 1em; font-weight: 600; }\n.b316-sessions-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }\n.b316-session { display: flex; flex-direction: column; gap: 2px; }\n.b316-session-device { display: flex; align-items: center; gap: 6px; font-size: 0.95em; }\n\n.b316-device { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-device-title { margin: 0; font-size: 1em; font-weight: 600; }\n/* What is being granted, listed rather than run together: somebody is deciding\n on this, and a comma-separated line is read as one thing. */\n.b316-device-scopes { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }\n.b316-device-scopes li { padding: 2px 8px; border-radius: 999px; font-size: 0.85em; background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); }\n.b316-device-actions { display: flex; gap: 8px; }\n\n.b316-privacy { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-privacy-title { margin: 0; font-size: 1em; font-weight: 600; }\n/* Wraps rather than squeezes: the explanation beside each control is the part\n that matters, and on a narrow screen it belongs above the button. */\n.b316-privacy-row { display: flex; flex-wrap: wrap; align-items: start; justify-content: space-between; gap: 10px; }\n.b316-privacy-row p { margin: 0; }\n.b316-privacy-confirm { display: flex; flex-direction: column; gap: 8px; }\n.b316-privacy-actions { display: flex; justify-content: flex-end; gap: 8px; }\n\n.b316-mfa { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-mfa-enrol, .b316-mfa-codes, .b316-mfa-on, .b316-mfa-off { display: flex; flex-direction: column; gap: 10px; }\n.b316-mfa-actions { display: flex; justify-content: flex-end; gap: 8px; }\n/* Selectable and wrapping: this is copied by hand on the device that cannot\n scan its own screen. */\n.b316-mfa-secret code {\n display: block;\n padding: 10px;\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n font-size: 1.05em;\n letter-spacing: .08em;\n word-break: break-all;\n user-select: all;\n}\n.b316-mfa-uri { font-size: 0.9em; }\n.b316-mfa-code-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }\n.b316-mfa-code-list code { user-select: all; }\n/* The enrolment choices: whole-width buttons with their explanation inside,\n so the explanation is part of what a screen reader announces. */\n.b316-mfa-methods { display: flex; flex-direction: column; gap: 8px; border: 0; margin: 0; padding: 0; min-width: 0; }\n.b316-mfa-method { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; text-align: left; }\n.b316-mfa-method .b316-muted { font-weight: 400; }\n/* Always on white with a margin: a QR code on a dark theme does not scan. */\n.b316-mfa-qr { align-self: center; width: 180px; height: 180px; padding: 8px; background: #fff; border-radius: var(--b316-radius); }\n\n@media (max-width: 560px) {\n .b316-mfa-code-list { grid-template-columns: 1fr; }\n .b316-detail-fields { grid-template-columns: 1fr; }\n .b316-detail-row { display: block; margin-bottom: 10px; }\n .b316-address { grid-template-columns: 1fr; }\n}\n\n/* --- Board --------------------------------------------------------------- */\n\n.b316-board-wrap { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n/* The board scrolls sideways inside itself. Six columns is normal and a page\n that scrolls horizontally puts everything else on it out of reach. */\n.b316-board { display: flex; gap: var(--b316-spacing); overflow-x: auto; align-items: flex-start; padding-bottom: 4px; }\n.b316-board-column {\n flex: 0 0 260px;\n background: var(--b316-color-surface-muted, rgba(0,0,0,.03));\n border: 1px solid transparent;\n border-radius: var(--b316-radius);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.b316-board-over { border-color: var(--b316-color-primary); }\n.b316-board-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }\n.b316-board-title { font-weight: 600; font-size: 0.92em; }\n.b316-board-cards { display: flex; flex-direction: column; gap: 8px; min-height: 40px; }\n.b316-board-card {\n background: var(--b316-color-surface, #fff);\n border: 1px solid var(--b316-color-border);\n border-radius: calc(var(--b316-radius) * .8);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 0.9em;\n}\n.b316-board-card[draggable=\"true\"] { cursor: grab; }\n.b316-board-card-title { font-weight: 600; }\n.b316-board-card-field { display: flex; justify-content: space-between; gap: 8px; }\n.b316-board-move { display: flex; align-items: center; gap: 6px; margin-top: 2px; }\n.b316-board-move select { flex: 1; font-size: 0.9em; padding: 2px 4px; }\n.b316-board-empty { color: var(--b316-color-muted); font-size: 0.87em; padding: 6px 2px; }\n\n/* --- Chart --------------------------------------------------------------- */\n\n.b316-chart { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-chart-title { font-weight: 600; font-size: 0.95em; }\n.b316-chart-plot { display: flex; align-items: flex-end; gap: 4px; overflow-x: auto; }\n.b316-chart-col { flex: 1 0 24px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 4px; }\n.b316-chart-bar { width: 100%; background: var(--b316-color-primary); border-radius: 3px 3px 0 0; min-height: 2px; }\n.b316-chart-label { font-size: 0.7em; color: var(--b316-color-muted); white-space: nowrap; transform: rotate(-45deg); transform-origin: top left; height: 1.6em; }\n.b316-chart-data summary { cursor: pointer; font-size: 0.87em; color: var(--b316-color-muted); }\n.b316-chart-data table { margin-top: 8px; }\n\n/* --- Billing portal ------------------------------------------------------ */\n\n.b316-billing-portal { display: grid; gap: var(--b316-spacing); }\n.b316-billing-portal-section-title { font-weight: 600; font-size: 1em; margin: 0 0 8px; }\n.b316-billing-portal .b316-plans { margin: 0; }\n.b316-invoice-row-actions { white-space: nowrap; text-align: right; }\n.b316-invoice-row-actions .b316-button-link + .b316-button-link { margin-left: 8px; }\n.b316-review-table { width: 100%; border-collapse: collapse; font-size: 0.92em; margin: 8px 0; }\n.b316-review-table th, .b316-review-table td { text-align: left; padding: 6px 4px; border-top: 1px solid var(--b316-color-border, #e5e7eb); }\n.b316-review-table th { color: var(--b316-color-muted); font-weight: 500; border-top: 0; }\n.b316-review-gain { color: #065f46; }\n.b316-review-loss { color: var(--b316-color-danger); }\n.b316-review-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }\n@media (max-width: 560px) {\n .b316-invoice-table th:nth-child(2), .b316-invoice-table td:nth-child(2) { display: none; }\n .b316-review-actions .b316-button { flex: 1 1 100%; }\n}\n`;\n","\"use client\";\n\nimport type { CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * The customer's logo, name and tagline, as configured in the dashboard.\n *\n * `brandDisplay` decides which of the logo and the name is shown, so an\n * application's own header matches the Base316-hosted sign-in page without the\n * customer setting their brand up twice. `LOGO` still renders the name as the\n * image's alt text, because a logo that fails to load must not leave the page\n * anonymous.\n */\nexport function Branding({\n\tshowTagline = true,\n\tclassName,\n\tstyle,\n}: {\n\tshowTagline?: boolean;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { branding } = useBase316();\n\n\tif (!branding) {\n\t\treturn null;\n\t}\n\n\tconst showLogo = branding.logoUrl && branding.brandDisplay !== \"NAME\";\n\tconst showName = branding.brandDisplay !== \"LOGO\" || !branding.logoUrl;\n\n\treturn (\n\t\t<div className={cls(\"b316-branding\", className)} style={style}>\n\t\t\t{showLogo ? (\n\t\t\t\t<img className=\"b316-branding-logo\" src={branding.logoUrl!} alt={branding.brandName} />\n\t\t\t) : null}\n\t\t\t{showName ? <div className=\"b316-branding-name\">{branding.brandName}</div> : null}\n\t\t\t{showTagline && branding.tagline ? (\n\t\t\t\t<div className=\"b316-branding-tagline\">{branding.tagline}</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { InvoiceDetail, InvoiceSummary } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\nfunction money(amount: string, currency: string): string {\n\tconst value = Number(amount);\n\n\tif (!Number.isFinite(value)) {\n\t\treturn `${amount} ${currency}`;\n\t}\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\treturn `${value} ${currency}`;\n\t}\n}\n\nfunction day(value: string | null): string {\n\treturn value ? new Date(value).toLocaleDateString() : \"—\";\n}\n\n/** Statuses an invoice can still be paid in: open, or written off and still owed. */\nconst PAYABLE = new Set([\"OPEN\", \"UNCOLLECTIBLE\"]);\n\n/**\n * The signed-in user's invoices: view one, download its PDF, and pay one that\n * is still open.\n *\n * The PDF is the server's own rendering (`/v1/me/invoices/:id/pdf`) — the same\n * document an operator downloads — fetched with the session and handed to the\n * browser as a download, so nothing about it depends on the host page's print\n * stylesheet. Viewing still opens the printable layout in the page.\n *\n * Paying sends the browser to the hosted pay page, minted on demand for that\n * invoice, where Stripe collects the card; the figure charged is read from the\n * invoice there, never from this list.\n *\n * Drafts never appear. They are the rating engine's working state and can still\n * change, so showing one as a bill would be wrong.\n */\nexport function Invoices({ className, style }: { className?: string; style?: CSSProperties }) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [invoices, setInvoices] = useState<InvoiceSummary[] | null>(null);\n\tconst [open, setOpen] = useState<InvoiceDetail | null>(null);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busyId, setBusyId] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (!token) {\n\t\t\tsetInvoices([]);\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.invoices(token)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) setInvoices(result.data);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load invoices\", cause);\n\t\t\t\tif (!cancelled) setError(\"Could not load your invoices.\");\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token]);\n\n\tconst view = useCallback(\n\t\tasync (id: string) => {\n\t\t\tif (!token) return;\n\n\t\t\ttry {\n\t\t\t\tsetOpen(await client.billing.invoice(token, id));\n\t\t\t} catch (cause) {\n\t\t\t\tconsole.error(\"[base316] could not load the invoice\", cause);\n\t\t\t\tsetError(\"Could not open that invoice.\");\n\t\t\t}\n\t\t},\n\t\t[client, token],\n\t);\n\n\tconst download = useCallback(\n\t\tasync (invoice: InvoiceSummary) => {\n\t\t\tif (!token) return;\n\n\t\t\tsetBusyId(invoice.id);\n\n\t\t\ttry {\n\t\t\t\tconst bytes = await client.billing.invoicePdf(token, invoice.id);\n\t\t\t\tconst url = URL.createObjectURL(new Blob([bytes as BlobPart], { type: \"application/pdf\" }));\n\t\t\t\tconst link = document.createElement(\"a\");\n\n\t\t\t\tlink.href = url;\n\t\t\t\tlink.download = `${invoice.number}.pdf`;\n\t\t\t\tdocument.body.appendChild(link);\n\t\t\t\tlink.click();\n\t\t\t\tlink.remove();\n\t\t\t\t// Released after the click has been handled, not before it.\n\t\t\t\tsetTimeout(() => URL.revokeObjectURL(url), 1_000);\n\t\t\t} catch (cause) {\n\t\t\t\tconsole.error(\"[base316] could not download the invoice\", cause);\n\t\t\t\tsetError(\"Could not download that invoice.\");\n\t\t\t} finally {\n\t\t\t\tsetBusyId(null);\n\t\t\t}\n\t\t},\n\t\t[client, token],\n\t);\n\n\tconst pay = useCallback(\n\t\tasync (invoice: InvoiceSummary) => {\n\t\t\tif (!token) return;\n\n\t\t\tsetBusyId(invoice.id);\n\n\t\t\ttry {\n\t\t\t\tconst { url } = await client.billing.invoicePayLink(token, invoice.id);\n\t\t\t\twindow.location.assign(url);\n\t\t\t} catch (cause) {\n\t\t\t\tconsole.error(\"[base316] could not start paying the invoice\", cause);\n\t\t\t\tsetError(\"That invoice cannot be paid online right now.\");\n\t\t\t\tsetBusyId(null);\n\t\t\t}\n\t\t},\n\t\t[client, token],\n\t);\n\n\t/**\n\t * A failure is reported before the loading state swallows it.\n\t *\n\t * `invoices` stays null on both a pending request and a failed one, so this\n\t * guard meant a customer whose fetch failed sat on \"Loading…\" for ever and\n\t * the error div further down was unreachable.\n\t */\n\tif (error) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (sessionLoading || invoices === null) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!token) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tSign in to see your invoices.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (invoices.length === 0) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tNo invoices yet.\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-invoices\", className)} style={style}>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<table className=\"b316-invoice-table\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Invoice</th>\n\t\t\t\t\t\t<th>Period</th>\n\t\t\t\t\t\t<th>Status</th>\n\t\t\t\t\t\t<th className=\"b316-num\">Total</th>\n\t\t\t\t\t\t<th />\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t{invoices.map((invoice) => (\n\t\t\t\t\t\t<tr key={invoice.id}>\n\t\t\t\t\t\t\t<td>{invoice.number}</td>\n\t\t\t\t\t\t\t<td className=\"b316-muted\">\n\t\t\t\t\t\t\t\t{day(invoice.periodStart)} – {day(invoice.periodEnd)}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td className=\"b316-muted\">{invoice.status.toLowerCase()}</td>\n\t\t\t\t\t\t\t<td className=\"b316-num\">{money(invoice.total, invoice.currency)}</td>\n\t\t\t\t\t\t\t<td className=\"b316-invoice-row-actions\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-link\"\n\t\t\t\t\t\t\t\t\tonClick={() => void view(invoice.id)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tView\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-link\"\n\t\t\t\t\t\t\t\t\tdisabled={busyId === invoice.id}\n\t\t\t\t\t\t\t\t\tonClick={() => void download(invoice)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tPDF\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t{PAYABLE.has(invoice.status) &&\n\t\t\t\t\t\t\t\tNumber(invoice.total) - Number(invoice.amountPaid) > 0 ? (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-link\"\n\t\t\t\t\t\t\t\t\t\tdisabled={busyId === invoice.id}\n\t\t\t\t\t\t\t\t\t\tonClick={() => void pay(invoice)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tPay\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t))}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t{open ? <InvoiceView invoice={open} onClose={() => setOpen(null)} /> : null}\n\t\t</div>\n\t);\n}\n\n/**\n * One invoice, laid out to be printed.\n *\n * `b316-print-only` and the print stylesheet mean the browser's print dialog\n * emits just this document rather than the whole application around it.\n */\nfunction InvoiceView({ invoice, onClose }: { invoice: InvoiceDetail; onClose: () => void }) {\n\treturn (\n\t\t<div className=\"b316-invoice-view\">\n\t\t\t<div className=\"b316-invoice-actions\">\n\t\t\t\t<button type=\"button\" className=\"b316-button b316-button-secondary\" onClick={onClose}>\n\t\t\t\t\tClose\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Claim the print stylesheet, print, and give it back.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * The \"print one element\" rule has to hide everything else on\n\t\t\t\t\t\t * the page, so it cannot be left switched on: the stylesheet\n\t\t\t\t\t\t * lives in the host application's `<head>`, and an always-on\n\t\t\t\t\t\t * rule blanked every print the host did for its own reasons.\n\t\t\t\t\t\t * The flag is set only for the moment this button prints.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst root = document.documentElement;\n\n\t\t\t\t\t\troot.setAttribute(\"data-b316-printing\", \"\");\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\twindow.print();\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t// `window.print()` is synchronous in every browser that\n\t\t\t\t\t\t\t// matters, but the attribute must come off even if it throws\n\t\t\t\t\t\t\t// — leaving it set would reinstate exactly the bug this\n\t\t\t\t\t\t\t// replaced.\n\t\t\t\t\t\t\troot.removeAttribute(\"data-b316-printing\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tDownload PDF\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-invoice-doc\">\n\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<div className=\"b316-plan-name\">{invoice.issuer.brandName}</div>\n\t\t\t\t\t\t{invoice.issuer.supportEmail ? (\n\t\t\t\t\t\t\t<div className=\"b316-muted\">{invoice.issuer.supportEmail}</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style={{ textAlign: \"right\" }}>\n\t\t\t\t\t\t<div className=\"b316-plan-name\">{invoice.number}</div>\n\t\t\t\t\t\t<div className=\"b316-muted\">{invoice.status.toLowerCase()}</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div className=\"b316-invoice-meta\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<div className=\"b316-label\">Billed to</div>\n\t\t\t\t\t\t<div>{invoice.customer.name ?? invoice.customer.email ?? \"—\"}</div>\n\t\t\t\t\t\t{invoice.customer.name && invoice.customer.email ? (\n\t\t\t\t\t\t\t<div className=\"b316-muted\">{invoice.customer.email}</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<div className=\"b316-label\">Period</div>\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t{day(invoice.periodStart)} – {day(invoice.periodEnd)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"b316-muted\">Issued {day(invoice.issuedAt)}</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<table className=\"b316-invoice-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th>Description</th>\n\t\t\t\t\t\t\t<th className=\"b316-num\">Qty</th>\n\t\t\t\t\t\t\t<th className=\"b316-num\">Unit</th>\n\t\t\t\t\t\t\t<th className=\"b316-num\">Amount</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{invoice.lineItems.map((line) => (\n\t\t\t\t\t\t\t<tr key={line.id}>\n\t\t\t\t\t\t\t\t<td>{line.description}</td>\n\t\t\t\t\t\t\t\t<td className=\"b316-num b316-muted\">\n\t\t\t\t\t\t\t\t\t{/* Billable, not consumed: the difference is the included\n\t\t\t\t\t\t\t\t\t allowance, and charging it would be wrong. */}\n\t\t\t\t\t\t\t\t\t{line.billable}\n\t\t\t\t\t\t\t\t\t{line.unit ? ` ${line.unit}` : \"\"}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td className=\"b316-num b316-muted\">\n\t\t\t\t\t\t\t\t\t{line.unitAmount === null ? \"—\" : money(line.unitAmount, invoice.currency)}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td className=\"b316-num\">{money(line.amount, invoice.currency)}</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\n\t\t\t\t<div className=\"b316-invoice-totals\">\n\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t<span className=\"b316-muted\">Subtotal</span>\n\t\t\t\t\t\t<span className=\"b316-num\">{money(invoice.subtotal, invoice.currency)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t{Number(invoice.discountTotal) > 0 ? (\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">Discount</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">−{money(invoice.discountTotal, invoice.currency)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{Number(invoice.taxTotal) > 0 ? (\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">Tax</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{money(invoice.taxTotal, invoice.currency)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div className=\"b316-row b316-invoice-total\">\n\t\t\t\t\t\t<span>Total</span>\n\t\t\t\t\t\t<span className=\"b316-num\">{money(invoice.total, invoice.currency)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t{Number(invoice.amountPaid) > 0 ? (\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">Paid</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{money(invoice.amountPaid, invoice.currency)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { UpcomingInvoice as UpcomingInvoiceData } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Formatted for display only. Every figure was computed server-side in decimal\n * arithmetic; nothing here adds amounts together.\n */\nfunction money(amount: string, currency: string): string {\n\tconst value = Number(amount);\n\n\tif (!Number.isFinite(value)) {\n\t\treturn `${amount} ${currency}`;\n\t}\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\treturn `${amount} ${currency}`;\n\t}\n}\n\nconst day = (value: string) => new Date(value).toLocaleDateString();\n\nconst REASON: Record<string, string> = {\n\tRENEWAL: \"Renews\",\n\tFINAL: \"Final invoice\",\n\tTRIAL_END: \"Trial ends\",\n};\n\ntype State =\n\t| { kind: \"loading\" }\n\t| { kind: \"ready\"; invoice: UpcomingInvoiceData }\n\t| { kind: \"none\" }\n\t| { kind: \"managed\" }\n\t| { kind: \"error\" };\n\n/**\n * The signed-in user's next bill: when it arrives, what is on it, and what it\n * comes to.\n *\n * The figures are the billing engine's own — usage so far, the plan fee,\n * addons, one-off charges, discount, tax and wallet balance — computed on\n * request and stored nowhere, so showing this costs the user nothing and can\n * never disagree with the invoice that follows, except by usage that arrives\n * in between.\n *\n * A client company whose plan a firm pays for sees a line saying so rather\n * than the firm's invoice, which lists every other client's usage too.\n */\nexport function UpcomingInvoice({\n\tshowLines = true,\n\tclassName,\n\tstyle,\n}: {\n\t/** Show the breakdown. Off gives one line: the amount and the date. */\n\tshowLines?: boolean;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [state, setState] = useState<State>({ kind: \"loading\" });\n\n\tuseEffect(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.upcomingInvoice(token)\n\t\t\t.then((invoice) => {\n\t\t\t\tif (!cancelled) setState({ kind: \"ready\", invoice });\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\t// Nothing to bill and somebody-else-pays are answers, not failures.\n\t\t\t\t// Read off the status rather than `instanceof`, which fails when the\n\t\t\t\t// host bundles a second copy of the SDK.\n\t\t\t\tconst status = (cause as { status?: unknown } | null)?.status;\n\n\t\t\t\tif (status === 404) {\n\t\t\t\t\tsetState({ kind: \"none\" });\n\t\t\t\t} else if (status === 403) {\n\t\t\t\t\tsetState({ kind: \"managed\" });\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"[base316] could not load the upcoming invoice\", cause);\n\t\t\t\t\tsetState({ kind: \"error\" });\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token]);\n\n\tconst card = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) {\n\t\treturn card(\"Loading…\");\n\t}\n\n\tif (!token) {\n\t\treturn card(\"Sign in to see your next invoice.\");\n\t}\n\n\tswitch (state.kind) {\n\t\tcase \"loading\":\n\t\t\treturn card(\"Loading…\");\n\t\tcase \"error\":\n\t\t\treturn card(\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your next invoice.\n\t\t\t\t</div>,\n\t\t\t);\n\t\tcase \"none\":\n\t\t\treturn card(\"No upcoming invoice.\");\n\t\tcase \"managed\":\n\t\t\treturn card(\"Your plan is provided by the organization that manages your account.\");\n\t}\n\n\tconst { invoice } = state;\n\tconst amount = (value: string) => money(value, invoice.currency);\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-upcoming-invoice\", className)} style={style}>\n\t\t\t<div className=\"b316-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<div className=\"b316-label\">Next invoice</div>\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t{REASON[invoice.reason] ?? \"Issued\"} {day(invoice.issuesAt)}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"b316-plan-name b316-num\">{amount(invoice.amountDue)}</div>\n\t\t\t</div>\n\n\t\t\t{showLines ? (\n\t\t\t\t<>\n\t\t\t\t\t{invoice.lines.length > 0 ? (\n\t\t\t\t\t\t<table className=\"b316-invoice-table\">\n\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t<th>Description</th>\n\t\t\t\t\t\t\t\t\t<th className=\"b316-num\">Amount</th>\n\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t{invoice.lines.map((line, index) => (\n\t\t\t\t\t\t\t\t\t// No ids until an invoice exists; the engine's order is stable.\n\t\t\t\t\t\t\t\t\t<tr key={`${line.kind}-${index}`}>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t{line.description}\n\t\t\t\t\t\t\t\t\t\t\t{line.kind === \"USAGE\" ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{line.billable} billable of {line.quantity}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{line.unit ? ` ${line.unit}` : \"\"}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td className=\"b316-num\">{amount(line.amount)}</td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t</table>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<div className=\"b316-muted\">Nothing to bill yet.</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<div className=\"b316-invoice-totals\">\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">Subtotal</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{amount(invoice.subtotal)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{Number(invoice.discountTotal) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\tDiscount{invoice.discount ? ` (${invoice.discount.code})` : \"\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">−{amount(invoice.discountTotal)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{Number(invoice.taxTotal) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Tax</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">{amount(invoice.taxTotal)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<div className=\"b316-row b316-invoice-total\">\n\t\t\t\t\t\t\t<span>Total</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{amount(invoice.total)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{Number(invoice.walletApplied) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Account balance</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">−{amount(invoice.walletApplied)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{invoice.amountDue !== invoice.total ? (\n\t\t\t\t\t\t\t<div className=\"b316-row b316-invoice-total\">\n\t\t\t\t\t\t\t\t<span>Amount due</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">{amount(invoice.amountDue)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\tUsage up to {day(invoice.issuesAt)} is still added before it is issued.\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { QuantityChangeOutcome, QuantityChangePreview } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Formatted for display only. Every figure was computed server-side in decimal\n * arithmetic; nothing here adds amounts together.\n */\nfunction money(amount: string, currency: string): string {\n\tconst value = Number(amount);\n\n\tif (!Number.isFinite(value)) {\n\t\treturn `${amount} ${currency}`;\n\t}\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\treturn `${amount} ${currency}`;\n\t}\n}\n\nconst day = (value: string) => new Date(value).toLocaleDateString();\n\n/** A fresh key per confirmed change, so a retried click can never charge twice. */\nfunction newIdempotencyKey(): string {\n\tconst random =\n\t\ttypeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\"\n\t\t\t? crypto.randomUUID()\n\t\t\t: `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n\treturn `seats-${random}`;\n}\n\n/** The status off an SDK error, read without `instanceof` (a second SDK copy breaks it). */\nconst statusOf = (cause: unknown) => (cause as { status?: unknown } | null)?.status;\n\ntype Load =\n\t| { kind: \"loading\" }\n\t| { kind: \"ready\"; quantity: number; scheduledQuantity: number | null; limit: string | null }\n\t| { kind: \"none\" }\n\t| { kind: \"managed\"; name: string | null }\n\t| { kind: \"error\" };\n\nexport interface SeatManagerProps {\n\t/** What a unit is called, plural. \"seats\" by default. */\n\tunitLabel?: string;\n\t/** Called after a change is made, with what it did. */\n\tonChange?: (outcome: QuantityChangeOutcome) => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/**\n * Let the signed-in user change how many seats their subscription is for —\n * with the price shown before anything is charged.\n *\n * Preview, then confirm. The preview is the server's own calculation: adding\n * seats is charged now for the part of the period that is left, removing them\n * takes effect at the period end and refunds nothing. The user only chooses the\n * number — how the change is paid for is the application's policy, not theirs.\n *\n * A client company whose plan a firm pays for is told so instead: resizing the\n * firm's subscription would reach every other client it has.\n */\nexport function SeatManager({ unitLabel = \"seats\", onChange, className, style }: SeatManagerProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [load, setLoad] = useState<Load>({ kind: \"loading\" });\n\tconst [target, setTarget] = useState(\"\");\n\tconst [preview, setPreview] = useState<QuantityChangePreview | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst [message, setMessage] = useState<{ tone: \"error\" | \"success\"; text: string } | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst { subscription, managedBy } = await client.billing.subscription(token);\n\n\t\t\tif (managedBy) {\n\t\t\t\tsetLoad({ kind: \"managed\", name: managedBy.name });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!subscription) {\n\t\t\t\tsetLoad({ kind: \"none\" });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The plan's seat cap, if it has one, comes from a preview of the count\n\t\t\t// already held — it changes nothing and answers what the limit is.\n\t\t\tconst current = await client.billing\n\t\t\t\t.previewQuantity(token, subscription.quantity)\n\t\t\t\t.catch(() => null);\n\n\t\t\tsetLoad({\n\t\t\t\tkind: \"ready\",\n\t\t\t\tquantity: subscription.quantity,\n\t\t\t\tscheduledQuantity: subscription.scheduledQuantity ?? null,\n\t\t\t\tlimit: current?.seatLimit?.limit ?? null,\n\t\t\t});\n\t\t\tsetTarget(String(subscription.quantity));\n\t\t} catch (cause) {\n\t\t\tif (statusOf(cause) === 403) {\n\t\t\t\tsetLoad({ kind: \"managed\", name: null });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconsole.error(\"[base316] could not load the subscription\", cause);\n\t\t\tsetLoad({ kind: \"error\" });\n\t\t}\n\t}, [client, token]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\tconst card = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card b316-seat-manager\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) {\n\t\treturn card(\"Loading…\");\n\t}\n\n\tif (!token) {\n\t\treturn card(`Sign in to manage your ${unitLabel}.`);\n\t}\n\n\tswitch (load.kind) {\n\t\tcase \"loading\":\n\t\t\treturn card(\"Loading…\");\n\t\tcase \"error\":\n\t\t\treturn card(\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your subscription.\n\t\t\t\t</div>,\n\t\t\t);\n\t\tcase \"none\":\n\t\t\treturn card(\"You are not subscribed to a plan.\");\n\t\tcase \"managed\":\n\t\t\treturn card(\n\t\t\t\t`Your plan is provided by ${load.name ?? \"the organization that manages your account\"}. Ask them to change your ${unitLabel}.`,\n\t\t\t);\n\t}\n\n\tconst count = Number(target);\n\tconst valid = Number.isInteger(count) && count >= 1;\n\n\t/** Why a request was refused, in words the user can act on. */\n\tconst refusal = (cause: unknown) => {\n\t\tswitch (statusOf(cause)) {\n\t\t\tcase 400:\n\t\t\t\treturn load.limit !== null\n\t\t\t\t\t? `Your plan allows up to ${load.limit} ${unitLabel}.`\n\t\t\t\t\t: `That number of ${unitLabel} is not available on your plan.`;\n\t\t\tcase 402:\n\t\t\t\treturn \"Add a payment method before adding more.\";\n\t\t\tcase 403:\n\t\t\t\treturn \"Your plan is managed by another organization.\";\n\t\t\tcase 409:\n\t\t\t\treturn \"Your subscription changed in the meantime. Preview again.\";\n\t\t\tdefault:\n\t\t\t\treturn `Could not change your ${unitLabel}.`;\n\t\t}\n\t};\n\n\tconst runPreview = async () => {\n\t\tsetBusy(true);\n\t\tsetMessage(null);\n\n\t\ttry {\n\t\t\tsetPreview(await client.billing.previewQuantity(token, count));\n\t\t} catch (cause) {\n\t\t\tsetPreview(null);\n\t\t\tsetMessage({ tone: \"error\", text: refusal(cause) });\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst confirm = async () => {\n\t\tif (!preview) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetMessage(null);\n\n\t\ttry {\n\t\t\tconst outcome = await client.billing.setQuantity(token, preview.quantity, {\n\t\t\t\tidempotencyKey: newIdempotencyKey(),\n\t\t\t});\n\n\t\t\tsetPreview(null);\n\t\t\tsetMessage({\n\t\t\t\ttone: \"success\",\n\t\t\t\ttext:\n\t\t\t\t\toutcome.effective === \"period_end\" && outcome.direction !== \"unchanged\"\n\t\t\t\t\t\t? `You will have ${outcome.quantity} ${unitLabel} from ${day(outcome.effectiveAt)}.`\n\t\t\t\t\t\t: `You now have ${outcome.quantity} ${unitLabel}.`,\n\t\t\t});\n\t\t\tonChange?.(outcome);\n\t\t\tawait refresh();\n\t\t} catch (cause) {\n\t\t\tsetMessage({ tone: \"error\", text: refusal(cause) });\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst amount = (value: string) => money(value, preview?.currency ?? \"USD\");\n\n\treturn card(\n\t\t<>\n\t\t\t<div className=\"b316-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<div className=\"b316-label\">{unitLabel.charAt(0).toUpperCase() + unitLabel.slice(1)}</div>\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t{load.quantity} now\n\t\t\t\t\t\t{load.scheduledQuantity !== null\n\t\t\t\t\t\t\t? ` · ${load.scheduledQuantity} from the end of this period`\n\t\t\t\t\t\t\t: \"\"}\n\t\t\t\t\t\t{load.limit !== null ? ` · up to ${load.limit} on your plan` : \"\"}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-row\">\n\t\t\t\t<input\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"number\"\n\t\t\t\t\tmin={1}\n\t\t\t\t\tmax={load.limit === null ? undefined : Number(load.limit)}\n\t\t\t\t\tstep={1}\n\t\t\t\t\taria-label={`Number of ${unitLabel}`}\n\t\t\t\t\tvalue={target}\n\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\tsetTarget(event.target.value);\n\t\t\t\t\t\t// A preview is for the number it was asked about. Confirming one\n\t\t\t\t\t\t// computed for a different number would charge the wrong amount.\n\t\t\t\t\t\tsetPreview(null);\n\t\t\t\t\t\tsetMessage(null);\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\tdisabled={!valid || busy || count === load.quantity}\n\t\t\t\t\tonClick={runPreview}\n\t\t\t\t>\n\t\t\t\t\tPreview\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t{preview ? (\n\t\t\t\t<div className=\"b316-invoice-totals\" data-testid=\"seat-preview\">\n\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t\t{preview.direction === \"increase\" ? \"Due now\" : \"Due now (nothing is refunded)\"}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span className=\"b316-num\">{amount(preview.total)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t<span className=\"b316-muted\">Each period from then</span>\n\t\t\t\t\t\t<span className=\"b316-num\">{amount(preview.newRecurringAmount)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t{preview.effective === \"period_end\"\n\t\t\t\t\t\t\t? `Takes effect at the end of this period, ${day(preview.effectiveAt)}.`\n\t\t\t\t\t\t\t: preview.proration === \"invoice_now\"\n\t\t\t\t\t\t\t\t? `Charged for the rest of this period, which ends ${day(preview.currentPeriodEnd)}.`\n\t\t\t\t\t\t\t\t: \"Takes effect now.\"}\n\t\t\t\t\t</div>\n\t\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={confirm}>\n\t\t\t\t\t\t{preview.direction === \"increase\" && Number(preview.total) > 0\n\t\t\t\t\t\t\t? `Pay ${amount(preview.total)} and change to ${preview.quantity}`\n\t\t\t\t\t\t\t: `Change to ${preview.quantity}`}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{message?.tone === \"error\" ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{message.text}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{message?.tone === \"success\" ? (\n\t\t\t\t<output className=\"b316-success\">{message.text}</output>\n\t\t\t) : null}\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { BillingDetails, CustomerAddress, TaxIdInput } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/** The tax id types offered when the application does not choose its own list. */\nconst DEFAULT_TAX_ID_TYPES: { type: string; label: string; example: string }[] = [\n\t{ type: \"eu_vat\", label: \"EU VAT number\", example: \"DE123456789\" },\n\t{ type: \"gb_vat\", label: \"UK VAT number\", example: \"GB123456789\" },\n\t{ type: \"ch_vat\", label: \"Swiss VAT number\", example: \"CHE-123.456.789 MWST\" },\n\t{ type: \"no_vat\", label: \"Norwegian VAT number\", example: \"123456789MVA\" },\n\t{ type: \"au_abn\", label: \"Australian ABN\", example: \"12345678912\" },\n\t{ type: \"nz_gst\", label: \"New Zealand GST number\", example: \"123456789\" },\n\t{ type: \"ca_gst_hst\", label: \"Canadian GST/HST number\", example: \"123456789RT0002\" },\n\t{ type: \"in_gst\", label: \"Indian GSTIN\", example: \"12ABCDE3456FGZH\" },\n\t{ type: \"us_ein\", label: \"US EIN\", example: \"12-3456789\" },\n];\n\nconst STATUS_TEXT: Record<string, string> = {\n\tVERIFIED: \"Verified\",\n\tUNVERIFIED: \"Not checked\",\n\tINVALID: \"Not registered\",\n\tUNAVAILABLE: \"Check pending\",\n};\n\n/** The status off an SDK error, read without `instanceof` (a second SDK copy breaks it). */\nconst statusOf = (cause: unknown) => (cause as { status?: unknown } | null)?.status;\nconst messageOf = (cause: unknown) =>\n\ttypeof (cause as { message?: unknown } | null)?.message === \"string\"\n\t\t? (cause as { message: string }).message\n\t\t: \"Your details could not be saved.\";\n\ntype Load =\n\t| { kind: \"loading\" }\n\t| { kind: \"ready\"; details: BillingDetails }\n\t| { kind: \"none\" }\n\t| { kind: \"managed\" }\n\t| { kind: \"error\" };\n\nconst EMPTY: Record<keyof CustomerAddress, string> = {\n\tline1: \"\",\n\tline2: \"\",\n\tcity: \"\",\n\tstate: \"\",\n\tpostalCode: \"\",\n\tcountry: \"\",\n};\n\nexport interface BillingDetailsFormProps {\n\t/**\n\t * The tax id types to offer, in order. Stripe's type names; the defaults\n\t * cover the EU, UK, Switzerland, Norway, Australia, New Zealand, Canada,\n\t * India and the US.\n\t */\n\ttaxIdTypes?: { type: string; label: string; example: string }[];\n\t/** Called after a save, with the details as stored — tax ids with their check result. */\n\tonSave?: (details: BillingDetails) => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/**\n * The signed-in user's billing address and tax ids.\n *\n * Saved against their own account only — the session decides which, never\n * anything the page sends. An EU VAT number is checked with the EU's VIES\n * service as it is saved, and its result shown: a number VIES does not know is\n * kept and marked, never silently dropped, and one VIES cannot reach right now\n * is checked again later. Invoices are made out to this address, and a valid\n * EU VAT number lets a cross-border business purchase be reverse charged.\n *\n * A client company whose plan a firm pays for is told so instead: the firm's\n * account is the one invoiced.\n */\nexport function BillingDetailsForm({\n\ttaxIdTypes = DEFAULT_TAX_ID_TYPES,\n\tonSave,\n\tclassName,\n\tstyle,\n}: BillingDetailsFormProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [load, setLoad] = useState<Load>({ kind: \"loading\" });\n\tconst [address, setAddress] = useState(EMPTY);\n\tconst [kept, setKept] = useState<TaxIdInput[]>([]);\n\tconst [newType, setNewType] = useState(taxIdTypes[0]?.type ?? \"eu_vat\");\n\tconst [newValue, setNewValue] = useState(\"\");\n\tconst [busy, setBusy] = useState(false);\n\tconst [message, setMessage] = useState<{ tone: \"error\" | \"success\"; text: string } | null>(null);\n\n\tconst show = useCallback((details: BillingDetails) => {\n\t\tsetLoad({ kind: \"ready\", details });\n\t\tsetAddress({\n\t\t\tline1: details.address.line1 ?? \"\",\n\t\t\tline2: details.address.line2 ?? \"\",\n\t\t\tcity: details.address.city ?? \"\",\n\t\t\tstate: details.address.state ?? \"\",\n\t\t\tpostalCode: details.address.postalCode ?? \"\",\n\t\t\tcountry: details.address.country ?? \"\",\n\t\t});\n\t\tsetKept(details.taxIds.map(({ type, value }) => ({ type, value })));\n\t}, []);\n\n\tconst refresh = useCallback(async () => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tshow(await client.billing.billingDetails(token));\n\t\t} catch (cause) {\n\t\t\tconst status = statusOf(cause);\n\n\t\t\tif (status === 403) {\n\t\t\t\tsetLoad({ kind: \"managed\" });\n\t\t\t} else if (status === 404) {\n\t\t\t\tsetLoad({ kind: \"none\" });\n\t\t\t} else {\n\t\t\t\tconsole.error(\"[base316] could not load billing details\", cause);\n\t\t\t\tsetLoad({ kind: \"error\" });\n\t\t\t}\n\t\t}\n\t}, [client, token, show]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\tconst card = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card b316-billing-details\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) {\n\t\treturn card(\"Loading…\");\n\t}\n\n\tif (!token) {\n\t\treturn card(\"Sign in to manage your billing details.\");\n\t}\n\n\tswitch (load.kind) {\n\t\tcase \"loading\":\n\t\t\treturn card(\"Loading…\");\n\t\tcase \"error\":\n\t\t\treturn card(\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your billing details.\n\t\t\t\t</div>,\n\t\t\t);\n\t\tcase \"none\":\n\t\t\treturn card(\"There is no billing account for you yet.\");\n\t\tcase \"managed\":\n\t\t\treturn card(\"Your billing is managed by the organization that provides your plan.\");\n\t}\n\n\tconst { details } = load;\n\n\tconst save = async () => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetMessage(null);\n\n\t\tconst taxIds = newValue.trim() ? [...kept, { type: newType, value: newValue.trim() }] : kept;\n\t\tconst value = (text: string) => text.trim() || null;\n\n\t\ttry {\n\t\t\tconst saved = await client.billing.updateBillingDetails(token, {\n\t\t\t\taddress: {\n\t\t\t\t\tline1: value(address.line1),\n\t\t\t\t\tline2: value(address.line2),\n\t\t\t\t\tcity: value(address.city),\n\t\t\t\t\tstate: value(address.state),\n\t\t\t\t\tpostalCode: value(address.postalCode),\n\t\t\t\t\tcountry: value(address.country)?.toUpperCase() ?? null,\n\t\t\t\t},\n\t\t\t\ttaxIds,\n\t\t\t});\n\n\t\t\tshow(saved);\n\t\t\tsetNewValue(\"\");\n\t\t\tsetMessage({ tone: \"success\", text: \"Billing details saved.\" });\n\t\t\tonSave?.(saved);\n\t\t} catch (cause) {\n\t\t\tsetMessage({ tone: \"error\", text: messageOf(cause) });\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst field = (key: keyof CustomerAddress, label: string, autoComplete: string) => (\n\t\t<label className=\"b316-field\">\n\t\t\t<span className=\"b316-label\">{label}</span>\n\t\t\t<input\n\t\t\t\tclassName=\"b316-input\"\n\t\t\t\tvalue={address[key]}\n\t\t\t\tautoComplete={autoComplete}\n\t\t\t\tmaxLength={key === \"country\" ? 2 : 200}\n\t\t\t\tonChange={(event) => setAddress({ ...address, [key]: event.target.value })}\n\t\t\t/>\n\t\t</label>\n\t);\n\n\tconst labelFor = (type: string) => taxIdTypes.find((entry) => entry.type === type)?.label ?? type;\n\tconst example = taxIdTypes.find((entry) => entry.type === newType)?.example;\n\n\treturn card(\n\t\t<form\n\t\t\tclassName=\"b316-form\"\n\t\t\tonSubmit={(event) => {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tvoid save();\n\t\t\t}}\n\t\t>\n\t\t\t<fieldset className=\"b316-fieldset\">\n\t\t\t\t<legend className=\"b316-legend\">Billing address</legend>\n\t\t\t\t{field(\"line1\", \"Address\", \"address-line1\")}\n\t\t\t\t{field(\"line2\", \"Address line 2\", \"address-line2\")}\n\t\t\t\t{field(\"city\", \"City\", \"address-level2\")}\n\t\t\t\t{field(\"postalCode\", \"Postal code\", \"postal-code\")}\n\t\t\t\t{field(\"state\", \"State, province or region\", \"address-level1\")}\n\t\t\t\t{field(\"country\", \"Country (two-letter code)\", \"country\")}\n\t\t\t</fieldset>\n\n\t\t\t<fieldset className=\"b316-fieldset\">\n\t\t\t\t<legend className=\"b316-legend\">Tax ids</legend>\n\n\t\t\t\t{details.taxIds.length > 0 && (\n\t\t\t\t\t<ul className=\"b316-list\" data-testid=\"tax-ids\">\n\t\t\t\t\t\t{details.taxIds\n\t\t\t\t\t\t\t.filter((taxId) =>\n\t\t\t\t\t\t\t\tkept.some((entry) => entry.type === taxId.type && entry.value === taxId.value),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.map((taxId) => (\n\t\t\t\t\t\t\t\t<li key={taxId.id} className=\"b316-list-item\">\n\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t{labelFor(taxId.type)} <code>{taxId.value}</code>{\" \"}\n\t\t\t\t\t\t\t\t\t\t<span className={`b316-status b316-status-${taxId.status.toLowerCase()}`}>\n\t\t\t\t\t\t\t\t\t\t\t{STATUS_TEXT[taxId.status] ?? taxId.status}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"b316-link\"\n\t\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\t\tsetKept(\n\t\t\t\t\t\t\t\t\t\t\t\tkept.filter(\n\t\t\t\t\t\t\t\t\t\t\t\t\t(entry) => !(entry.type === taxId.type && entry.value === taxId.value),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tRemove\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t)}\n\n\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t<span className=\"b316-label\">Type</span>\n\t\t\t\t\t<select\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tvalue={newType}\n\t\t\t\t\t\tonChange={(event) => setNewType(event.target.value)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{taxIdTypes.map((entry) => (\n\t\t\t\t\t\t\t<option key={entry.type} value={entry.type}>\n\t\t\t\t\t\t\t\t{entry.label}\n\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</select>\n\t\t\t\t</label>\n\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t<span className=\"b316-label\">Tax id</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tvalue={newValue}\n\t\t\t\t\t\tplaceholder={example}\n\t\t\t\t\t\tmaxLength={64}\n\t\t\t\t\t\tonChange={(event) => setNewValue(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t</label>\n\t\t\t</fieldset>\n\n\t\t\t{message?.tone === \"error\" && (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{message.text}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{message?.tone === \"success\" && (\n\t\t\t\t<div className=\"b316-success\" role=\"status\">\n\t\t\t\t\t{message.text}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy}>\n\t\t\t\t{busy ? \"Saving…\" : \"Save billing details\"}\n\t\t\t</button>\n\t\t</form>,\n\t);\n}\n","\"use client\";\n\nimport {\n\tBase316Error,\n\tisPasskeyAutofillAvailable,\n\tisPasskeySupported,\n\tneedsSecondFactor,\n\ttype SignInPending,\n} from \"@base316/sdk\";\nimport { useEffect, useRef, useState, type CSSProperties, type FormEvent } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\nimport { SecondFactorStep, type SecondFactorLabels } from \"./SecondFactorStep\";\n\n/**\n * Email and password sign-in, and — where the application turns them on — a\n * magic link or a code by text message.\n *\n * Handles the MFA branch, because an account with a second factor gets a\n * challenge instead of a session, and a form that ignores that case appears to\n * fail for exactly the users who most need it to work. That includes the case\n * where the environment requires a factor and the person has none: they enrol\n * one here (`SecondFactorStep`), see their recovery codes, and are signed in.\n */\nexport function SignIn({\n\tonSignedIn,\n\tpasskeys = true,\n\tmagicLinkRedirectUrl,\n\tphone = false,\n\tsecondFactorLabels,\n\tclassName,\n\tstyle,\n}: {\n\tonSignedIn?: () => void;\n\t/** Offer passkeys alongside the password. On by default where supported. */\n\tpasskeys?: boolean;\n\t/**\n\t * Where an emailed sign-in link lands. Offering magic link at all requires\n\t * it, because the link has to point somewhere this application controls —\n\t * and the URL must be registered on the environment's sign-in page, the same\n\t * list that governs redirects.\n\t *\n\t * The page it names should render this component: arriving with `?token=`\n\t * redeems it automatically.\n\t */\n\tmagicLinkRedirectUrl?: string;\n\t/**\n\t * Offer signing in with a code sent by text message.\n\t *\n\t * Off by default, because it needs the environment switched on for it and,\n\t * in production, the environment's own Twilio account.\n\t */\n\tphone?: boolean;\n\t/** Override the second-factor step's wording, for translation. */\n\tsecondFactorLabels?: Partial<SecondFactorLabels>;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { client, setToken } = useBase316();\n\tconst [email, setEmail] = useState(\"\");\n\tconst [password, setPassword] = useState(\"\");\n\tconst [code, setCode] = useState(\"\");\n\t// A sign-in that owes a second factor — a code for one they have, or an\n\t// enrolment when the environment requires one and they have none. The step\n\t// renders from this rather than assuming an authenticator app.\n\tconst [pending, setPending] = useState<SignInPending | null>(null);\n\tconst pendingChallenge = pending?.challengeToken ?? null;\n\tconst [phoneNumber, setPhoneNumber] = useState(\"\");\n\tconst [phoneChallenge, setPhoneChallenge] = useState<{ token: string; hint: string } | null>(\n\t\tnull,\n\t);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\t// Whether to draw a passkey button at all. Resolved in an effect rather than\n\t// during render: it asks the browser, and it is false on the server.\n\tconst [passkeyReady, setPasskeyReady] = useState(false);\n\n\tconst [mode, setMode] = useState<\"password\" | \"magic\" | \"phone\">(\"password\");\n\tconst [linkSent, setLinkSent] = useState(false);\n\tconst abortRef = useRef<AbortController | null>(null);\n\n\tconst signInWithPasskey = async (conditional: boolean, signal?: AbortSignal) => {\n\t\tif (!conditional) {\n\t\t\tsetBusy(true);\n\t\t\tsetError(null);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await client.auth.passkeys.signIn({ conditional, signal });\n\n\t\t\tsetToken(result.token);\n\t\t\tonSignedIn?.();\n\t\t} catch (cause) {\n\t\t\t// Cancelling is an answer, not an error — and a conditional ceremony\n\t\t\t// aborts every time the component unmounts, which must stay silent.\n\t\t\tif (\n\t\t\t\tcause instanceof DOMException &&\n\t\t\t\t(cause.name === \"NotAllowedError\" || cause.name === \"AbortError\")\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!conditional) {\n\t\t\t\tconsole.error(\"[base316] passkey sign-in failed\", cause);\n\t\t\t\tsetError(\"That passkey did not work.\");\n\t\t\t}\n\t\t} finally {\n\t\t\tif (!conditional) {\n\t\t\t\tsetBusy(false);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Offer the passkey in the browser's own autofill list.\n\t *\n\t * This is what makes a passkey better than a password rather than merely\n\t * different: the credential appears in the email field's suggestions and one\n\t * tap signs in. The promise stays pending until somebody picks one, so it is\n\t * aborted on unmount.\n\t */\n\tuseEffect(() => {\n\t\tif (!passkeys || !isPasskeySupported() || pendingChallenge) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetPasskeyReady(true);\n\n\t\tconst controller = new AbortController();\n\t\tabortRef.current = controller;\n\n\t\tvoid isPasskeyAutofillAvailable().then((available) => {\n\t\t\tif (available && !controller.signal.aborted) {\n\t\t\t\tvoid signInWithPasskey(true, controller.signal);\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tcontroller.abort();\n\t\t};\n\t\t// Re-running this on every render would start a new ceremony each time,\n\t\t// so it deliberately depends only on what decides whether to run at all.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [passkeys, pendingChallenge]);\n\n\t/**\n\t * Redeem a token the link put in the address bar.\n\t *\n\t * Removed from the URL as soon as it is read: a sign-in token sitting in\n\t * history, or in whatever the page sends to an analytics service, is a\n\t * credential lying around in public.\n\t */\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(window.location.href);\n\t\tconst token = url.searchParams.get(\"token\");\n\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\turl.searchParams.delete(\"token\");\n\t\twindow.history.replaceState({}, \"\", url.toString());\n\n\t\tlet cancelled = false;\n\n\t\tvoid client.auth.magicLink\n\t\t\t.verify({ token })\n\t\t\t.then((result) => {\n\t\t\t\tif (cancelled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// A link proves the mailbox, not the second factor. Treating the\n\t\t\t\t// challenge as a session used to call setToken(undefined) — which\n\t\t\t\t// looked exactly like being signed out.\n\t\t\t\tif (needsSecondFactor(result)) {\n\t\t\t\t\tsetPending(result);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsetToken(result.token);\n\t\t\t\tonSignedIn?.();\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(\"That sign-in link is no longer valid. Ask for a new one.\");\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t\t// Once, on arrival. Re-running would redeem a token already spent.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, []);\n\n\tasync function sendLink() {\n\t\tif (!magicLinkRedirectUrl) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.magicLink.request({ email, redirectUrl: magicLinkRedirectUrl });\n\n\t\t\t// Shown whether or not the address has an account: a sign-in form is\n\t\t\t// not a place to find out who has registered.\n\t\t\tsetLinkSent(true);\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] magic link request failed\", cause);\n\t\t\tsetError(\"We could not send that link. Try again.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function submit(event: FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tif (mode === \"magic\" && !pendingChallenge) {\n\t\t\t\tawait sendLink();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (mode === \"phone\") {\n\t\t\t\tif (!phoneChallenge) {\n\t\t\t\t\tconst started = await client.auth.phone.start({ phone: phoneNumber });\n\n\t\t\t\t\t// The same answer whether or not the number has an account, so the\n\t\t\t\t\t// next step is always the code box.\n\t\t\t\t\tsetPhoneChallenge({ token: started.challengeToken, hint: started.destinationHint });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst signedIn = await client.auth.phone.verify({\n\t\t\t\t\tchallengeToken: phoneChallenge.token,\n\t\t\t\t\tcode,\n\t\t\t\t});\n\n\t\t\t\tif (needsSecondFactor(signedIn)) {\n\t\t\t\t\tsetPending(signedIn);\n\t\t\t\t\tsetCode(\"\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsetToken(signedIn.token);\n\t\t\t\tonSignedIn?.();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst result = await client.auth.signIn({ email, password });\n\n\t\t\t// `needsSecondFactor` is the SDK's narrowing helper; the response itself\n\t\t\t// carries `mfaRequired`. Testing for a field of the helper's name never\n\t\t\t// matched, so a second-factor account fell through to \"wrong password\".\n\t\t\tif (needsSecondFactor(result)) {\n\t\t\t\tsetPending(result);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetToken(result.token);\n\t\t\tonSignedIn?.();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] sign-in failed\", cause);\n\t\t\tsetError(\n\t\t\t\tmode === \"phone\"\n\t\t\t\t\t? phoneChallenge\n\t\t\t\t\t\t? \"That code did not work. Check it, or ask for a new one.\"\n\t\t\t\t\t\t: // Why a text could not be sent is worth saying — a number in the\n\t\t\t\t\t\t\t// wrong format, or too many requests — and the server words it\n\t\t\t\t\t\t\t// without saying anything about accounts.\n\t\t\t\t\t\t\tcause instanceof Error && cause.message\n\t\t\t\t\t\t\t? cause.message\n\t\t\t\t\t\t\t: \"We could not send a code. Try again.\"\n\t\t\t\t\t: // An unconfirmed address and a throttle are worth naming; the\n\t\t\t\t\t\t// server words both without saying whether an account exists.\n\t\t\t\t\t\tcause instanceof Base316Error &&\n\t\t\t\t\t\t (cause.reason === \"EMAIL_NOT_VERIFIED\" || cause.code === \"RATE_LIMITED\")\n\t\t\t\t\t\t? cause.message\n\t\t\t\t\t\t: \"That email and password did not match.\",\n\t\t\t);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\t// Only where the host gave somewhere for the link to land. A tab that cannot\n\t// work is worse than an absent one.\n\tconst magicAvailable = Boolean(magicLinkRedirectUrl) && !pendingChallenge;\n\tconst tabsShown = (magicAvailable || phone) && !pendingChallenge;\n\n\tif (pending) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<SecondFactorStep\n\t\t\t\t\tpending={pending}\n\t\t\t\t\tlabels={secondFactorLabels}\n\t\t\t\t\tonSignedIn={onSignedIn}\n\t\t\t\t\tonRestart={() => {\n\t\t\t\t\t\tsetPending(null);\n\t\t\t\t\t\tsetPassword(\"\");\n\t\t\t\t\t\tsetCode(\"\");\n\t\t\t\t\t\tsetPhoneChallenge(null);\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (linkSent) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div style={{ fontWeight: 600, marginBottom: 6 }}>Check your email</div>\n\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\tIf an account exists for {email}, a sign-in link is on its way. It expires shortly and can\n\t\t\t\t\tbe used once.\n\t\t\t\t</div>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\tstyle={{ marginTop: 16 }}\n\t\t\t\t\tonClick={() => setLinkSent(false)}\n\t\t\t\t>\n\t\t\t\t\tBack to sign in\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form onSubmit={submit} className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{tabsShown ? (\n\t\t\t\t<div className=\"b316-tabs\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName={cls(\"b316-tab\", mode === \"password\" ? \"b316-tab-on\" : undefined)}\n\t\t\t\t\t\tonClick={() => setMode(\"password\")}\n\t\t\t\t\t>\n\t\t\t\t\t\tPassword\n\t\t\t\t\t</button>\n\t\t\t\t\t{magicAvailable ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={cls(\"b316-tab\", mode === \"magic\" ? \"b316-tab-on\" : undefined)}\n\t\t\t\t\t\t\tonClick={() => setMode(\"magic\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tMagic link\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{phone ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={cls(\"b316-tab\", mode === \"phone\" ? \"b316-tab-on\" : undefined)}\n\t\t\t\t\t\t\tonClick={() => setMode(\"phone\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tText message\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{mode === \"phone\" ? (\n\t\t\t\tphoneChallenge ? (\n\t\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-phone-code\">\n\t\t\t\t\t\t\tCode\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tid=\"b316-phone-code\"\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\tvalue={code}\n\t\t\t\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\t\t\t\tautoComplete=\"one-time-code\"\n\t\t\t\t\t\t\tinputMode=\"numeric\"\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t\tWe sent a code to {phoneChallenge.hint}. It expires in ten minutes.{\" \"}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tsetPhoneChallenge(null);\n\t\t\t\t\t\t\t\t\tsetCode(\"\");\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tUse a different number\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t) : (\n\t\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-phone\">\n\t\t\t\t\t\t\tMobile number\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tid=\"b316-phone\"\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\ttype=\"tel\"\n\t\t\t\t\t\t\tvalue={phoneNumber}\n\t\t\t\t\t\t\tonChange={(event) => setPhoneNumber(event.target.value)}\n\t\t\t\t\t\t\tautoComplete=\"tel\"\n\t\t\t\t\t\t\tplaceholder=\"+14155550123\"\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<span className=\"b316-muted\">Include the country code.</span>\n\t\t\t\t\t</div>\n\t\t\t\t)\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-email\">\n\t\t\t\t\t\t\tEmail\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tid=\"b316-email\"\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\tvalue={email}\n\t\t\t\t\t\t\tonChange={(event) => setEmail(event.target.value)}\n\t\t\t\t\t\t\tautoComplete={passkeyReady ? \"email webauthn\" : \"email\"}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t{mode === \"password\" ? (\n\t\t\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-password\">\n\t\t\t\t\t\t\t\tPassword\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tid=\"b316-password\"\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\tvalue={password}\n\t\t\t\t\t\t\t\tonChange={(event) => setPassword(event.target.value)}\n\t\t\t\t\t\t\t\tautoComplete=\"current-password\"\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t)}\n\n\t\t\t<button className=\"b316-button\" type=\"submit\" disabled={busy}>\n\t\t\t\t{busy\n\t\t\t\t\t? \"Working…\"\n\t\t\t\t\t: mode === \"magic\"\n\t\t\t\t\t\t? \"Email me a link\"\n\t\t\t\t\t\t: mode === \"phone\" && !phoneChallenge\n\t\t\t\t\t\t\t? \"Text me a code\"\n\t\t\t\t\t\t\t: \"Sign in\"}\n\t\t\t</button>\n\n\t\t\t{passkeyReady && !pendingChallenge ? (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"b316-muted\" style={{ textAlign: \"center\", margin: \"10px 0\" }}>\n\t\t\t\t\t\tor\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t// The conditional ceremony holds the only credential request\n\t\t\t\t\t\t\t// the browser allows at a time; it has to go before a\n\t\t\t\t\t\t\t// deliberate one can start.\n\t\t\t\t\t\t\tabortRef.current?.abort();\n\t\t\t\t\t\t\tvoid signInWithPasskey(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tSign in with a passkey\n\t\t\t\t\t</button>\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport {\n\tBase316Error,\n\ttype RequiredEnrollmentMethod,\n\ttype RequiredEnrollmentStart,\n\ttype SignInPending,\n} from \"@base316/sdk\";\nimport { useEffect, useRef, useState, type CSSProperties, type FormEvent } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * The second half of a sign-in that owes a second factor.\n *\n * Two shapes, decided by the server rather than guessed here:\n *\n * - **A challenge** (`enroll: false`): a code box for the factor the person\n * already has — their authenticator app, or the code just sent to their inbox\n * or phone — or one of their recovery codes.\n * - **An enrolment** (`enroll: true`): the environment requires a second factor\n * and this person has none, so there is nothing a code box could check. They\n * choose one of `enrollMethods`, prove it with its first code, and are shown\n * their recovery codes once before the session is handed over.\n *\n * The enrolment branch is what used to be missing. `SignIn` showed \"from your\n * authenticator app\" to somebody who had never set one up, and `SignUp`\n * silently stopped — so under a required policy nobody new could ever get in.\n *\n * Every visible string comes from `labels`, so a translated application passes\n * its own and nothing here needs forking.\n */\n\nexport interface SecondFactorLabels {\n\tchallengeTitle: string;\n\tcodeLabel: string;\n\t/** Under the code box when the code went to an inbox or phone. */\n\tcodeSentTo: (destinationHint: string) => string;\n\t/** Under the code box when it comes from an authenticator app. */\n\tcodeFromApp: string;\n\tverify: string;\n\tresend: string;\n\tresent: string;\n\tenrollTitle: string;\n\tenrollIntro: string;\n\tmethodTotp: string;\n\tmethodTotpHint: string;\n\tmethodEmail: string;\n\tmethodEmailHint: string;\n\tmethodSms: string;\n\tmethodSmsHint: string;\n\ttotpInstructions: string;\n\tqrAlt: string;\n\tmanualKey: string;\n\topenInApp: string;\n\tsixDigitCode: string;\n\t/** Under the code box while enrolling a factor whose first code was sent. */\n\tenrollCodeSentTo: (destinationHint: string) => string;\n\tconfirm: string;\n\tphoneLabel: string;\n\tphoneHint: string;\n\tsendCode: string;\n\tchooseAnother: string;\n\tcodesTitle: string;\n\tcodesIntro: string;\n\tcopy: string;\n\tcopied: string;\n\tdownload: string;\n\t/** The file the codes download as. */\n\tdownloadName: string;\n\tsavedConfirm: string;\n\tcontinue: string;\n\tworking: string;\n\tstartOver: string;\n\t/** A failure the server did not word. */\n\tgenericError: string;\n}\n\nexport const DEFAULT_SECOND_FACTOR_LABELS: SecondFactorLabels = {\n\tchallengeTitle: \"Two-step verification\",\n\tcodeLabel: \"Authentication code\",\n\tcodeSentTo: (hint) => `We sent a code to ${hint}. Enter it, or one of your recovery codes.`,\n\tcodeFromApp: \"From your authenticator app, or one of your recovery codes.\",\n\tverify: \"Verify\",\n\tresend: \"Send another code\",\n\tresent: \"A new code is on its way.\",\n\tenrollTitle: \"Set up two-step verification\",\n\tenrollIntro:\n\t\t\"This account needs a second step at sign-in. Choose how you want to receive your codes.\",\n\tmethodTotp: \"Authenticator app\",\n\tmethodTotpHint: \"Google Authenticator, 1Password, Authy or similar. The most secure choice.\",\n\tmethodEmail: \"Email me a code\",\n\tmethodEmailHint: \"A code is sent to your inbox each time you sign in.\",\n\tmethodSms: \"Text me a code\",\n\tmethodSmsHint: \"A code is sent to your phone each time you sign in.\",\n\ttotpInstructions:\n\t\t\"Scan this QR code with your authenticator app, or enter the key by hand. Then type the six-digit code it shows.\",\n\tqrAlt: \"QR code to add this account to an authenticator app\",\n\tmanualKey: \"Setup key\",\n\topenInApp: \"Open in an authenticator app\",\n\tsixDigitCode: \"Six-digit code\",\n\tenrollCodeSentTo: (hint) => `We sent a code to ${hint}. Enter it to finish setting this up.`,\n\tconfirm: \"Confirm\",\n\tphoneLabel: \"Mobile number\",\n\tphoneHint: \"Include the country code, for example +14155550123.\",\n\tsendCode: \"Send code\",\n\tchooseAnother: \"Choose another way\",\n\tcodesTitle: \"Save your recovery codes\",\n\tcodesIntro:\n\t\t\"Each code signs you in once if you lose access to your second step. Keep them somewhere safe — they will not be shown again.\",\n\tcopy: \"Copy codes\",\n\tcopied: \"Copied\",\n\tdownload: \"Download\",\n\tdownloadName: \"recovery-codes.txt\",\n\tsavedConfirm: \"I have saved these codes\",\n\tcontinue: \"Continue\",\n\tworking: \"Working…\",\n\tstartOver: \"Start over\",\n\tgenericError: \"Something went wrong. Try again.\",\n};\n\nexport interface SecondFactorStepProps {\n\t/** What `signIn`, `magicLink.verify` or `phone.verify` returned with `mfaRequired`. */\n\tpending: SignInPending;\n\t/** Called once the session has been handed to the provider. */\n\tonSignedIn?: () => void;\n\t/**\n\t * Back to the start of the sign-in, for a challenge that has expired or been\n\t * used up. Without it, no \"Start over\" button is drawn.\n\t */\n\tonRestart?: () => void;\n\tlabels?: Partial<SecondFactorLabels>;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\ntype Stage =\n\t| { name: \"challenge\" }\n\t| { name: \"choose\" }\n\t| { name: \"smsNumber\" }\n\t| { name: \"confirm\"; enrollment: RequiredEnrollmentStart }\n\t| { name: \"codes\"; token: string; recoveryCodes: string[] };\n\n/** The server's sentence where it wrote one; ours where it did not. */\nfunction messageFrom(cause: unknown, fallback: string): string {\n\treturn cause instanceof Base316Error && cause.message ? cause.message : fallback;\n}\n\n/** A challenge that cannot be answered any more — start the sign-in again. */\nfunction challengeGone(cause: unknown): boolean {\n\treturn (\n\t\tcause instanceof Base316Error &&\n\t\t(cause.reason === \"ALREADY_ENROLLED\" ||\n\t\t\t(cause.code === \"INVALID_API_KEY\" && cause.param === \"challengeToken\"))\n\t);\n}\n\nexport function SecondFactorStep({\n\tpending,\n\tonSignedIn,\n\tonRestart,\n\tlabels: overrides,\n\tclassName,\n\tstyle,\n}: SecondFactorStepProps) {\n\tconst labels = { ...DEFAULT_SECOND_FACTOR_LABELS, ...overrides };\n\tconst { client, setToken } = useBase316();\n\tconst [stage, setStage] = useState<Stage>(\n\t\tpending.enroll ? { name: \"choose\" } : { name: \"challenge\" },\n\t);\n\tconst [code, setCode] = useState(\"\");\n\tconst [phone, setPhone] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [gone, setGone] = useState(false);\n\tconst [notice, setNotice] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst [saved, setSaved] = useState(false);\n\tconst [copied, setCopied] = useState(false);\n\tconst headingRef = useRef<HTMLHeadingElement>(null);\n\n\t// Each step is a new screen to a screen reader too: move focus to its\n\t// heading, or the reader stays on a button that no longer exists.\n\tuseEffect(() => {\n\t\theadingRef.current?.focus();\n\t}, [stage.name]);\n\n\tfunction fail(cause: unknown) {\n\t\tconsole.error(\"[base316] second factor failed\", cause);\n\t\tsetError(messageFrom(cause, labels.genericError));\n\t\tsetGone(challengeGone(cause));\n\t}\n\n\tfunction finish(token: string) {\n\t\tsetToken(token);\n\t\tonSignedIn?.();\n\t}\n\n\tasync function verify(event: FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\t\tsetNotice(null);\n\n\t\ttry {\n\t\t\tconst verified = await client.auth.verifyMfa({\n\t\t\t\tchallengeToken: pending.challengeToken,\n\t\t\t\tcode: code.trim(),\n\t\t\t});\n\n\t\t\tfinish(verified.token);\n\t\t} catch (cause) {\n\t\t\tfail(cause);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function resend() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.mfa.resend({ challengeToken: pending.challengeToken });\n\t\t\tsetNotice(labels.resent);\n\t\t} catch (cause) {\n\t\t\tfail(cause);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function start(method: RequiredEnrollmentMethod, again = false) {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\t\tsetNotice(null);\n\n\t\ttry {\n\t\t\tconst enrollment = await client.auth.startRequiredEnrollment({\n\t\t\t\tchallengeToken: pending.challengeToken,\n\t\t\t\tmethod,\n\t\t\t\t...(method === \"SMS_OTP\" && phone.trim() ? { phone: phone.trim() } : {}),\n\t\t\t});\n\n\t\t\tsetCode(\"\");\n\t\t\tsetStage({ name: \"confirm\", enrollment });\n\n\t\t\tif (again) {\n\t\t\t\tsetNotice(labels.resent);\n\t\t\t}\n\t\t} catch (cause) {\n\t\t\tfail(cause);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function confirm(event: FormEvent) {\n\t\tevent.preventDefault();\n\n\t\tif (stage.name !== \"confirm\") {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\t\tsetNotice(null);\n\n\t\ttry {\n\t\t\tconst result = await client.auth.completeRequiredEnrollment({\n\t\t\t\tchallengeToken: pending.challengeToken,\n\t\t\t\tfactorId: stage.enrollment.factorId,\n\t\t\t\tcode: code.trim(),\n\t\t\t});\n\n\t\t\t// Not signed in yet: the codes are shown once, and handing over the\n\t\t\t// session first would let the page navigate away before anybody saw\n\t\t\t// them.\n\t\t\tsetStage({ name: \"codes\", token: result.token, recoveryCodes: result.recoveryCodes });\n\t\t} catch (cause) {\n\t\t\tfail(cause);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function copyCodes(codes: string[]) {\n\t\ttry {\n\t\t\tawait navigator.clipboard.writeText(codes.join(\"\\n\"));\n\t\t\tsetCopied(true);\n\t\t} catch {\n\t\t\t// No clipboard (an insecure origin, or permission refused). The codes\n\t\t\t// are selectable and downloadable, so this is not worth an error.\n\t\t}\n\t}\n\n\tfunction downloadCodes(codes: string[]) {\n\t\tconst url = URL.createObjectURL(new Blob([`${codes.join(\"\\n\")}\\n`], { type: \"text/plain\" }));\n\t\tconst link = document.createElement(\"a\");\n\n\t\tlink.href = url;\n\t\tlink.download = labels.downloadName;\n\t\tdocument.body.appendChild(link);\n\t\tlink.click();\n\t\tlink.remove();\n\t\tURL.revokeObjectURL(url);\n\t}\n\n\tconst deliveredFactor = pending.factors.find((factor) => factor.destinationHint);\n\tconst methods = pending.enrollMethods ?? [];\n\n\tconst banner = (\n\t\t<>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t\t{gone && onRestart ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{\" \"}\n\t\t\t\t\t\t\t<button type=\"button\" className=\"b316-button-link\" onClick={onRestart}>\n\t\t\t\t\t\t\t\t{labels.startOver}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{notice ? <output className=\"b316-muted\">{notice}</output> : null}\n\t\t</>\n\t);\n\n\tconst heading = (text: string) => (\n\t\t<h3 className=\"b316-form-title\" tabIndex={-1} ref={headingRef}>\n\t\t\t{text}\n\t\t</h3>\n\t);\n\n\tconst codeInput = (id: string, label: string, describedBy?: string) => (\n\t\t<div className=\"b316-field\">\n\t\t\t<label className=\"b316-label\" htmlFor={id}>\n\t\t\t\t{label}\n\t\t\t</label>\n\t\t\t<input\n\t\t\t\tid={id}\n\t\t\t\tclassName=\"b316-input\"\n\t\t\t\tvalue={code}\n\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\tautoComplete=\"one-time-code\"\n\t\t\t\tinputMode=\"numeric\"\n\t\t\t\taria-describedby={describedBy}\n\t\t\t\trequired\n\t\t\t/>\n\t\t</div>\n\t);\n\n\tlet body;\n\n\tif (stage.name === \"challenge\") {\n\t\tbody = (\n\t\t\t<form onSubmit={verify} className=\"b316-mfa-enrol\">\n\t\t\t\t{heading(labels.challengeTitle)}\n\t\t\t\t{banner}\n\t\t\t\t{codeInput(\"b316-code\", labels.codeLabel, \"b316-code-hint\")}\n\t\t\t\t<span id=\"b316-code-hint\" className=\"b316-muted\">\n\t\t\t\t\t{deliveredFactor?.destinationHint\n\t\t\t\t\t\t? labels.codeSentTo(deliveredFactor.destinationHint)\n\t\t\t\t\t\t: labels.codeFromApp}\n\t\t\t\t</span>\n\t\t\t\t<button className=\"b316-button\" type=\"submit\" disabled={busy}>\n\t\t\t\t\t{busy ? labels.working : labels.verify}\n\t\t\t\t</button>\n\t\t\t\t{deliveredFactor ? (\n\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" disabled={busy} onClick={resend}>\n\t\t\t\t\t\t{labels.resend}\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t</form>\n\t\t);\n\t} else if (stage.name === \"choose\") {\n\t\tconst hint: Record<RequiredEnrollmentMethod, [string, string]> = {\n\t\t\tTOTP: [labels.methodTotp, labels.methodTotpHint],\n\t\t\tEMAIL_OTP: [labels.methodEmail, labels.methodEmailHint],\n\t\t\tSMS_OTP: [labels.methodSms, labels.methodSmsHint],\n\t\t};\n\n\t\tbody = (\n\t\t\t<div className=\"b316-mfa-enrol\">\n\t\t\t\t{heading(labels.enrollTitle)}\n\t\t\t\t{banner}\n\t\t\t\t<p className=\"b316-muted\">{labels.enrollIntro}</p>\n\t\t\t\t<fieldset className=\"b316-mfa-methods\" aria-label={labels.enrollTitle}>\n\t\t\t\t\t{methods.map((method) => (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={method}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary b316-mfa-method\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\taria-describedby={`b316-method-${method}`}\n\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\tmethod === \"SMS_OTP\" ? setStage({ name: \"smsNumber\" }) : void start(method)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span>{hint[method][0]}</span>\n\t\t\t\t\t\t\t<span id={`b316-method-${method}`} className=\"b316-muted\">\n\t\t\t\t\t\t\t\t{hint[method][1]}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t))}\n\t\t\t\t</fieldset>\n\t\t\t</div>\n\t\t);\n\t} else if (stage.name === \"smsNumber\") {\n\t\tbody = (\n\t\t\t<form\n\t\t\t\tclassName=\"b316-mfa-enrol\"\n\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tvoid start(\"SMS_OTP\");\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{heading(labels.methodSms)}\n\t\t\t\t{banner}\n\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-enrol-phone\">\n\t\t\t\t\t\t{labels.phoneLabel}\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-enrol-phone\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\ttype=\"tel\"\n\t\t\t\t\t\tautoComplete=\"tel\"\n\t\t\t\t\t\tplaceholder=\"+14155550123\"\n\t\t\t\t\t\taria-describedby=\"b316-enrol-phone-hint\"\n\t\t\t\t\t\tvalue={phone}\n\t\t\t\t\t\tonChange={(event) => setPhone(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t\t<span id=\"b316-enrol-phone-hint\" className=\"b316-muted\">\n\t\t\t\t\t\t{labels.phoneHint}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\tonClick={() => setStage({ name: \"choose\" })}\n\t\t\t\t\t>\n\t\t\t\t\t\t{labels.chooseAnother}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy}>\n\t\t\t\t\t\t{busy ? labels.working : labels.sendCode}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</form>\n\t\t);\n\t} else if (stage.name === \"confirm\") {\n\t\tconst { enrollment } = stage;\n\n\t\tbody = (\n\t\t\t<form onSubmit={confirm} className=\"b316-mfa-enrol\">\n\t\t\t\t{heading(enrollment.method === \"TOTP\" ? labels.methodTotp : labels.enrollTitle)}\n\t\t\t\t{banner}\n\t\t\t\t{enrollment.method === \"TOTP\" ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<p className=\"b316-muted\">{labels.totpInstructions}</p>\n\t\t\t\t\t\t{/* An image of the server's SVG, never markup put into the page:\n\t\t\t\t\t\t an <img> cannot run anything the string might contain. */}\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tclassName=\"b316-mfa-qr\"\n\t\t\t\t\t\t\tsrc={`data:image/svg+xml;charset=utf-8,${encodeURIComponent(enrollment.qrSvg)}`}\n\t\t\t\t\t\t\talt={labels.qrAlt}\n\t\t\t\t\t\t\twidth={180}\n\t\t\t\t\t\t\theight={180}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{/* The key as text too: a QR code is unreadable on the device\n\t\t\t\t\t\t showing it, which is the case when somebody sets this up on\n\t\t\t\t\t\t their phone. */}\n\t\t\t\t\t\t<div className=\"b316-mfa-secret\">\n\t\t\t\t\t\t\t<span className=\"b316-label\" id=\"b316-manual-key\">\n\t\t\t\t\t\t\t\t{labels.manualKey}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<code aria-labelledby=\"b316-manual-key\">{enrollment.secret}</code>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<a className=\"b316-mfa-uri\" href={enrollment.uri}>\n\t\t\t\t\t\t\t{labels.openInApp}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t{codeInput(\"b316-enrol-code\", labels.sixDigitCode)}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{codeInput(\"b316-enrol-code\", labels.codeLabel, \"b316-enrol-code-hint\")}\n\t\t\t\t\t\t<span id=\"b316-enrol-code-hint\" className=\"b316-muted\">\n\t\t\t\t\t\t\t{labels.enrollCodeSentTo(enrollment.destinationHint)}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t\t<button className=\"b316-button\" type=\"submit\" disabled={busy || !code.trim()}>\n\t\t\t\t\t{busy ? labels.working : labels.confirm}\n\t\t\t\t</button>\n\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t{enrollment.method !== \"TOTP\" ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={() => void start(enrollment.method, true)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{labels.resend}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{methods.length > 1 ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tsetError(null);\n\t\t\t\t\t\t\t\tsetStage({ name: \"choose\" });\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{labels.chooseAnother}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</form>\n\t\t);\n\t} else {\n\t\tconst { recoveryCodes, token } = stage;\n\n\t\tbody = (\n\t\t\t<div className=\"b316-mfa-codes\">\n\t\t\t\t{heading(labels.codesTitle)}\n\t\t\t\t<p>{labels.codesIntro}</p>\n\t\t\t\t<ul className=\"b316-mfa-code-list\">\n\t\t\t\t\t{recoveryCodes.map((recovery) => (\n\t\t\t\t\t\t<li key={recovery}>\n\t\t\t\t\t\t\t<code>{recovery}</code>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\tonClick={() => void copyCodes(recoveryCodes)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{copied ? labels.copied : labels.copy}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\tonClick={() => downloadCodes(recoveryCodes)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{labels.download}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<label className=\"b316-checkbox\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tchecked={saved}\n\t\t\t\t\t\tonChange={(event) => setSaved(event.target.checked)}\n\t\t\t\t\t/>\n\t\t\t\t\t<span>{labels.savedConfirm}</span>\n\t\t\t\t</label>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\tdisabled={!saved}\n\t\t\t\t\tonClick={() => finish(token)}\n\t\t\t\t>\n\t\t\t\t\t{labels.continue}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-mfa\", className)} style={style}>\n\t\t\t{body}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport {\n\tBase316Error,\n\ttype InvitationPreview,\n\tneedsSecondFactor,\n\ttype PasswordPolicy,\n\ttype SignInPending,\n} from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties, type FormEvent } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\nimport { SecondFactorStep, type SecondFactorLabels } from \"./SecondFactorStep\";\n\n/**\n * Create an account.\n *\n * Signing up provisions the billing identity too, so the user this returns can\n * be put on a plan immediately — there is no second step to link them to a\n * customer record.\n *\n * Sign-up does not itself produce a session, since the account still has to\n * verify its email. The form signs in straight afterwards so the common case\n * does not make people type their password twice — and when that sign-in owes\n * a second factor, including enrolling one under a policy that requires it,\n * the form carries on into that step rather than stopping with nothing on\n * screen.\n *\n * The password rules shown are the environment's own, read from the API, and a\n * refusal is the server's sentence for the rule that was missed.\n *\n * On a page reached from an invitation (`?invitation=`, or `invitationToken`)\n * the token rides along with the sign-up. The account is then created straight\n * into the inviting team — no personal workspace — with its address counted as\n * verified, because the token reached that mailbox. The form says which team\n * and fills in the address the invitation went to.\n */\n\nexport interface SignUpLabels {\n\tname: string;\n\temail: string;\n\tpassword: string;\n\tsubmit: string;\n\tworking: string;\n\t/** Rules under the password box, joined by the component. */\n\truleMinLength: (count: number) => string;\n\truleUppercase: string;\n\truleLowercase: string;\n\truleNumber: string;\n\truleSymbol: string;\n\truleBreached: string;\n\t/** Account made, but the environment wants the address confirmed first. */\n\tconfirmEmailTitle: string;\n\tconfirmEmail: (email: string) => string;\n\t/** Account made, but signing in straight after failed for another reason. */\n\tcreatedSignInFailed: (reason: string) => string;\n\t/** A failure the server did not word. */\n\tgenericError: string;\n\t/** Above the form when the page came from an invitation. */\n\tjoining: (organizationName: string, roleName: string) => string;\n}\n\nexport const DEFAULT_SIGN_UP_LABELS: SignUpLabels = {\n\tname: \"Name\",\n\temail: \"Email\",\n\tpassword: \"Password\",\n\tsubmit: \"Create account\",\n\tworking: \"Creating…\",\n\truleMinLength: (count) => `At least ${count} characters`,\n\truleUppercase: \"a capital letter\",\n\truleLowercase: \"a lowercase letter\",\n\truleNumber: \"a number\",\n\truleSymbol: \"a symbol\",\n\truleBreached: \"not one found in a known data breach\",\n\tconfirmEmailTitle: \"Check your email\",\n\tconfirmEmail: (email) =>\n\t\t`Your account is ready. We sent a confirmation link to ${email} — open it, then sign in.`,\n\tcreatedSignInFailed: (reason) =>\n\t\t`Your account was created, but we could not sign you in: ${reason}`,\n\tgenericError: \"We could not create that account. Try again.\",\n\tjoining: (organizationName, roleName) =>\n\t\t`You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`,\n};\n\nexport interface SignUpProps {\n\tonSignedUp?: () => void;\n\t/**\n\t * The invitation this sign-up accepts. Read from `?invitation=` when\n\t * omitted; pass `null` to ignore the URL.\n\t */\n\tinvitationToken?: string | null;\n\t/** Called with the team's id when the sign-up accepted an invitation. */\n\tonJoined?: (organizationId: string) => void;\n\tlabels?: Partial<SignUpLabels>;\n\t/** Override the second-factor step's wording, for translation. */\n\tsecondFactorLabels?: Partial<SecondFactorLabels>;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/** The environment's rules as one line, e.g. \"At least 12 characters, with a symbol.\" */\nfunction describeRules(policy: PasswordPolicy, labels: SignUpLabels): string {\n\tconst extras = [\n\t\tpolicy.requireUppercase ? labels.ruleUppercase : null,\n\t\tpolicy.requireLowercase ? labels.ruleLowercase : null,\n\t\tpolicy.requireNumber ? labels.ruleNumber : null,\n\t\tpolicy.requireSymbol ? labels.ruleSymbol : null,\n\t].filter(Boolean);\n\n\tconst base = labels.ruleMinLength(policy.minLength);\n\tconst withExtras = extras.length > 0 ? `${base}, with ${extras.join(\", \")}` : base;\n\n\treturn `${policy.checkBreached ? `${withExtras}; ${labels.ruleBreached}` : withExtras}.`;\n}\n\nexport function SignUp({\n\tonSignedUp,\n\tinvitationToken: suppliedInvitation,\n\tonJoined,\n\tlabels: overrides,\n\tsecondFactorLabels,\n\tclassName,\n\tstyle,\n}: SignUpProps) {\n\tconst labels = { ...DEFAULT_SIGN_UP_LABELS, ...overrides };\n\tconst { client, setToken } = useBase316();\n\tconst [name, setName] = useState(\"\");\n\tconst [email, setEmail] = useState(\"\");\n\tconst [password, setPassword] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst [policy, setPolicy] = useState<PasswordPolicy | null>(null);\n\tconst [pending, setPending] = useState<SignInPending | null>(null);\n\tconst [confirmEmail, setConfirmEmail] = useState(false);\n\tconst [urlInvitation, setUrlInvitation] = useState<string | null>(null);\n\tconst [loaded, setLoaded] = useState<{ token: string; preview: InvitationPreview } | null>(null);\n\n\t// A supplied token wins; `null` means \"ignore the page's\".\n\tconst invitation = suppliedInvitation === undefined ? urlInvitation : suppliedInvitation;\n\t// Only the preview of the token in force, so a changed prop never shows the\n\t// previous team's name.\n\tconst preview = loaded && loaded.token === invitation ? loaded.preview : null;\n\n\t// The page's own invitation. Read after mount, as `<AcceptInvitation />`\n\t// does, so server rendering never sees it.\n\tuseEffect(() => {\n\t\tif (suppliedInvitation !== undefined || typeof window === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tsetUrlInvitation(new URL(window.location.href).searchParams.get(\"invitation\"));\n\t}, [suppliedInvitation]);\n\n\t// Which team, and which address. A dead token leaves the form as it was:\n\t// the sign-up itself then says the invitation is no longer valid.\n\tuseEffect(() => {\n\t\tif (!invitation) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.teams\n\t\t\t.preview(invitation)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetLoaded({ token: invitation, preview: result });\n\t\t\t\t\tsetEmail((current) => current || result.email);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => undefined);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, invitation]);\n\n\t// The rules in force, so the hint under the box is true. A failure leaves\n\t// the hint off rather than guessing \"8 characters\" under a stricter policy.\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tclient.auth\n\t\t\t.passwordPolicy()\n\t\t\t.then((loaded) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetPolicy(loaded);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => undefined);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client]);\n\n\tasync function submit(event: FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst created = await client.auth.signUp({\n\t\t\t\temail,\n\t\t\t\tpassword,\n\t\t\t\tname: name || undefined,\n\t\t\t\tinvitationToken: invitation ?? undefined,\n\t\t\t});\n\n\t\t\tif (created.invitationAccepted && created.organizationId) {\n\t\t\t\tonJoined?.(created.organizationId);\n\t\t\t}\n\t\t} catch (cause) {\n\t\t\t// The friendly message is what the person sees; the cause goes to the\n\t\t\t// console so a developer integrating this is not left guessing. The\n\t\t\t// server's own sentence is the friendly message where it wrote one:\n\t\t\t// \"That email is already registered\", \"Password needs a symbol\".\n\t\t\tconsole.error(\"[base316] sign-up failed\", cause);\n\t\t\tsetError(\n\t\t\t\tcause instanceof Base316Error &&\n\t\t\t\t\t(cause.code === \"INVALID_REQUEST\" ||\n\t\t\t\t\t\tcause.code === \"RATE_LIMITED\" ||\n\t\t\t\t\t\tcause.code === \"CONFLICT\") &&\n\t\t\t\t\tcause.message\n\t\t\t\t\t? cause.message\n\t\t\t\t\t: labels.genericError,\n\t\t\t);\n\t\t\tsetBusy(false);\n\n\t\t\treturn;\n\t\t}\n\n\t\t// The account exists from here on. Whatever happens next, saying \"we could\n\t\t// not create that account\" would be untrue.\n\t\ttry {\n\t\t\tconst signedIn = await client.auth.signIn({ email, password });\n\n\t\t\tif (needsSecondFactor(signedIn)) {\n\t\t\t\tsetPending(signedIn);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetToken(signedIn.token);\n\t\t\tonSignedUp?.();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] sign-in after sign-up failed\", cause);\n\n\t\t\tif (cause instanceof Base316Error && cause.reason === \"EMAIL_NOT_VERIFIED\") {\n\t\t\t\tsetConfirmEmail(true);\n\t\t\t\tonSignedUp?.();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetError(\n\t\t\t\tlabels.createdSignInFailed(\n\t\t\t\t\tcause instanceof Base316Error && cause.message ? cause.message : labels.genericError,\n\t\t\t\t),\n\t\t\t);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (pending) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<SecondFactorStep pending={pending} labels={secondFactorLabels} onSignedIn={onSignedUp} />\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (confirmEmail) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">{labels.confirmEmailTitle}</h3>\n\t\t\t\t<output className=\"b316-muted\">{labels.confirmEmail(email)}</output>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form onSubmit={submit} className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{preview ? (\n\t\t\t\t<p className=\"b316-muted\">{labels.joining(preview.organizationName, preview.roleName)}</p>\n\t\t\t) : null}\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-name\">\n\t\t\t\t\t{labels.name}\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-name\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\tvalue={name}\n\t\t\t\t\tonChange={(event) => setName(event.target.value)}\n\t\t\t\t\tautoComplete=\"name\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-signup-email\">\n\t\t\t\t\t{labels.email}\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-signup-email\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"email\"\n\t\t\t\t\tvalue={email}\n\t\t\t\t\tonChange={(event) => setEmail(event.target.value)}\n\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\trequired\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-signup-password\">\n\t\t\t\t\t{labels.password}\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-signup-password\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"password\"\n\t\t\t\t\tvalue={password}\n\t\t\t\t\tonChange={(event) => setPassword(event.target.value)}\n\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\tminLength={policy?.minLength}\n\t\t\t\t\tmaxLength={policy?.maxLength}\n\t\t\t\t\taria-describedby={policy ? \"b316-signup-password-rules\" : undefined}\n\t\t\t\t\trequired\n\t\t\t\t/>\n\t\t\t\t{policy ? (\n\t\t\t\t\t<span id=\"b316-signup-password-rules\" className=\"b316-muted\">\n\t\t\t\t\t\t{describeRules(policy, labels)}\n\t\t\t\t\t</span>\n\t\t\t\t) : null}\n\t\t\t</div>\n\n\t\t\t<button className=\"b316-button\" type=\"submit\" disabled={busy}>\n\t\t\t\t{busy ? labels.working : labels.submit}\n\t\t\t</button>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport type { CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Who is signed in, and a way out.\n *\n * Reads the session the provider already resolved rather than fetching again,\n * so a page with several of these components makes one round trip, not several.\n */\nexport function UserProfile({ className, style }: { className?: string; style?: CSSProperties }) {\n\tconst { session, loading, signOut } = useBase316();\n\n\tif (loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!session) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tNot signed in.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst user = (session.user ?? {}) as {\n\t\tname?: string;\n\t\temail?: string;\n\t\temailVerified?: boolean;\n\t};\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t<div className=\"b316-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<div style={{ fontWeight: 600 }}>{user.name || user.email || \"Signed in\"}</div>\n\t\t\t\t\t{user.name && user.email ? <div className=\"b316-muted\">{user.email}</div> : null}\n\t\t\t\t\t{user.emailVerified === false ? (\n\t\t\t\t\t\t<div className=\"b316-muted\">Email not verified</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\tonClick={() => void signOut()}\n\t\t\t\t>\n\t\t\t\t\tSign out\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { isPasskeySupported, type PasskeySummary } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * The signed-in user's passkeys, and a way to add one.\n *\n * Belongs on an account screen next to \"change password\". A passkey is bound to\n * the origin it was created on, so one registered here works on this site and\n * not on the hosted sign-in page — which is why this component exists at all\n * rather than sending people somewhere else to manage them.\n */\nexport function PasskeyManager({\n\tclassName,\n\tstyle,\n\ttitle = \"Passkeys\",\n}: {\n\tclassName?: string;\n\tstyle?: CSSProperties;\n\ttitle?: string;\n}) {\n\tconst { client, token, session } = useBase316();\n\n\tconst [passkeys, setPasskeys] = useState<PasskeySummary[] | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [name, setName] = useState(\"\");\n\n\t/**\n\t * Whether this browser can do WebAuthn at all.\n\t *\n\t * Asked in an effect rather than during render. It is false on a server and\n\t * usually true in the browser, so deciding during render renders one thing on\n\t * the server and another on the client — which React reports as a hydration\n\t * error rather than as the section quietly appearing.\n\t */\n\tconst [supported, setSupported] = useState(false);\n\n\tconst load = useCallback(async () => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await client.auth.passkeys.list(token);\n\t\t\tsetPasskeys(result.data);\n\t\t} catch (cause) {\n\t\t\t// An account screen that cannot list passkeys should still render the\n\t\t\t// rest of itself — but an empty list is not the way to say so. It reads\n\t\t\t// as \"you have no passkeys\", which to somebody with three registered is\n\t\t\t// a claim that their credentials are gone, shown at exactly the moment\n\t\t\t// they are trying to check.\n\t\t\tconsole.error(\"[base316] could not list passkeys\", cause);\n\t\t\tsetError(\"Could not load your passkeys. They have not been changed.\");\n\t\t\tsetPasskeys(null);\n\t\t}\n\t}, [client, token]);\n\n\tuseEffect(() => {\n\t\tif (!isPasskeySupported()) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetSupported(true);\n\t\tvoid load();\n\t}, [load]);\n\n\t// An \"add a passkey\" button in a browser that cannot make one is worse than\n\t// no section at all.\n\tif (!session || !token || !supported) {\n\t\treturn null;\n\t}\n\n\tconst add = async () => {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.passkeys.register(token, { name: name.trim() || undefined });\n\t\t\tsetName(\"\");\n\t\t\tawait load();\n\t\t} catch (caught) {\n\t\t\t// A cancelled ceremony is not a failure worth shouting about: the\n\t\t\t// person closed the dialog, which is an answer.\n\t\t\tif (caught instanceof DOMException && caught.name === \"NotAllowedError\") {\n\t\t\t\tsetError(null);\n\t\t\t} else {\n\t\t\t\tsetError(caught instanceof Error ? caught.message : \"That did not work.\");\n\t\t\t}\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst remove = async (id: string) => {\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.passkeys.remove(token, id);\n\t\t\tawait load();\n\t\t} catch (caught) {\n\t\t\tsetError(caught instanceof Error ? caught.message : \"That did not work.\");\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t<div style={{ fontWeight: 600, marginBottom: 4 }}>{title}</div>\n\t\t\t<div className=\"b316-muted\" style={{ marginBottom: 12 }}>\n\t\t\t\tSign in with your fingerprint, face or a security key — nothing to type and nothing to\n\t\t\t\tremember.\n\t\t\t</div>\n\n\t\t\t{passkeys === null ? (\n\t\t\t\t<div className=\"b316-muted\">Loading…</div>\n\t\t\t) : passkeys.length === 0 ? (\n\t\t\t\t<div className=\"b316-muted\">No passkeys yet.</div>\n\t\t\t) : (\n\t\t\t\t<ul style={{ listStyle: \"none\", margin: 0, padding: 0 }}>\n\t\t\t\t\t{passkeys.map((passkey) => (\n\t\t\t\t\t\t<li key={passkey.id} className=\"b316-row\" style={{ padding: \"8px 0\" }}>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<div>{passkey.name || \"Passkey\"}</div>\n\t\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\t{passkey.lastUsedAt\n\t\t\t\t\t\t\t\t\t\t? `Last used ${formatDate(passkey.lastUsedAt)}`\n\t\t\t\t\t\t\t\t\t\t: `Added ${formatDate(passkey.createdAt)}`}\n\t\t\t\t\t\t\t\t\t{/* A passkey that is not backed up lives on one device, and\n\t\t\t\t\t\t\t\t\t losing that device loses the passkey. Worth saying. */}\n\t\t\t\t\t\t\t\t\t{passkey.backedUp ? \"\" : \" · this device only\"}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{/*\n\t\t\t\t\t\t\t * On a passwordless account, removing the last passkey locks the\n\t\t\t\t\t\t\t * person out of their own account — so it asks. In the page, not\n\t\t\t\t\t\t\t * in a dialog the embedding iframe will suppress.\n\t\t\t\t\t\t\t */}\n\t\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\t\tconfirmLabel={`Remove ${passkey.name ?? \"this passkey\"} for good`}\n\t\t\t\t\t\t\t\tonConfirm={() => remove(passkey.id)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tRemove\n\t\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t)}\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\" style={{ marginTop: 12 }}>\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-row\" style={{ marginTop: 12, gap: 8 }}>\n\t\t\t\t<input\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\tplaceholder=\"Name this passkey (optional)\"\n\t\t\t\t\tvalue={name}\n\t\t\t\t\tonChange={(event) => setName(event.target.value)}\n\t\t\t\t/>\n\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={() => void add()}>\n\t\t\t\t\t{busy ? \"Waiting…\" : \"Add a passkey\"}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction formatDate(value: string): string {\n\tconst date = new Date(value);\n\n\treturn Number.isNaN(date.getTime()) ? \"\" : date.toLocaleDateString();\n}\n","import { useEffect, useRef, useState, type ReactNode } from \"react\";\n\n/**\n * Asking \"are you sure\" without `window.confirm`.\n *\n * These components are embedded in the customer's own page, and a page that\n * embeds them in a sandboxed iframe — which is the recommended way to embed\n * anything — does not get modal dialogs unless `allow-modals` is set. Chrome\n * and Firefox both block the call and return `false`.\n *\n * So `window.confirm` in this package was not a confirmation. It was a silent\n * no: somebody clicked Revoke, the browser suppressed the dialog, the function\n * returned false, and the component did nothing at all. No error, no dialog,\n * nothing — the worst failure shape there is, because the user's next move is\n * to click it again.\n *\n * The replacement asks in the page itself. One click arms it, a second\n * confirms, and anywhere else cancels. No portal, no modal, no dependency on\n * what the embedding page allows.\n */\n\nexport interface ConfirmButtonProps {\n\t/** What the button says at rest. */\n\tchildren: ReactNode;\n\t/** What it says once armed. Make it name the consequence. */\n\tconfirmLabel: string;\n\tonConfirm: () => void | Promise<void>;\n\tclassName?: string;\n\tdisabled?: boolean;\n\t/** How long the armed state survives without an answer. */\n\ttimeoutMs?: number;\n}\n\n/**\n * Long enough to read the question, short enough that an armed button is never\n * a surprise on a page somebody came back to.\n */\nconst DEFAULT_TIMEOUT_MS = 5_000;\n\nexport function ConfirmButton({\n\tchildren,\n\tconfirmLabel,\n\tonConfirm,\n\tclassName,\n\tdisabled,\n\ttimeoutMs = DEFAULT_TIMEOUT_MS,\n}: ConfirmButtonProps) {\n\tconst [armed, setArmed] = useState(false);\n\tconst confirmRef = useRef<HTMLButtonElement>(null);\n\n\tuseEffect(() => {\n\t\tif (!armed) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Focus moves to the confirmation, so a keyboard user answers the question\n\t\t// rather than tabbing past it, and a screen reader reads it aloud.\n\t\tconfirmRef.current?.focus();\n\n\t\tconst timer = setTimeout(() => setArmed(false), timeoutMs);\n\n\t\treturn () => clearTimeout(timer);\n\t}, [armed, timeoutMs]);\n\n\tif (!armed) {\n\t\treturn (\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={className}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonClick={() => setArmed(true)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</button>\n\t\t);\n\t}\n\n\treturn (\n\t\t// No `role=\"group\"`: both buttons already say what they do, and the\n\t\t// grouping would only repeat the question a screen reader has just read.\n\t\t<span className=\"b316-confirm\">\n\t\t\t<button\n\t\t\t\tref={confirmRef}\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={className}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonClick={async () => {\n\t\t\t\t\tsetArmed(false);\n\t\t\t\t\tawait onConfirm();\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{confirmLabel}\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\tonClick={() => setArmed(false)}\n\t\t\t>\n\t\t\t\tCancel\n\t\t\t</button>\n\t\t</span>\n\t);\n}\n","\"use client\";\n\nimport type { SessionSummary } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Where this account is signed in, and a way to end the rest.\n *\n * The panel somebody opens when they think they have been compromised, which\n * is why the copy is plain and the button does not hedge. It shows where and\n * when rather than anything identifying the session itself: the token digest is\n * the value the database authenticates against and never reaches the browser.\n *\n * Revoking keeps the caller's own session. Signing somebody out of the device\n * they are holding, in response to a button about their *other* devices, would\n * be a surprise at the worst possible moment.\n */\n\nexport interface ActiveSessionsProps {\n\t/** Called after other sessions are ended, with how many went. */\n\tonRevoked?: (count: number) => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/** \"Chrome on macOS\" out of a user-agent string, or null when it says nothing useful. */\nfunction describeDevice(userAgent: string | null): string | null {\n\tif (!userAgent) {\n\t\treturn null;\n\t}\n\n\tconst browser = /Edg\\//.test(userAgent)\n\t\t? \"Edge\"\n\t\t: /OPR\\//.test(userAgent)\n\t\t\t? \"Opera\"\n\t\t\t: /Chrome\\//.test(userAgent)\n\t\t\t\t? \"Chrome\"\n\t\t\t\t: /Safari\\//.test(userAgent)\n\t\t\t\t\t? \"Safari\"\n\t\t\t\t\t: /Firefox\\//.test(userAgent)\n\t\t\t\t\t\t? \"Firefox\"\n\t\t\t\t\t\t: null;\n\n\tconst platform = /iPhone|iPad/.test(userAgent)\n\t\t? \"iOS\"\n\t\t: /Android/.test(userAgent)\n\t\t\t? \"Android\"\n\t\t\t: /Mac OS X/.test(userAgent)\n\t\t\t\t? \"macOS\"\n\t\t\t\t: /Windows/.test(userAgent)\n\t\t\t\t\t? \"Windows\"\n\t\t\t\t\t: /Linux/.test(userAgent)\n\t\t\t\t\t\t? \"Linux\"\n\t\t\t\t\t\t: null;\n\n\tif (!browser && !platform) {\n\t\t// Better to show the raw string than to claim knowledge: somebody chasing a\n\t\t// session they do not recognise needs whatever there is.\n\t\treturn userAgent.slice(0, 60);\n\t}\n\n\treturn [browser, platform].filter(Boolean).join(\" on \");\n}\n\nfunction when(value: string): string {\n\tconst date = new Date(value);\n\n\treturn Number.isNaN(date.getTime()) ? \"\" : date.toLocaleString();\n}\n\nexport function ActiveSessions({ onRevoked, className, style }: ActiveSessionsProps) {\n\tconst { client, token } = useBase316();\n\tconst [sessions, setSessions] = useState<SessionSummary[] | null>(null);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\tconst load = useCallback(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tclient.auth\n\t\t\t.sessions(token)\n\t\t\t.then((result) => {\n\t\t\t\t// Revoked ones are history, not devices somebody is signed in on.\n\t\t\t\tsetSessions(result.data.filter((session) => !session.revokedAt));\n\t\t\t\tsetError(null);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not load your sessions.\");\n\t\t\t});\n\t}, [client, token]);\n\n\tuseEffect(load, [load]);\n\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!sessions) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tasync function revokeOthers() {\n\t\tsetBusy(true);\n\n\t\ttry {\n\t\t\tconst result = await client.auth.revokeOtherSessions(token as string);\n\n\t\t\tonRevoked?.(result.revoked);\n\t\t\tload();\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not end those sessions.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-sessions\", className)} style={style}>\n\t\t\t<div className=\"b316-sessions-head\">\n\t\t\t\t<h3 className=\"b316-sessions-title\">Where you are signed in</h3>\n\t\t\t\t{sessions.length > 1 ? (\n\t\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={revokeOthers}>\n\t\t\t\t\t\t{busy ? \"Ending…\" : \"Sign out other devices\"}\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t</div>\n\n\t\t\t<ul className=\"b316-sessions-list\">\n\t\t\t\t{sessions.map((session) => (\n\t\t\t\t\t<li key={session.id} className=\"b316-session\">\n\t\t\t\t\t\t<div className=\"b316-session-device\">\n\t\t\t\t\t\t\t{describeDevice(session.userAgent) ?? \"Unknown device\"}\n\t\t\t\t\t\t\t{session.impersonatedBy ? (\n\t\t\t\t\t\t\t\t// Worth saying loudly: somebody is acting as this account.\n\t\t\t\t\t\t\t\t<span className=\"b316-chip\"> Support access</span>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t{session.ipAddress ? `${session.ipAddress} · ` : \"\"}\n\t\t\t\t\t\t\tlast used {when(session.lastSeenAt)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ul>\n\n\t\t\t{sessions.length === 0 ? <div className=\"b316-muted\">No active sessions.</div> : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { DeviceRequest } from \"@base316/sdk\";\nimport { useState, type CSSProperties, type FormEvent } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Approving a sign-in that started somewhere with no browser.\n *\n * Drop this on a page in your own application — `/device` is the convention —\n * and point your device's verification URI at it. The person is already signed\n * in here, which is the whole reason this belongs in your app rather than on a\n * page of ours: there is nothing to log into, and the page looks like yours.\n *\n * Two steps, deliberately. The code is checked first so that what is being\n * approved can be named before anybody presses Approve; a single button that\n * takes a code and grants access in one motion is a button people press without\n * reading.\n */\n\nexport interface DeviceApprovalProps {\n\t/**\n\t * The code, when your page already has it.\n\t *\n\t * A device that can show a link or a QR code puts the code in the URL, which\n\t * saves exactly the typing this flow exists to avoid. Read it off your router\n\t * and pass it here; the entry step is skipped.\n\t */\n\tuserCode?: string;\n\t/** Called after the person answers, with what they chose. */\n\tonDecided?: (approved: boolean) => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function DeviceApproval({\n\tuserCode = \"\",\n\tonDecided,\n\tclassName,\n\tstyle,\n}: DeviceApprovalProps) {\n\tconst { client, token } = useBase316();\n\tconst [code, setCode] = useState(userCode);\n\tconst [request, setRequest] = useState<DeviceRequest | null>(null);\n\tconst [decided, setDecided] = useState<boolean | null>(null);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\t// Without a signed-in user there is nobody to approve *as*. Rendering a code\n\t// box anyway would collect a code and then fail at the one step that matters.\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tasync function lookUp(event: FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tsetRequest(await client.device.lookup(code));\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"We could not check that code.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function decide(approve: boolean) {\n\t\tif (!request) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.device.decide(token as string, { id: request.id, approve });\n\t\t\tsetDecided(approve);\n\t\t\tonDecided?.(approve);\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"We could not record that.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (decided !== null) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card b316-device\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-device-title\">{decided ? \"You're all set\" : \"Not approved\"}</h3>\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t{decided\n\t\t\t\t\t\t? \"You can close this page and go back to your device.\"\n\t\t\t\t\t\t: \"Nothing was granted. You can close this page.\"}\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (request) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card b316-device\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-device-title\">Sign in to {request.clientName}</h3>\n\t\t\t\t<p className=\"b316-muted\">{request.clientName} is asking to sign in as you.</p>\n\n\t\t\t\t{request.scopes.length > 0 ? (\n\t\t\t\t\t<ul className=\"b316-device-scopes\">\n\t\t\t\t\t\t{request.scopes.map((scope) => (\n\t\t\t\t\t\t\t<li key={scope}>{scope}</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t) : null}\n\n\t\t\t\t{error ? (\n\t\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t\t{error}\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\n\t\t\t\t<div className=\"b316-device-actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => decide(true)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{busy ? \"Approving…\" : \"Approve\"}\n\t\t\t\t\t</button>\n\t\t\t\t\t{/* A real refusal, not just closing the tab: it tells the device to\n\t\t\t\t\t stop polling instead of leaving it to time out. */}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-quiet\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => decide(false)}\n\t\t\t\t\t>\n\t\t\t\t\t\tDeny\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-card b316-device\", className)} style={style} onSubmit={lookUp}>\n\t\t\t<h3 className=\"b316-device-title\">Connect your device</h3>\n\t\t\t<p className=\"b316-muted\">Enter the code shown on your device.</p>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<input\n\t\t\t\tclassName=\"b316-input\"\n\t\t\t\tvalue={code}\n\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\t// Not `one-time-code`: that invites the browser to offer an SMS\n\t\t\t\t// passcode, which this is not.\n\t\t\t\tautoComplete=\"off\"\n\t\t\t\tautoCapitalize=\"characters\"\n\t\t\t\tspellCheck={false}\n\t\t\t\tplaceholder=\"XXXX-XXXX\"\n\t\t\t\taria-label=\"Device code\"\n\t\t\t/>\n\n\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy || code.trim().length < 4}>\n\t\t\t\t{busy ? \"Checking…\" : \"Continue\"}\n\t\t\t</button>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport { useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Download my data, and delete my account.\n *\n * The two things a privacy notice promises and most products never build, so\n * the promise gets kept by an inbox and a person doing it by hand. Both here\n * take the signed-in user's own session, so neither needs your server to be\n * trusted with somebody else's account.\n *\n * Deletion asks twice, and the second time it asks the person to type. That is\n * not friction for its own sake: this is the one control on the page that\n * cannot be undone, and a misplaced click should not be able to reach it.\n */\n\nexport interface PrivacyControlsProps {\n\t/**\n\t * What must be typed to confirm deletion.\n\t *\n\t * Defaults to the English word, which is wrong in every other language —\n\t * pass the one your interface is written in.\n\t */\n\tconfirmWord?: string;\n\t/** Called after the account is gone. Sign them out and send them somewhere. */\n\tonErased?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function PrivacyControls({\n\tconfirmWord = \"DELETE\",\n\tonErased,\n\tclassName,\n\tstyle,\n}: PrivacyControlsProps) {\n\tconst { client, token } = useBase316();\n\tconst [confirming, setConfirming] = useState(false);\n\tconst [typed, setTyped] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tasync function download() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst data = await client.auth.privacy.export(token as string);\n\n\t\t\t// A file, because the useful outcome is a copy they keep — not\n\t\t\t// something on screen they have to select and paste.\n\t\t\tconst url = URL.createObjectURL(\n\t\t\t\tnew Blob([JSON.stringify(data, null, 2)], { type: \"application/json\" }),\n\t\t\t);\n\t\t\tconst link = document.createElement(\"a\");\n\n\t\t\tlink.href = url;\n\t\t\tlink.download = \"my-data.json\";\n\t\t\tlink.click();\n\t\t\tURL.revokeObjectURL(url);\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not build your export.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function erase() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.privacy.erase(token as string);\n\t\t\tonErased?.();\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not delete your account.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-privacy\", className)} style={style}>\n\t\t\t<h3 className=\"b316-privacy-title\">Your data</h3>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-privacy-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<p>Download a copy</p>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tEverything we hold about you, as a file. Passwords and security keys are not included —\n\t\t\t\t\t\tthey are what protect the account rather than anything you can use.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" disabled={busy} onClick={download}>\n\t\t\t\t\t{busy ? \"Preparing…\" : \"Download\"}\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-privacy-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<p>Delete your account</p>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tPermanent. Invoices already raised are kept, because the law requires it; everything\n\t\t\t\t\t\tthat identifies you is removed from them.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\n\t\t\t\t{confirming ? null : (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => setConfirming(true)}\n\t\t\t\t\t>\n\t\t\t\t\t\tDelete\n\t\t\t\t\t</button>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{confirming ? (\n\t\t\t\t<div className=\"b316-privacy-confirm\">\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-privacy-confirm\">\n\t\t\t\t\t\tType {confirmWord} to confirm\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-privacy-confirm\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tvalue={typed}\n\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\tonChange={(event) => setTyped(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t\t<div className=\"b316-privacy-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tsetConfirming(false);\n\t\t\t\t\t\t\t\tsetTyped(\"\");\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button b316-danger\"\n\t\t\t\t\t\t\t// Trimmed but not case-folded: typing it exactly is the point.\n\t\t\t\t\t\t\tdisabled={busy || typed.trim() !== confirmWord}\n\t\t\t\t\t\t\tonClick={erase}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{busy ? \"Deleting…\" : \"Delete my account\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Turning on two-factor authentication.\n *\n * Three ways in: an authenticator app, a code to the inbox, and — where the\n * application turns it on — a code by text message. The app is the strongest\n * and is offered first; the other two are the ones people who will not install\n * anything actually use, and a factor somebody turns on beats a stronger one\n * they decline.\n *\n * Three steps, kept separate because the middle one is what stops people\n * locking themselves out: enrolling produces a secret that is useless until a\n * code proves the app actually holds it. Activating on enrolment would mean a\n * QR code that failed to scan leaves somebody unable to sign in, with no way\n * back.\n *\n * The recovery codes are shown once. They are password equivalents, so nothing\n * stores them anywhere they can be read back — which makes \"I have saved these\"\n * a real step rather than a formality, and the dialog says so.\n */\n\nexport interface TwoFactorManagerProps {\n\t/** Whether this account already has a factor. Drives which side is shown. */\n\tenabled?: boolean;\n\t/**\n\t * Offer a code by text message.\n\t *\n\t * Off by default, because it only works once the environment can send one —\n\t * its own Twilio account in production — and a button that can only fail is\n\t * worse than no button.\n\t */\n\tallowSms?: boolean;\n\tonEnabled?: () => void;\n\tonDisabled?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\ntype Stage =\n\t| { name: \"idle\" }\n\t| { name: \"enrolling\"; factorId: string; secret: string; uri: string }\n\t/** The same confirm step, with a code that was sent rather than derived. */\n\t| { name: \"enrollingEmail\"; factorId: string; destinationHint: string }\n\t/** Which number a text-message factor should use, before anything is sent. */\n\t| { name: \"smsNumber\" }\n\t| { name: \"saved\"; recoveryCodes: string[] };\n\nexport function TwoFactorManager({\n\tenabled = false,\n\tallowSms = false,\n\tonEnabled,\n\tonDisabled,\n\tclassName,\n\tstyle,\n}: TwoFactorManagerProps) {\n\tconst { client, token } = useBase316();\n\tconst [stage, setStage] = useState<Stage>({ name: \"idle\" });\n\tconst [on, setOn] = useState(enabled);\n\tconst [code, setCode] = useState(\"\");\n\tconst [phone, setPhone] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tasync function begin() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst enrollment = await client.auth.mfa.enroll(token as string);\n\n\t\t\tsetStage({ name: \"enrolling\", ...enrollment });\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not start setup.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function beginEmail() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst enrollment = await client.auth.mfa.enrollEmail(token as string);\n\n\t\t\tsetStage({ name: \"enrollingEmail\", ...enrollment });\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not send a code.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function beginSms() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\t// Blank means the account's own number, which the server looks up.\n\t\t\tconst enrollment = await client.auth.mfa.enrollSms(\n\t\t\t\ttoken as string,\n\t\t\t\tphone.trim() ? { phone: phone.trim() } : {},\n\t\t\t);\n\n\t\t\tsetStage({ name: \"enrollingEmail\", ...enrollment });\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not send a code.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function confirm() {\n\t\tif (stage.name !== \"enrolling\" && stage.name !== \"enrollingEmail\") {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.auth.mfa.confirm(token as string, {\n\t\t\t\tfactorId: stage.factorId,\n\t\t\t\tcode: code.trim(),\n\t\t\t});\n\n\t\t\tsetStage({ name: \"saved\", recoveryCodes: result.recoveryCodes });\n\t\t\tsetOn(true);\n\t\t\tsetCode(\"\");\n\t\t\tonEnabled?.();\n\t\t} catch (cause) {\n\t\t\t// The common case by far is a mistyped or expired code, and the server\n\t\t\t// deliberately says no more than that.\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That code did not match.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function disable() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.mfa.disable(token as string);\n\n\t\t\tsetOn(false);\n\t\t\tsetStage({ name: \"idle\" });\n\t\t\tonDisabled?.();\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not turn it off.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-mfa\", className)} style={style}>\n\t\t\t<h3 className=\"b316-mfa-title\">Two-factor authentication</h3>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{stage.name === \"saved\" ? (\n\t\t\t\t<div className=\"b316-mfa-codes\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\tSave these recovery codes somewhere safe. Each one signs you in once if you lose your\n\t\t\t\t\t\tauthenticator, and they are not shown again.\n\t\t\t\t\t</p>\n\t\t\t\t\t<ul className=\"b316-mfa-code-list\">\n\t\t\t\t\t\t{stage.recoveryCodes.map((recovery) => (\n\t\t\t\t\t\t\t<li key={recovery}>\n\t\t\t\t\t\t\t\t<code>{recovery}</code>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t\t<button type=\"button\" className=\"b316-button\" onClick={() => setStage({ name: \"idle\" })}>\n\t\t\t\t\t\tI have saved them\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : stage.name === \"smsNumber\" ? (\n\t\t\t\t<div className=\"b316-mfa-enrol\">\n\t\t\t\t\t<p>We will text a code to this number now, and each time you sign in.</p>\n\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-mfa-phone\">\n\t\t\t\t\t\tMobile number\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-mfa-phone\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\ttype=\"tel\"\n\t\t\t\t\t\tautoComplete=\"tel\"\n\t\t\t\t\t\tplaceholder=\"+14155550123\"\n\t\t\t\t\t\tvalue={phone}\n\t\t\t\t\t\tonChange={(event) => setPhone(event.target.value)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => setStage({ name: \"idle\" })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={beginSms}>\n\t\t\t\t\t\t\t{busy ? \"Sending…\" : \"Send code\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : stage.name === \"enrollingEmail\" ? (\n\t\t\t\t<div className=\"b316-mfa-enrol\">\n\t\t\t\t\t<p>We sent a code to {stage.destinationHint}. Enter it below to turn this on.</p>\n\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-mfa-code\">\n\t\t\t\t\t\tCode\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-mfa-code\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tinputMode=\"numeric\"\n\t\t\t\t\t\tautoComplete=\"one-time-code\"\n\t\t\t\t\t\tvalue={code}\n\t\t\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => setStage({ name: \"idle\" })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\t\tdisabled={busy || !code}\n\t\t\t\t\t\t\tonClick={confirm}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{busy ? \"Checking…\" : \"Turn on\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : stage.name === \"enrolling\" ? (\n\t\t\t\t<div className=\"b316-mfa-enrol\">\n\t\t\t\t\t<p>Add this to your authenticator app, then enter the six-digit code it shows.</p>\n\t\t\t\t\t{/* The secret in text as well as the URI: a QR code is unreadable on\n\t\t\t\t\t the device that is displaying it, which is exactly the case when\n\t\t\t\t\t somebody sets this up on a phone. */}\n\t\t\t\t\t<div className=\"b316-mfa-secret\">\n\t\t\t\t\t\t<code>{stage.secret}</code>\n\t\t\t\t\t</div>\n\t\t\t\t\t<a className=\"b316-mfa-uri\" href={stage.uri}>\n\t\t\t\t\t\tOpen in an authenticator app\n\t\t\t\t\t</a>\n\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-mfa-code\">\n\t\t\t\t\t\tCode\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-mfa-code\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tinputMode=\"numeric\"\n\t\t\t\t\t\tautoComplete=\"one-time-code\"\n\t\t\t\t\t\tvalue={code}\n\t\t\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => setStage({ name: \"idle\" })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\t\tdisabled={busy || !code}\n\t\t\t\t\t\t\tonClick={confirm}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{busy ? \"Checking…\" : \"Turn on\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : on ? (\n\t\t\t\t<div className=\"b316-mfa-on\">\n\t\t\t\t\t<p className=\"b316-muted\">On. You will be asked for a code when you sign in.</p>\n\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tconfirmLabel=\"Turn off two-factor authentication\"\n\t\t\t\t\t\tonConfirm={disable}\n\t\t\t\t\t>\n\t\t\t\t\t\tTurn off\n\t\t\t\t\t</ConfirmButton>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-mfa-off\">\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tOff. Turning it on means a code as well as your password, every time you sign in.\n\t\t\t\t\t</p>\n\t\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={begin}>\n\t\t\t\t\t\t\t{busy ? \"Starting…\" : \"Use an authenticator app\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t{/* Offered second, and described honestly: it is only as strong as\n\t\t\t\t\t\t the mailbox. Still far better than nothing, which is what the\n\t\t\t\t\t\t people who decline an app otherwise have. */}\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={beginEmail}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tEmail me a code\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t{allowSms ? (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\tonClick={() => setStage({ name: \"smsNumber\" })}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tText me a code\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Asking for a reset link.\n *\n * The screen always says the same thing afterwards, whether or not the address\n * has an account. That is not politeness: a form that said \"no account with\n * that address\" is a way to discover who has registered, one address at a time,\n * and the API already refuses to distinguish them — so a component that showed\n * a different message for each would be inventing information the server\n * deliberately withheld.\n *\n * There is no prop for where the link lands. That URL is configured on the\n * environment, for the same reason a checkout return URL is — a form that could\n * name it would be a way to have a sign-in link emailed to somewhere else.\n */\n\nexport interface ForgotPasswordProps {\n\tonSent?: (email: string) => void;\n\t/** Back to sign-in. Rendered as a link when given. */\n\tsignInUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function ForgotPassword({ onSent, signInUrl, className, style }: ForgotPasswordProps) {\n\tconst { client } = useBase316();\n\tconst [email, setEmail] = useState(\"\");\n\tconst [sent, setSent] = useState(false);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tasync function submit(event: React.FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.requestPasswordReset({ email: email.trim() });\n\n\t\t\tsetSent(true);\n\t\t\tonSent?.(email.trim());\n\t\t} catch (cause) {\n\t\t\t// Only a transport failure reaches here — the endpoint resolves for an\n\t\t\t// unknown address on purpose.\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not send the link.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (sent) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">Check your email</h3>\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tIf there is an account for {email.trim()}, a link to set a new password is on its way.\n\t\t\t\t</p>\n\t\t\t\t{signInUrl ? (\n\t\t\t\t\t<a className=\"b316-button-link\" href={signInUrl}>\n\t\t\t\t\t\tBack to sign in\n\t\t\t\t\t</a>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-card b316-form\", className)} style={style} onSubmit={submit}>\n\t\t\t<h3 className=\"b316-form-title\">Reset your password</h3>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-forgot-email\">\n\t\t\t\t\tEmail\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-forgot-email\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"email\"\n\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\trequired\n\t\t\t\t\tvalue={email}\n\t\t\t\t\tonChange={(event) => setEmail(event.target.value)}\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy || !email}>\n\t\t\t\t{busy ? \"Sending…\" : \"Send reset link\"}\n\t\t\t</button>\n\n\t\t\t{signInUrl ? (\n\t\t\t\t<a className=\"b316-button-link\" href={signInUrl}>\n\t\t\t\t\tBack to sign in\n\t\t\t\t</a>\n\t\t\t) : null}\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport { useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Setting a new password from an emailed link.\n *\n * The page the link lands on renders this; the token comes from `?token=` and\n * is removed from the address bar as soon as it is read. A reset token sitting\n * in browser history, in a referrer header or in a shared screenshot is a way\n * into the account for as long as it is unspent.\n *\n * The confirmation field is checked here rather than by the server, because it\n * is the one thing the server cannot help with: two different strings are both\n * valid passwords, and only the person typing knows which they meant.\n */\n\nexport interface ResetPasswordProps {\n\t/** Supply the token directly. Read from `?token=` when omitted. */\n\ttoken?: string;\n\tonReset?: () => void;\n\t/** Where to go afterwards. Rendered as a link when given. */\n\tsignInUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function ResetPassword({\n\ttoken: supplied,\n\tonReset,\n\tsignInUrl,\n\tclassName,\n\tstyle,\n}: ResetPasswordProps) {\n\tconst { client } = useBase316();\n\tconst [token, setToken] = useState<string | null>(supplied ?? null);\n\tconst [password, setPassword] = useState(\"\");\n\tconst [confirmation, setConfirmation] = useState(\"\");\n\tconst [done, setDone] = useState(false);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\t// Read once, on arrival, and scrub it from the URL. `replaceState` rather\n\t// than a navigation so the page does not reload and lose what was typed.\n\tuseEffect(() => {\n\t\tif (supplied || typeof window === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(window.location.href);\n\t\tconst found = url.searchParams.get(\"token\");\n\n\t\tif (!found) {\n\t\t\treturn;\n\t\t}\n\n\t\turl.searchParams.delete(\"token\");\n\t\twindow.history.replaceState({}, \"\", url.toString());\n\t\tsetToken(found);\n\t}, [supplied]);\n\n\tasync function submit(event: React.FormEvent) {\n\t\tevent.preventDefault();\n\n\t\tif (password !== confirmation) {\n\t\t\tsetError(\"Those do not match.\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.completePasswordReset({ token, password });\n\n\t\t\tsetDone(true);\n\t\t\tonReset?.();\n\t\t} catch (cause) {\n\t\t\t// Covers expired, already used and never valid. The server does not\n\t\t\t// distinguish them and neither should this.\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That link is no longer valid.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (done) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">Password changed</h3>\n\t\t\t\t<p className=\"b316-muted\">You can sign in with your new password.</p>\n\t\t\t\t{signInUrl ? (\n\t\t\t\t\t<a className=\"b316-button-link\" href={signInUrl}>\n\t\t\t\t\t\tSign in\n\t\t\t\t\t</a>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!token) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">Nothing to reset</h3>\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tThis page needs the link from your email. Request a new one if yours has expired.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-card b316-form\", className)} style={style} onSubmit={submit}>\n\t\t\t<h3 className=\"b316-form-title\">Choose a new password</h3>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-reset-password\">\n\t\t\t\t\tNew password\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-reset-password\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"password\"\n\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\trequired\n\t\t\t\t\tvalue={password}\n\t\t\t\t\tonChange={(event) => setPassword(event.target.value)}\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-reset-confirm\">\n\t\t\t\t\tRepeat it\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-reset-confirm\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"password\"\n\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\trequired\n\t\t\t\t\tvalue={confirmation}\n\t\t\t\t\tonChange={(event) => setConfirmation(event.target.value)}\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy || !password}>\n\t\t\t\t{busy ? \"Saving…\" : \"Set password\"}\n\t\t\t</button>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Confirming an address from an emailed link.\n *\n * The whole component is one effect: read `?token=`, spend it, say what\n * happened. Two details carry it.\n *\n * The token is removed from the URL before it is spent, so it does not sit in\n * browser history or leak through a referrer. And the effect runs exactly once\n * — the token is single-use, so a re-run in development's double-invoked\n * effects would spend it and then report that it was invalid, which looks like\n * a broken link to everybody who sees it.\n */\n\nexport interface VerifyEmailProps {\n\t/** Supply the token directly. Read from `?token=` when omitted. */\n\ttoken?: string;\n\tonVerified?: () => void;\n\t/** Where to go next. Rendered as a link when given. */\n\tcontinueUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\ntype State = \"waiting\" | \"verifying\" | \"verified\" | \"failed\" | \"missing\";\n\nexport function VerifyEmail({\n\ttoken: supplied,\n\tonVerified,\n\tcontinueUrl,\n\tclassName,\n\tstyle,\n}: VerifyEmailProps) {\n\tconst { client } = useBase316();\n\tconst [state, setState] = useState<State>(\"waiting\");\n\tconst spent = useRef(false);\n\n\tuseEffect(() => {\n\t\t// Once. A single-use token spent twice reports failure the second time,\n\t\t// and React invokes effects twice in development.\n\t\t//\n\t\t// Not covered by a test: deleting this guard fails nothing, even under\n\t\t// StrictMode, because the test harness does not reproduce the\n\t\t// double-invocation for this component. Kept because it is correct, and\n\t\t// flagged because an untested guard is exactly what a later cleanup\n\t\t// removes as dead code.\n\t\tif (spent.current) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet token = supplied ?? null;\n\n\t\tif (!token && typeof window !== \"undefined\") {\n\t\t\tconst url = new URL(window.location.href);\n\n\t\t\ttoken = url.searchParams.get(\"token\");\n\n\t\t\tif (token) {\n\t\t\t\turl.searchParams.delete(\"token\");\n\t\t\t\twindow.history.replaceState({}, \"\", url.toString());\n\t\t\t}\n\t\t}\n\n\t\tif (!token) {\n\t\t\tsetState(\"missing\");\n\t\t\treturn;\n\t\t}\n\n\t\tspent.current = true;\n\t\tsetState(\"verifying\");\n\n\t\tclient.auth\n\t\t\t.verifyEmail({ token })\n\t\t\t.then(() => {\n\t\t\t\tsetState(\"verified\");\n\t\t\t\tonVerified?.();\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t// Expired, already used, or never valid — the server does not say\n\t\t\t\t// which, and guessing would be worse than the honest sentence below.\n\t\t\t\tsetState(\"failed\");\n\t\t\t});\n\t}, [client, supplied, onVerified]);\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{state === \"verified\" ? (\n\t\t\t\t<>\n\t\t\t\t\t<h3 className=\"b316-form-title\">Email confirmed</h3>\n\t\t\t\t\t<p className=\"b316-muted\">Thanks — your address is verified.</p>\n\t\t\t\t\t{continueUrl ? (\n\t\t\t\t\t\t<a className=\"b316-button-link\" href={continueUrl}>\n\t\t\t\t\t\t\tContinue\n\t\t\t\t\t\t</a>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t) : state === \"failed\" ? (\n\t\t\t\t<>\n\t\t\t\t\t<h3 className=\"b316-form-title\">That link did not work</h3>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tIt may have expired or already been used. Ask for a new one and try again.\n\t\t\t\t\t</p>\n\t\t\t\t</>\n\t\t\t) : state === \"missing\" ? (\n\t\t\t\t<>\n\t\t\t\t\t<h3 className=\"b316-form-title\">Nothing to confirm</h3>\n\t\t\t\t\t<p className=\"b316-muted\">This page needs the link from your email.</p>\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<p className=\"b316-muted\">Confirming your email…</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { TeamInvitation, TeamMember, TeamSummary } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Who is in a team, who has been invited, and the way in and out.\n *\n * One component rather than four, because these are one screen everywhere they\n * appear: a list of people, a list of people who have not arrived yet, a box to\n * add another, and a way to leave. Splitting them would make the common case —\n * a Team settings page — four imports and some layout, which is exactly the\n * assembly work the catalogue exists to remove.\n *\n * What it offers depends on what the viewer may do, and that is the server's\n * answer rather than this component's guess: inviting and removing are gated on\n * a permission the customer's own roles grant, so a member who cannot manage\n * the team simply is not shown those controls.\n *\n * Sending the invitation email is the application's job. The token comes back\n * once from the API and is never recoverable, so `onInvited` is where it goes —\n * without a handler, the link is shown on screen to be copied, which is honest\n * rather than silently losing it.\n */\n\nexport interface TeamMembersProps {\n\t/**\n\t * Which team. Defaults to the only one this person is in.\n\t *\n\t * Left out with several, the component says which is which rather than\n\t * guessing — picking one at random is how somebody invites a colleague into\n\t * the wrong company.\n\t */\n\torganizationId?: string;\n\t/**\n\t * Called with the invitation link after inviting.\n\t *\n\t * Where an application sends the email. Without it the link is shown on\n\t * screen instead, because the token is returned once and cannot be fetched\n\t * again.\n\t */\n\tonInvited?: (invitation: { email: string; token: string; url?: string }) => void;\n\t/** Where an invitation link should point. Used to build the URL for `onInvited`. */\n\tacceptUrl?: string;\n\tonLeft?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function TeamMembers({\n\torganizationId,\n\tonInvited,\n\tacceptUrl,\n\tonLeft,\n\tclassName,\n\tstyle,\n}: TeamMembersProps) {\n\tconst { client, token, session } = useBase316();\n\n\tconst [teams, setTeams] = useState<TeamSummary[] | null>(null);\n\tconst [members, setMembers] = useState<TeamMember[] | null>(null);\n\tconst [invitations, setInvitations] = useState<TeamInvitation[] | null>(null);\n\tconst [email, setEmail] = useState(\"\");\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [copied, setCopied] = useState<string | null>(null);\n\n\tconst chosen = organizationId ?? (teams?.length === 1 ? teams[0]!.id : null);\n\tconst team = teams?.find((candidate) => candidate.id === chosen) ?? null;\n\n\tconst load = useCallback(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tclient.teams\n\t\t\t.list(token)\n\t\t\t.then((result) => setTeams(result.data))\n\t\t\t.catch((cause) =>\n\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not load your teams.\"),\n\t\t\t);\n\t}, [client, token]);\n\n\tuseEffect(load, [load]);\n\n\tuseEffect(() => {\n\t\tif (!token || !chosen) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.teams\n\t\t\t.members(token, chosen)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetMembers(result.data);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not load the members.\");\n\t\t\t\t}\n\t\t\t});\n\n\t\t// Managers only, and a refusal here is not an error worth showing: it is\n\t\t// simply how the screen looks for somebody who cannot manage the team.\n\t\tclient.teams\n\t\t\t.invitations(token, chosen)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetInvitations(result.data);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetInvitations(null);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, chosen]);\n\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tif (!teams) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{error ?? \"Loading…\"}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!chosen) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{teams.length === 0\n\t\t\t\t\t? \"You are not in a team yet.\"\n\t\t\t\t\t: \"You are in more than one team. Name which with the organizationId prop.\"}\n\t\t\t</div>\n\t\t);\n\t}\n\n\t/** Managers get the pending list; everybody else gets null from that call. */\n\tconst canManage = invitations !== null;\n\n\tasync function invite(event: React.FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.teams.invite(token as string, chosen as string, {\n\t\t\t\temail: email.trim(),\n\t\t\t});\n\n\t\t\tconst url = acceptUrl\n\t\t\t\t? `${acceptUrl}${acceptUrl.includes(\"?\") ? \"&\" : \"?\"}invitation=${encodeURIComponent(result.token)}`\n\t\t\t\t: undefined;\n\n\t\t\tonInvited?.({ email: email.trim(), token: result.token, url });\n\n\t\t\tif (!onInvited) {\n\t\t\t\t// Shown rather than lost. The token is returned once and only a digest\n\t\t\t\t// is stored, so there is no second chance to fetch it.\n\t\t\t\tsetCopied(url ?? result.token);\n\t\t\t}\n\n\t\t\tsetEmail(\"\");\n\t\t\tsetInvitations((current) => [result.invitation, ...(current ?? [])]);\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That invitation could not be sent.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function remove(userId: string) {\n\t\tconst leaving = userId === session?.userId;\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.teams.removeMember(token as string, chosen as string, userId);\n\n\t\t\tif (leaving) {\n\t\t\t\tonLeft?.();\n\t\t\t\tload();\n\t\t\t} else {\n\t\t\t\tsetMembers((current) => (current ?? []).filter((member) => member.user.id !== userId));\n\t\t\t}\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That did not work.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function withdraw(invitationId: string) {\n\t\ttry {\n\t\t\tawait client.teams.revokeInvitation(token as string, chosen as string, invitationId);\n\t\t\tsetInvitations((current) => (current ?? []).filter((one) => one.id !== invitationId));\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That invitation could not be withdrawn.\");\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-team\", className)} style={style}>\n\t\t\t<h3 className=\"b316-team-title\">{team?.name ?? \"Team\"}</h3>\n\n\t\t\t{team?.inherited ? (\n\t\t\t\t// Not a member of this team, so not in the list below and with nothing\n\t\t\t\t// to leave: access comes from the team that manages it, and ends there.\n\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\tYou have access through{\" \"}\n\t\t\t\t\t{teams.find((candidate) => candidate.id === team.via)?.name ??\n\t\t\t\t\t\t\"the organization that manages this team\"}\n\t\t\t\t\t.\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<ul className=\"b316-team-list\">\n\t\t\t\t{(members ?? []).map((member) => (\n\t\t\t\t\t<li key={member.id} className=\"b316-team-member\">\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<div>{member.user.name ?? member.user.email ?? \"Someone\"}</div>\n\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t{member.user.email}\n\t\t\t\t\t\t\t\t{member.user.id === session?.userId ? \" · you\" : \"\"}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"b316-team-member-side\">\n\t\t\t\t\t\t\t<span className=\"b316-chip\">{member.role.name}</span>\n\t\t\t\t\t\t\t{canManage || member.user.id === session?.userId ? (\n\t\t\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tconfirmLabel={\n\t\t\t\t\t\t\t\t\t\tmember.user.id === session?.userId\n\t\t\t\t\t\t\t\t\t\t\t? \"Leave this team\"\n\t\t\t\t\t\t\t\t\t\t\t: `Remove ${member.user.name ?? member.user.email ?? \"them\"}`\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tonConfirm={() => remove(member.user.id)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{member.user.id === session?.userId ? \"Leave\" : \"Remove\"}\n\t\t\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ul>\n\n\t\t\t{canManage && (invitations ?? []).length > 0 ? (\n\t\t\t\t<>\n\t\t\t\t\t<h4 className=\"b316-team-subtitle\">Invited</h4>\n\t\t\t\t\t<ul className=\"b316-team-list\">\n\t\t\t\t\t\t{(invitations ?? []).map((invitation) => (\n\t\t\t\t\t\t\t<li key={invitation.id} className=\"b316-team-member\">\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<div>{invitation.email}</div>\n\t\t\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\t\t{invitation.role.name} · expires{\" \"}\n\t\t\t\t\t\t\t\t\t\t{new Date(invitation.expiresAt).toLocaleDateString()}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\t\t\tonClick={() => void withdraw(invitation.id)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tWithdraw\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</>\n\t\t\t) : null}\n\n\t\t\t{canManage ? (\n\t\t\t\t<form className=\"b316-team-invite\" onSubmit={invite}>\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-invite-email\">\n\t\t\t\t\t\tInvite by email\n\t\t\t\t\t</label>\n\t\t\t\t\t<div className=\"b316-team-invite-row\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tid=\"b316-invite-email\"\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\tplaceholder=\"colleague@example.com\"\n\t\t\t\t\t\t\tvalue={email}\n\t\t\t\t\t\t\tonChange={(event) => setEmail(event.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy || !email}>\n\t\t\t\t\t\t\t{busy ? \"Sending…\" : \"Invite\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t) : null}\n\n\t\t\t{copied ? (\n\t\t\t\t<div className=\"b316-team-link\">\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\tSend them this link. It is shown once and cannot be fetched again.\n\t\t\t\t\t</div>\n\t\t\t\t\t<code>{copied}</code>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { InvitationPreview } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * The other end of an invitation.\n *\n * Reads the token from the URL and says what it is for *before* asking anybody\n * to sign in, because \"join Acme as a Member\" is a reason to create an account\n * and \"accept invitation\" is not. That preview is the one call here that needs\n * no session — the person holding the link may have no account at all, which is\n * the entire reason invitations exist.\n *\n * The token is not scrubbed from the URL, unlike a password reset. It is\n * useless to anybody but the address it was sent to, and leaving it in place\n * means the page survives a sign-in round trip that navigates away and back —\n * which is the normal path for somebody who has just created an account.\n */\n\n/**\n * The sign-up link, carrying the invitation.\n *\n * `<SignUp />` reads `?invitation=` and sends it with the sign-up, which is\n * what creates the account inside this team instead of in a personal\n * workspace nobody asked for. A link the caller already gave a token is left\n * alone; a fragment stays at the end, where it belongs.\n */\nexport function signUpUrlWithInvitation(url: string, token: string): string {\n\tconst [beforeHash, ...hash] = url.split(\"#\");\n\tconst base = beforeHash ?? \"\";\n\n\tif (/[?&]invitation=/.test(base)) {\n\t\treturn url;\n\t}\n\n\tconst joined = `${base}${base.includes(\"?\") ? \"&\" : \"?\"}invitation=${encodeURIComponent(token)}`;\n\n\treturn hash.length > 0 ? `${joined}#${hash.join(\"#\")}` : joined;\n}\n\nexport interface AcceptInvitationProps {\n\t/** Supply the token directly. Read from `?invitation=` when omitted. */\n\ttoken?: string;\n\tonAccepted?: (organizationId: string) => void;\n\t/**\n\t * Where to send somebody who needs an account first — a page with\n\t * `<SignUp />`. The invitation is appended as `?invitation=`, so the\n\t * account is created inside this team rather than in a workspace of its\n\t * own.\n\t */\n\tsignUpUrl?: string;\n\tsignInUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function AcceptInvitation({\n\ttoken: supplied,\n\tonAccepted,\n\tsignUpUrl,\n\tsignInUrl,\n\tclassName,\n\tstyle,\n}: AcceptInvitationProps) {\n\tconst { client, token: session, session: user } = useBase316();\n\tconst [invitationToken, setInvitationToken] = useState<string | null>(supplied ?? null);\n\tconst [preview, setPreview] = useState<InvitationPreview | null>(null);\n\tconst [state, setState] = useState<\"loading\" | \"ready\" | \"invalid\" | \"accepted\">(\"loading\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (supplied || typeof window === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tsetInvitationToken(new URL(window.location.href).searchParams.get(\"invitation\"));\n\t}, [supplied]);\n\n\tuseEffect(() => {\n\t\tif (!invitationToken) {\n\t\t\tsetState(supplied === undefined ? \"loading\" : \"invalid\");\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.teams\n\t\t\t.preview(invitationToken)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetPreview(result);\n\t\t\t\t\tsetState(\"ready\");\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t// One answer for missing, expired, spent and withdrawn — the API does\n\t\t\t\t// not distinguish them, so that somebody cannot probe for live tokens.\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetState(\"invalid\");\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, invitationToken, supplied]);\n\n\tasync function accept() {\n\t\tif (!session || !invitationToken) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.teams.accept(session, invitationToken);\n\n\t\t\tsetState(\"accepted\");\n\t\t\tonAccepted?.(result.organizationId);\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That invitation could not be accepted.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (state === \"loading\") {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (state === \"invalid\") {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">That invitation is no longer valid</h3>\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tIt may have expired, been withdrawn, or already been used. Ask for a new one.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (state === \"accepted\") {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">You have joined {preview?.organizationName}</h3>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst matches = !user || (user.user.email ?? \"\").toLowerCase() === preview?.email.toLowerCase();\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-invitation\", className)} style={style}>\n\t\t\t<h3 className=\"b316-form-title\">Join {preview?.organizationName}</h3>\n\t\t\t<p className=\"b316-muted\">\n\t\t\t\tInvited as {preview?.email} · {preview?.roleName}\n\t\t\t</p>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{!session ? (\n\t\t\t\t<>\n\t\t\t\t\t<p>Sign in as {preview?.email} to accept.</p>\n\t\t\t\t\t<div className=\"b316-invitation-actions\">\n\t\t\t\t\t\t{signInUrl ? (\n\t\t\t\t\t\t\t<a className=\"b316-button\" href={signInUrl}>\n\t\t\t\t\t\t\t\tSign in\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{signUpUrl ? (\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\tclassName=\"b316-button-link\"\n\t\t\t\t\t\t\t\thref={\n\t\t\t\t\t\t\t\t\tinvitationToken ? signUpUrlWithInvitation(signUpUrl, invitationToken) : signUpUrl\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tCreate an account\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t) : !matches ? (\n\t\t\t\t// Said before they press anything. The server refuses this, but\n\t\t\t\t// finding out after a click reads as a broken invitation rather than\n\t\t\t\t// as being signed in as the wrong person.\n\t\t\t\t<p>\n\t\t\t\t\tYou are signed in as {user?.user.email}. This invitation was sent to {preview?.email} —\n\t\t\t\t\tsign in as that address to accept it.\n\t\t\t\t</p>\n\t\t\t) : (\n\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={accept}>\n\t\t\t\t\t{busy ? \"Joining…\" : `Join ${preview?.organizationName}`}\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Pay an invoice, inside the host application's own page.\n *\n * The Base316-hosted pay page exists for the case where there is nowhere else to\n * send somebody — a scanned QR code, a link in an email. This is the other case:\n * a customer who already has their own portal and wants the payment step to\n * happen there, under their own navigation, without a redirect.\n *\n * It takes a payment-link token rather than an invoice id on purpose. The token\n * is a capability — it says *this* invoice may be paid by whoever holds it — and\n * that is what makes the component usable on a page the payer reached from an\n * email, where there is no session to check them against.\n *\n * Stripe.js is loaded by injecting a script tag rather than by depending on\n * `@stripe/stripe-js`. This package has exactly one dependency today and the\n * card field has to be a cross-origin iframe either way, so a hard dependency\n * would buy nothing but weight in every bundle that imports anything from here.\n */\n\nconst STRIPE_SRC = \"https://js.stripe.com/v3/\";\n\ninterface StripeElements {\n\tcreate(type: string): { mount(selector: string | HTMLElement): void };\n}\n\ninterface StripeLike {\n\telements(options: { clientSecret: string }): StripeElements;\n\tconfirmPayment(options: {\n\t\telements: StripeElements;\n\t\tconfirmParams: { return_url: string };\n\t\tredirect: \"if_required\";\n\t}): Promise<{ error?: { message?: string } }>;\n}\n\ndeclare global {\n\tinterface Window {\n\t\tStripe?: (key: string, options?: { stripeAccount: string }) => StripeLike;\n\t}\n}\n\n/** Resolves once Stripe.js is on the page, loading it if nobody else has. */\nfunction loadStripeScript(): Promise<void> {\n\tif (typeof window === \"undefined\") {\n\t\treturn Promise.reject(new Error(\"Stripe.js cannot load during server rendering.\"));\n\t}\n\n\tif (window.Stripe) {\n\t\treturn Promise.resolve();\n\t}\n\n\treturn new Promise((resolve, reject) => {\n\t\t// Reused rather than appended again: two copies of Stripe.js on one page\n\t\t// is a support case nobody enjoys, and a host app may already have it.\n\t\tconst existing = document.querySelector<HTMLScriptElement>(`script[src=\"${STRIPE_SRC}\"]`);\n\n\t\tif (existing) {\n\t\t\texisting.addEventListener(\"load\", () => resolve());\n\t\t\texisting.addEventListener(\"error\", () => reject(new Error(\"Stripe.js failed to load.\")));\n\t\t\treturn;\n\t\t}\n\n\t\tconst script = document.createElement(\"script\");\n\t\tscript.src = STRIPE_SRC;\n\t\tscript.async = true;\n\t\tscript.onload = () => resolve();\n\t\tscript.onerror = () => reject(new Error(\"Stripe.js failed to load.\"));\n\t\tdocument.head.appendChild(script);\n\t});\n}\n\nexport function PayInvoice({\n\ttoken,\n\tenvironmentId,\n\tonPaid,\n\tclassName,\n\tstyle,\n}: {\n\t/** From `invoices.createPaymentLink` on your server. */\n\ttoken: string;\n\t/** The environment the link belongs to; it is in the link URL too. */\n\tenvironmentId: string;\n\t/** Runs once the payment is complete. */\n\tonPaid?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { client } = useBase316();\n\tconst mountRef = useRef<HTMLDivElement | null>(null);\n\tconst stripeRef = useRef<StripeLike | null>(null);\n\tconst elementsRef = useRef<StripeElements | null>(null);\n\n\tconst [ready, setReady] = useState(false);\n\tconst [paying, setPaying] = useState(false);\n\tconst [done, setDone] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tasync function start() {\n\t\t\t// The pay routes sit outside /v1 and take no API key: the token in the\n\t\t\t// path is the whole credential, which is what lets this work on a page\n\t\t\t// the payer reached from an email with no session at all.\n\t\t\tconst base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;\n\t\t\tconst response = await fetch(`${base}/intent`, { method: \"POST\" });\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(\"This payment link is no longer valid.\");\n\t\t\t}\n\n\t\t\tconst intent = (await response.json()) as {\n\t\t\t\tclientSecret: string;\n\t\t\t\tpublishableKey: string;\n\t\t\t\taccountId: string | null;\n\t\t\t};\n\n\t\t\tawait loadStripeScript();\n\n\t\t\tif (cancelled || !window.Stripe || !mountRef.current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst stripe = window.Stripe(\n\t\t\t\tintent.publishableKey,\n\t\t\t\tintent.accountId ? { stripeAccount: intent.accountId } : undefined,\n\t\t\t);\n\t\t\tconst elements = stripe.elements({ clientSecret: intent.clientSecret });\n\n\t\t\telements.create(\"payment\").mount(mountRef.current);\n\t\t\tstripeRef.current = stripe;\n\t\t\telementsRef.current = elements;\n\t\t\tsetReady(true);\n\t\t}\n\n\t\tstart().catch((cause: unknown) => {\n\t\t\tif (!cancelled) {\n\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not prepare this payment.\");\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, environmentId, token]);\n\n\tconst submit = async (event: React.FormEvent) => {\n\t\tevent.preventDefault();\n\n\t\tif (!stripeRef.current || !elementsRef.current) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetPaying(true);\n\t\tsetError(null);\n\n\t\t// \"if_required\" keeps an ordinary card payment on this page and leaves it\n\t\t// only when the method genuinely needs a redirect — a 3-D Secure\n\t\t// challenge, or a bank's own app.\n\t\tconst result = await stripeRef.current.confirmPayment({\n\t\t\telements: elementsRef.current,\n\t\t\tconfirmParams: { return_url: window.location.href },\n\t\t\tredirect: \"if_required\",\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tsetError(result.error.message ?? \"That payment could not be completed.\");\n\t\t\tsetPaying(false);\n\t\t\treturn;\n\t\t}\n\n\t\tsetDone(true);\n\t\tonPaid?.();\n\t};\n\n\tif (done) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-pay\", className)} style={style}>\n\t\t\t\t<p className=\"b316-pay__done\">Paid — thank you.</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-pay\", className)} style={style} onSubmit={submit}>\n\t\t\t{error ? (\n\t\t\t\t<p className=\"b316-pay__error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t<div ref={mountRef} className=\"b316-pay__element\" />\n\t\t\t<button className=\"b316-pay__submit\" type=\"submit\" disabled={!ready || paying}>\n\t\t\t\t{paying ? \"Paying…\" : \"Pay\"}\n\t\t\t</button>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { useBase316 } from \"./provider\";\n\n/**\n * Watch a payment link until it is paid.\n *\n * For the merchant's *screen*, not their server. A webhook tells a backend that\n * a walk-up customer paid; it cannot tell the tablet propped on the counter with\n * the QR code on it. This is what flips that screen over.\n *\n * A poll rather than a socket, matching the rest of the platform: there is no\n * streaming endpoint, and a poll is what survives a tablet sleeping and a phone\n * hopping between wifi and cellular mid-payment.\n *\n * Use it with the token you got back from `invoices.createPaymentLink` on your\n * server. Polling stops on its own once the invoice settles, so a forgotten\n * component does not keep asking for ever.\n */\n\nexport type PaymentLinkStatus =\n\t| { state: \"loading\" }\n\t| { state: \"payable\"; number: string; due: string; currency: string }\n\t| { state: \"settled\"; number: string }\n\t/** Unknown, expired, or withdrawn — the API does not say which. */\n\t| { state: \"invalid\" };\n\nexport function usePaymentLink({\n\ttoken,\n\tenvironmentId,\n\tintervalMs = 2000,\n\tonPaid,\n}: {\n\ttoken: string;\n\tenvironmentId: string;\n\t/**\n\t * How often to ask. The default is chosen against the thing being waited for\n\t * — somebody tapping a phone a metre away — rather than against server load.\n\t */\n\tintervalMs?: number;\n\tonPaid?: () => void;\n}): PaymentLinkStatus {\n\tconst { client } = useBase316();\n\tconst [status, setStatus] = useState<PaymentLinkStatus>({ state: \"loading\" });\n\n\t// Held in a ref so that passing a new inline function on every render does\n\t// not tear down and restart the poll.\n\tconst onPaidRef = useRef(onPaid);\n\tonPaidRef.current = onPaid;\n\n\tuseEffect(() => {\n\t\tlet stopped = false;\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\t\tconst statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;\n\n\t\tasync function check() {\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(statusUrl, { cache: \"no-store\" });\n\n\t\t\t\tif (stopped) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (response.status === 404) {\n\t\t\t\t\tsetStatus({ state: \"invalid\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (response.ok) {\n\t\t\t\t\tconst body = (await response.json()) as {\n\t\t\t\t\t\tstate: \"payable\" | \"settled\";\n\t\t\t\t\t\tnumber: string;\n\t\t\t\t\t\tdue: string | null;\n\t\t\t\t\t\tcurrency: string | null;\n\t\t\t\t\t};\n\n\t\t\t\t\tif (stopped) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (body.state === \"settled\") {\n\t\t\t\t\t\tsetStatus({ state: \"settled\", number: body.number });\n\t\t\t\t\t\tonPaidRef.current?.();\n\t\t\t\t\t\t// Deliberately no reschedule: this is terminal.\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tsetStatus({\n\t\t\t\t\t\tstate: \"payable\",\n\t\t\t\t\t\tnumber: body.number,\n\t\t\t\t\t\tdue: body.due ?? \"0\",\n\t\t\t\t\t\tcurrency: body.currency ?? \"USD\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// A dropped request is ordinary — a phone changing network does this.\n\t\t\t\t// The next tick asks again rather than showing an error to somebody\n\t\t\t\t// whose customer is probably mid-payment.\n\t\t\t}\n\n\t\t\tif (!stopped) {\n\t\t\t\t// Scheduled after the response rather than on a fixed interval, so a\n\t\t\t\t// slow network cannot stack requests on top of each other.\n\t\t\t\ttimer = setTimeout(check, intervalMs);\n\t\t\t}\n\t\t}\n\n\t\tvoid check();\n\n\t\treturn () => {\n\t\t\tstopped = true;\n\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t};\n\t}, [client, environmentId, token, intervalMs]);\n\n\treturn status;\n}\n","\"use client\";\n\nimport type { PublicPlan } from \"@base316/sdk\";\nimport { type CSSProperties, useState } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { usePlans } from \"./usePlans\";\n\nfunction formatAmount(amount: string | null, currency: string): string {\n\tif (amount === null) return \"Free\";\n\n\tconst value = Number(amount);\n\tif (!Number.isFinite(value)) return \"Free\";\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\t// An unknown currency code should not blank the price.\n\t\treturn `${value} ${currency}`;\n\t}\n}\n\nfunction cadence(plan: PublicPlan, amount: string | null): string {\n\tif (amount === null) {\n\t\treturn \"\\u00a0\";\n\t}\n\n\tconst unit = plan.interval.toLowerCase();\n\treturn plan.intervalCount === 1 ? `per ${unit}` : `every ${plan.intervalCount} ${unit}s`;\n}\n\n/**\n * What a plan's trial says on the card, or null when it has none.\n *\n * A `CONVERT` trial is the familiar \"14-day free trial\": it bills when it\n * ends. A `DOWNGRADE` trial — the reverse trial — does not bill a subscriber\n * who never added a card; it moves them to `trialDowngradePlanVersionId`. The\n * card has to say so, or a visitor reads \"free trial\" as \"then I'm charged\"\n * and never starts one. The target is named when it is among the published\n * plans (it usually is: the Free plan); otherwise the label says what keeps\n * the plan instead of guessing at a name.\n */\nexport function describeTrial(plan: PublicPlan, plans: readonly PublicPlan[]): string | null {\n\tif (!plan.trialDays) {\n\t\treturn null;\n\t}\n\n\tconst trial = `${plan.trialDays}-day free trial`;\n\n\tif (plan.trialEndAction !== \"DOWNGRADE\") {\n\t\treturn trial;\n\t}\n\n\tconst target = plans.find(\n\t\t(candidate) => candidate.planVersionId === plan.trialDowngradePlanVersionId,\n\t);\n\n\treturn target\n\t\t? `${trial}, then ${target.name} unless you add a card`\n\t\t: `${trial}, no card needed. Add one to keep ${plan.name}`;\n}\n\n/**\n * The plans, as an end user picks them.\n *\n * Drop it in with no props and it works: it loads the published plans, marks\n * the one the signed-in user is on, and completes the purchase.\n *\n * Choosing a plan used to be the caller's job, because minting a checkout\n * session needs a secret key that cannot live in a browser. That is still\n * true — but it is an argument about *key custody*, not about who names the\n * plan. `POST /v1/me/checkout/sessions` resolves the customer from the session\n * and reads the price from the database against the plan id, so a browser\n * naming a cheaper plan subscribes to a cheaper plan rather than paying less\n * for an expensive one. That is what makes this droppable.\n *\n * Two routes, because a subscriber and a newcomer need different things:\n *\n * - Already subscribed, card on file → change plan in place, prorated, no\n * card re-entry and no second subscription beside the first.\n * - Otherwise → a checkout session, which is the thing that collects a card.\n *\n * `onSelectPlan` remains as an override for an application that wants to run\n * its own flow — a quote, an approval step, its own backend route.\n */\nexport function PricingTable({\n\tonSelectPlan,\n\tcurrentPlanVersionId,\n\tfeaturedPlanKey,\n\tsignInUrl,\n\tclassName,\n\tstyle,\n}: {\n\t/**\n\t * Take over what \"Choose\" does.\n\t *\n\t * Optional. Without it the component completes the purchase itself, which\n\t * is what most applications want.\n\t */\n\tonSelectPlan?: (planVersionId: string, plan: PublicPlan) => void | Promise<void>;\n\t/**\n\t * Marks the plan the viewer is already on.\n\t *\n\t * Discovered from the signed-in user's subscription when not given. Pass it\n\t * to override — on a marketing page rendering someone else's plan, say.\n\t */\n\tcurrentPlanVersionId?: string | null;\n\t/** The plan to present as the default choice, by its key. */\n\tfeaturedPlanKey?: string;\n\t/**\n\t * Where to send a signed-out visitor who picks a plan.\n\t *\n\t * Checkout needs a session, so without a signed-in user there is nobody to\n\t * bill. Given a URL the button goes there; without one it says so rather\n\t * than failing on click.\n\t */\n\tsignInUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\t// Every decision worth getting right lives in the hook. What remains here is\n\t// markup — which is the point: an application that wants a different table\n\t// calls `usePlans()` and writes its own rather than forking this one.\n\tconst {\n\t\tplans,\n\t\terror,\n\t\tcurrentPlanVersionId: current,\n\t\tbusyPlanVersionId: busy,\n\t\tlastError,\n\t\tsignedIn,\n\t\tmanagedBy,\n\t\tselectPlan,\n\t} = usePlans({ currentPlanVersionId });\n\t// Said after a downgrade, which waits for the renewal: without it the click\n\t// appears to do nothing, because the current plan rightly stays current.\n\tconst [scheduled, setScheduled] = useState<string | null>(null);\n\n\tasync function choose(plan: PublicPlan) {\n\t\tif (onSelectPlan) {\n\t\t\tawait onSelectPlan(plan.planVersionId, plan);\n\t\t\treturn;\n\t\t}\n\n\t\tsetScheduled(null);\n\t\tconst outcome = await selectPlan(plan);\n\n\t\tif (outcome.status === \"scheduled\") {\n\t\t\tconst on = outcome.effectiveAt\n\t\t\t\t? new Date(outcome.effectiveAt).toLocaleDateString()\n\t\t\t\t: \"your next renewal\";\n\t\t\tsetScheduled(`${plan.name} starts on ${on}. You keep your current plan until then.`);\n\t\t}\n\n\t\t// The hook reports rather than navigates for this one, because where a\n\t\t// signed-out visitor should go is the application's decision.\n\t\tif (outcome.status === \"needs-sign-in\" && signInUrl && typeof window !== \"undefined\") {\n\t\t\twindow.location.assign(signInUrl);\n\t\t}\n\t}\n\n\tif (error) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tPlans are unavailable right now.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!plans) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading plans…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (plans.length === 0) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tNo plans are published yet.\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Whether a slot is rendered is a property of the table, not of one plan:\n\t// reserving space on every card is what keeps the rows aligned.\n\tconst anyTrial = plans.some((plan) => Boolean(plan.trialDays));\n\tconst anyDescription = plans.some((plan) => Boolean(plan.description));\n\tconst anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);\n\n\treturn (\n\t\t<div className={cls(\"b316-plans\", className)} style={style}>\n\t\t\t{/* A failed upgrade is silent otherwise: the button stops spinning and\n\t\t\t nothing about the page says why the plan did not change. */}\n\t\t\t{managedBy ? (\n\t\t\t\t// A client company's plan comes from the firm that runs it. The table\n\t\t\t\t// still shows what is on offer, with the current plan marked, but\n\t\t\t\t// nothing here can be bought: it would grant this account nothing.\n\t\t\t\t<div className=\"b316-plans-managed b316-muted\">\n\t\t\t\t\tYour plan is provided by {managedBy.name ?? \"the organization that manages your account\"}.\n\t\t\t\t\tAsk them to change it.\n\t\t\t\t</div>\n\t\t\t) : lastError ? (\n\t\t\t\t<div className=\"b316-plans-error\" role=\"alert\">\n\t\t\t\t\t{lastError}\n\t\t\t\t</div>\n\t\t\t) : scheduled ? (\n\t\t\t\t<div className=\"b316-plans-managed b316-muted\" role=\"status\">\n\t\t\t\t\t{scheduled}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{plans.map((plan) => {\n\t\t\t\tconst base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];\n\t\t\t\tconst isCurrent = current === plan.planVersionId;\n\t\t\t\tconst featured = featuredPlanKey === plan.key;\n\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={plan.id}\n\t\t\t\t\t\tclassName={featured ? \"b316-card b316-plan b316-plan-featured\" : \"b316-card b316-plan\"}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div className=\"b316-plan-head\">\n\t\t\t\t\t\t\t{anyFeatured ? (\n\t\t\t\t\t\t\t\t<div className={featured ? \"b316-plan-badge\" : \"b316-plan-badge-spacer\"}>\n\t\t\t\t\t\t\t\t\t{featured ? \"Recommended\" : \"\\u00a0\"}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<div className=\"b316-plan-name\">{plan.name}</div>\n\t\t\t\t\t\t\t{anyDescription ? (\n\t\t\t\t\t\t\t\t<div className=\"b316-plan-desc\">{plan.description ?? \"\\u00a0\"}</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div className=\"b316-plan-pricing\">\n\t\t\t\t\t\t\t<div className=\"b316-plan-price\">\n\t\t\t\t\t\t\t\t{formatAmount(base?.amount ?? null, plan.currency)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{/* Rendered even when empty so every card's feature list starts\n\t\t\t\t\t\t\t at the same height — otherwise a free plan pulls its rows up\n\t\t\t\t\t\t\t and nothing lines up across the table. */}\n\t\t\t\t\t\t\t<div className=\"b316-plan-cadence\">{cadence(plan, base?.amount ?? null)}</div>\n\t\t\t\t\t\t\t{anyTrial ? (\n\t\t\t\t\t\t\t\t<div className=\"b316-plan-trial\">{describeTrial(plan, plans) ?? \"\\u00a0\"}</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<ul className=\"b316-plan-features\">\n\t\t\t\t\t\t\t{plan.entitlements\n\t\t\t\t\t\t\t\t.filter((entitlement) => entitlement.enabled)\n\t\t\t\t\t\t\t\t.map((entitlement) => (\n\t\t\t\t\t\t\t\t\t<li key={entitlement.featureId} className=\"b316-plan-feature\">\n\t\t\t\t\t\t\t\t\t\t<span>{entitlement.featureName}</span>\n\t\t\t\t\t\t\t\t\t\t<span className=\"b316-plan-feature-value\">\n\t\t\t\t\t\t\t\t\t\t\t{entitlement.limit === null\n\t\t\t\t\t\t\t\t\t\t\t\t? \"Unlimited\"\n\t\t\t\t\t\t\t\t\t\t\t\t: // A usage price on the feature makes the limit an\n\t\t\t\t\t\t\t\t\t\t\t\t\t// allowance billed past, not a ceiling — the same\n\t\t\t\t\t\t\t\t\t\t\t\t\t// rule `check()` applies (any non-FLAT price).\n\t\t\t\t\t\t\t\t\t\t\t\t\tplan.prices.some(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(price) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprice.featureId === entitlement.featureId && price.model !== \"FLAT\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t\t\t\t\t\t\t? `${entitlement.limit} included`\n\t\t\t\t\t\t\t\t\t\t\t\t\t: entitlement.limit}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</ul>\n\n\t\t\t\t\t\t<div className=\"b316-plan-action\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName={isCurrent ? \"b316-button b316-button-current\" : \"b316-button\"}\n\t\t\t\t\t\t\t\t// Signed out with nowhere to send them is the one case with no\n\t\t\t\t\t\t\t\t// useful action, so the button says so instead of failing on\n\t\t\t\t\t\t\t\t// click. An override is assumed to handle it itself.\n\t\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\t\tisCurrent ||\n\t\t\t\t\t\t\t\t\tmanagedBy !== null ||\n\t\t\t\t\t\t\t\t\tbusy !== null ||\n\t\t\t\t\t\t\t\t\t(!signedIn && !signInUrl && !onSelectPlan)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tvoid choose(plan);\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{isCurrent\n\t\t\t\t\t\t\t\t\t? \"Current plan\"\n\t\t\t\t\t\t\t\t\t: busy === plan.planVersionId\n\t\t\t\t\t\t\t\t\t\t? \"Working…\"\n\t\t\t\t\t\t\t\t\t\t: !signedIn && !signInUrl && !onSelectPlan\n\t\t\t\t\t\t\t\t\t\t\t? \"Sign in to choose\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Choose\"}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { PublicPlan } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport { useBase316 } from \"./provider\";\n\n/**\n * The plans, and what happens when somebody picks one — without any markup.\n *\n * This is the escape hatch that keeps a component library from being forked.\n * `PricingTable` is a few dozen lines of JSX over this hook; an application\n * with its own design system calls the hook directly, renders whatever it\n * likes, and still gets the part that is easy to get wrong:\n *\n * - which plan the signed-in user is actually on,\n * - whether picking one should prorate in place or collect a card,\n * - resolving the customer from the session rather than trusting the browser.\n *\n * The rule the whole library follows: logic lives in a hook, presentation\n * lives in a component, and the component is thin enough to be worth\n * replacing. Fusing the two is what forces a fork the first time somebody\n * wants a different table.\n */\n\n/** What picking a plan did. Returned so a custom UI can respond in kind. */\nexport type SelectPlanOutcome =\n\t| { status: \"changed\"; planVersionId: string }\n\t/**\n\t * A downgrade, scheduled for the renewal rather than made now: the user\n\t * keeps the plan they paid for until `effectiveAt`, so it stays current.\n\t */\n\t| { status: \"scheduled\"; planVersionId: string; effectiveAt: string | null }\n\t| { status: \"checkout\"; url: string }\n\t| { status: \"needs-sign-in\" }\n\t| { status: \"failed\"; reason: string };\n\nexport interface UsePlansOptions {\n\t/**\n\t * Override the plan shown as current.\n\t *\n\t * Discovered from the signed-in user's subscription when omitted.\n\t */\n\tcurrentPlanVersionId?: string | null;\n\t/**\n\t * Where a checkout URL should send the browser.\n\t *\n\t * Defaults to navigating. Pass `false` to keep `selectPlan` free of side\n\t * effects and handle the URL from the outcome — a modal checkout, a native\n\t * shell, or a test.\n\t */\n\tnavigate?: boolean | ((url: string) => void);\n}\n\nexport interface UsePlansResult {\n\t/** Null until loaded. Empty means nothing is published yet. */\n\tplans: PublicPlan[] | null;\n\tloading: boolean;\n\t/** True when the catalog could not be read at all. */\n\terror: boolean;\n\t/** The plan the viewer is on, discovered or supplied. */\n\tcurrentPlanVersionId: string | null;\n\t/** The plan version currently being acted on, for a pending state. */\n\tbusyPlanVersionId: string | null;\n\t/** Why the last selection failed, if it did. Cleared on the next attempt. */\n\tlastError: string | null;\n\t/** Whether there is a session to bill. */\n\tsignedIn: boolean;\n\t/**\n\t * Who provides this account's plan, when it is not the account itself — a\n\t * client company billed through the firm that manages it. Plans cannot be\n\t * bought or changed from here then; `selectPlan` refuses without calling.\n\t */\n\tmanagedBy: { name: string | null } | null;\n\tselectPlan: (plan: PublicPlan) => Promise<SelectPlanOutcome>;\n\treload: () => void;\n}\n\n/**\n * Statuses that mean \"this account cannot be changed in place, send it to\n * checkout\".\n *\n * The API says so explicitly with `useCheckout: true` on the body, but the SDK\n * error carries the status rather than the body. These two codes are exactly\n * and only that case — 409 for no subscription, 402 for no stored card — so\n * branching on them loses nothing.\n */\nconst CHECKOUT_STATUSES = new Set([402, 409]);\n\nexport function usePlans(options: UsePlansOptions = {}): UsePlansResult {\n\tconst { client, token } = useBase316();\n\tconst [plans, setPlans] = useState<PublicPlan[] | null>(null);\n\tconst [error, setError] = useState(false);\n\tconst [busyPlanVersionId, setBusy] = useState<string | null>(null);\n\tconst [lastError, setLastError] = useState<string | null>(null);\n\tconst [ownPlanVersionId, setOwnPlanVersionId] = useState<string | null>(null);\n\tconst [managedBy, setManagedBy] = useState<{ name: string | null } | null>(null);\n\tconst [reloadCount, setReloadCount] = useState(0);\n\n\tconst supplied = options.currentPlanVersionId;\n\tconst discover = supplied === undefined;\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.plans()\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetPlans(result.data);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load plans\", cause);\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(true);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, reloadCount]);\n\n\t// Marking the current plan is what turns a price list into an account\n\t// screen, and asking the caller to supply it means every caller has to\n\t// fetch the subscription themselves before they can render a table.\n\tuseEffect(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.subscription(token)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetManagedBy(result.managedBy ?? null);\n\t\t\t\t\t// A caller-supplied current plan still wins for the marker.\n\t\t\t\t\tif (discover) {\n\t\t\t\t\t\tsetOwnPlanVersionId(result.subscription?.planVersion.id ?? null);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\t// Not an error worth surfacing: a signed-in user with no subscription\n\t\t\t// is the normal case on a pricing page, and the table still renders.\n\t\t\t.catch(() => null);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, discover, reloadCount]);\n\n\tconst reload = useCallback(() => {\n\t\tsetError(false);\n\t\tsetReloadCount((count) => count + 1);\n\t}, []);\n\n\tconst selectPlan = useCallback(\n\t\tasync (plan: PublicPlan): Promise<SelectPlanOutcome> => {\n\t\t\tsetLastError(null);\n\n\t\t\tif (managedBy) {\n\t\t\t\t// Refused here rather than by the API, so nobody is sent to a checkout\n\t\t\t\t// for a plan that would grant them nothing.\n\t\t\t\tconst reason = `Your plan is provided by ${managedBy.name ?? \"the organization that manages your account\"}.`;\n\t\t\t\tsetLastError(reason);\n\n\t\t\t\treturn { status: \"failed\", reason };\n\t\t\t}\n\n\t\t\tif (!token) {\n\t\t\t\t// Checkout resolves the customer from the session, so without one\n\t\t\t\t// there is nobody to bill. Reported rather than thrown: a signed-out\n\t\t\t\t// visitor on a marketing page is expected, not broken.\n\t\t\t\treturn { status: \"needs-sign-in\" };\n\t\t\t}\n\n\t\t\tsetBusy(plan.planVersionId);\n\n\t\t\tconst go = (url: string) => {\n\t\t\t\tconst navigate = options.navigate ?? true;\n\n\t\t\t\tif (typeof navigate === \"function\") {\n\t\t\t\t\tnavigate(url);\n\t\t\t\t} else if (navigate && typeof window !== \"undefined\") {\n\t\t\t\t\twindow.location.assign(url);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\t// The cheaper path, and the one a subscriber wants: no card re-entry\n\t\t\t\t// and no second subscription opened beside the first.\n\t\t\t\tconst result = await client.billing.changePlan(token, plan.planVersionId);\n\n\t\t\t\t// A downgrade waits for the renewal by default. Marking the new plan\n\t\t\t\t// current now would tell the user they had already lost what they\n\t\t\t\t// paid for this period.\n\t\t\t\tif (result.scheduled) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"scheduled\",\n\t\t\t\t\t\tplanVersionId: plan.planVersionId,\n\t\t\t\t\t\teffectiveAt: result.effectiveAt ?? null,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tsetOwnPlanVersionId(plan.planVersionId);\n\n\t\t\t\treturn { status: \"changed\", planVersionId: plan.planVersionId };\n\t\t\t} catch (cause) {\n\t\t\t\tconst status = (cause as { status?: number | null }).status ?? null;\n\n\t\t\t\tif (status === null || !CHECKOUT_STATUSES.has(status)) {\n\t\t\t\t\tconst reason = cause instanceof Error ? cause.message : \"Could not change plan.\";\n\t\t\t\t\tsetLastError(reason);\n\n\t\t\t\t\treturn { status: \"failed\", reason };\n\t\t\t\t}\n\n\t\t\t\t// No subscription or no card on file — both mean the account needs\n\t\t\t\t// the thing checkout exists to do.\n\t\t\t\ttry {\n\t\t\t\t\tconst session = await client.billing.checkout(token, plan.planVersionId);\n\t\t\t\t\tgo(session.url);\n\n\t\t\t\t\treturn { status: \"checkout\", url: session.url };\n\t\t\t\t} catch (checkoutCause) {\n\t\t\t\t\tconst reason =\n\t\t\t\t\t\tcheckoutCause instanceof Error ? checkoutCause.message : \"Could not start checkout.\";\n\t\t\t\t\tsetLastError(reason);\n\n\t\t\t\t\treturn { status: \"failed\", reason };\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tsetBusy(null);\n\t\t\t}\n\t\t},\n\t\t[client, token, options.navigate, managedBy],\n\t);\n\n\treturn {\n\t\tplans,\n\t\tloading: plans === null && !error,\n\t\terror,\n\t\tcurrentPlanVersionId: discover ? ownPlanVersionId : (supplied ?? null),\n\t\tbusyPlanVersionId,\n\t\tlastError,\n\t\tsignedIn: token !== null,\n\t\tmanagedBy,\n\t\tselectPlan,\n\t\treload,\n\t};\n}\n","\"use client\";\n\nimport { type CollectionRecord, type FieldDescriptor, specFor } from \"@base316/sdk\";\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { FieldCell } from \"./fields\";\nimport { RecordForm } from \"./RecordForm\";\nimport { useCollection, type UseCollectionOptions } from \"./useCollection\";\n\n/**\n * A table of data nobody wrote a table for.\n *\n * Drop it in with a collection key and it works: it reads the schema, derives\n * its columns from the field types, sorts on the fields that can be sorted,\n * searches the ones that can be searched, and offers editing only if this\n * viewer may write.\n *\n * <DataTable collection=\"jobs\" />\n *\n * It never names a field type. Every cell goes through the renderer registry,\n * so a type added later works here without this file being touched — which is\n * the same reason a board or a calendar can be built against the same schema.\n *\n * Wants a different table? Call `useCollection()` and write one. You keep the\n * schema loading, the paging, the permission handling and the write errors,\n * and lose only the markup, which is the part worth replacing.\n */\n\nexport interface DataTableProps extends UseCollectionOptions {\n\t/** The collection key, as the schema defines it. */\n\tcollection: string;\n\t/**\n\t * Which fields to show, in order.\n\t *\n\t * Defaults to every field in its declared position. Name them to trim a wide\n\t * collection down to what this screen is about.\n\t */\n\tcolumns?: string[];\n\t/** Replace the cell for one field. Everything else keeps the default. */\n\trenderCell?: (record: CollectionRecord, field: FieldDescriptor) => ReactNode | undefined;\n\t/** Row click. Without it, rows are not interactive. */\n\tonSelect?: (record: CollectionRecord) => void;\n\t/**\n\t * Called after this table creates, edits or deletes a record.\n\t *\n\t * The table refreshes itself; this is for anything else on the page bound to\n\t * the same collection. Each component holds its own data and they share no\n\t * cache, so without this a `<Chart>` beside a table silently lags by every\n\t * record added through it — which is exactly what an agent building against\n\t * this hit, with no event to hook.\n\t */\n\tonChanged?: () => void;\n\t/** Hide the search box even when the collection has searchable fields. */\n\thideSearch?: boolean;\n\t/** Hide New, Edit and Delete even for a viewer who may write. */\n\treadOnly?: boolean;\n\t/** Shown when there is nothing to list. */\n\temptyState?: ReactNode;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function DataTable({\n\tcollection,\n\tcolumns,\n\trenderCell,\n\tonSelect,\n\tonChanged,\n\thideSearch,\n\treadOnly,\n\temptyState,\n\tclassName,\n\tstyle,\n\t...options\n}: DataTableProps) {\n\tconst {\n\t\tschema,\n\t\trecords,\n\t\tloading,\n\t\terror,\n\t\ttotal,\n\t\thasMore,\n\t\tcanWrite,\n\t\tsearch,\n\t\tsetSearch,\n\t\tsort,\n\t\ttoggleSort,\n\t\tloadMore,\n\t\tremove,\n\t} = useCollection(collection, options);\n\n\t/** The record being edited, or \"new\". Null when the form is closed. */\n\tconst [editing, setEditing] = useState<CollectionRecord | \"new\" | null>(null);\n\n\t/**\n\t * A delete that did not happen.\n\t *\n\t * `remove` returns false on failure and routes the reason into the hook's\n\t * `fieldErrors`, which only `RecordForm` reads — so this table discarded the\n\t * result and called `onChanged` regardless. The row stayed, nothing was\n\t * said, and the reasonable next move was to press Delete again.\n\t *\n\t * Shown above the table rather than replacing it: the data is still good,\n\t * and swapping the whole table for a message would lose the reader's place.\n\t */\n\tconst [removeFailed, setRemoveFailed] = useState<string | null>(null);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst shown = columns\n\t\t? // Ordered by what was asked for, not by the schema: a caller naming\n\t\t\t// columns means that order.\n\t\t\tcolumns\n\t\t\t\t.map((key) => schema.fields.find((field) => field.key === key))\n\t\t\t\t.filter((field): field is FieldDescriptor => Boolean(field))\n\t\t: schema.fields;\n\n\tconst searchable = schema.fields.some((field) => specFor(field).capabilities.searchable);\n\tconst writable = canWrite && !readOnly;\n\n\treturn (\n\t\t<div className={cls(\"b316-table-wrap\", className)} style={style}>\n\t\t\t{removeFailed ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{removeFailed}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-table-bar\">\n\t\t\t\t{searchable && !hideSearch ? (\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tplaceholder={`Search ${schema.namePlural.toLowerCase()}`}\n\t\t\t\t\t\taria-label={`Search ${schema.namePlural}`}\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tonChange={(event) => setSearch(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<span />\n\t\t\t\t)}\n\n\t\t\t\t<div className=\"b316-table-actions\">\n\t\t\t\t\t{/* Counted from the server rather than from the rows on screen,\n\t\t\t\t\t which are one page of them. */}\n\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t{total} {total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()}\n\t\t\t\t\t</span>\n\t\t\t\t\t{writable ? (\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button\" onClick={() => setEditing(\"new\")}>\n\t\t\t\t\t\t\tNew {schema.name.toLowerCase()}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-table-scroll\">\n\t\t\t\t<table className=\"b316-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t{shown.map((field) => {\n\t\t\t\t\t\t\t\tconst sortable = specFor(field).capabilities.sortable;\n\t\t\t\t\t\t\t\tconst active = sort?.field === field.key;\n\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<th key={field.key} scope=\"col\" aria-sort={ariaSort(active, sort?.direction)}>\n\t\t\t\t\t\t\t\t\t\t{sortable ? (\n\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-sort\"\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => toggleSort(field.key)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{field.label}\n\t\t\t\t\t\t\t\t\t\t\t\t<span aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{active ? (sort?.direction === \"desc\" ? \" ↓\" : \" ↑\") : \" ↕\"}\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\tfield.label\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t{writable ? <th scope=\"col\" className=\"b316-table-rowactions\" /> : null}\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{records.map((record) => (\n\t\t\t\t\t\t\t<tr\n\t\t\t\t\t\t\t\tkey={record.id}\n\t\t\t\t\t\t\t\tclassName={onSelect ? \"b316-row-clickable\" : undefined}\n\t\t\t\t\t\t\t\tonClick={onSelect ? () => onSelect(record) : undefined}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{shown.map((field) => (\n\t\t\t\t\t\t\t\t\t<td key={field.key}>\n\t\t\t\t\t\t\t\t\t\t{renderCell?.(record, field) ?? (\n\t\t\t\t\t\t\t\t\t\t\t<FieldCell\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={record.fields[field.key] ?? null}\n\t\t\t\t\t\t\t\t\t\t\t\tfield={field}\n\t\t\t\t\t\t\t\t\t\t\t\trelated={record.related[field.key]}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t{writable ? (\n\t\t\t\t\t\t\t\t\t<td className=\"b316-table-rowactions\">\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t// The row may itself be clickable, and editing is not\n\t\t\t\t\t\t\t\t\t\t\t\t// what a click on the row means.\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\tsetEditing(record);\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tEdit\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\t\t\t\t\t\tconfirmLabel={`Delete ${record.title ?? \"this record\"} for good`}\n\t\t\t\t\t\t\t\t\t\t\t// Deleting is not undoable and the button sits beside\n\t\t\t\t\t\t\t\t\t\t\t// one that is harmless.\n\t\t\t\t\t\t\t\t\t\t\tonConfirm={() =>\n\t\t\t\t\t\t\t\t\t\t\t\tremove(record.id).then((ok) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (ok) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetRemoveFailed(null);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonChanged?.();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetRemoveFailed(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t`${record.title ?? \"That record\"} could not be deleted. It is still here.`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t</div>\n\n\t\t\t{records.length === 0 && !loading ? (\n\t\t\t\t<div className=\"b316-empty\">\n\t\t\t\t\t{emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.`}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{loading ? <div className=\"b316-empty\">Loading…</div> : null}\n\n\t\t\t{hasMore ? (\n\t\t\t\t<div className=\"b316-table-more\">\n\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={loadMore} disabled={loading}>\n\t\t\t\t\t\tLoad more\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{editing ? (\n\t\t\t\t<RecordForm\n\t\t\t\t\tcollection={collection}\n\t\t\t\t\trecordId={editing === \"new\" ? undefined : editing.id}\n\t\t\t\t\ttenant={options.tenant}\n\t\t\t\t\tonSaved={() => {\n\t\t\t\t\t\tsetEditing(null);\n\t\t\t\t\t\tonChanged?.();\n\t\t\t\t\t}}\n\t\t\t\t\tonCancel={() => setEditing(null)}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\n/** What a screen reader announces about a sorted column. */\nfunction ariaSort(\n\tactive: boolean,\n\tdirection?: \"asc\" | \"desc\",\n): \"ascending\" | \"descending\" | \"none\" | undefined {\n\tif (!active) {\n\t\treturn undefined;\n\t}\n\n\treturn direction === \"desc\" ? \"descending\" : \"ascending\";\n}\n","\"use client\";\n\nimport {\n\ttype AddressValue,\n\ttype FieldDescriptor,\n\ttype FieldValue,\n\tformatAddress,\n\tspecFor,\n} from \"@base316/sdk\";\nimport type { ReactNode } from \"react\";\n\n/**\n * How each field type looks, and how each is edited.\n *\n * The other half of the registry. `@base316/sdk`'s `fields.ts` says what a\n * field *is* — groupable, summable, searchable — and this says what it looks\n * like. They are split because the server needs the first and must never\n * import React, and because a customer replacing the rendering should not have\n * to restate the semantics.\n *\n * Every component goes through here rather than switching on types itself.\n * That is what makes a new field type cheap: one entry in the SDK registry,\n * one here, and the table, the form, the detail view and anything built later\n * all understand it without being touched.\n */\n\nexport interface CellProps {\n\tvalue: FieldValue;\n\tfield: FieldDescriptor;\n\t/** A relation's resolved label, when this field is one. */\n\trelated?: { id: string; title: string | null };\n}\n\nexport interface InputProps {\n\tvalue: FieldValue;\n\tfield: FieldDescriptor;\n\tonChange: (value: FieldValue) => void;\n\t/** Rendered under the input. Set when the server rejected this field. */\n\terror?: string | null;\n\tdisabled?: boolean;\n}\n\nfunction formatNumber(value: FieldValue, fraction = 0): string {\n\tconst number = Number(value);\n\n\treturn Number.isFinite(number)\n\t\t? new Intl.NumberFormat(undefined, {\n\t\t\t\tminimumFractionDigits: fraction,\n\t\t\t\tmaximumFractionDigits: 2,\n\t\t\t}).format(number)\n\t\t: \"\";\n}\n\n/**\n * Seconds as something a person reads.\n *\n * Durations are stored in seconds so they can be summed; nobody wants to read\n * 5400 on a timesheet.\n */\nfunction formatDuration(value: FieldValue): string {\n\tconst total = Number(value);\n\n\tif (!Number.isFinite(total)) {\n\t\treturn \"\";\n\t}\n\n\tconst hours = Math.floor(total / 3600);\n\tconst minutes = Math.round((total % 3600) / 60);\n\n\tif (hours === 0) {\n\t\treturn `${minutes}m`;\n\t}\n\n\treturn minutes === 0 ? `${hours}h` : `${hours}h ${minutes}m`;\n}\n\n/** The cell for one field. Null and empty render as a dash, never as \"null\". */\nexport function FieldCell({ value, field, related }: CellProps): ReactNode {\n\tif (field.type === \"RELATION\") {\n\t\t// The label if it resolved, the id if it did not — which happens when the\n\t\t// record was deleted or belongs to a tenant this viewer cannot see.\n\t\treturn related?.title ?? (related?.id ? <code className=\"b316-muted\">{related.id}</code> : \"—\");\n\t}\n\n\tif (value === null || value === undefined || value === \"\") {\n\t\treturn <span className=\"b316-muted\">—</span>;\n\t}\n\n\tswitch (field.type) {\n\t\tcase \"BOOLEAN\":\n\t\t\treturn value ? \"Yes\" : \"No\";\n\n\t\tcase \"MONEY\":\n\t\t\treturn formatNumber(value, 2);\n\n\t\tcase \"PERCENT\":\n\t\t\treturn `${formatNumber(value)}%`;\n\n\t\tcase \"DURATION\":\n\t\t\treturn formatDuration(value);\n\n\t\tcase \"RATING\": {\n\t\t\tconst stars = Math.round(Number(value));\n\n\t\t\treturn (\n\t\t\t\t<span aria-label={`${stars} out of 5`}>\n\t\t\t\t\t{\"★\".repeat(stars)}\n\t\t\t\t\t<span className=\"b316-muted\">{\"★\".repeat(Math.max(0, 5 - stars))}</span>\n\t\t\t\t</span>\n\t\t\t);\n\t\t}\n\n\t\tcase \"DATE\":\n\t\t\t// Parsed as a plain date rather than through the Date constructor's\n\t\t\t// timezone handling: \"2026-03-01\" must not display as February 28th\n\t\t\t// west of Greenwich.\n\t\t\treturn String(value).split(\"T\")[0];\n\n\t\tcase \"DATETIME\":\n\t\t\treturn new Date(String(value)).toLocaleString();\n\n\t\tcase \"SELECT\":\n\t\t\treturn <span className=\"b316-chip\">{String(value)}</span>;\n\n\t\tcase \"MULTISELECT\":\n\t\t\treturn (\n\t\t\t\t<span className=\"b316-chips\">\n\t\t\t\t\t{(Array.isArray(value) ? value : [value]).map((item) => (\n\t\t\t\t\t\t<span key={String(item)} className=\"b316-chip\">\n\t\t\t\t\t\t\t{String(item)}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t))}\n\t\t\t\t</span>\n\t\t\t);\n\n\t\tcase \"URL\":\n\t\t\treturn (\n\t\t\t\t<a href={String(value)} target=\"_blank\" rel=\"noreferrer noopener\">\n\t\t\t\t\t{String(value)}\n\t\t\t\t</a>\n\t\t\t);\n\n\t\tcase \"EMAIL\":\n\t\t\treturn <a href={`mailto:${String(value)}`}>{String(value)}</a>;\n\n\t\tcase \"PHONE\":\n\t\t\treturn <a href={`tel:${String(value)}`}>{String(value)}</a>;\n\n\t\tcase \"ADDRESS\":\n\t\t\treturn formatAddress(value as AddressValue);\n\n\t\tcase \"ATTACHMENT\": {\n\t\t\tconst files = Array.isArray(value) ? value : [value];\n\n\t\t\treturn `${files.length} file${files.length === 1 ? \"\" : \"s\"}`;\n\t\t}\n\n\t\tcase \"LONGTEXT\": {\n\t\t\tconst text = String(value);\n\n\t\t\t// Truncated in a cell, whole in the detail view. A paragraph in a table\n\t\t\t// row pushes every other column out of sight.\n\t\t\treturn text.length > 80 ? `${text.slice(0, 80)}…` : text;\n\t\t}\n\n\t\tcase \"JSON\":\n\t\t\treturn <code className=\"b316-muted\">{JSON.stringify(value).slice(0, 60)}</code>;\n\n\t\tdefault:\n\t\t\treturn String(value);\n\t}\n}\n\n/**\n * The input for one field.\n *\n * Returns null for a computed field: an AUTONUMBER, LOOKUP or ROLLUP is\n * produced by the server, and offering an input for one invites somebody to\n * type a value that will be silently discarded.\n */\nexport function FieldInput({ value, field, onChange, error, disabled }: InputProps): ReactNode {\n\tif (specFor(field).computed) {\n\t\treturn null;\n\t}\n\n\tconst id = `b316-field-${field.key}`;\n\tconst described = error ? `${id}-error` : undefined;\n\tconst common = {\n\t\tid,\n\t\tdisabled,\n\t\t\"aria-invalid\": error ? true : undefined,\n\t\t\"aria-describedby\": described,\n\t\tclassName: error ? \"b316-input b316-input-invalid\" : \"b316-input\",\n\t};\n\n\tfunction control(): ReactNode {\n\t\tswitch (field.type) {\n\t\t\tcase \"LONGTEXT\":\n\t\t\t\treturn (\n\t\t\t\t\t<textarea\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\trows={4}\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"BOOLEAN\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclassName=\"b316-checkbox\"\n\t\t\t\t\t\tchecked={Boolean(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.checked)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"SELECT\":\n\t\t\t\treturn (\n\t\t\t\t\t<select\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value === \"\" ? null : event.target.value)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{/* Present unless the field is required: without it there is no\n\t\t\t\t\t\t way to clear a choice once one has been made. */}\n\t\t\t\t\t\t{field.required ? null : <option value=\"\">—</option>}\n\t\t\t\t\t\t{(field.options ?? []).map((option) => (\n\t\t\t\t\t\t\t<option key={option} value={option}>\n\t\t\t\t\t\t\t\t{option}\n\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</select>\n\t\t\t\t);\n\n\t\t\tcase \"MULTISELECT\": {\n\t\t\t\tconst selected = new Set(Array.isArray(value) ? value.map(String) : []);\n\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"b316-choices\">\n\t\t\t\t\t\t{(field.options ?? []).map((option) => (\n\t\t\t\t\t\t\t<label key={option} className=\"b316-choice\">\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tchecked={selected.has(option)}\n\t\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\t\tconst next = new Set(selected);\n\n\t\t\t\t\t\t\t\t\t\tif (event.target.checked) {\n\t\t\t\t\t\t\t\t\t\t\tnext.add(option);\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tnext.delete(option);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tonChange([...next]);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{option}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"NUMBER\":\n\t\t\tcase \"MONEY\":\n\t\t\tcase \"PERCENT\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tstep={field.type === \"NUMBER\" ? 1 : 0.01}\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\t// Empty means cleared, not zero. Coercing \"\" to 0 writes a number\n\t\t\t\t\t\t// nobody typed.\n\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\tonChange(event.target.value === \"\" ? null : Number(event.target.value))\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"RATING\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tmin={0}\n\t\t\t\t\t\tmax={5}\n\t\t\t\t\t\tstep={1}\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\tonChange(event.target.value === \"\" ? null : Number(event.target.value))\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"DURATION\": {\n\t\t\t\t// Entered in minutes, stored in seconds. Asking for seconds is how a\n\t\t\t\t// timesheet ends up with someone typing 5400.\n\t\t\t\tconst minutes = value === null || value === undefined ? \"\" : String(Number(value) / 60);\n\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"b316-suffixed\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t{...common}\n\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\tmin={0}\n\t\t\t\t\t\t\tvalue={minutes}\n\t\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\t\tonChange(event.target.value === \"\" ? null : Number(event.target.value) * 60)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<span className=\"b316-muted\">minutes</span>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"DATE\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value).slice(0, 10)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value === \"\" ? null : event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"DATETIME\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"datetime-local\"\n\t\t\t\t\t\t// `datetime-local` will not accept an offset or trailing Z, and\n\t\t\t\t\t\t// silently shows nothing rather than complaining.\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value).slice(0, 16)}\n\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\tonChange(\n\t\t\t\t\t\t\t\tevent.target.value === \"\" ? null : new Date(event.target.value).toISOString(),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"ADDRESS\": {\n\t\t\t\tconst address = (value ?? {}) as AddressValue;\n\t\t\t\tconst part = (key: keyof AddressValue, label: string) => (\n\t\t\t\t\t<input\n\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tplaceholder={label}\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\tvalue={(address[key] as string) ?? \"\"}\n\t\t\t\t\t\tonChange={(event) => onChange({ ...address, [key]: event.target.value })}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"b316-address\">\n\t\t\t\t\t\t{part(\"line1\", \"Address line 1\")}\n\t\t\t\t\t\t{part(\"line2\", \"Address line 2\")}\n\t\t\t\t\t\t{part(\"city\", \"City\")}\n\t\t\t\t\t\t{part(\"region\", \"Region\")}\n\t\t\t\t\t\t{part(\"postalCode\", \"Postal code\")}\n\t\t\t\t\t\t{part(\"country\", \"Country\")}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"EMAIL\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"URL\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"url\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"PHONE\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"tel\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tdefault:\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className=\"b316-field\">\n\t\t\t<label className=\"b316-label\" htmlFor={id}>\n\t\t\t\t{field.label}\n\t\t\t\t{field.required ? <span aria-hidden=\"true\"> *</span> : null}\n\t\t\t</label>\n\t\t\t{control()}\n\t\t\t{field.description ? <div className=\"b316-hint\">{field.description}</div> : null}\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" id={described} role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { type FieldValue, specFor } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { FieldInput } from \"./fields\";\nimport { RelationPicker } from \"./RelationPicker\";\nimport { useCollection } from \"./useCollection\";\n\n/**\n * Creating or editing one record, with the form derived from the schema.\n *\n * Nobody writes the inputs. The field types decide which control each value\n * gets, which ones are required, and which are not editable at all — an\n * AUTONUMBER, a LOOKUP and a ROLLUP are produced by the server, so offering an\n * input for one would invite somebody to type a value that is discarded.\n *\n * <RecordForm collection=\"jobs\" /> // create\n * <RecordForm collection=\"jobs\" recordId={id} /> // edit\n *\n * Errors come back per field and land under the input that caused them.\n * Validation is not repeated here: the same `validateRecord` the server uses\n * would have to be kept in step, and a second implementation that drifts is\n * worse than one round trip.\n */\n\nexport interface RecordFormProps {\n\tcollection: string;\n\t/** Omit to create. */\n\trecordId?: string;\n\ttenant?: string;\n\tonSaved?: (id: string) => void;\n\tonCancel?: () => void;\n\t/** Start with these values filled in. Ignored when editing. */\n\tdefaults?: Record<string, FieldValue>;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function RecordForm({\n\tcollection,\n\trecordId,\n\ttenant,\n\tonSaved,\n\tonCancel,\n\tdefaults,\n\tclassName,\n\tstyle,\n}: RecordFormProps) {\n\tconst { schema, records, create, update, saving, fieldErrors, error } = useCollection(\n\t\tcollection,\n\t\t{\n\t\t\ttenant,\n\t\t\t// Fetched by id, not filtered for: `id` is not a schema field, so a filter\n\t\t\t// naming it is dropped and the form would quietly load the first page and\n\t\t\t// hope the record was on it.\n\t\t\trecordId,\n\t\t},\n\t);\n\n\tconst [values, setValues] = useState<Record<string, FieldValue>>(defaults ?? {});\n\tconst [loaded, setLoaded] = useState(!recordId);\n\n\tconst existing = recordId ? records.find((record) => record.id === recordId) : undefined;\n\n\t// Fill the form once, when the record arrives. Re-running would discard\n\t// whatever the person had typed since.\n\tuseEffect(() => {\n\t\tif (existing && !loaded) {\n\t\t\tsetValues(existing.fields);\n\t\t\tsetLoaded(true);\n\t\t}\n\t}, [existing, loaded]);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema || !loaded) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Computed fields have nothing to edit, so they are left out of the form\n\t// rather than rendered disabled — a row of greyed inputs is noise.\n\tconst editable = schema.fields.filter((field) => !specFor(field).computed);\n\n\tasync function submit(event: React.FormEvent) {\n\t\tevent.preventDefault();\n\n\t\tconst saved = recordId ? await update(recordId, values) : await create(values);\n\n\t\tif (saved) {\n\t\t\tonSaved?.(saved.id);\n\t\t}\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-card b316-form\", className)} style={style} onSubmit={submit}>\n\t\t\t<h3 className=\"b316-form-title\">\n\t\t\t\t{recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}`}\n\t\t\t</h3>\n\n\t\t\t{/* A failure with no field attached — a permission or a network problem.\n\t\t\t Without this the form just stops saving and says nothing. */}\n\t\t\t{fieldErrors._ ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{fieldErrors._}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{editable.map((field) =>\n\t\t\t\tfield.type === \"RELATION\" ? (\n\t\t\t\t\t<RelationPicker\n\t\t\t\t\t\tkey={field.key}\n\t\t\t\t\t\tfield={field}\n\t\t\t\t\t\ttenant={tenant}\n\t\t\t\t\t\tdisabled={saving}\n\t\t\t\t\t\terror={fieldErrors[field.key]}\n\t\t\t\t\t\tvalue={(values[field.key] as string | null) ?? null}\n\t\t\t\t\t\tonChange={(next) => setValues((current) => ({ ...current, [field.key]: next }))}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<FieldInput\n\t\t\t\t\t\tkey={field.key}\n\t\t\t\t\t\tfield={field}\n\t\t\t\t\t\tdisabled={saving}\n\t\t\t\t\t\terror={fieldErrors[field.key]}\n\t\t\t\t\t\tvalue={values[field.key] ?? null}\n\t\t\t\t\t\tonChange={(next) => setValues((current) => ({ ...current, [field.key]: next }))}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t)}\n\n\t\t\t<div className=\"b316-form-actions\">\n\t\t\t\t{onCancel ? (\n\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={onCancel} disabled={saving}>\n\t\t\t\t\t\tCancel\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={saving}>\n\t\t\t\t\t{saving ? \"Saving…\" : \"Save\"}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport type { FieldDescriptor } from \"@base316/sdk\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { useBase316 } from \"./provider\";\n\n/**\n * Choosing a record in another collection, by typing its name.\n *\n * The alternative is a text box holding an id, which nobody can fill in\n * without going to look one up — so a relation field without this is a\n * relation field nobody uses.\n *\n * Two fetches, and they answer different questions. The title of what is\n * already chosen has to be known before anybody types, or an existing record\n * opens showing an id. The search results are what typing produces. Conflating\n * them means an edit form that looks empty until the user searches for the\n * value it already has.\n */\n\nexport function RelationPicker({\n\tfield,\n\tvalue,\n\tonChange,\n\terror,\n\tdisabled,\n\ttenant,\n}: {\n\tfield: FieldDescriptor;\n\tvalue: string | null;\n\tonChange: (value: string | null) => void;\n\terror?: string | null;\n\tdisabled?: boolean;\n\ttenant?: string;\n}) {\n\tconst { client, token } = useBase316();\n\tconst [query, setQuery] = useState(\"\");\n\tconst [results, setResults] = useState<{ id: string; title: string | null }[]>([]);\n\tconst [chosenTitle, setChosenTitle] = useState<string | null>(null);\n\tconst [open, setOpen] = useState(false);\n\tconst id = `b316-field-${field.key}`;\n\tconst box = useRef<HTMLDivElement>(null);\n\n\t// What is already chosen, named. Runs on the id rather than on the query, so\n\t// an edit form shows \"Acme\" the moment it opens.\n\tuseEffect(() => {\n\t\tif (!token || !value || !field.relationTo) {\n\t\t\tsetChosenTitle(null);\n\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.collections\n\t\t\t.titles(token, field.relationTo, [value], tenant ? { tenant } : undefined)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetChosenTitle(result.titles[value] ?? null);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => null);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, value, field.relationTo, tenant]);\n\n\t// The search itself, debounced. Without the delay every keystroke is a\n\t// request, and the answers arrive out of order.\n\tuseEffect(() => {\n\t\tif (!token || !field.relationTo || !open) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\t\tconst timer = setTimeout(() => {\n\t\t\tclient.collections\n\t\t\t\t.list(\n\t\t\t\t\ttoken,\n\t\t\t\t\tfield.relationTo as string,\n\t\t\t\t\t{ search: query || undefined, limit: 10 },\n\t\t\t\t\ttenant ? { tenant } : undefined,\n\t\t\t\t)\n\t\t\t\t.then((page) => {\n\t\t\t\t\tif (!cancelled) {\n\t\t\t\t\t\tsetResults(page.data.map((record) => ({ id: record.id, title: record.title })));\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(() => {\n\t\t\t\t\tif (!cancelled) {\n\t\t\t\t\t\tsetResults([]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t}, 200);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t\tclearTimeout(timer);\n\t\t};\n\t}, [client, token, field.relationTo, query, open, tenant]);\n\n\t// Clicking away closes the list. Without this it stays open over whatever the\n\t// user moved on to.\n\tuseEffect(() => {\n\t\tif (!open || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst onDocumentClick = (event: MouseEvent) => {\n\t\t\tif (box.current && !box.current.contains(event.target as Node)) {\n\t\t\t\tsetOpen(false);\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener(\"mousedown\", onDocumentClick);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"mousedown\", onDocumentClick);\n\t\t};\n\t}, [open]);\n\n\treturn (\n\t\t<div className=\"b316-field\" ref={box}>\n\t\t\t<label className=\"b316-label\" htmlFor={id}>\n\t\t\t\t{field.label}\n\t\t\t\t{field.required ? <span aria-hidden=\"true\"> *</span> : null}\n\t\t\t</label>\n\n\t\t\t{value && !open ? (\n\t\t\t\t<div className=\"b316-relation-chosen\">\n\t\t\t\t\t{/* The id when the title did not resolve: the record was deleted, or\n\t\t\t\t\t belongs to a tenant this viewer cannot see. Showing nothing would\n\t\t\t\t\t look like the field was empty. */}\n\t\t\t\t\t<span>{chosenTitle ?? value}</span>\n\t\t\t\t\t{disabled ? null : (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tsetQuery(\"\");\n\t\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tChange\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t\t{disabled || field.required ? null : (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => onChange(null)}\n\t\t\t\t\t\t\taria-label={`Clear ${field.label}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tClear\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-expanded={open}\n\t\t\t\t\t\taria-controls={`${id}-results`}\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tclassName={error ? \"b316-input b316-input-invalid\" : \"b316-input\"}\n\t\t\t\t\t\tplaceholder={`Search ${field.label.toLowerCase()}`}\n\t\t\t\t\t\tvalue={query}\n\t\t\t\t\t\tonFocus={() => setOpen(true)}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tsetQuery(event.target.value);\n\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{open ? (\n\t\t\t\t\t\t<ul className=\"b316-relation-results\" id={`${id}-results`} role=\"listbox\">\n\t\t\t\t\t\t\t{results.length === 0 ? (\n\t\t\t\t\t\t\t\t<li className=\"b316-muted b316-relation-empty\">No matches</li>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tresults.map((result) => (\n\t\t\t\t\t\t\t\t\t<li key={result.id}>\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\t\t\taria-selected={result.id === value}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-relation-result\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tonChange(result.id);\n\t\t\t\t\t\t\t\t\t\t\t\tsetChosenTitle(result.title);\n\t\t\t\t\t\t\t\t\t\t\t\tsetOpen(false);\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{result.title ?? result.id}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t)}\n\n\t\t\t{field.description ? <div className=\"b316-hint\">{field.description}</div> : null}\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type {\n\tCollectionRecord,\n\tCollectionSchema,\n\tFieldValue,\n\tRecordFilterInput,\n} from \"@base316/sdk\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { useBase316 } from \"./provider\";\n\n/**\n * One collection: its shape, its rows, and how to change them.\n *\n * The headless half of every data component. `DataTable`, `RecordForm` and\n * `RecordDetail` are markup over this, and an application with its own design\n * system calls it directly and writes its own — which is the escape hatch that\n * stops a component library from being forked the first time somebody wants a\n * different table.\n *\n * What it does that is worth not rewriting:\n *\n * - loads the schema before the rows, because nothing can render a column\n * without knowing the field types;\n * - keeps filters, sort, search and paging in one place, so they compose\n * instead of fighting;\n * - refetches after a write, so a saved row appears where it belongs rather\n * than where it was;\n * - keeps per-field errors from the server, so a form can put each message\n * under the input that caused it.\n */\n\nexport interface UseCollectionOptions {\n\t/** Applied on top of whatever the UI sets. For a fixed view of one tenant's data. */\n\tfilters?: RecordFilterInput[];\n\tsort?: { field: string; direction?: \"asc\" | \"desc\" };\n\tlimit?: number;\n\t/**\n\t * Load one record instead of a page.\n\t *\n\t * Fetched by id rather than filtered for. `id` is not a schema field, so a\n\t * filter naming it is dropped on the server and the caller quietly gets the\n\t * first page instead — which works until the record is not on it.\n\t */\n\trecordId?: string;\n\t/**\n\t * Which tenant to read and write as.\n\t *\n\t * Only needed when somebody belongs to several organizations. A user in one\n\t * is scoped to it automatically.\n\t */\n\ttenant?: string;\n}\n\nexport interface UseCollectionResult {\n\t/** Null until loaded. */\n\tschema: CollectionSchema | null;\n\trecords: CollectionRecord[];\n\tloading: boolean;\n\t/** Set when the collection could not be read at all — missing, or forbidden. */\n\terror: string | null;\n\t/** Total matching rows, for \"1–25 of 340\". */\n\ttotal: number;\n\t/** Whether a further page exists. */\n\thasMore: boolean;\n\t/** Whether this viewer may create, edit and delete. False until the schema loads. */\n\tcanWrite: boolean;\n\n\tsearch: string;\n\tsetSearch: (search: string) => void;\n\tfilters: RecordFilterInput[];\n\tsetFilters: (filters: RecordFilterInput[]) => void;\n\tsort: { field: string; direction?: \"asc\" | \"desc\" } | null;\n\t/** Ascending, then descending, then off — the order a table header cycles. */\n\ttoggleSort: (field: string) => void;\n\n\tloadMore: () => void;\n\treload: () => void;\n\n\t/** Per-field messages from the last rejected write. */\n\tfieldErrors: Record<string, string>;\n\tsaving: boolean;\n\tcreate: (fields: Record<string, FieldValue>) => Promise<CollectionRecord | null>;\n\tupdate: (id: string, fields: Record<string, FieldValue>) => Promise<CollectionRecord | null>;\n\tremove: (id: string) => Promise<boolean>;\n}\n\n/** Pull the per-field messages out of a rejected write. */\nfunction fieldErrorFrom(cause: unknown): Record<string, string> {\n\tconst param = (cause as { param?: string | null })?.param;\n\tconst message = cause instanceof Error ? cause.message : \"That value was not accepted.\";\n\n\t// The API names one offending field at a time. Keyed anyway, so a form puts\n\t// the message under the right input rather than in a banner above them all.\n\treturn param ? { [param]: message } : { _: message };\n}\n\nexport function useCollection(\n\tcollection: string,\n\toptions: UseCollectionOptions = {},\n): UseCollectionResult {\n\tconst { client, token } = useBase316();\n\n\tconst [schema, setSchema] = useState<CollectionSchema | null>(null);\n\tconst [records, setRecords] = useState<CollectionRecord[]>([]);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [loading, setLoading] = useState(true);\n\tconst [total, setTotal] = useState(0);\n\tconst [cursor, setCursor] = useState<string | null>(null);\n\tconst [reloadCount, setReloadCount] = useState(0);\n\n\tconst [search, setSearch] = useState(\"\");\n\tconst [filters, setFilters] = useState<RecordFilterInput[]>([]);\n\tconst [sort, setSort] = useState<{ field: string; direction?: \"asc\" | \"desc\" } | null>(\n\t\toptions.sort ?? null,\n\t);\n\n\tconst [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n\tconst [saving, setSaving] = useState(false);\n\n\tconst { tenant, limit, recordId } = options;\n\t// Serialised, so a caller passing a fresh array literal every render does not\n\t// restart the query on every render.\n\tconst fixedFilters = JSON.stringify(options.filters ?? []);\n\n\tconst scope = useMemo(() => (tenant ? { tenant } : undefined), [tenant]);\n\n\t// --- The schema, first ----------------------------------------------------\n\n\tuseEffect(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.collections\n\t\t\t.schema(token, collection, scope)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetSchema(result);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\t// Fatal, unlike a failed row fetch: without the field types there is\n\t\t\t\t\t// nothing to render, not even an empty table with headings.\n\t\t\t\t\tsetError(cause instanceof Error ? cause.message : \"This collection is unavailable.\");\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, collection, scope]);\n\n\t// --- Then the rows --------------------------------------------------------\n\n\tuseEffect(() => {\n\t\tif (!token || !schema) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tsetLoading(true);\n\n\t\tif (recordId) {\n\t\t\tclient.collections\n\t\t\t\t.get(token, collection, recordId, scope)\n\t\t\t\t.then((record) => {\n\t\t\t\t\tif (cancelled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tsetRecords([record]);\n\t\t\t\t\tsetCursor(null);\n\t\t\t\t\tsetTotal(1);\n\t\t\t\t\tsetError(null);\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t})\n\t\t\t\t.catch((cause) => {\n\t\t\t\t\tif (!cancelled) {\n\t\t\t\t\t\t// Not found covers another tenant's record too, which is the point:\n\t\t\t\t\t\t// an id belonging to somebody else is indistinguishable from one\n\t\t\t\t\t\t// belonging to nobody.\n\t\t\t\t\t\tsetRecords([]);\n\t\t\t\t\t\tsetTotal(0);\n\t\t\t\t\t\tsetError(cause instanceof Error ? cause.message : \"That record is not available.\");\n\t\t\t\t\t\tsetLoading(false);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tcancelled = true;\n\t\t\t};\n\t\t}\n\n\t\tclient.collections\n\t\t\t.list(\n\t\t\t\ttoken,\n\t\t\t\tcollection,\n\t\t\t\t{\n\t\t\t\t\tfilters: [...(JSON.parse(fixedFilters) as RecordFilterInput[]), ...filters],\n\t\t\t\t\tsearch: search || undefined,\n\t\t\t\t\tsort: sort ?? undefined,\n\t\t\t\t\tlimit,\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t)\n\t\t\t.then((page) => {\n\t\t\t\tif (cancelled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Replaces rather than appends: this effect runs when the query\n\t\t\t\t// changed, and appending would stack the old filter's rows under the\n\t\t\t\t// new one's. `loadMore` is what appends.\n\t\t\t\tsetRecords(page.data);\n\t\t\t\tsetCursor(page.cursor);\n\t\t\t\tsetTotal(page.total);\n\t\t\t\tsetError(null);\n\t\t\t\tsetLoading(false);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not load these records.\");\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [\n\t\tclient,\n\t\ttoken,\n\t\tcollection,\n\t\tschema,\n\t\trecordId,\n\t\tfixedFilters,\n\t\tfilters,\n\t\tsearch,\n\t\tsort,\n\t\tlimit,\n\t\tscope,\n\t\treloadCount,\n\t]);\n\n\tconst reload = useCallback(() => {\n\t\tsetReloadCount((count) => count + 1);\n\t}, []);\n\n\tconst loadMore = useCallback(() => {\n\t\tif (!token || !cursor) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetLoading(true);\n\n\t\tclient.collections\n\t\t\t.list(\n\t\t\t\ttoken,\n\t\t\t\tcollection,\n\t\t\t\t{\n\t\t\t\t\tfilters: [...(JSON.parse(fixedFilters) as RecordFilterInput[]), ...filters],\n\t\t\t\t\tsearch: search || undefined,\n\t\t\t\t\tsort: sort ?? undefined,\n\t\t\t\t\tlimit,\n\t\t\t\t\tcursor,\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t)\n\t\t\t.then((page) => {\n\t\t\t\tsetRecords((existing) => [...existing, ...page.data]);\n\t\t\t\tsetCursor(page.cursor);\n\t\t\t\tsetLoading(false);\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tsetLoading(false);\n\t\t\t});\n\t}, [client, token, collection, cursor, fixedFilters, filters, search, sort, limit, scope]);\n\n\tconst toggleSort = useCallback((field: string) => {\n\t\tsetSort((current) => {\n\t\t\tif (current?.field !== field) {\n\t\t\t\treturn { field, direction: \"asc\" };\n\t\t\t}\n\n\t\t\t// Third press clears it rather than sticking on descending, so there is\n\t\t\t// a way back to the collection's own order.\n\t\t\treturn current.direction === \"asc\" ? { field, direction: \"desc\" } : null;\n\t\t});\n\t}, []);\n\n\t// --- Writing --------------------------------------------------------------\n\n\tconst create = useCallback(\n\t\tasync (fields: Record<string, FieldValue>) => {\n\t\t\tif (!token) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tsetSaving(true);\n\t\t\tsetFieldErrors({});\n\n\t\t\ttry {\n\t\t\t\tconst record = await client.collections.create(token, collection, fields, scope);\n\n\t\t\t\t// Refetched rather than pushed onto the list: the new row belongs\n\t\t\t\t// wherever the current sort and filters put it, which is not\n\t\t\t\t// necessarily at the top and may be on another page entirely.\n\t\t\t\treload();\n\n\t\t\t\treturn record;\n\t\t\t} catch (cause) {\n\t\t\t\tsetFieldErrors(fieldErrorFrom(cause));\n\n\t\t\t\treturn null;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t},\n\t\t[client, token, collection, scope, reload],\n\t);\n\n\tconst update = useCallback(\n\t\tasync (id: string, fields: Record<string, FieldValue>) => {\n\t\t\tif (!token) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tsetSaving(true);\n\t\t\tsetFieldErrors({});\n\n\t\t\ttry {\n\t\t\t\tconst record = await client.collections.update(token, collection, id, fields, scope);\n\n\t\t\t\t// Replaced in place: an edit that did not move the row should not\n\t\t\t\t// cost a round trip for everything else on the page.\n\t\t\t\tsetRecords((existing) =>\n\t\t\t\t\texisting.map((candidate) => (candidate.id === id ? record : candidate)),\n\t\t\t\t);\n\n\t\t\t\treturn record;\n\t\t\t} catch (cause) {\n\t\t\t\tsetFieldErrors(fieldErrorFrom(cause));\n\n\t\t\t\treturn null;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t},\n\t\t[client, token, collection, scope],\n\t);\n\n\tconst remove = useCallback(\n\t\tasync (id: string) => {\n\t\t\tif (!token) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tsetSaving(true);\n\n\t\t\ttry {\n\t\t\t\tawait client.collections.remove(token, collection, id, scope);\n\n\t\t\t\tsetRecords((existing) => existing.filter((candidate) => candidate.id !== id));\n\t\t\t\tsetTotal((count) => Math.max(0, count - 1));\n\n\t\t\t\treturn true;\n\t\t\t} catch (cause) {\n\t\t\t\tsetFieldErrors(fieldErrorFrom(cause));\n\n\t\t\t\treturn false;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t},\n\t\t[client, token, collection, scope],\n\t);\n\n\treturn {\n\t\tschema,\n\t\trecords,\n\t\tloading,\n\t\terror,\n\t\ttotal,\n\t\thasMore: cursor !== null,\n\t\tcanWrite: schema?.canWrite ?? false,\n\t\tsearch,\n\t\tsetSearch,\n\t\tfilters,\n\t\tsetFilters,\n\t\tsort,\n\t\ttoggleSort,\n\t\tloadMore,\n\t\treload,\n\t\tfieldErrors,\n\t\tsaving,\n\t\tcreate,\n\t\tupdate,\n\t\tremove,\n\t};\n}\n","\"use client\";\n\nimport {\n\ttype CollectionRecord,\n\ttype FieldDescriptor,\n\tdefaultGroupFieldOf,\n\tspecFor,\n\ttitleFieldOf,\n} from \"@base316/sdk\";\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { FieldCell } from \"./fields\";\nimport { useCollection, type UseCollectionOptions } from \"./useCollection\";\n\n/**\n * A board, over a collection that was never designed to have one.\n *\n * This component is the proof of the whole design. It was written after the\n * schema and the table, it knows nothing about jobs or tickets or deals, and it\n * asks the schema one question:\n *\n * defaultGroupFieldOf(schema.fields) // \"which field makes columns?\"\n *\n * The registry answers with the SELECT field, because a status or a stage is\n * what somebody means by grouping — and so `<Kanban collection=\"jobs\" />`\n * works with no props at all. Had fields been described in rendering terms\n * (\"this column is right-aligned\"), there would have been nothing here to ask,\n * and every board would need its own configuration naming its own columns.\n *\n * Moving a card writes the grouping field. That is the only mutation a board\n * makes, and it is why the field has to be one with a fixed set of values: a\n * column header has to be a value somebody can drop onto.\n */\n\nexport interface KanbanProps extends UseCollectionOptions {\n\tcollection: string;\n\t/**\n\t * Which field makes the columns.\n\t *\n\t * Discovered when omitted. Name it when a collection has several groupable\n\t * fields and the first choice is not the one this board is about.\n\t */\n\tgroupBy?: string;\n\t/** Fields to show on a card, in order. Defaults to the title and the next two. */\n\tcardFields?: string[];\n\tonSelect?: (record: CollectionRecord) => void;\n\temptyState?: ReactNode;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function Kanban({\n\tcollection,\n\tgroupBy,\n\tcardFields,\n\tonSelect,\n\temptyState,\n\tclassName,\n\tstyle,\n\t...options\n}: KanbanProps) {\n\tconst { schema, records, loading, error, canWrite, update, total, hasMore, loadMore } =\n\t\tuseCollection(collection, {\n\t\t\t// A board shows everything at once by its nature — a column holding the\n\t\t\t// first twenty-five of two hundred is misleading rather than partial.\n\t\t\tlimit: options.limit ?? 100,\n\t\t\t...options,\n\t\t});\n\n\tconst [dragging, setDragging] = useState<string | null>(null);\n\tconst [over, setOver] = useState<string | null>(null);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst field = groupBy\n\t\t? (schema.fields.find((candidate) => candidate.key === groupBy) ?? null)\n\t\t: defaultGroupFieldOf(schema.fields);\n\n\t// Said plainly rather than rendered as one empty column. A board over a\n\t// collection with nothing to group by is a mistake in the schema or in the\n\t// choice of component, and both are worth naming.\n\tif (!field || !specFor(field).capabilities.groupable) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{groupBy\n\t\t\t\t\t? `\"${groupBy}\" cannot make columns. A board groups by a choice, a yes/no or a date.`\n\t\t\t\t\t: `${schema.namePlural} have no field to group by. Add a choice field — a status or a stage — and this board will use it.`}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst columns = columnsFor(field);\n\tconst shown = cardFields\n\t\t? cardFields\n\t\t\t\t.map((key) => schema.fields.find((candidate) => candidate.key === key))\n\t\t\t\t.filter((candidate): candidate is FieldDescriptor => Boolean(candidate))\n\t\t: // The first few fields that are neither the grouping one nor the title.\n\t\t\t// The grouping field is already the column heading and the title is\n\t\t\t// already the card heading, so both would be printed twice on every card.\n\t\t\tschema.fields\n\t\t\t\t.filter(\n\t\t\t\t\t(candidate) =>\n\t\t\t\t\t\tcandidate.key !== field.key && candidate.key !== titleFieldOf(schema.fields)?.key,\n\t\t\t\t)\n\t\t\t\t.slice(0, 3);\n\n\tasync function move(record: CollectionRecord, value: string | boolean | null) {\n\t\tif (!canWrite || record.fields[field!.key] === value) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait update(record.id, { [field!.key]: value });\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-board-wrap\", className)} style={style}>\n\t\t\t<div className=\"b316-board\" role=\"list\">\n\t\t\t\t{columns.map((column) => {\n\t\t\t\t\tconst inColumn = records.filter(\n\t\t\t\t\t\t(record) => String(record.fields[field.key] ?? \"\") === String(column.value ?? \"\"),\n\t\t\t\t\t);\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<section\n\t\t\t\t\t\t\tkey={String(column.value)}\n\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\tover === String(column.value)\n\t\t\t\t\t\t\t\t\t? \"b316-board-column b316-board-over\"\n\t\t\t\t\t\t\t\t\t: \"b316-board-column\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trole=\"listitem\"\n\t\t\t\t\t\t\taria-label={column.label}\n\t\t\t\t\t\t\tonDragOver={(event) => {\n\t\t\t\t\t\t\t\tif (!canWrite || !dragging) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Without this the drop never fires: the default is to refuse.\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tsetOver(String(column.value));\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonDragLeave={() => setOver(null)}\n\t\t\t\t\t\t\tonDrop={(event) => {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tsetOver(null);\n\n\t\t\t\t\t\t\t\tconst record = records.find((candidate) => candidate.id === dragging);\n\n\t\t\t\t\t\t\t\tif (record) {\n\t\t\t\t\t\t\t\t\tvoid move(record, column.value);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsetDragging(null);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<header className=\"b316-board-head\">\n\t\t\t\t\t\t\t\t<span className=\"b316-board-title\">{column.label}</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">{inColumn.length}</span>\n\t\t\t\t\t\t\t</header>\n\n\t\t\t\t\t\t\t<div className=\"b316-board-cards\">\n\t\t\t\t\t\t\t\t{inColumn.map((record) => (\n\t\t\t\t\t\t\t\t\t<article\n\t\t\t\t\t\t\t\t\t\tkey={record.id}\n\t\t\t\t\t\t\t\t\t\tclassName=\"b316-board-card\"\n\t\t\t\t\t\t\t\t\t\tdraggable={canWrite}\n\t\t\t\t\t\t\t\t\t\tonDragStart={() => setDragging(record.id)}\n\t\t\t\t\t\t\t\t\t\tonDragEnd={() => {\n\t\t\t\t\t\t\t\t\t\t\tsetDragging(null);\n\t\t\t\t\t\t\t\t\t\t\tsetOver(null);\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tonClick={onSelect ? () => onSelect(record) : undefined}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<div className=\"b316-board-card-title\">{record.title ?? \"Untitled\"}</div>\n\n\t\t\t\t\t\t\t\t\t\t{shown.map((candidate) => (\n\t\t\t\t\t\t\t\t\t\t\t<div key={candidate.key} className=\"b316-board-card-field\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"b316-muted\">{candidate.label}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<FieldCell\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue={record.fields[candidate.key] ?? null}\n\t\t\t\t\t\t\t\t\t\t\t\t\tfield={candidate}\n\t\t\t\t\t\t\t\t\t\t\t\t\trelated={record.related[candidate.key]}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t\t\t\t\t{canWrite ? (\n\t\t\t\t\t\t\t\t\t\t\t// Dragging is not reachable by keyboard and is awkward on a\n\t\t\t\t\t\t\t\t\t\t\t// phone. This is the same action by other means, not a\n\t\t\t\t\t\t\t\t\t\t\t// lesser fallback.\n\t\t\t\t\t\t\t\t\t\t\t<label className=\"b316-board-move\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Move to</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<select\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue={String(record.fields[field.key] ?? \"\")}\n\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => event.stopPropagation()}\n\t\t\t\t\t\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst chosen = columns.find(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(candidate) => String(candidate.value) === event.target.value,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvoid move(record, chosen?.value ?? null);\n\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{columns.map((candidate) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<option key={String(candidate.value)} value={String(candidate.value)}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{candidate.label}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t</article>\n\t\t\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t\t\t{inColumn.length === 0 ? (\n\t\t\t\t\t\t\t\t\t<div className=\"b316-board-empty\">{emptyState ?? \"Nothing here\"}</div>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</section>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\n\t\t\t{hasMore ? (\n\t\t\t\t<div className=\"b316-table-more\">\n\t\t\t\t\t{/* Named, because a board silently showing a hundred of two hundred\n\t\t\t\t\t cards is worse than a table doing the same: the columns look\n\t\t\t\t\t complete. */}\n\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={loadMore} disabled={loading}>\n\t\t\t\t\t\tShowing {records.length} of {total} — load more\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\n/**\n * The columns a field makes.\n *\n * A SELECT has its options. A BOOLEAN has two. A date does not have a fixed\n * set, which is why the registry marks it groupable for a chart but a board\n * over one would invent a column per day.\n */\nfunction columnsFor(field: FieldDescriptor): { value: string | boolean | null; label: string }[] {\n\tif (field.type === \"BOOLEAN\") {\n\t\treturn [\n\t\t\t{ value: true, label: \"Yes\" },\n\t\t\t{ value: false, label: \"No\" },\n\t\t];\n\t}\n\n\tconst options = (field.options ?? []).map((option) => ({ value: option, label: option }));\n\n\t// A column for records with no value, so nothing is invisible. A card that\n\t// exists but appears nowhere is the worst thing a board can do.\n\treturn [...options, { value: null, label: \"None\" }];\n}\n","\"use client\";\n\nimport {\n\ttype AggregateKind,\n\ttype FieldDescriptor,\n\tfieldsAggregatableBy,\n\tfieldsFor,\n\tspecFor,\n} from \"@base316/sdk\";\nimport { useMemo, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useCollection, type UseCollectionOptions } from \"./useCollection\";\n\n/**\n * A chart, over a collection that was never designed to have one.\n *\n * The second proof, and it asks the schema different questions from the board:\n *\n * fieldsFor(fields, \"timeAxis\") // \"what can be an x-axis?\"\n * fieldsAggregatableBy(fields, \"sum\") // \"what can be added up?\"\n *\n * Neither question mentions a field type, and this file names none. That is the\n * point: the board found a SELECT, this finds a date and a number, and both did\n * it by describing what they needed rather than by being configured.\n *\n * Drawn as SVG rather than with a charting library. Artifacts and customer\n * pages both restrict which scripts may load, a charting dependency is larger\n * than everything else in this package put together, and bars with a baseline\n * are not the hard part of charting.\n */\n\nexport interface ChartProps extends UseCollectionOptions {\n\tcollection: string;\n\t/** The date field along the bottom. Discovered when omitted. */\n\tx?: string;\n\t/**\n\t * What to measure.\n\t *\n\t * Omitted means count the records, which is the question that always has an\n\t * answer: a collection may have no numeric field, but it always has rows.\n\t */\n\ty?: string;\n\t/** How to combine. Ignored when counting. */\n\taggregate?: Exclude<AggregateKind, \"count\">;\n\t/** How wide a bar is in time. */\n\tbucket?: \"day\" | \"week\" | \"month\";\n\ttitle?: string;\n\theight?: number;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\ninterface Bucket {\n\tkey: string;\n\tlabel: string;\n\tvalue: number;\n}\n\nexport function Chart({\n\tcollection,\n\tx,\n\ty,\n\taggregate = \"sum\",\n\tbucket = \"day\",\n\ttitle,\n\theight = 220,\n\tclassName,\n\tstyle,\n\t...options\n}: ChartProps) {\n\tconst { schema, records, error, loading } = useCollection(collection, {\n\t\t// A chart of one page is a chart of an arbitrary subset, which is worse\n\t\t// than no chart: it looks like an answer.\n\t\tlimit: options.limit ?? 200,\n\t\t...options,\n\t});\n\n\tconst axis = useMemo(() => {\n\t\tif (!schema) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst timeFields = fieldsFor(schema.fields, \"timeAxis\");\n\t\tconst chosen = x\n\t\t\t? (schema.fields.find((field) => field.key === x) ?? null)\n\t\t\t: (timeFields[0] ?? null);\n\n\t\treturn chosen && specFor(chosen).capabilities.timeAxis ? chosen : null;\n\t}, [schema, x]);\n\n\tconst measure = useMemo(() => {\n\t\tif (!schema || !y) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst candidates = fieldsAggregatableBy(schema.fields, aggregate);\n\n\t\treturn candidates.find((field) => field.key === y) ?? null;\n\t}, [schema, y, aggregate]);\n\n\tconst buckets = useMemo(\n\t\t() => (axis ? bucketise(records, axis, measure, y ? aggregate : \"count\", bucket) : []),\n\t\t[records, axis, measure, aggregate, bucket, y],\n\t);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema || loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!axis) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{x\n\t\t\t\t\t? `\"${x}\" is not a date, so it cannot be a time axis.`\n\t\t\t\t\t: `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.`}\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Named rather than silently counting instead: a chart labelled \"total value\"\n\t// that is quietly showing a row count is a wrong answer presented confidently.\n\tif (y && !measure) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{`\"${y}\" cannot be ${aggregate === \"avg\" ? \"averaged\" : `combined with ${aggregate}`}.`}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst peak = Math.max(...buckets.map((entry) => entry.value), 0);\n\tconst heading =\n\t\ttitle ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;\n\n\treturn (\n\t\t<figure className={cls(\"b316-card b316-chart\", className)} style={style}>\n\t\t\t<figcaption className=\"b316-chart-title\">{heading}</figcaption>\n\n\t\t\t{buckets.length === 0 || peak === 0 ? (\n\t\t\t\t<div className=\"b316-empty\">Nothing to chart yet.</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-chart-plot\" style={{ height }}>\n\t\t\t\t\t{buckets.map((entry) => (\n\t\t\t\t\t\t<div className=\"b316-chart-col\" key={entry.key}>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"b316-chart-bar\"\n\t\t\t\t\t\t\t\t// A minimum height so a small non-zero value is still visible:\n\t\t\t\t\t\t\t\t// a bar of one pixel reads as nothing at all.\n\t\t\t\t\t\t\t\tstyle={{ height: `${Math.max(2, (entry.value / peak) * 100)}%` }}\n\t\t\t\t\t\t\t\ttitle={`${entry.label}: ${format(entry.value)}`}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span className=\"b316-chart-label\">{entry.label}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* The table is not decoration. An SVG of bars is unreadable to a screen\n\t\t\t reader and unusable to anybody who needs the numbers, and the data is\n\t\t\t already here. */}\n\t\t\t<details className=\"b316-chart-data\">\n\t\t\t\t<summary>Values</summary>\n\t\t\t\t<table className=\"b316-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th scope=\"col\">{axis.label}</th>\n\t\t\t\t\t\t\t<th scope=\"col\">{measure ? measure.label : \"Count\"}</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{buckets.map((entry) => (\n\t\t\t\t\t\t\t<tr key={entry.key}>\n\t\t\t\t\t\t\t\t<td>{entry.label}</td>\n\t\t\t\t\t\t\t\t<td>{format(entry.value)}</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t</details>\n\t\t</figure>\n\t);\n}\n\nfunction format(value: number): string {\n\treturn new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(value);\n}\n\n/** The bucket a date falls in, as a sortable key. */\nfunction keyFor(date: Date, bucket: \"day\" | \"week\" | \"month\"): string {\n\tif (bucket === \"month\") {\n\t\treturn `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, \"0\")}`;\n\t}\n\n\tif (bucket === \"week\") {\n\t\t// Monday of that week. Sunday is day 0, which would otherwise start the\n\t\t// week on the day most people consider its end.\n\t\tconst monday = new Date(date);\n\t\tconst offset = (date.getUTCDay() + 6) % 7;\n\n\t\tmonday.setUTCDate(date.getUTCDate() - offset);\n\n\t\treturn monday.toISOString().slice(0, 10);\n\t}\n\n\treturn date.toISOString().slice(0, 10);\n}\n\nfunction bucketise(\n\trecords: readonly { fields: Record<string, unknown> }[],\n\taxis: FieldDescriptor,\n\tmeasure: FieldDescriptor | null,\n\taggregate: AggregateKind,\n\tbucket: \"day\" | \"week\" | \"month\",\n): Bucket[] {\n\tconst groups = new Map<string, number[]>();\n\n\tfor (const record of records) {\n\t\tconst raw = record.fields[axis.key];\n\n\t\tif (raw === null || raw === undefined || raw === \"\") {\n\t\t\t// A record with no date has no place on a time axis. Dropped rather than\n\t\t\t// bucketed under today, which would invent a spike that is not there.\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst date = new Date(String(raw));\n\n\t\tif (Number.isNaN(date.getTime())) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst key = keyFor(date, bucket);\n\t\tconst value = measure ? Number(record.fields[measure.key]) : 1;\n\n\t\tgroups.set(key, [...(groups.get(key) ?? []), Number.isFinite(value) ? value : 0]);\n\t}\n\n\treturn (\n\t\t[...groups.entries()]\n\t\t\t// Keys are ISO, so lexical order is chronological order.\n\t\t\t.sort(([left], [right]) => left.localeCompare(right))\n\t\t\t.map(([key, values]) => ({\n\t\t\t\tkey,\n\t\t\t\tlabel: key,\n\t\t\t\tvalue: combine(values, aggregate),\n\t\t\t}))\n\t);\n}\n\nfunction combine(values: number[], aggregate: AggregateKind): number {\n\tswitch (aggregate) {\n\t\tcase \"count\":\n\t\t\treturn values.length;\n\t\tcase \"avg\":\n\t\t\treturn values.length === 0\n\t\t\t\t? 0\n\t\t\t\t: values.reduce((total, value) => total + value, 0) / values.length;\n\t\tcase \"min\":\n\t\t\treturn values.length === 0 ? 0 : Math.min(...values);\n\t\tcase \"max\":\n\t\t\treturn values.length === 0 ? 0 : Math.max(...values);\n\t\tdefault:\n\t\t\treturn values.reduce((total, value) => total + value, 0);\n\t}\n}\n","\"use client\";\n\nimport { specFor } from \"@base316/sdk\";\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { FieldCell } from \"./fields\";\nimport { RecordForm } from \"./RecordForm\";\nimport { useCollection } from \"./useCollection\";\n\n/**\n * One record, read.\n *\n * The other half of a table: a row shows what fits in a column, and this shows\n * everything — including the fields a table deliberately truncates, like a\n * paragraph of notes, and the derived ones a form leaves out because they\n * cannot be typed.\n *\n * <RecordDetail collection=\"jobs\" recordId={id} />\n *\n * Edit is offered only when the viewer may write, which the schema already\n * says. There is no second permission check here and there should not be: the\n * server decides, and a component that decided for itself would eventually\n * disagree with it.\n */\n\nexport interface RecordDetailProps {\n\tcollection: string;\n\trecordId: string;\n\ttenant?: string;\n\t/** Hide Edit and Delete even for a viewer who may write. */\n\treadOnly?: boolean;\n\tonDeleted?: () => void;\n\tonClose?: () => void;\n\t/** Rendered under the fields — related lists, actions, anything. */\n\tchildren?: ReactNode;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function RecordDetail({\n\tcollection,\n\trecordId,\n\ttenant,\n\treadOnly,\n\tonDeleted,\n\tonClose,\n\tchildren,\n\tclassName,\n\tstyle,\n}: RecordDetailProps) {\n\tconst { schema, records, canWrite, remove, loading, error } = useCollection(collection, {\n\t\ttenant,\n\t\trecordId,\n\t});\n\n\tconst [editing, setEditing] = useState(false);\n\tconst record = records.find((candidate) => candidate.id === recordId);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema || loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!record) {\n\t\t// Also what another tenant's record looks like: not found rather than\n\t\t// forbidden, because an id belonging to somebody else is indistinguishable\n\t\t// from one belonging to nobody.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tThat {schema.name.toLowerCase()} is not available.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (editing) {\n\t\treturn (\n\t\t\t<RecordForm\n\t\t\t\tcollection={collection}\n\t\t\t\trecordId={recordId}\n\t\t\t\ttenant={tenant}\n\t\t\t\tclassName={className}\n\t\t\t\tstyle={style}\n\t\t\t\tonSaved={() => setEditing(false)}\n\t\t\t\tonCancel={() => setEditing(false)}\n\t\t\t/>\n\t\t);\n\t}\n\n\tconst writable = canWrite && !readOnly;\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-detail\", className)} style={style}>\n\t\t\t<div className=\"b316-detail-head\">\n\t\t\t\t<h3 className=\"b316-detail-title\">\n\t\t\t\t\t{/* The title field, or the type. A heading reading `rec_01J…` tells\n\t\t\t\t\t somebody looking at a record nothing about it. */}\n\t\t\t\t\t{record.title ?? schema.name}\n\t\t\t\t</h3>\n\n\t\t\t\t<div className=\"b316-detail-actions\">\n\t\t\t\t\t{writable ? (\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={() => setEditing(true)}>\n\t\t\t\t\t\t\tEdit\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{writable ? (\n\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\t\tconfirmLabel={`Delete ${record.title ?? \"this record\"} for good`}\n\t\t\t\t\t\t\tonConfirm={async () => {\n\t\t\t\t\t\t\t\tif (await remove(recordId)) {\n\t\t\t\t\t\t\t\t\tonDeleted?.();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{onClose ? (\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={onClose}>\n\t\t\t\t\t\t\tClose\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<dl className=\"b316-detail-fields\">\n\t\t\t\t{schema.fields.map((field) => (\n\t\t\t\t\t<div className=\"b316-detail-row\" key={field.key}>\n\t\t\t\t\t\t<dt className=\"b316-label\">\n\t\t\t\t\t\t\t{field.label}\n\t\t\t\t\t\t\t{/* Named as computed, because a reader who cannot find it in the\n\t\t\t\t\t\t\t edit form should know why rather than assume it is broken. */}\n\t\t\t\t\t\t\t{specFor(field).computed ? <span className=\"b316-muted\"> (calculated)</span> : null}\n\t\t\t\t\t\t</dt>\n\t\t\t\t\t\t<dd>\n\t\t\t\t\t\t\t<FieldCell\n\t\t\t\t\t\t\t\tvalue={record.fields[field.key] ?? null}\n\t\t\t\t\t\t\t\tfield={field}\n\t\t\t\t\t\t\t\trelated={record.related[field.key]}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</dd>\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</dl>\n\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { BillingSubscription, SubscriptionPhase } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { useBase316 } from \"./provider\";\n\nfunction statusLabel(status: string): string {\n\tconst words = status.toLowerCase().split(\"_\");\n\treturn words.map((w, i) => (i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w)).join(\" \");\n}\n\n/**\n * The signed-in user's own subscription.\n *\n * Reads through the session, never a customer id from props: the account is\n * whoever the session says it is, so one user cannot be pointed at another's\n * billing by changing a prop.\n */\nexport function SubscriptionManager({\n\tonChange,\n\tclassName,\n\tstyle,\n}: {\n\t/**\n\t * Called after a cancel, a resume or an undone plan change, so a sibling\n\t * showing the same subscription — an upcoming invoice, a plan picker — can\n\t * refresh. `BillingPortal` uses it to keep its pieces in step.\n\t */\n\tonChange?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [subscription, setSubscription] = useState<BillingSubscription | null>(null);\n\tconst [loading, setLoading] = useState(true);\n\t// Set when the plan is provided by the organization that manages this\n\t// account. It is shown, but changing or cancelling it is theirs to do.\n\tconst [managedBy, setManagedBy] = useState<{ name: string | null } | null>(null);\n\t// A downgrade scheduled for the renewal, or a ramp: said plainly, with the\n\t// undo beside it, because \"why is my plan changing next month\" is the\n\t// question it answers.\n\tconst [schedule, setSchedule] = useState<SubscriptionPhase[]>([]);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst load = useCallback(async () => {\n\t\tif (!token) {\n\t\t\tsetSubscription(null);\n\t\t\tsetLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await client.billing.subscription(token);\n\t\t\tsetSubscription(result.subscription);\n\t\t\tsetManagedBy(result.managedBy ?? null);\n\t\t\tsetSchedule(result.schedule ?? []);\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not load the subscription\", cause);\n\t\t\tsetError(\"Could not load your subscription.\");\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, [client, token]);\n\n\tuseEffect(() => {\n\t\tvoid load();\n\t}, [load]);\n\n\t/** Run a change, then re-read the subscription and tell the host. */\n\tconst act = async (change: () => Promise<unknown>, failure: string) => {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait change();\n\t\t\tawait load();\n\t\t\tonChange?.();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] subscription change failed\", cause);\n\t\t\tsetError(failure);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tif (sessionLoading || loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!token) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tSign in to manage your subscription.\n\t\t\t</div>\n\t\t);\n\t}\n\n\t/**\n\t * A failure is reported before anything is claimed about the account.\n\t *\n\t * The error was stored and then never reached: this guard ran first, so a\n\t * customer whose request failed was told \"You are not subscribed to a plan\"\n\t * — a confident, wrong statement to make to somebody who is paying. The\n\t * error div further down was unreachable for the whole life of the file.\n\t *\n\t * `ActiveSessions` has the ordering right; this is the same.\n\t */\n\tif (error) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!subscription) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tYou are not subscribed to a plan.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();\n\tconst next = schedule[0] ?? null;\n\tconst nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-plan-name\">{subscription.planVersion.plan.name}</div>\n\t\t\t<div className=\"b316-muted\">\n\t\t\t\t{/* PAST_DUE reads as \"Past due\", not \"past_due\". */}\n\t\t\t\t{statusLabel(subscription.status)}\n\t\t\t\t{\" · \"}\n\t\t\t\t{subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`}\n\t\t\t</div>\n\n\t\t\t{next && !managedBy ? (\n\t\t\t\t<div className=\"b316-muted\" role=\"status\" style={{ marginTop: 10 }}>\n\t\t\t\t\tMoves to {next.plan.name} on {nextOn}. You keep {subscription.planVersion.plan.name} until\n\t\t\t\t\tthen.\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\tstyle={{ marginTop: 10 }}\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={async () => {\n\t\t\t\t\t\t\t\tsetBusy(true);\n\t\t\t\t\t\t\t\tsetError(null);\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait client.billing.cancelScheduledChange(token);\n\t\t\t\t\t\t\t\t\tawait load();\n\t\t\t\t\t\t\t\t\tonChange?.();\n\t\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t\tconsole.error(\"[base316] could not undo the scheduled change\", cause);\n\t\t\t\t\t\t\t\t\tsetError(\"Could not keep your current plan. Try again.\");\n\t\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{busy ? \"Working…\" : `Keep ${subscription.planVersion.plan.name}`}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{managedBy ? (\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tProvided by {managedBy.name ?? \"the organization that manages your account\"}. Ask them to\n\t\t\t\t\tchange or cancel it.\n\t\t\t\t</p>\n\t\t\t) : subscription.cancelAtPeriodEnd ? (\n\t\t\t\t<div>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tThis subscription will not renew. You keep access until {renews}.\n\t\t\t\t\t</p>\n\t\t\t\t\t{/* The undo for a cancel, offered for as long as it can be taken:\n\t\t\t\t\t until the period actually ends. */}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\tvoid act(() => client.billing.resume(token), \"Could not resume. Try again.\")\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t{busy ? \"Working…\" : \"Resume subscription\"}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div style={{ marginTop: 14 }}>\n\t\t\t\t\t{/* Asked in the page rather than with `window.confirm`, which a\n\t\t\t\t\t sandboxed embed silently answers \"no\". */}\n\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tconfirmLabel={`Cancel at the end of the period (${renews})`}\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonConfirm={() =>\n\t\t\t\t\t\t\t// Cancels at period end: the user paid for the period they\n\t\t\t\t\t\t\t// are in, and ending it now would forfeit it.\n\t\t\t\t\t\t\tact(() => client.billing.cancel(token), \"Could not cancel. Try again.\")\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t{busy ? \"Working…\" : \"Cancel subscription\"}\n\t\t\t\t\t</ConfirmButton>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { BillingCustomer, BillingSubscription } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { BillingDetailsForm } from \"./BillingDetailsForm\";\nimport { CreditBalances } from \"./CreditBalances\";\nimport { Invoices } from \"./Invoices\";\nimport { PaymentMethod } from \"./PaymentMethod\";\nimport { PlanChangeReview } from \"./PlanChangeReview\";\nimport { PricingTable } from \"./PricingTable\";\nimport { useBase316 } from \"./provider\";\nimport { SeatManager } from \"./SeatManager\";\nimport { SubscriptionManager } from \"./SubscriptionManager\";\nimport { UpcomingInvoice } from \"./UpcomingInvoice\";\n\nexport interface BillingPortalProps {\n\t/**\n\t * Where the browser comes back to after updating the card on Stripe's page.\n\t * Must be one of the environment's redirect URIs. Defaults to the current\n\t * page.\n\t */\n\treturnUrl?: string;\n\t/** The plan to present as the default choice in the plan picker, by key. */\n\tfeaturedPlanKey?: string;\n\t/** What a seat is called, plural. \"seats\" by default. */\n\tunitLabel?: string;\n\t/**\n\t * The \"Billing details\" section: the billing address and tax IDs.\n\t *\n\t * Replace it with your own form, or pass `null` to leave it out. By default\n\t * it is `<BillingDetailsForm />`: the address invoices are made out to and\n\t * the tax IDs on them, EU VAT numbers checked with VIES as they are saved.\n\t */\n\tbillingDetails?: ReactNode;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\ninterface Overview {\n\tcustomer: BillingCustomer | null;\n\tsubscription: BillingSubscription | null;\n\tmanagedBy: { name: string | null } | null;\n\tquantityPriced: boolean;\n}\n\n/**\n * A whole billing page for the signed-in user, in one component.\n *\n * The embeddable counterpart to the hosted billing portal: plan and status,\n * the next invoice, a scheduled change with its undo, a plan picker whose\n * choice opens a review step, seats when the plan is priced per seat, credit\n * balances with buying and auto-recharge when the product sells credit packs,\n * the saved cards, invoices with their PDFs and a way to pay an open one, and cancel\n * and resume. Everything goes through the signed-in user's session and the\n * `/v1/me` routes, which apply the same rules as the hosted page.\n *\n * It is the existing pieces composed — `SubscriptionManager`,\n * `UpcomingInvoice`, `PricingTable`, `PlanChangeReview`, `SeatManager`,\n * `CreditBalances`, `PaymentMethod` and `Invoices` — so a page that wants a different layout\n * uses those directly. After any change the pieces are re-read together, so\n * the invoice preview never disagrees with the plan above it.\n *\n * A client company billed by the firm that manages it sees the firm's plan,\n * read-only and named, and its own invoices — nothing it could change.\n */\nexport function BillingPortal({\n\treturnUrl,\n\tfeaturedPlanKey,\n\tunitLabel,\n\tbillingDetails,\n\tclassName,\n\tstyle,\n}: BillingPortalProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [overview, setOverview] = useState<Overview | null>(null);\n\tconst [failed, setFailed] = useState(false);\n\t// Bumped after any change: every piece is keyed on it, so they all re-read.\n\tconst [version, setVersion] = useState(0);\n\tconst [reviewing, setReviewing] = useState<string | null>(null);\n\tconst [notice, setNotice] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (!token) return;\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.subscription(token)\n\t\t\t.then((result) => {\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\tsetOverview({\n\t\t\t\t\tcustomer: result.customer,\n\t\t\t\t\tsubscription: result.subscription,\n\t\t\t\t\tmanagedBy: result.managedBy ?? null,\n\t\t\t\t\tquantityPriced: result.quantityPriced ?? false,\n\t\t\t\t});\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load billing\", cause);\n\t\t\t\tif (!cancelled) setFailed(true);\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, version]);\n\n\t// A notice describes the last change; any later one makes it stale.\n\tconst refresh = useCallback(() => {\n\t\tsetNotice(null);\n\t\tsetVersion((value) => value + 1);\n\t}, []);\n\n\tconst shell = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-billing-portal\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) return shell(<div className=\"b316-card\">Loading…</div>);\n\tif (!token) return shell(<div className=\"b316-card\">Sign in to manage your billing.</div>);\n\n\tif (failed) {\n\t\treturn shell(\n\t\t\t<div className=\"b316-card\">\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your billing.\n\t\t\t\t</div>\n\t\t\t</div>,\n\t\t);\n\t}\n\n\tif (!overview) return shell(<div className=\"b316-card\">Loading…</div>);\n\n\tconst { subscription, managedBy, quantityPriced } = overview;\n\tconst canChange = Boolean(subscription) && !managedBy;\n\n\treturn shell(\n\t\t<>\n\t\t\t{notice ? (\n\t\t\t\t<div className=\"b316-card b316-notice\" role=\"status\">\n\t\t\t\t\t{notice}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<SubscriptionManager key={`plan-${version}`} onChange={refresh} />\n\n\t\t\t{canChange ? <UpcomingInvoice key={`next-${version}`} /> : null}\n\n\t\t\t{canChange && quantityPriced ? (\n\t\t\t\t<SeatManager key={`seats-${version}`} unitLabel={unitLabel} onChange={refresh} />\n\t\t\t) : null}\n\n\t\t\t{reviewing ? (\n\t\t\t\t<PlanChangeReview\n\t\t\t\t\tplanVersionId={reviewing}\n\t\t\t\t\tonCancel={() => setReviewing(null)}\n\t\t\t\t\tonDone={({ scheduled }) => {\n\t\t\t\t\t\tsetReviewing(null);\n\t\t\t\t\t\trefresh();\n\t\t\t\t\t\tsetNotice(\n\t\t\t\t\t\t\tscheduled\n\t\t\t\t\t\t\t\t? \"Your plan change is scheduled for the end of this billing period.\"\n\t\t\t\t\t\t\t\t: \"Your plan has been changed.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<section>\n\t\t\t\t\t<h2 className=\"b316-billing-portal-section-title\">\n\t\t\t\t\t\t{subscription ? \"Change plan\" : \"Choose a plan\"}\n\t\t\t\t\t</h2>\n\t\t\t\t\t<PricingTable\n\t\t\t\t\t\tkey={`plans-${version}`}\n\t\t\t\t\t\tfeaturedPlanKey={featuredPlanKey}\n\t\t\t\t\t\t// A subscriber reviews a change before making it. Without a\n\t\t\t\t\t\t// subscription the table's own checkout is the right route.\n\t\t\t\t\t\tonSelectPlan={\n\t\t\t\t\t\t\tcanChange\n\t\t\t\t\t\t\t\t? (planVersionId) => {\n\t\t\t\t\t\t\t\t\t\tsetNotice(null);\n\t\t\t\t\t\t\t\t\t\tsetReviewing(planVersionId);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t</section>\n\t\t\t)}\n\n\t\t\t<CreditBalances key={`credits-${version}`} />\n\n\t\t\t{managedBy ? null : <PaymentMethod key={`card-${version}`} returnUrl={returnUrl} />}\n\n\t\t\t<Invoices key={`invoices-${version}`} />\n\n\t\t\t{/* The billing address and tax IDs, through `/v1/me/billing-details` —\n\t\t\t the same self-service rules as the hosted portal's form, including\n\t\t\t the refusal for a managed tenant. A host can pass its own. */}\n\t\t\t{billingDetails === undefined ? (\n\t\t\t\t<BillingDetailsForm key={`details-${version}`} />\n\t\t\t) : (\n\t\t\t\tbillingDetails\n\t\t\t)}\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { MyCreditFeature, MyCredits } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties, type FormEvent, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\ntype State = { kind: \"loading\" } | { kind: \"ready\"; credits: MyCredits } | { kind: \"error\" };\n\nexport interface CreditBalancesProps {\n\t/** Called after auto-recharge is saved. */\n\tonChange?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nfunction units(value: number | string | null): string {\n\treturn value === null ? \"Unlimited\" : Number(value).toLocaleString(\"en\");\n}\n\nfunction money(amount: string, currency: string): string {\n\ttry {\n\t\treturn new Intl.NumberFormat(\"en\", { style: \"currency\", currency }).format(Number(amount));\n\t} catch {\n\t\treturn `${currency} ${amount}`;\n\t}\n}\n\n/** What the user needs to know about their auto-recharge right now, if anything. */\nfunction status(feature: MyCreditFeature): string | null {\n\tconst setting = feature.autoRecharge;\n\n\tif (!setting) return null;\n\tif (setting.disabledAt && setting.disabledReason === \"PAYMENT_FAILED\") {\n\t\treturn \"Auto-recharge was turned off because your card was declined twice. Update your card, then turn it back on.\";\n\t}\n\tif (setting.disabledAt && setting.disabledReason === \"PACK_UNAVAILABLE\") {\n\t\treturn \"Auto-recharge was turned off because the pack it bought is no longer available. Choose another pack.\";\n\t}\n\tif (setting.enabled && setting.needsPaymentMethod) {\n\t\treturn \"Auto-recharge is on, but there is no card on file to charge. Add a card and it will recharge next time.\";\n\t}\n\tif (setting.enabled && setting.inFlight) {\n\t\treturn \"A recharge is being processed. Your credits appear as soon as the payment clears.\";\n\t}\n\n\treturn null;\n}\n\nfunction Feature({\n\tfeature,\n\tmanaged,\n\tonSaved,\n}: {\n\tfeature: MyCreditFeature;\n\tmanaged: boolean;\n\tonSaved: () => void;\n}) {\n\tconst { client, token } = useBase316();\n\tconst setting = feature.autoRecharge;\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [saved, setSaved] = useState<string | null>(null);\n\tconst [pack, setPack] = useState(feature.packs[0]?.id ?? \"\");\n\tconst unit = feature.unit ? ` ${feature.unit}` : \"\";\n\tconst warning = status(feature);\n\n\tconst buy = async () => {\n\t\tif (!token || !pack) return;\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.billing.buyCredits(token, pack);\n\n\t\t\tif (result.url) {\n\t\t\t\twindow.location.assign(result.url);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetSaved(\"Paid from your account balance. Your credits are ready.\");\n\t\t\tonSaved();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not buy credits\", cause);\n\t\t\tsetError(\"That pack could not be bought. Try another.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst save = async (event: FormEvent<HTMLFormElement>) => {\n\t\tevent.preventDefault();\n\t\tif (!token) return;\n\n\t\tconst form = new FormData(event.currentTarget);\n\t\tconst text = (name: string) => {\n\t\t\tconst value = form.get(name);\n\n\t\t\treturn typeof value === \"string\" ? value.trim() : \"\";\n\t\t};\n\t\tconst count = text(\"monthlyMaxCount\");\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\t\tsetSaved(null);\n\n\t\ttry {\n\t\t\tconst result = await client.billing.setAutoRecharge(token, {\n\t\t\t\tfeatureId: feature.featureId,\n\t\t\t\tenabled: form.get(\"enabled\") === \"on\",\n\t\t\t\tthreshold: text(\"threshold\"),\n\t\t\t\tcreditPackId: text(\"creditPackId\") || null,\n\t\t\t\tmonthlyMaxCount: count ? Number.parseInt(count, 10) : null,\n\t\t\t\tmonthlyMaxAmount: text(\"monthlyMaxAmount\") || null,\n\t\t\t});\n\n\t\t\tsetSaved(result.enabled ? \"Auto-recharge is on.\" : \"Auto-recharge is off.\");\n\t\t\tonSaved();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not save auto-recharge\", cause);\n\t\t\tsetError(\n\t\t\t\t\"Auto-recharge was not saved. Check the threshold and set a monthly maximum: a number of purchases, an amount, or both.\",\n\t\t\t);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className=\"b316-card b316-credit-balance\">\n\t\t\t<div className=\"b316-label\">{feature.featureName}</div>\n\t\t\t<div>\n\t\t\t\t<strong>{units(feature.remaining)}</strong>\n\t\t\t\t{unit} left\n\t\t\t</div>\n\t\t\t<div className=\"b316-muted\">\n\t\t\t\t{feature.allowance === null\n\t\t\t\t\t? \"Unlimited allowance\"\n\t\t\t\t\t: `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`}{\" \"}\n\t\t\t\t· {units(feature.purchasedRemaining)} purchased\n\t\t\t</div>\n\n\t\t\t{warning && !managed ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{warning}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{saved ? (\n\t\t\t\t<div className=\"b316-notice\" role=\"status\">\n\t\t\t\t\t{saved}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{managed || feature.packs.length === 0 ? null : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"b316-row\" style={{ marginTop: 12 }}>\n\t\t\t\t\t\t<select\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\taria-label=\"Pack to buy\"\n\t\t\t\t\t\t\tvalue={pack}\n\t\t\t\t\t\t\tonChange={(event) => setPack(event.target.value)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{feature.packs.map((option) => (\n\t\t\t\t\t\t\t\t<option key={option.id} value={option.id}>\n\t\t\t\t\t\t\t\t\t{option.name} — {units(option.units)} for {money(option.amount, option.currency)}\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</select>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={buy}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tBuy now\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<form onSubmit={save} style={{ marginTop: 16 }}>\n\t\t\t\t\t\t<label className=\"b316-checkbox\">\n\t\t\t\t\t\t\t<input type=\"checkbox\" name=\"enabled\" defaultChecked={setting?.enabled ?? false} />{\" \"}\n\t\t\t\t\t\t\tBuy credits automatically when my balance runs low\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t\t\t<span className=\"b316-label\">When fewer than this many{unit} are left</span>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\tname=\"threshold\"\n\t\t\t\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t\tdefaultValue={setting?.threshold ?? \"\"}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t\t\t<span className=\"b316-label\">Buy</span>\n\t\t\t\t\t\t\t<select\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\tname=\"creditPackId\"\n\t\t\t\t\t\t\t\tdefaultValue={setting?.creditPackId ?? feature.packs[0]?.id}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{feature.packs.map((option) => (\n\t\t\t\t\t\t\t\t\t<option key={option.id} value={option.id}>\n\t\t\t\t\t\t\t\t\t\t{option.name}\n\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t\t\t<span className=\"b316-label\">At most this many times a month</span>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\tname=\"monthlyMaxCount\"\n\t\t\t\t\t\t\t\tinputMode=\"numeric\"\n\t\t\t\t\t\t\t\tdefaultValue={setting ? String(setting.monthlyMaxCount ?? \"\") : \"3\"}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t\t\t<span className=\"b316-label\">\n\t\t\t\t\t\t\t\tSpending at most ({setting?.currency ?? feature.packs[0]?.currency ?? \"USD\"}) a\n\t\t\t\t\t\t\t\tmonth\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\tname=\"monthlyMaxAmount\"\n\t\t\t\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\t\t\t\tdefaultValue={setting?.monthlyMaxAmount ?? \"\"}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy}>\n\t\t\t\t\t\t\tSave auto-recharge\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</form>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n/**\n * The signed-in user's credit balances: what is left of each metered feature\n * sold in packs, a way to buy a pack now, and auto-recharge — a threshold, the\n * pack to buy, and a monthly maximum.\n *\n * Buying goes to the hosted pay page; auto-recharge charges the card on file\n * (`PaymentMethod`). A client company whose credits a firm pays for sees the\n * pool it spends, with nothing to change. Renders nothing when the product\n * sells no credit packs.\n */\nexport function CreditBalances({ onChange, className, style }: CreditBalancesProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [state, setState] = useState<State>({ kind: \"loading\" });\n\tconst [version, setVersion] = useState(0);\n\n\tuseEffect(() => {\n\t\tif (!token) return;\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.credits(token)\n\t\t\t.then((credits) => {\n\t\t\t\tif (!cancelled) setState({ kind: \"ready\", credits });\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load credits\", cause);\n\t\t\t\tif (!cancelled) setState({ kind: \"error\" });\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, version]);\n\n\tconst wrap = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-credit-balances\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading || !token || state.kind === \"loading\") return null;\n\n\tif (state.kind === \"error\") {\n\t\treturn wrap(\n\t\t\t<div className=\"b316-card\">\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your credits.\n\t\t\t\t</div>\n\t\t\t</div>,\n\t\t);\n\t}\n\n\tconst { credits } = state;\n\n\tif (credits.features.length === 0) return null;\n\n\treturn wrap(\n\t\t<>\n\t\t\t{credits.managedBy ? (\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tCredits for this account come from{\" \"}\n\t\t\t\t\t{credits.managedBy.name ?? \"the organization that manages it\"}, which manages them.\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t{credits.features.map((feature) => (\n\t\t\t\t<Feature\n\t\t\t\t\tkey={feature.featureId}\n\t\t\t\t\tfeature={feature}\n\t\t\t\t\tmanaged={Boolean(credits.managedBy)}\n\t\t\t\t\tonSaved={() => {\n\t\t\t\t\t\tsetVersion((value) => value + 1);\n\t\t\t\t\t\tonChange?.();\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { SavedCard } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\ntype State =\n\t| { kind: \"loading\" }\n\t| { kind: \"ready\"; cards: SavedCard[] }\n\t| { kind: \"managed\" }\n\t| { kind: \"error\" };\n\nexport interface PaymentMethodProps {\n\t/**\n\t * Where the browser comes back to once the new card is stored. Must be one\n\t * of the environment's redirect URIs. Defaults to the current page.\n\t */\n\treturnUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nfunction brandName(brand: string | null): string {\n\tif (!brand) return \"Card\";\n\n\treturn brand.charAt(0).toUpperCase() + brand.slice(1);\n}\n\n/**\n * The card the signed-in user's invoices are charged against, and a way to\n * replace it — plus any other saved cards, each of which can be made the\n * default or removed.\n *\n * Replacing it goes to a page hosted by Stripe, on the application's connected\n * account: the card is never typed into this component, the host page or\n * Base316, so adding this to an application adds nothing to its PCI scope.\n * The browser returns to `returnUrl` once the card is stored.\n *\n * A client company whose plan a firm pays for is told so instead — the firm's\n * card is the one charged.\n */\nexport function PaymentMethod({ returnUrl, className, style }: PaymentMethodProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [state, setState] = useState<State>({ kind: \"loading\" });\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\t// Bumped after a card is made default or removed, to re-read the list.\n\tconst [version, setVersion] = useState(0);\n\n\tuseEffect(() => {\n\t\tif (!token) return;\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.paymentMethods(token)\n\t\t\t.then((result) => {\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\tsetState(\n\t\t\t\t\tresult.billedByParent ? { kind: \"managed\" } : { kind: \"ready\", cards: result.data },\n\t\t\t\t);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load the payment method\", cause);\n\t\t\t\tif (!cancelled) setState({ kind: \"error\" });\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, version]);\n\n\tconst wrap = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card b316-payment-method\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) return wrap(\"Loading…\");\n\tif (!token) return wrap(\"Sign in to manage your payment method.\");\n\n\tswitch (state.kind) {\n\t\tcase \"loading\":\n\t\t\treturn wrap(\"Loading…\");\n\t\tcase \"error\":\n\t\t\treturn wrap(\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your payment method.\n\t\t\t\t</div>,\n\t\t\t);\n\t\tcase \"managed\":\n\t\t\treturn wrap(\n\t\t\t\t<p className=\"b316-muted\">Your plan is paid for by the organization that manages it.</p>,\n\t\t\t);\n\t}\n\n\tconst card = state.cards.find((saved) => saved.isDefault) ?? null;\n\tconst others = state.cards.filter((saved) => !saved.isDefault);\n\n\tconst act = async (label: string, run: () => Promise<unknown>) => {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait run();\n\t\t\tsetVersion((value) => value + 1);\n\t\t} catch (cause) {\n\t\t\tconsole.error(`[base316] could not ${label}`, cause);\n\t\t\tsetError(\"That card could not be changed. Try again.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\treturn wrap(\n\t\t<>\n\t\t\t<div className=\"b316-label\">Payment method</div>\n\t\t\t{card ? (\n\t\t\t\t<div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{brandName(card.brand)} ending {card.last4 ?? \"????\"}\n\t\t\t\t\t</div>\n\t\t\t\t\t{card.expMonth && card.expYear ? (\n\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\tExpires {String(card.expMonth).padStart(2, \"0\")}/{card.expYear}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<p className=\"b316-muted\">No card on file.</p>\n\t\t\t)}\n\n\t\t\t{others.length > 0 ? (\n\t\t\t\t<div style={{ marginTop: 12 }}>\n\t\t\t\t\t<div className=\"b316-label\">Other saved cards</div>\n\t\t\t\t\t{others.map((saved) => (\n\t\t\t\t\t\t<div key={saved.id} className=\"b316-row\" style={{ marginTop: 6 }}>\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t{brandName(saved.brand)} ending {saved.last4 ?? \"????\"}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button-link\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\tact(\"make the card the default\", () =>\n\t\t\t\t\t\t\t\t\t\t\tclient.billing.setDefaultPaymentMethod(token, saved.id),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tMake default\n\t\t\t\t\t\t\t\t</button>{\" \"}\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button-link\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\tact(\"remove the card\", () =>\n\t\t\t\t\t\t\t\t\t\t\tclient.billing.removePaymentMethod(token, saved.id),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRemove\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\tstyle={{ marginTop: 12 }}\n\t\t\t\tdisabled={busy}\n\t\t\t\tonClick={async () => {\n\t\t\t\t\tsetBusy(true);\n\t\t\t\t\tsetError(null);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst { url } = await client.billing.updatePaymentMethod(token, {\n\t\t\t\t\t\t\t...(returnUrl ? { returnUrl } : {}),\n\t\t\t\t\t\t});\n\t\t\t\t\t\twindow.location.assign(url);\n\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\tconsole.error(\"[base316] could not start a card update\", cause);\n\t\t\t\t\t\tsetError(\"Cards cannot be updated here right now.\");\n\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{busy ? \"Opening Stripe…\" : card ? \"Update card\" : \"Add a card\"}\n\t\t\t</button>\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { PlanChangePreview, PlanChangeTiming } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/** Display only: every figure was computed server-side in decimal arithmetic. */\nfunction money(amount: string | null, currency: string): string {\n\tif (amount === null) return \"—\";\n\n\tconst value = Number(amount);\n\n\tif (!Number.isFinite(value)) return `${amount} ${currency}`;\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\treturn `${amount} ${currency}`;\n\t}\n}\n\nconst day = (value: string | null) => (value ? new Date(value).toLocaleDateString() : \"—\");\n\n/** A feature's grant in words: a switch is included or not; a quantity has a number. */\nfunction limitText(terms: { enabled: boolean; limit: string | null } | null, type: string): string {\n\tif (!terms || !terms.enabled || terms.limit === \"0\") return \"Not included\";\n\tif (type === \"BOOLEAN\") return \"Included\";\n\n\treturn terms.limit === null ? \"Unlimited\" : terms.limit;\n}\n\nconst statusOf = (cause: unknown) => (cause as { status?: unknown } | null)?.status;\n\nconst TIMING_CLOSED: Record<string, string> = {\n\tTRIALING: \"During a trial a change happens now, and costs nothing until the trial ends.\",\n\tCANCELLATION_PENDING: \"Resume your subscription to schedule a change for the period end.\",\n\tCURRENCY_MISMATCH: \"This plan is billed in a different currency, so it can only start now.\",\n\tNOT_RENEWING: \"This subscription is not renewing, so nothing can wait for the period end.\",\n};\n\nexport interface PlanChangeReviewProps {\n\t/** The plan version being moved to — a `PublicPlan`'s `planVersionId`. */\n\tplanVersionId: string;\n\t/** Called once the change is made or scheduled. */\n\tonDone?: (outcome: { scheduled: boolean }) => void;\n\t/** Called when the user backs out. Without it there is no back button. */\n\tonCancel?: () => void;\n\t/**\n\t * Called when a change now needs a card the account does not have. Without\n\t * it the review offers to start a card update itself.\n\t */\n\tonNeedsCard?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/**\n * The review step before a plan change: what is gained and lost, what it\n * costs, and when it happens — then confirm.\n *\n * The figures are `previewPlanChange`'s, the same function the change runs, so\n * the amount shown is the amount charged. The default timing is the server's\n * (an upgrade now, a downgrade at the renewal); the other is offered when it is\n * open, and the reason is said when it is not.\n */\nexport function PlanChangeReview({\n\tplanVersionId,\n\tonDone,\n\tonCancel,\n\tonNeedsCard,\n\tclassName,\n\tstyle,\n}: PlanChangeReviewProps) {\n\tconst { client, token } = useBase316();\n\tconst [timing, setTiming] = useState<PlanChangeTiming | undefined>(undefined);\n\tconst [preview, setPreview] = useState<PlanChangePreview | null>(null);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [needsCard, setNeedsCard] = useState(false);\n\tconst [busy, setBusy] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (!token) return;\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.previewPlanChange(token, planVersionId, timing)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) setPreview(result);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not preview the plan change\", cause);\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(\n\t\t\t\t\t\tstatusOf(cause) === 403\n\t\t\t\t\t\t\t? \"Your plan is provided by the organization that manages your account.\"\n\t\t\t\t\t\t\t: \"That plan change is not available.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, planVersionId, timing]);\n\n\tconst confirm = useCallback(async () => {\n\t\tif (!token || !preview) return;\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.billing.changePlan(token, {\n\t\t\t\tplanVersionId,\n\t\t\t\ttiming: preview.timing,\n\t\t\t});\n\n\t\t\tonDone?.({ scheduled: result.scheduled });\n\t\t} catch (cause) {\n\t\t\tif (statusOf(cause) === 402) {\n\t\t\t\tsetNeedsCard(true);\n\t\t\t} else {\n\t\t\t\tconsole.error(\"[base316] plan change failed\", cause);\n\t\t\t\tsetError(\"Could not change your plan. Try again.\");\n\t\t\t}\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}, [client, token, preview, planVersionId, onDone]);\n\n\tconst addCard = useCallback(async () => {\n\t\tif (onNeedsCard) {\n\t\t\tonNeedsCard();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!token) return;\n\n\t\ttry {\n\t\t\tconst { url } = await client.billing.updatePaymentMethod(token);\n\t\t\twindow.location.assign(url);\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not start a card update\", cause);\n\t\t\tsetError(\"Cards cannot be added here right now.\");\n\t\t}\n\t}, [client, token, onNeedsCard]);\n\n\tconst card = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card b316-plan-review\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (error && !preview) {\n\t\treturn card(\n\t\t\t<>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t\t{onCancel ? (\n\t\t\t\t\t<button type=\"button\" className=\"b316-button b316-button-secondary\" onClick={onCancel}>\n\t\t\t\t\t\tBack\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t</>,\n\t\t);\n\t}\n\n\tif (!preview) {\n\t\treturn card(\"Loading…\");\n\t}\n\n\tconst { from, to, now } = preview;\n\tconst other: PlanChangeTiming = preview.timing === \"NOW\" ? \"PERIOD_END\" : \"NOW\";\n\tconst otherOpen = preview.timings[other]?.available ?? false;\n\tconst otherReason = preview.timings[other]?.reason ?? null;\n\tconst changes = preview.entitlements.filter((change) => change.change !== \"UNCHANGED\");\n\n\treturn card(\n\t\t<>\n\t\t\t<div className=\"b316-plan-name\">Change to {to.planName}</div>\n\t\t\t<div className=\"b316-muted\">From {from.planName}</div>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{changes.length === 0 ? (\n\t\t\t\t<p className=\"b316-muted\">Every feature stays the same.</p>\n\t\t\t) : (\n\t\t\t\t<table className=\"b316-review-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th>Feature</th>\n\t\t\t\t\t\t\t<th>{from.planName}</th>\n\t\t\t\t\t\t\t<th>{to.planName}</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{changes.map((change) => (\n\t\t\t\t\t\t\t<tr key={change.featureId}>\n\t\t\t\t\t\t\t\t<td>{change.featureName}</td>\n\t\t\t\t\t\t\t\t<td>{limitText(change.before, change.type)}</td>\n\t\t\t\t\t\t\t\t<td\n\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\tchange.change === \"GAINED\" || change.change === \"INCREASED\"\n\t\t\t\t\t\t\t\t\t\t\t? \"b316-review-gain\"\n\t\t\t\t\t\t\t\t\t\t\t: \"b316-review-loss\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{limitText(change.after, change.type)}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t)}\n\n\t\t\t{preview.timing === \"NOW\" ? (\n\t\t\t\tnow.trialing ? (\n\t\t\t\t\t<p>\n\t\t\t\t\t\tThe change happens now. Your trial carries on until {day(now.trialEndsAt)}, and nothing\n\t\t\t\t\t\tis charged before then.\n\t\t\t\t\t</p>\n\t\t\t\t) : (\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{Number(now.credit) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Credit for the unused part of {from.planName}</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">−{money(now.credit, from.currency)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{Number(now.closingUsage) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Usage so far this period</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">{money(now.closingUsage, from.currency)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t\t\t{to.planName}, {day(now.newPeriod.start)} – {day(now.newPeriod.end)}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{money(now.newPeriodCharge, to.currency)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{now.net !== null ? (\n\t\t\t\t\t\t\t<div className=\"b316-row b316-invoice-total\">\n\t\t\t\t\t\t\t\t<span>Due now</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">{money(now.net, to.currency)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t)\n\t\t\t) : (\n\t\t\t\t<p>\n\t\t\t\t\tYou keep {from.planName} until {day(preview.atPeriodEnd?.effectiveAt ?? null)}, then move\n\t\t\t\t\tto {to.planName}. Nothing is charged now.\n\t\t\t\t\t{preview.atPeriodEnd?.nextInvoice\n\t\t\t\t\t\t? ` Your first invoice on ${to.planName} is ${money(\n\t\t\t\t\t\t\t\tpreview.atPeriodEnd.nextInvoice.amountDue,\n\t\t\t\t\t\t\t\tpreview.atPeriodEnd.nextInvoice.currency,\n\t\t\t\t\t\t\t)}.`\n\t\t\t\t\t\t: \"\"}\n\t\t\t\t</p>\n\t\t\t)}\n\n\t\t\t{otherOpen ? (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-link\"\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t// Back to loading until the other timing's figures arrive.\n\t\t\t\t\t\tsetPreview(null);\n\t\t\t\t\t\tsetTiming(other);\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{other === \"NOW\" ? \"Change now instead\" : \"Wait until the end of the period instead\"}\n\t\t\t\t</button>\n\t\t\t) : otherReason && TIMING_CLOSED[otherReason] ? (\n\t\t\t\t<p className=\"b316-muted\">{TIMING_CLOSED[otherReason]}</p>\n\t\t\t) : null}\n\n\t\t\t{needsCard ? (\n\t\t\t\t<div className=\"b316-notice\" role=\"status\">\n\t\t\t\t\tA card is needed for a change that is charged now.\n\t\t\t\t\t<div className=\"b316-review-actions\">\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button\" onClick={() => void addCard()}>\n\t\t\t\t\t\t\tAdd a card\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-review-actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => void confirm()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{busy\n\t\t\t\t\t\t\t? \"Working…\"\n\t\t\t\t\t\t\t: preview.timing === \"NOW\"\n\t\t\t\t\t\t\t\t? `Change to ${to.planName} now`\n\t\t\t\t\t\t\t\t: `Schedule ${to.planName}`}\n\t\t\t\t\t</button>\n\t\t\t\t\t{onCancel ? (\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button b316-button-secondary\" onClick={onCancel}>\n\t\t\t\t\t\t\tKeep {from.planName}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { ApiCredential, CustomerApiResource } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { useBase316 } from \"./provider\";\n\n/** `900` reads as nothing; `15m` reads as a decision somebody made. */\nfunction duration(seconds: number): string {\n\tif (seconds % 3600 === 0) {\n\t\treturn `${seconds / 3600}h`;\n\t}\n\n\tif (seconds % 60 === 0) {\n\t\treturn `${seconds / 60}m`;\n\t}\n\n\treturn `${seconds}s`;\n}\n\n/**\n * The signed-in user's credentials for this application's API.\n *\n * Drop this on an account or developer-settings page and the account manages\n * its own keys: issue, rotate, revoke. Reads through the session, never a\n * customer id from props — the account is whoever the session says it is, so\n * one user cannot be pointed at another's keys by changing a prop.\n *\n * What it deliberately does *not* offer is changing the rate limit. A caller\n * who can raise their own ceiling does not have one. The limit is shown, and so\n * are the scopes the plan withholds, which is an upgrade prompt arriving at the\n * moment somebody actually wants the capability.\n */\nexport function ApiKeyManager({\n\tclassName,\n\tstyle,\n\t/** Restrict to one API. Omit to show every one the account can reach. */\n\taudience,\n}: {\n\tclassName?: string;\n\tstyle?: CSSProperties;\n\taudience?: string;\n}) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\n\tconst [resources, setResources] = useState<CustomerApiResource[]>([]);\n\tconst [credentials, setCredentials] = useState<ApiCredential[]>([]);\n\tconst [loading, setLoading] = useState(true);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst [creating, setCreating] = useState(false);\n\tconst [name, setName] = useState(\"\");\n\tconst [chosen, setChosen] = useState<string[]>([]);\n\tconst [resourceId, setResourceId] = useState<string | null>(null);\n\t// Held only until dismissed: the secret exists here and nowhere else.\n\tconst [issued, setIssued] = useState<{ clientId: string; secret: string } | null>(null);\n\n\tconst load = useCallback(async () => {\n\t\tif (!token) {\n\t\t\tsetLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst [available, held] = await Promise.all([\n\t\t\t\tclient.apiCredentials.resources(token),\n\t\t\t\tclient.apiCredentials.list(token),\n\t\t\t]);\n\n\t\t\tconst visible = audience\n\t\t\t\t? available.data.filter((resource) => resource.audience === audience)\n\t\t\t\t: available.data;\n\n\t\t\tsetResources(visible);\n\t\t\tsetCredentials(audience ? held.data.filter((item) => item.audience === audience) : held.data);\n\t\t\tsetResourceId((current) => current ?? visible[0]?.id ?? null);\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not load API credentials\", cause);\n\t\t\tsetError(\"Could not load your API keys.\");\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, [client, token, audience]);\n\n\tuseEffect(() => {\n\t\tvoid load();\n\t}, [load]);\n\n\tif (sessionLoading || loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!token) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tSign in to manage your API keys.\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Before the empty state, which is otherwise what a failed load looks like:\n\t// \"There are no APIs available to your account\" is a claim, and the request\n\t// simply not arriving is not evidence for it.\n\tif (error) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (resources.length === 0) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tThere are no APIs available to your account.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst resource = resources.find((item) => item.id === resourceId) ?? resources[0]!;\n\n\tconst reset = () => {\n\t\tsetCreating(false);\n\t\tsetName(\"\");\n\t\tsetChosen([]);\n\t\tsetIssued(null);\n\t};\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{resources.length > 1 ? (\n\t\t\t\t<select\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\tvalue={resource.id}\n\t\t\t\t\tonChange={(event) => setResourceId(event.target.value)}\n\t\t\t\t\tstyle={{ marginBottom: 14 }}\n\t\t\t\t>\n\t\t\t\t\t{resources.map((item) => (\n\t\t\t\t\t\t<option key={item.id} value={item.id}>\n\t\t\t\t\t\t\t{item.name}\n\t\t\t\t\t\t</option>\n\t\t\t\t\t))}\n\t\t\t\t</select>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-plan-name\">{resource.name}</div>\n\t\t\t)}\n\n\t\t\t{resource.rateLimit ? (\n\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t{resource.rateLimit.requestsPerWindow} requests per{\" \"}\n\t\t\t\t\t{duration(resource.rateLimit.windowSeconds)}\n\t\t\t\t\t{resource.rateLimit.burst > resource.rateLimit.requestsPerWindow\n\t\t\t\t\t\t? `, bursting to ${resource.rateLimit.burst}`\n\t\t\t\t\t\t: null}\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-muted\">No rate limit.</div>\n\t\t\t)}\n\n\t\t\t{/* --- What they hold --- */}\n\n\t\t\t{credentials.length === 0 ? (\n\t\t\t\t<p className=\"b316-muted\" style={{ marginTop: 14 }}>\n\t\t\t\t\tYou have no API keys yet.\n\t\t\t\t</p>\n\t\t\t) : (\n\t\t\t\t<ul className=\"b316-list\" style={{ marginTop: 14 }}>\n\t\t\t\t\t{credentials.map((credential) => (\n\t\t\t\t\t\t<li key={credential.clientId} className=\"b316-list-item\">\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<div className=\"b316-plan-name\">{credential.name}</div>\n\t\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\t<code>{credential.clientId}</code>\n\t\t\t\t\t\t\t\t\t{credential.secretLastFour ? ` · …${credential.secretLastFour}` : null}\n\t\t\t\t\t\t\t\t\t{credential.disabled ? \" · Disabled\" : null}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"b316-muted\">{credential.scopes.join(\", \")}</div>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<div style={{ display: \"flex\", gap: 8 }}>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tonClick={async () => {\n\t\t\t\t\t\t\t\t\t\tsetBusy(true);\n\t\t\t\t\t\t\t\t\t\tsetError(null);\n\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tconst rotated = await client.apiCredentials.rotate(\n\t\t\t\t\t\t\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t\t\t\t\t\t\tcredential.clientId,\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\t// Same client id, new secret — so the surface shows it\n\t\t\t\t\t\t\t\t\t\t\t// once, exactly as it does on creation.\n\t\t\t\t\t\t\t\t\t\t\tsetIssued({\n\t\t\t\t\t\t\t\t\t\t\t\tclientId: credential.clientId,\n\t\t\t\t\t\t\t\t\t\t\t\tsecret: rotated.issuedSecret,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\tawait load();\n\t\t\t\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.error(\"[base316] rotate failed\", cause);\n\t\t\t\t\t\t\t\t\t\t\tsetError(\"Could not rotate that key.\");\n\t\t\t\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRotate\n\t\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t\t{/*\n\t\t\t\t\t\t\t\t * Irreversible, and the caller's integration stops as soon as\n\t\t\t\t\t\t\t\t * its current token expires. Worth one confirmation — asked in\n\t\t\t\t\t\t\t\t * the page, because `window.confirm` is suppressed in the\n\t\t\t\t\t\t\t\t * sandboxed iframe these are meant to be embedded in.\n\t\t\t\t\t\t\t\t */}\n\t\t\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tconfirmLabel={`Revoke ${credential.name} for good`}\n\t\t\t\t\t\t\t\t\tonConfirm={async () => {\n\t\t\t\t\t\t\t\t\t\tsetBusy(true);\n\t\t\t\t\t\t\t\t\t\tsetError(null);\n\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tawait client.apiCredentials.revoke(token, credential.clientId);\n\t\t\t\t\t\t\t\t\t\t\tawait load();\n\t\t\t\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.error(\"[base316] revoke failed\", cause);\n\t\t\t\t\t\t\t\t\t\t\tsetError(\"Could not revoke that key.\");\n\t\t\t\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRevoke\n\t\t\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t)}\n\n\t\t\t{/* --- The secret, shown once --- */}\n\n\t\t\t{issued ? (\n\t\t\t\t<div className=\"b316-notice\" style={{ marginTop: 14 }}>\n\t\t\t\t\t<strong>Copy this now.</strong> It is shown once and cannot be retrieved again.\n\t\t\t\t\t<div style={{ marginTop: 8 }}>\n\t\t\t\t\t\t<code style={{ wordBreak: \"break-all\" }}>{issued.secret}</code>\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tstyle={{ marginTop: 10 }}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t// Clipboard access can be refused — an insecure origin, a denied\n\t\t\t\t\t\t\t// permission. The value is on screen either way, so a failure is\n\t\t\t\t\t\t\t// not worth interrupting for.\n\t\t\t\t\t\t\tvoid navigator.clipboard?.writeText(issued.secret).catch(() => {});\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tCopy\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tstyle={{ marginTop: 10, marginLeft: 8 }}\n\t\t\t\t\t\tonClick={reset}\n\t\t\t\t\t>\n\t\t\t\t\t\tDone\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{/* --- Issue a new one --- */}\n\n\t\t\t{creating && !issued ? (\n\t\t\t\t<div style={{ marginTop: 14 }}>\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tplaceholder=\"What is this key for?\"\n\t\t\t\t\t\tvalue={name}\n\t\t\t\t\t\tonChange={(event) => setName(event.target.value)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div style={{ marginTop: 10 }}>\n\t\t\t\t\t\t{resource.availableScopes.map((scope) => (\n\t\t\t\t\t\t\t<label key={scope.key} className=\"b316-checkbox\">\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\tchecked={chosen.includes(scope.key)}\n\t\t\t\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\t\t\t\tsetChosen((current) =>\n\t\t\t\t\t\t\t\t\t\t\tevent.target.checked\n\t\t\t\t\t\t\t\t\t\t\t\t? [...current, scope.key]\n\t\t\t\t\t\t\t\t\t\t\t\t: current.filter((key) => key !== scope.key),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<code>{scope.key}</code>\n\t\t\t\t\t\t\t\t{scope.description ? (\n\t\t\t\t\t\t\t\t\t<span className=\"b316-muted\"> — {scope.description}</span>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t{/* Shown rather than hidden: somebody who cannot see the capability\n\t\t\t\t\t\t cannot know an upgrade would give it to them. */}\n\t\t\t\t\t\t{resource.lockedScopes.map((scope) => (\n\t\t\t\t\t\t\t<label key={scope.key} className=\"b316-checkbox b316-muted\">\n\t\t\t\t\t\t\t\t<input type=\"checkbox\" disabled />\n\t\t\t\t\t\t\t\t<code>{scope.key}</code>\n\t\t\t\t\t\t\t\t<span> — not included in your plan</span>\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\tstyle={{ marginTop: 12 }}\n\t\t\t\t\t\tdisabled={busy || !name.trim() || chosen.length === 0}\n\t\t\t\t\t\tonClick={async () => {\n\t\t\t\t\t\t\tsetBusy(true);\n\t\t\t\t\t\t\tsetError(null);\n\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst created = await client.apiCredentials.create(token, {\n\t\t\t\t\t\t\t\t\tapiResourceId: resource.id,\n\t\t\t\t\t\t\t\t\tname: name.trim(),\n\t\t\t\t\t\t\t\t\tscopes: chosen,\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tif (created.issuedSecret) {\n\t\t\t\t\t\t\t\t\tsetIssued({ clientId: created.clientId, secret: created.issuedSecret });\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsetCreating(false);\n\t\t\t\t\t\t\t\tsetName(\"\");\n\t\t\t\t\t\t\t\tsetChosen([]);\n\t\t\t\t\t\t\t\tawait load();\n\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t// The API names the scope a plan withholds, which is more\n\t\t\t\t\t\t\t\t// useful than anything generic written here.\n\t\t\t\t\t\t\t\tconst message =\n\t\t\t\t\t\t\t\t\tcause instanceof Error ? cause.message : \"Could not create that key.\";\n\n\t\t\t\t\t\t\t\tconsole.error(\"[base316] create failed\", cause);\n\t\t\t\t\t\t\t\tsetError(message);\n\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tCreate key\n\t\t\t\t\t</button>\n\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tstyle={{ marginTop: 12, marginLeft: 8 }}\n\t\t\t\t\t\tonClick={reset}\n\t\t\t\t\t>\n\t\t\t\t\t\tCancel\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{!creating && !issued ? (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\tstyle={{ marginTop: 14 }}\n\t\t\t\t\tdisabled={resource.availableScopes.length === 0}\n\t\t\t\t\tonClick={() => setCreating(true)}\n\t\t\t\t>\n\t\t\t\t\t{resource.availableScopes.length === 0\n\t\t\t\t\t\t? \"No scopes available on your plan\"\n\t\t\t\t\t\t: \"New API key\"}\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","/**\n * What is in this package, described so that something assembling a page does\n * not have to guess.\n *\n * The audience is an agent building an application, and a drag-and-drop canvas\n * later. Both need the same four answers, and none of them can be had by\n * reading a type definition:\n *\n * 1. **What exists.** Otherwise a component gets invented, and the failure is a\n * build error nobody can act on.\n * 2. **What it needs before it works.** This is the big one. Almost everything\n * here renders nothing without a signed-in user — which looks like a broken\n * component rather than a missing precondition, and is the single most\n * expensive way to lose an hour with this package.\n * 3. **Which sibling to reach for.** A table, a board and a chart all bind to a\n * collection and answer different questions.\n * 4. **What the props actually are.** Not their types — TypeScript has those —\n * but what they mean and what happens when they are left out.\n *\n * Every component here takes no required props. That is a rule rather than a\n * coincidence: a thing that cannot be dropped in as `<Thing />` is a thing an\n * agent has to be taught, and the whole point is that it does not.\n *\n * **This file drifts if nobody stops it**, so `manifest.test.ts` fails when an\n * export is added or removed without a matching entry. A manifest that lies is\n * worse than no manifest, because both an agent and a person will believe it.\n */\n\n/**\n * What must already be true, or the component renders nothing useful.\n *\n * Ordered by how often each one is the answer to \"why is this blank\".\n */\nexport type Requirement =\n\t/** A signed-in end user. Without one, most of these render nothing at all. */\n\t| \"session\"\n\t/** A collection defined in this environment, named by the `collection` prop. */\n\t| \"collection\"\n\t/** At least one published plan in the catalog. */\n\t| \"plans\"\n\t/** A connected payment account, or checkout refuses before a card is asked for. */\n\t| \"paymentAccount\"\n\t/** An API resource defined, so there are credentials to manage. */\n\t| \"apiResource\";\n\nexport interface PropEntry {\n\tname: string;\n\t/** What it does, and what happens without it. */\n\tsummary: string;\n\t/** True for none of them, by design. Present so the rule is machine-checkable. */\n\trequired: boolean;\n}\n\nexport interface ManifestEntry {\n\tname: string;\n\tkind: \"component\" | \"hook\" | \"provider\";\n\t/** One line: what this is. */\n\tsummary: string;\n\t/** When to reach for this one rather than a sibling. */\n\tuseWhen: string;\n\trequires: Requirement[];\n\t/** Parameterised by a collection defined at runtime. */\n\tbindsToCollection?: boolean;\n\tprops: PropEntry[];\n\t/** What appears when a requirement is not met. The answer to \"why is it blank\". */\n\twhenUnmet?: string;\n\tseeAlso?: string[];\n}\n\nconst appearance: PropEntry[] = [\n\t{ name: \"className\", summary: \"Your own classes on the wrapper.\", required: false },\n\t{ name: \"style\", summary: \"Inline styles on the wrapper.\", required: false },\n];\n\nexport const MANIFEST: ManifestEntry[] = [\n\t// --- Setup ---------------------------------------------------------------\n\t{\n\t\tname: \"Base316Provider\",\n\t\tkind: \"provider\",\n\t\tsummary: \"Holds the client, the session and the theme. Everything else must be inside it.\",\n\t\tuseWhen: \"Once, around the part of the application that uses any other export here.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"publishableKey\", summary: \"The environment's publishable key.\", required: true },\n\t\t\t{ name: \"baseUrl\", summary: \"Where the API lives. Defaults to production.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"token\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Supply to own session storage yourself. Left out, the session is kept in localStorage.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onTokenChange\",\n\t\t\t\tsummary: \"Called when the session changes. Pair with `token` for an httpOnly cookie.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"appearance\",\n\t\t\t\tsummary: \"Colours, radius and font as tokens. Restyles everything at once.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"tenant\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"White-label everything inside for one tenant — `{ organizationId }` or `{ organizationExternalId }`. A firm's name, logo and colours on the screens it runs its clients on; its own branding, then its parent's, then the environment's. Change it when the user switches team.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"useBase316\", \"useSession\"],\n\t},\n\t{\n\t\tname: \"useBase316\",\n\t\tkind: \"hook\",\n\t\tsummary: \"The client, the session token and the branding, from inside the provider.\",\n\t\tuseWhen: \"Writing a component of your own that needs to call the API directly.\",\n\t\trequires: [],\n\t\tprops: [],\n\t\tseeAlso: [\"Base316Provider\"],\n\t},\n\t{\n\t\tname: \"useSession\",\n\t\tkind: \"hook\",\n\t\tsummary:\n\t\t\t\"The resolved session, or null. Carries `userId`, `user` (id, email, name, image, and the customer's own declared fields) and `tenants` — every team this person is in, each with their role.\",\n\t\tuseWhen: \"Deciding what to render for a signed-in versus a signed-out visitor.\",\n\t\trequires: [],\n\t\tprops: [],\n\t},\n\n\t// --- Signing in ----------------------------------------------------------\n\t{\n\t\tname: \"SignIn\",\n\t\tkind: \"component\",\n\t\tsummary: \"Password, passkey, magic-link and text-message sign-in in one form.\",\n\t\tuseWhen: \"The application renders its own sign-in rather than redirecting to the hosted page.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"onSignedIn\", summary: \"Called once a session exists.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"passkeys\",\n\t\t\t\tsummary: \"Offer passkeys where supported. On by default.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"magicLinkRedirectUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Where an emailed link lands, which must be registered on the environment. Without it, magic link is not offered at all.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"phone\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"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.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"secondFactorLabels\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"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.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"SignUp\", \"ForgotPassword\", \"SecondFactorStep\"],\n\t},\n\t{\n\t\tname: \"SignUp\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"Create an account with an email and a password, showing the environment's password rules, then sign in — through the second-factor step when one is owed or must be enrolled.\",\n\t\tuseWhen: \"Alongside SignIn, on a page that registers new users.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"onSignedUp\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called once the account is created and signed in, or created and waiting on email confirmation.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"invitationToken\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The invitation this sign-up accepts; read from `?invitation=` when omitted, `null` to ignore the URL. The account joins the inviting team instead of getting a personal workspace, and its address counts as verified.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onJoined\",\n\t\t\t\tsummary: \"Called with the team's organizationId when the sign-up accepted an invitation.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"labels\", summary: \"Wording for the form, for translation.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"secondFactorLabels\",\n\t\t\t\tsummary: \"Wording for the second-factor step, for translation.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"SignIn\", \"VerifyEmail\", \"SecondFactorStep\"],\n\t},\n\t{\n\t\tname: \"SecondFactorStep\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The second half of a sign-in that returned `mfaRequired`: a code box for an existing factor, or — when the environment requires a factor and the user has none — choosing an authenticator app (QR code and key), an emailed code or a text, confirming it, and showing the recovery codes once.\",\n\t\tuseWhen:\n\t\t\t\"Your own first step (a custom form, a magic-link landing) got a `SignInPending` back. SignIn and SignUp already include it.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"pending\",\n\t\t\t\tsummary: \"The `SignInPending` from signIn, magicLink.verify or phone.verify.\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onSignedIn\",\n\t\t\t\tsummary: \"Called once the session is handed to the provider.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onRestart\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Back to the start, for a challenge that expired or ran out of attempts. Without it no Start over button is drawn.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"labels\",\n\t\t\t\tsummary: \"Wording, for translation. English when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"SignIn\", \"TwoFactorManager\"],\n\t},\n\t{\n\t\tname: \"ForgotPassword\",\n\t\tkind: \"component\",\n\t\tsummary: \"Ask for a reset link by email.\",\n\t\tuseWhen: \"Linked from a sign-in form.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"onSent\", summary: \"Called with the address after the request.\", required: false },\n\t\t\t{ name: \"signInUrl\", summary: \"Renders a link back to sign-in.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"ResetPassword\"],\n\t},\n\t{\n\t\tname: \"ResetPassword\",\n\t\tkind: \"component\",\n\t\tsummary: \"Set a new password from an emailed link.\",\n\t\tuseWhen: \"On the page the reset link lands on.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"token\",\n\t\t\t\tsummary: \"Read from `?token=` when omitted, and removed from the URL.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onReset\", summary: \"Called once the password is changed.\", required: false },\n\t\t\t{ name: \"signInUrl\", summary: \"Renders a link onward to sign-in.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"With no token in the URL or props, explains that the link is needed.\",\n\t\tseeAlso: [\"ForgotPassword\"],\n\t},\n\t{\n\t\tname: \"VerifyEmail\",\n\t\tkind: \"component\",\n\t\tsummary: \"Confirm an address from an emailed link.\",\n\t\tuseWhen: \"On the page the verification link lands on.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"token\",\n\t\t\t\tsummary: \"Read from `?token=` when omitted, and removed from the URL.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onVerified\", summary: \"Called once confirmed.\", required: false },\n\t\t\t{ name: \"continueUrl\", summary: \"Renders a link onward.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"SignUp\"],\n\t},\n\n\t// --- The account ---------------------------------------------------------\n\t{\n\t\tname: \"UserProfile\",\n\t\tkind: \"component\",\n\t\tsummary: \"Name, email and the customer's own declared fields.\",\n\t\tuseWhen: \"An account settings page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"ActiveSessions\", \"TwoFactorManager\", \"PasskeyManager\"],\n\t},\n\t{\n\t\tname: \"ActiveSessions\",\n\t\tkind: \"component\",\n\t\tsummary: \"Where the account is signed in, and a button to end the other devices.\",\n\t\tuseWhen: \"A security settings page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{ name: \"onRevoked\", summary: \"Called with the number of sessions ended.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"TwoFactorManager\"],\n\t},\n\t{\n\t\tname: \"DeviceApproval\",\n\t\tkind: \"component\",\n\t\tsummary: \"Approve a sign-in that started on a CLI, a TV, or anything with no browser.\",\n\t\tuseWhen:\n\t\t\t\"You point a device's verification URI at a page in your own app. Put this on that page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"userCode\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The code, when the URL already carries it. Skips the entry step; without it the person types the code.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onDecided\", summary: \"Called with whether they approved.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Renders nothing without a session — there is nobody to approve as, and collecting a code first would fail at the step that matters.\",\n\t\tseeAlso: [\"SignIn\", \"ActiveSessions\"],\n\t},\n\t{\n\t\tname: \"PrivacyControls\",\n\t\tkind: \"component\",\n\t\tsummary: \"Download a copy of everything held about you, or delete your account.\",\n\t\tuseWhen:\n\t\t\t\"An account settings page. These are the two things a privacy notice promises and most products never build.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"confirmWord\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"What must be typed to confirm deletion. Defaults to the English word, which is wrong in every other language.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onErased\",\n\t\t\t\tsummary: \"Called once the account is gone. Sign them out and send them somewhere.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"UserProfile\", \"ActiveSessions\"],\n\t},\n\t{\n\t\tname: \"TwoFactorManager\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"Turn two-factor authentication on or off, by authenticator app, a code to the inbox or a code by text message.\",\n\t\tuseWhen:\n\t\t\t\"A security settings page. The app is strongest; the emailed or texted code is the one people who will not install an app actually use.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"enabled\",\n\t\t\t\tsummary: \"Whether a factor already exists, which decides which side is shown.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"allowSms\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Offer a code by text message. Off by default: it only works once the environment can send one.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onEnabled\", summary: \"Called once a factor is confirmed.\", required: false },\n\t\t\t{ name: \"onDisabled\", summary: \"Called once it is removed.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"ActiveSessions\", \"PasskeyManager\"],\n\t},\n\t{\n\t\tname: \"PasskeyManager\",\n\t\tkind: \"component\",\n\t\tsummary: \"Add and remove passkeys.\",\n\t\tuseWhen: \"A security settings page, beside two-factor.\",\n\t\trequires: [\"session\"],\n\t\tprops: [{ name: \"title\", summary: \"Heading text.\", required: false }, ...appearance],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"TwoFactorManager\"],\n\t},\n\t{\n\t\tname: \"Branding\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The logo, name and tagline — the environment's, or the tenant's when the provider is given a `tenant`.\",\n\t\tuseWhen: \"Above a sign-in form, so your pages match the hosted ones.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"showTagline\", summary: \"Include the tagline under the name.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t},\n\n\t// --- Teams ---------------------------------------------------------------\n\t{\n\t\tname: \"TeamMembers\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"Who is in a team, who has been invited, and the way in and out. A team reached only through the organization that manages it says so, and offers nothing to leave.\",\n\t\tuseWhen:\n\t\t\t\"A Team or Members settings page. One component covers the list, the pending invitations, the invite box and leaving.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"organizationId\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Which team. Defaults to the only one this person is in; with several it says so rather than guessing.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onInvited\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called with `{ email, token, url }` — the address invited, the raw token, and the accept URL when `acceptUrl` was given. This is where your application sends the email. Without a handler the link is shown on screen instead, because the token is returned once and cannot be fetched again.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"acceptUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The page hosting AcceptInvitation. The component appends `?invitation=<token>` and hands the finished link back as `url` on onInvited; without it, onInvited gets the raw token and you build the link yourself.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onLeft\", summary: \"Called after the viewer leaves the team.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Renders nothing without a session. Inviting and removing appear only for somebody whose role grants team.manage, and are refused for a role granting anything the viewer does not hold. Addresses are shown only to such a viewer.\",\n\t\tseeAlso: [\"AcceptInvitation\"],\n\t},\n\t{\n\t\tname: \"AcceptInvitation\",\n\t\tkind: \"component\",\n\t\tsummary: \"The other end of an invitation: what it is for, and joining.\",\n\t\tuseWhen: \"On the page an invitation link lands on.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"token\",\n\t\t\t\tsummary: \"Read from `?invitation=` when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onAccepted\",\n\t\t\t\tsummary: \"Called with the organizationId once they have joined.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"signUpUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"For somebody with no account yet: a page with SignUp. The link carries `?invitation=`, so the account is created inside this team without a personal workspace.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"signInUrl\", summary: \"For somebody who has one.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Says what the invitation is for without a session, since the point is that they may have no account. Names the address to sign in as when the signed-in one does not match.\",\n\t\tseeAlso: [\"TeamMembers\", \"SignUp\"],\n\t},\n\n\t// --- Money ---------------------------------------------------------------\n\t{\n\t\tname: \"PricingTable\",\n\t\tkind: \"component\",\n\t\tsummary: \"The published plans, and completing the purchase.\",\n\t\tuseWhen: \"A pricing page, or an upgrade screen.\",\n\t\trequires: [\"plans\", \"paymentAccount\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"onSelectPlan\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Take over what Choose does. Left out, the component changes the plan or starts a checkout itself.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"currentPlanVersionId\",\n\t\t\t\tsummary: \"Marks the current plan. Discovered from the session when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"featuredPlanKey\",\n\t\t\t\tsummary: \"Which plan to present as the default.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"signInUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Where a signed-out visitor goes on choosing. Without it the button says so rather than failing.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Says plans are unavailable when the catalog is empty.\",\n\t\tseeAlso: [\"SubscriptionManager\", \"usePlans\"],\n\t},\n\t{\n\t\tname: \"usePlans\",\n\t\tkind: \"hook\",\n\t\tsummary: \"The plans, the current one, and the prorate-or-checkout branch — without markup.\",\n\t\tuseWhen: \"You want your own pricing table but not your own billing logic.\",\n\t\trequires: [\"plans\"],\n\t\tprops: [],\n\t\tseeAlso: [\"PricingTable\"],\n\t},\n\t{\n\t\tname: \"SubscriptionManager\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The current plan, its renewal date, a scheduled plan change with its undo, cancelling at the period end (confirmed in the page) and resuming a cancelled one.\",\n\t\tuseWhen: \"A billing settings page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"onChange\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called after a cancel, a resume or an undone plan change, so a sibling showing the same subscription can refresh.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"BillingPortal\", \"PricingTable\", \"Invoices\"],\n\t},\n\t{\n\t\tname: \"Invoices\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The signed-in user's invoices, newest first: view one, download its PDF, and pay one that is still open on the hosted pay page.\",\n\t\tuseWhen: \"A billing settings page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [...appearance],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"BillingPortal\", \"SubscriptionManager\", \"UpcomingInvoice\"],\n\t},\n\t{\n\t\tname: \"BillingPortal\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"A whole billing page for the signed-in user: plan and status, next invoice, scheduled change with undo, plan change with a review step, seats, credit balances with auto-recharge, saved cards, invoices with PDFs and pay, cancel and resume, and a Billing details slot.\",\n\t\tuseWhen:\n\t\t\t\"You want a complete self-service billing screen inside your own application. For a page you do not host at all, mint a hosted billing portal session from your server instead (`billingPortal.createSession`). For a different layout, compose the pieces it is made of.\",\n\t\trequires: [\"session\", \"plans\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"returnUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Where the browser comes back to after updating the card on Stripe's page. Must be an environment redirect URI. The current page when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"featuredPlanKey\",\n\t\t\t\tsummary: \"The plan to present as the default choice in the plan picker.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"unitLabel\",\n\t\t\t\tsummary: 'What a seat is called, plural. \"seats\" by default.',\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"billingDetails\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Your own Billing details section (address, tax IDs). By default it is BillingDetailsForm — the address and tax IDs, EU VAT numbers checked with VIES; pass null to leave it out.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session. With no subscription it offers the plans through checkout. A managed tenant sees the firm's plan read-only and its own invoices.\",\n\t\tseeAlso: [\n\t\t\t\"SubscriptionManager\",\n\t\t\t\"UpcomingInvoice\",\n\t\t\t\"PlanChangeReview\",\n\t\t\t\"SeatManager\",\n\t\t\t\"CreditBalances\",\n\t\t\t\"PaymentMethod\",\n\t\t\t\"Invoices\",\n\t\t],\n\t},\n\t{\n\t\tname: \"CreditBalances\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The signed-in user's credit balances: what is left of each metered feature sold in packs, buying a pack now, and auto-recharge (threshold, pack, monthly maximum).\",\n\t\tuseWhen:\n\t\t\t\"A billing or usage page in a product that sells credit packs. `BillingPortal` includes it. Buying goes to the hosted pay page; auto-recharge charges the card on file.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{ name: \"onChange\", summary: \"Called after auto-recharge is saved.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Renders nothing without a session or when no credit packs are on sale. A managed tenant sees the balance it spends, read-only.\",\n\t\tseeAlso: [\"BillingPortal\", \"PaymentMethod\"],\n\t},\n\t{\n\t\tname: \"PlanChangeReview\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The review step before a plan change: features gained and lost, the prorated credit and charge or the date it waits for, then confirm.\",\n\t\tuseWhen:\n\t\t\t\"Your own plan picker, between choosing a plan and changing to it. `BillingPortal` opens it when a subscriber picks a plan.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"planVersionId\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The plan version to move to — a PublicPlan's planVersionId. Required in practice.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onDone\", summary: \"Called once the change is made or scheduled.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"onCancel\",\n\t\t\t\tsummary: \"Called when the user keeps their plan. Without it there is no back button.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onNeedsCard\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called when a change now needs a card the account lacks. Without it the review starts a card update itself.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Says the change is not available when the plan cannot be moved to, and that the plan is provided by their organization for a managed tenant.\",\n\t\tseeAlso: [\"BillingPortal\", \"PricingTable\", \"usePlans\"],\n\t},\n\t{\n\t\tname: \"PaymentMethod\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The card the signed-in user's invoices are charged against, a button that replaces it on a Stripe-hosted page, and their other saved cards to make default or remove.\",\n\t\tuseWhen:\n\t\t\t\"A billing page. The card is entered on Stripe's page on your connected account, never in your page or Base316, so it adds nothing to your PCI scope.\",\n\t\trequires: [\"session\", \"paymentAccount\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"returnUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Where the browser comes back to once the card is stored. Must be an environment redirect URI. The current page when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session; says cards cannot be updated when the environment has no connected payment account; says the plan is paid for by their organization for a managed tenant.\",\n\t\tseeAlso: [\"BillingPortal\", \"Invoices\"],\n\t},\n\t{\n\t\tname: \"UpcomingInvoice\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The signed-in user's next bill: when it is issued, its lines, discount, tax, wallet balance and the amount due.\",\n\t\tuseWhen:\n\t\t\t\"A billing or account page that answers 'what will I be charged next'. Computed on request and stored nowhere, so it is safe to show on every visit.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"showLines\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Show the breakdown. Off gives one line: the amount due and the date. On by default.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session; says there is no upcoming invoice when nothing will bill them; says the plan is provided by their organization for a managed tenant.\",\n\t\tseeAlso: [\"Invoices\", \"SubscriptionManager\"],\n\t},\n\t{\n\t\tname: \"BillingDetailsForm\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The signed-in user's billing address and tax ids, with EU VAT numbers checked against VIES as they are saved.\",\n\t\tuseWhen:\n\t\t\t\"A billing or account page where a business customer enters the address its invoices are made out to and its VAT, GST or similar number. Saved against the session's own account only.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"taxIdTypes\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The tax id types to offer, as Stripe type names with a label and example. Defaults to the EU, UK, Switzerland, Norway, Australia, New Zealand, Canada, India and the US.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onSave\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called after a save, with the details as stored — each tax id with its check result.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session; says there is no billing account when the user has none; says billing is managed by their organization for a managed tenant, and offers nothing to change.\",\n\t\tseeAlso: [\"Invoices\", \"UpcomingInvoice\", \"SubscriptionManager\"],\n\t},\n\t{\n\t\tname: \"SeatManager\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"Change how many seats the signed-in user's subscription is for, with the prorated price previewed before anything is charged.\",\n\t\tuseWhen:\n\t\t\t\"A billing or team page on a plan sold per seat. Adding seats is charged now for the rest of the period; removing them takes effect at the period end with no refund. The user picks only the number.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"unitLabel\",\n\t\t\t\tsummary: 'What a unit is called, plural. \"seats\" by default.',\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onChange\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called after a change is made, with what it did (amount, invoice, when it applies).\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session; says there is no plan when they have no subscription; says the plan is provided by their organization for a managed tenant, and offers no change.\",\n\t\tseeAlso: [\"SubscriptionManager\", \"UpcomingInvoice\", \"TeamMembers\"],\n\t},\n\t{\n\t\tname: \"PayInvoice\",\n\t\tkind: \"component\",\n\t\tsummary: \"Pay one invoice from a link, with no account needed.\",\n\t\tuseWhen: \"A page reached from a payment link or a QR code — a walk-up customer.\",\n\t\trequires: [\"paymentAccount\"],\n\t\tprops: [\n\t\t\t{ name: \"token\", summary: \"The link token, from the URL.\", required: false },\n\t\t\t{ name: \"environmentId\", summary: \"Which environment the link belongs to.\", required: false },\n\t\t\t{ name: \"onPaid\", summary: \"Called once payment succeeds.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"usePaymentLink\"],\n\t},\n\t{\n\t\tname: \"usePaymentLink\",\n\t\tkind: \"hook\",\n\t\tsummary: \"Watches a payment link and reports when it is paid.\",\n\t\tuseWhen: \"Showing your own waiting screen beside a QR code.\",\n\t\trequires: [],\n\t\tprops: [],\n\t\tseeAlso: [\"PayInvoice\"],\n\t},\n\t{\n\t\tname: \"ApiKeyManager\",\n\t\tkind: \"component\",\n\t\tsummary: \"A customer managing their own API credentials and seeing their rate limits.\",\n\t\tuseWhen: \"A developer-settings page inside your application.\",\n\t\trequires: [\"session\", \"apiResource\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"audience\",\n\t\t\t\tsummary: \"Limit to one protected API. All of them when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session; says so when no API resource is defined.\",\n\t},\n\n\t// --- The application's own data ------------------------------------------\n\t{\n\t\tname: \"DataTable\",\n\t\tkind: \"component\",\n\t\tsummary: \"A table of a collection's records, with columns derived from its fields.\",\n\t\tuseWhen:\n\t\t\t\"Listing records. Reach for Kanban instead to group them by a status, or Chart to count or total them over time.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"columns\",\n\t\t\t\tsummary: \"Which fields to show, in order. Every field when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"renderCell\", summary: \"Replace the cell for one field.\", required: false },\n\t\t\t{ name: \"onSelect\", summary: \"Row click. Rows are inert without it.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"onChanged\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called after this table creates, edits or deletes a record. The table refreshes itself; use this to refresh anything else on the page bound to the same collection, such as a Chart.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"hideSearch\", summary: \"Hide the search box.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"readOnly\",\n\t\t\t\tsummary: \"Hide New, Edit and Delete even for a writer.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"emptyState\", summary: \"Shown when there is nothing to list.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Without the read permission it says which permission is missing, rather than showing an empty table.\",\n\t\tseeAlso: [\"Kanban\", \"Chart\", \"RecordDetail\", \"RecordForm\", \"useCollection\"],\n\t},\n\t{\n\t\tname: \"Kanban\",\n\t\tkind: \"component\",\n\t\tsummary: \"A board, grouped by a choice field it finds on its own.\",\n\t\tuseWhen: \"The records move through stages — a status, a pipeline.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"groupBy\",\n\t\t\t\tsummary: \"Which field makes the columns. Discovered when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"cardFields\", summary: \"What to show on a card.\", required: false },\n\t\t\t{ name: \"onSelect\", summary: \"Card click.\", required: false },\n\t\t\t{ name: \"emptyState\", summary: \"Shown in a column with nothing in it.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"A collection with no groupable field says to add a choice field, rather than drawing one column.\",\n\t\tseeAlso: [\"DataTable\", \"Chart\"],\n\t},\n\t{\n\t\tname: \"Chart\",\n\t\tkind: \"component\",\n\t\tsummary: \"Records over time, counted or totalled.\",\n\t\tuseWhen: \"The question is how many or how much, by day, week or month.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{ name: \"x\", summary: \"The date field. Discovered when omitted.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"y\",\n\t\t\t\tsummary: \"What to measure. Counts the records when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"aggregate\", summary: \"sum, avg, min or max. Defaults to sum.\", required: false },\n\t\t\t{ name: \"bucket\", summary: \"day, week or month. Defaults to day.\", required: false },\n\t\t\t{ name: \"title\", summary: \"Overrides the derived caption.\", required: false },\n\t\t\t{ name: \"height\", summary: \"Plot height in pixels.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"A collection with no date field says so. A field that cannot be summed is refused rather than quietly counted.\",\n\t\tseeAlso: [\"DataTable\", \"Kanban\"],\n\t},\n\t{\n\t\tname: \"RecordDetail\",\n\t\tkind: \"component\",\n\t\tsummary: \"One record in full, including the fields a table truncates.\",\n\t\tuseWhen: \"After a row or card is clicked.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{ name: \"recordId\", summary: \"Which record. Required in practice.\", required: false },\n\t\t\t{ name: \"tenant\", summary: \"Only when the user is in several.\", required: false },\n\t\t\t{ name: \"readOnly\", summary: \"Hide Edit and Delete.\", required: false },\n\t\t\t{ name: \"onDeleted\", summary: \"Called after deletion.\", required: false },\n\t\t\t{ name: \"onClose\", summary: \"Renders a Close button when given.\", required: false },\n\t\t\t{ name: \"children\", summary: \"Rendered under the fields.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"DataTable\", \"RecordForm\"],\n\t},\n\t{\n\t\tname: \"RecordForm\",\n\t\tkind: \"component\",\n\t\tsummary: \"Create or edit a record, with inputs derived from the field types.\",\n\t\tuseWhen: \"Adding a record, or editing one outside the detail view.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{ name: \"recordId\", summary: \"Omit to create, supply to edit.\", required: false },\n\t\t\t{ name: \"tenant\", summary: \"Only when the user is in several.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"onSaved\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called with the record id. Does not refresh a sibling table — see the composition rules.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onCancel\", summary: \"Renders a Cancel button when given.\", required: false },\n\t\t\t{ name: \"defaults\", summary: \"Values to start with. Ignored when editing.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Computed fields get no input at all, because the server produces them.\",\n\t\tseeAlso: [\"RecordDetail\", \"RelationPicker\"],\n\t},\n\t{\n\t\tname: \"RelationPicker\",\n\t\tkind: \"component\",\n\t\tsummary: \"Choose a record in another collection by typing its name.\",\n\t\tuseWhen: \"Building your own form. RecordForm uses this for relation fields already.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tprops: [\n\t\t\t{ name: \"field\", summary: \"The relation field descriptor.\", required: true },\n\t\t\t{ name: \"value\", summary: \"The chosen record id, or null.\", required: true },\n\t\t\t{ name: \"onChange\", summary: \"Called with the new id.\", required: true },\n\t\t\t{ name: \"error\", summary: \"Message shown under the input.\", required: false },\n\t\t\t{ name: \"disabled\", summary: \"Read-only.\", required: false },\n\t\t\t{ name: \"tenant\", summary: \"Only when the user is in several.\", required: false },\n\t\t],\n\t\tseeAlso: [\"RecordForm\"],\n\t},\n\t{\n\t\tname: \"useCollection\",\n\t\tkind: \"hook\",\n\t\tsummary:\n\t\t\t\"A collection's schema, records, filters, paging, permissions and writes — without markup.\",\n\t\tuseWhen: \"You want your own table, board or form but not your own data layer.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [],\n\t\tseeAlso: [\"DataTable\", \"FieldCell\", \"FieldInput\"],\n\t},\n\t{\n\t\tname: \"FieldCell\",\n\t\tkind: \"component\",\n\t\tsummary: \"One field value, rendered the way the tables render it.\",\n\t\tuseWhen: \"Building your own table over useCollection.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"value\", summary: \"The stored value.\", required: true },\n\t\t\t{ name: \"field\", summary: \"The field descriptor.\", required: true },\n\t\t\t{ name: \"related\", summary: \"A relation's resolved label.\", required: false },\n\t\t],\n\t\tseeAlso: [\"FieldInput\", \"useCollection\"],\n\t},\n\t{\n\t\tname: \"FieldInput\",\n\t\tkind: \"component\",\n\t\tsummary: \"The input for one field, chosen by its type.\",\n\t\tuseWhen: \"Building your own form over useCollection.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"value\", summary: \"The current value.\", required: true },\n\t\t\t{ name: \"field\", summary: \"The field descriptor.\", required: true },\n\t\t\t{ name: \"onChange\", summary: \"Called with the new value.\", required: true },\n\t\t\t{ name: \"error\", summary: \"Message shown under the input.\", required: false },\n\t\t\t{ name: \"disabled\", summary: \"Read-only.\", required: false },\n\t\t],\n\t\twhenUnmet: \"Renders nothing for a computed field — the server produces those.\",\n\t\tseeAlso: [\"FieldCell\", \"RecordForm\"],\n\t},\n];\n\n/**\n * How the pieces go together.\n *\n * Listed separately from the entries because it is not a fact about any one of\n * them, and it is the thing most often got wrong: a component dropped outside\n * the provider throws, and one dropped on a page with no signed-in user renders\n * nothing and reads as broken. Neither is discoverable from a prop list.\n */\nexport const COMPOSITION = {\n\trules: [\n\t\t\"Everything must be inside Base316Provider. Outside it, hooks throw.\",\n\t\t\"Most components need a signed-in user. Gate on useSession and render SignIn when there is none — see `requires: session` on each entry.\",\n\t\t\"A collection must exist before anything can bind to it. Define one in the dashboard under Collections, or through POST /v1/collections with a secret key.\",\n\t\t\"No component takes a prop you must supply to make it behave. Naming the subject is different: a collection component needs `collection` and a detail view needs `recordId`, because those say *what* to show rather than patch *how* it works. Everything else has a default.\",\n\t\t\"Each component bound to a collection holds its own data — DataTable, Kanban, Chart, RecordForm, RecordDetail, every one. None of them share a cache, so a write in one leaves the others showing what they already had. Put the form inside the table, where New and Edit refresh it; pass `onChanged` to refresh a sibling such as a Chart; or lift `useCollection` and render your own, which is what the hook is for.\",\n\t\t\"Next.js App Router: put Base316Provider in a Client Component wrapper used by the root layout. Every component here is a Client Component; none of them run on the server.\",\n\t],\n\t/** The shape almost every application ends up with. */\n\texample: `\nimport { Base316Provider, DataTable, RecordForm, SignIn, useSession } from \"@base316/react\";\n\nfunction Jobs() {\n const session = useSession();\n\n // Without this the table renders nothing and looks broken.\n if (!session) return <SignIn />;\n\n return (\n <>\n <DataTable collection=\"jobs\" onSelect={(record) => console.log(record.id)} />\n <RecordForm collection=\"jobs\" />\n </>\n );\n}\n\nexport function App() {\n return (\n <Base316Provider publishableKey={process.env.NEXT_PUBLIC_BASE316_PUBLISHABLE_KEY!}>\n <Jobs />\n </Base316Provider>\n );\n}\n`.trim(),\n} as const;\n\n/** Look one up by name. */\nexport function describeComponent(name: string): ManifestEntry | undefined {\n\treturn MANIFEST.find((entry) => entry.name === name);\n}\n\n/** Everything that needs a particular precondition — the \"why is this blank\" list. */\nexport function componentsRequiring(requirement: Requirement): ManifestEntry[] {\n\treturn MANIFEST.filter((entry) => entry.requires.includes(requirement));\n}\n"],"mappings":"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","names":["appearance","appearance","jsx","useCallback","useEffect","useState","jsx","jsxs","useState","useEffect","useCallback","useEffect","useState","jsx","jsxs","money","day","useState","useEffect","invoice","status","useCallback","useEffect","useState","Fragment","jsx","jsxs","money","day","useState","useCallback","useEffect","useCallback","useEffect","useState","jsx","jsxs","statusOf","useState","useCallback","details","status","useEffect","Base316Error","useEffect","useRef","useState","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","Fragment","jsx","jsxs","useState","useRef","useEffect","Base316Error","Base316Error","needsSecondFactor","useEffect","useState","jsx","jsxs","useState","useEffect","loaded","Base316Error","needsSecondFactor","jsx","jsxs","isPasskeySupported","useCallback","useEffect","useState","useEffect","useRef","useState","jsx","jsxs","jsx","jsxs","useState","useCallback","useEffect","isPasskeySupported","useCallback","useEffect","useState","jsx","jsxs","useState","useCallback","useEffect","useState","jsx","jsxs","useState","useState","jsx","jsxs","useState","useState","jsx","jsxs","useState","useState","jsx","jsxs","useState","useEffect","useState","jsx","jsxs","useState","useEffect","useEffect","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","useEffect","useState","Fragment","jsx","jsxs","useState","useCallback","useEffect","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","useEffect","useRef","useState","jsx","jsxs","useRef","useState","useEffect","useEffect","useRef","useState","status","useState","useRef","useEffect","useState","useCallback","useEffect","useState","useState","useEffect","useCallback","status","jsx","jsxs","useState","specFor","useState","jsx","jsxs","specFor","useEffect","useState","useEffect","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","useEffect","useMemo","useState","useState","useMemo","useEffect","useCallback","jsx","jsxs","useState","useEffect","specFor","jsx","jsxs","useState","specFor","specFor","useState","jsx","jsxs","useState","specFor","specFor","useMemo","jsx","jsxs","useMemo","specFor","specFor","useState","jsx","jsxs","useState","specFor","useCallback","useEffect","useState","jsx","jsxs","status","useState","useCallback","useEffect","useCallback","useEffect","useState","useEffect","useState","Fragment","jsx","jsxs","money","useState","useEffect","credits","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","useCallback","useEffect","useState","Fragment","jsx","jsxs","money","day","statusOf","useState","useEffect","useCallback","Fragment","jsx","jsxs","useState","useEffect","useCallback","useCallback","useEffect","useState","jsx","jsxs","useState","useCallback","resource","useEffect"]}
1
+ {"version":3,"sources":["../src/provider.tsx","../src/appearance.ts","../src/Branding.tsx","../src/Invoices.tsx","../src/UpcomingInvoice.tsx","../src/SeatManager.tsx","../src/BillingDetailsForm.tsx","../src/SignIn.tsx","../src/SecondFactorStep.tsx","../src/SignUp.tsx","../src/UserProfile.tsx","../src/PasskeyManager.tsx","../src/confirm.tsx","../src/ActiveSessions.tsx","../src/DeviceApproval.tsx","../src/PrivacyControls.tsx","../src/TwoFactorManager.tsx","../src/QrCode.tsx","../src/ForgotPassword.tsx","../src/ResetPassword.tsx","../src/VerifyEmail.tsx","../src/TeamMembers.tsx","../src/AcceptInvitation.tsx","../src/PayInvoice.tsx","../src/usePaymentLink.ts","../src/PricingTable.tsx","../src/usePlans.ts","../src/DataTable.tsx","../src/fields.tsx","../src/RecordForm.tsx","../src/RelationPicker.tsx","../src/useCollection.ts","../src/Kanban.tsx","../src/Chart.tsx","../src/RecordDetail.tsx","../src/SubscriptionManager.tsx","../src/BillingPortal.tsx","../src/CreditBalances.tsx","../src/PaymentMethod.tsx","../src/PlanChangeReview.tsx","../src/ApiKeyManager.tsx","../src/manifest.ts"],"sourcesContent":["\"use client\";\n\nimport { Base316Browser } from \"@base316/sdk\";\nimport type { Branding as BrandingInfo, ResolvedSession } from \"@base316/sdk\";\nimport {\n\tcreateContext,\n\tuseCallback,\n\tuseContext,\n\tuseEffect,\n\tuseMemo,\n\tuseState,\n\ttype ReactNode,\n} from \"react\";\n\nimport {\n\tappearanceToStyle,\n\tSTYLESHEET,\n\tSTYLESHEET_EXTRA,\n\tSTYLE_ELEMENT_ID,\n\ttype Base316Appearance,\n} from \"./appearance\";\n\n/**\n * Shared state for the Base316 components.\n *\n * Holds one browser client and the end user's session. The session token is the\n * credential these components send alongside the publishable key: the key says\n * which environment, the token says who, and billing answers need both.\n *\n * The token is kept in `localStorage` by default because that is what a\n * single-page app needs to survive a refresh. An application that would rather\n * hold it in an httpOnly cookie can pass `token` and `onTokenChange` and own\n * the storage itself — which is the better choice if the app has a server.\n */\n\ninterface Base316ContextValue {\n\tclient: Base316Browser;\n\t/** The environment's logo, name and colours. Null until it loads. */\n\tbranding: BrandingInfo | null;\n\ttoken: string | null;\n\tsetToken: (token: string | null) => void;\n\tsession: ResolvedSession | null;\n\tloading: boolean;\n\trefresh: () => Promise<void>;\n\tsignOut: () => Promise<void>;\n}\n\nconst Base316Context = createContext<Base316ContextValue | null>(null);\n\nconst STORAGE_KEY = \"base316.session\";\n\nfunction readStoredToken(): string | null {\n\ttry {\n\t\treturn window.localStorage.getItem(STORAGE_KEY);\n\t} catch {\n\t\t// Private browsing and blocked site data both throw here. A signed-out\n\t\t// render is correct in that case, not a crash.\n\t\treturn null;\n\t}\n}\n\nfunction writeStoredToken(token: string | null): void {\n\ttry {\n\t\tif (token === null) {\n\t\t\twindow.localStorage.removeItem(STORAGE_KEY);\n\t\t} else {\n\t\t\twindow.localStorage.setItem(STORAGE_KEY, token);\n\t\t}\n\t} catch {\n\t\t// Nothing to do: the session simply will not survive a refresh.\n\t}\n}\n\nexport function Base316Provider({\n\tpublishableKey,\n\tbaseUrl,\n\ttoken: controlledToken,\n\tonTokenChange,\n\tappearance,\n\ttenant,\n\tclassName,\n\tchildren,\n}: {\n\tpublishableKey: string;\n\tbaseUrl?: string;\n\t/** Supply this to own session storage yourself. */\n\ttoken?: string | null;\n\tonTokenChange?: (token: string | null) => void;\n\t/** Colours, radius and font, as tokens. See `Base316Appearance`. */\n\tappearance?: Base316Appearance;\n\t/**\n\t * White-label every component under this provider for one tenant: a firm's\n\t * name, logo and colours on the screens your application shows its clients.\n\t * Its own branding, then its parent's, then the environment's, field by\n\t * field. Change it — when the user switches team, say — and the components\n\t * restyle without a reload. Omit it for the environment's own branding.\n\t */\n\ttenant?: { organizationId: string } | { organizationExternalId: string } | null;\n\t/** Your own classes on the wrapper — a Tailwind scope, for instance. */\n\tclassName?: string;\n\tchildren: ReactNode;\n}) {\n\tconst client = useMemo(\n\t\t() => new Base316Browser({ publishableKey, baseUrl }),\n\t\t[publishableKey, baseUrl],\n\t);\n\n\t// Injected once per document rather than imported. The package ships as\n\t// source, and a bare `import \"./styles.css\"` would force every consumer to\n\t// have a CSS loader configured before anything would render at all.\n\tuseEffect(() => {\n\t\tif (document.getElementById(STYLE_ELEMENT_ID)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst element = document.createElement(\"style\");\n\t\telement.id = STYLE_ELEMENT_ID;\n\t\telement.textContent = STYLESHEET + STYLESHEET_EXTRA;\n\t\tdocument.head.appendChild(element);\n\t}, []);\n\n\tconst controlled = controlledToken !== undefined;\n\tconst [internalToken, setInternalToken] = useState<string | null>(null);\n\tconst [session, setSession] = useState<ResolvedSession | null>(null);\n\tconst [branding, setBranding] = useState<BrandingInfo | null>(null);\n\tconst [loading, setLoading] = useState(true);\n\n\tconst token = controlled ? controlledToken : internalToken;\n\n\t// Read storage after mount rather than in the initial state, so a server\n\t// render and the first client render agree and React does not warn.\n\tuseEffect(() => {\n\t\tif (controlled) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetInternalToken(readStoredToken());\n\t}, [controlled]);\n\n\t// Branding needs only the publishable key, so it loads independently of the\n\t// session and is available on a signed-out page too.\n\t// Keyed by value rather than identity, so an inline `tenant={{ … }}` does\n\t// not refetch on every render.\n\tconst tenantKey = tenant\n\t\t? \"organizationId\" in tenant\n\t\t\t? `id:${tenant.organizationId}`\n\t\t\t: `ext:${tenant.organizationExternalId}`\n\t\t: null;\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tconst request = tenantKey\n\t\t\t? client.billing.tenantBranding(\n\t\t\t\t\ttenantKey.startsWith(\"id:\")\n\t\t\t\t\t\t? { organizationId: tenantKey.slice(3) }\n\t\t\t\t\t\t: { organizationExternalId: tenantKey.slice(4) },\n\t\t\t\t)\n\t\t\t: client.billing.branding();\n\n\t\trequest\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) setBranding(result);\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t// A page without branding is still usable: the components that show\n\t\t\t\t// it render nothing rather than blocking everything else.\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, tenantKey]);\n\n\tconst setToken = useCallback(\n\t\t(next: string | null) => {\n\t\t\tif (controlled) {\n\t\t\t\tonTokenChange?.(next);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\twriteStoredToken(next);\n\t\t\tsetInternalToken(next);\n\t\t\tonTokenChange?.(next);\n\t\t},\n\t\t[controlled, onTokenChange],\n\t);\n\n\tconst refresh = useCallback(async () => {\n\t\tif (!token) {\n\t\t\tsetSession(null);\n\t\t\tsetLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tsetSession(await client.auth.session(token));\n\t\t} catch {\n\t\t\t// An expired or revoked token is indistinguishable from a bad one and\n\t\t\t// both mean the same thing here: this browser is signed out.\n\t\t\tsetSession(null);\n\t\t\tsetToken(null);\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, [client, token, setToken]);\n\n\tuseEffect(() => {\n\t\tsetLoading(true);\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\tconst signOut = useCallback(async () => {\n\t\tif (token) {\n\t\t\tawait client.auth.signOut(token).catch(() => {\n\t\t\t\t// The local session is cleared regardless: a failed revoke must not\n\t\t\t\t// leave someone apparently still signed in.\n\t\t\t});\n\t\t}\n\n\t\tsetToken(null);\n\t\tsetSession(null);\n\t}, [client, token, setToken]);\n\n\tconst value = useMemo(\n\t\t() => ({ client, branding, token, setToken, session, loading, refresh, signOut }),\n\t\t[client, branding, token, setToken, session, loading, refresh, signOut],\n\t);\n\n\treturn (\n\t\t<Base316Context.Provider value={value}>\n\t\t\t<div\n\t\t\t\tclassName={className ? `b316-root ${className}` : \"b316-root\"}\n\t\t\t\tstyle={appearanceToStyle({\n\t\t\t\t\t// Whatever was set in the sign-in designer arrives here, so a\n\t\t\t\t\t// customer styles their login once on Base316 and the embedded\n\t\t\t\t\t// components follow — rather than configuring the same colours\n\t\t\t\t\t// twice and watching them drift apart.\n\t\t\t\t\t//\n\t\t\t\t\t// An explicit `appearance` still wins, because a host that has\n\t\t\t\t\t// gone to the trouble of passing tokens means them.\n\t\t\t\t\t...(branding\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tcolorPrimary: branding.primaryColor,\n\t\t\t\t\t\t\t\tcolorBackground: branding.backgroundColor,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t...appearance,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</Base316Context.Provider>\n\t);\n}\n\nexport function useBase316(): Base316ContextValue {\n\tconst value = useContext(Base316Context);\n\n\tif (!value) {\n\t\tthrow new Error(\"Base316 components must be rendered inside <Base316Provider>.\");\n\t}\n\n\treturn value;\n}\n\n/** The signed-in user, or null. `loading` distinguishes \"no one\" from \"not yet\". */\nexport function useSession(): { session: ResolvedSession | null; loading: boolean } {\n\tconst { session, loading } = useBase316();\n\treturn { session, loading };\n}\n","import type { CSSProperties } from \"react\";\n\n/**\n * How these components are styled, and why it works this way.\n *\n * They drop into an application whose CSS we cannot see. Three approaches were\n * possible and only one of them is actually controllable by the host:\n *\n * - Inline styles are self-contained but *unoverridable* — they beat any\n * stylesheet short of `!important`, so a customer cannot restyle anything.\n * - A shipped stylesheet fights the host's cascade unpredictably.\n * - CSS custom properties, with every value read through a variable, let the\n * host restyle without either side guessing at specificity.\n *\n * So: one small stylesheet, injected once, with every colour, radius and font\n * behind a `--b316-*` variable. A customer can restyle in three ways, from\n * least to most invasive:\n *\n * 1. `appearance` on the provider — tokens, no CSS to write.\n * 2. Their own CSS targeting the `b316-*` class names.\n * 3. `className` on any component, to hand it their own utility classes.\n *\n * Nothing here inherits the host's design automatically. That is deliberate:\n * silently absorbing whatever `body { font }` and `button { }` rules exist\n * produces components that look broken in ways neither side can predict.\n */\n\nexport interface Base316Appearance {\n\t/** Buttons, links, focus rings. */\n\tcolorPrimary?: string;\n\t/** Text on primary-coloured surfaces. */\n\tcolorPrimaryText?: string;\n\tcolorText?: string;\n\tcolorMuted?: string;\n\tcolorBackground?: string;\n\tcolorBorder?: string;\n\tcolorDanger?: string;\n\tcolorDangerBackground?: string;\n\tcolorSuccess?: string;\n\tborderRadius?: string;\n\tfontFamily?: string;\n\tfontSize?: string;\n\tspacing?: string;\n}\n\nconst VARIABLES: Record<keyof Base316Appearance, string> = {\n\tcolorPrimary: \"--b316-color-primary\",\n\tcolorPrimaryText: \"--b316-color-primary-text\",\n\tcolorText: \"--b316-color-text\",\n\tcolorMuted: \"--b316-color-muted\",\n\tcolorBackground: \"--b316-color-background\",\n\tcolorBorder: \"--b316-color-border\",\n\tcolorDanger: \"--b316-color-danger\",\n\tcolorDangerBackground: \"--b316-color-danger-bg\",\n\tcolorSuccess: \"--b316-color-success\",\n\tborderRadius: \"--b316-radius\",\n\tfontFamily: \"--b316-font\",\n\tfontSize: \"--b316-font-size\",\n\tspacing: \"--b316-spacing\",\n};\n\n/** Turn the token object into inline custom properties for the root element. */\nexport function appearanceToStyle(appearance?: Base316Appearance): CSSProperties {\n\tif (!appearance) {\n\t\treturn {};\n\t}\n\n\tconst style: Record<string, string> = {};\n\n\tfor (const [key, variable] of Object.entries(VARIABLES)) {\n\t\tconst value = appearance[key as keyof Base316Appearance];\n\n\t\tif (value !== undefined) {\n\t\t\tstyle[variable] = value;\n\t\t}\n\t}\n\n\treturn style as CSSProperties;\n}\n\nexport const STYLE_ELEMENT_ID = \"base316-components\";\n\n/**\n * The stylesheet, injected once per document.\n *\n * Defaults live on `.b316-root` rather than `:root` so an application that\n * never sets a token still gets a coherent look, and one that sets tokens on a\n * parent still wins through normal inheritance.\n */\nexport const STYLESHEET = `\n.b316-root {\n --b316-color-primary: #111827;\n --b316-color-primary-text: #ffffff;\n --b316-color-text: #111827;\n --b316-color-muted: #6b7280;\n --b316-color-background: #ffffff;\n --b316-color-border: #e5e7eb;\n --b316-color-danger: #991b1b;\n --b316-color-danger-bg: #fef2f2;\n --b316-color-success: #166534;\n --b316-radius: 12px;\n --b316-font: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n --b316-font-size: 15px;\n --b316-spacing: 12px;\n\n font-family: var(--b316-font);\n font-size: var(--b316-font-size);\n line-height: 1.5;\n color: var(--b316-color-text);\n}\n\n.b316-card {\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n padding: calc(var(--b316-spacing) * 1.6);\n background: var(--b316-color-background);\n}\n\n.b316-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: var(--b316-spacing); }\n.b316-label { font-size: 0.87em; color: var(--b316-color-muted); }\n\n.b316-input {\n padding: 9px 11px;\n border: 1px solid var(--b316-color-border);\n border-radius: calc(var(--b316-radius) / 1.6);\n font: inherit;\n color: inherit;\n background: var(--b316-color-background);\n}\n.b316-input:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 1px; }\n\n.b316-button {\n width: 100%;\n padding: 10px 14px;\n border: 0;\n border-radius: calc(var(--b316-radius) / 1.6);\n background: var(--b316-color-primary);\n color: var(--b316-color-primary-text);\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n.b316-button:hover:not([disabled]) { filter: brightness(1.12); }\n.b316-button:active:not([disabled]) { transform: translateY(1px); }\n.b316-button:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }\n.b316-button[disabled] { opacity: .55; cursor: not-allowed; }\n\n.b316-button-secondary {\n width: auto;\n transition: background-color .12s ease;\n background: var(--b316-color-background);\n color: var(--b316-color-text);\n border: 1px solid var(--b316-color-border);\n font-weight: 500;\n}\n\n.b316-button-link {\n width: auto;\n background: none;\n border: 0;\n padding: 0;\n color: var(--b316-color-primary);\n font: inherit;\n cursor: pointer;\n text-decoration: underline;\n}\n\n/*\n * An armed confirmation: the question and its way out, side by side.\n *\n * Inline rather than a dialog, because a sandboxed iframe does not get dialogs\n * and these components are meant to be embedded in one.\n */\n.b316-confirm {\n display: inline-flex;\n gap: .4rem;\n align-items: center;\n}\n\n.b316-error {\n background: var(--b316-color-danger-bg);\n color: var(--b316-color-danger);\n padding: 8px 10px;\n border-radius: calc(var(--b316-radius) / 2);\n font-size: 0.9em;\n margin-bottom: var(--b316-spacing);\n}\n\n.b316-muted { color: var(--b316-color-muted); font-size: 0.87em; }\n.b316-success { color: var(--b316-color-success); }\n\n.b316-plans {\n display: grid;\n gap: calc(var(--b316-spacing) * 1.3);\n grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\n align-items: stretch;\n}\n\n/* Messages above the cards span the row rather than taking a card's column. */\n.b316-plans-error,\n.b316-plans-managed { grid-column: 1 / -1; }\n\n.b316-plan {\n display: flex;\n flex-direction: column;\n padding: 0;\n overflow: hidden;\n}\n\n/* The recommended plan. Lifted rather than merely tinted: on a pricing table\n the eye needs one obvious default, and colour alone does not survive being\n viewed in greyscale or by someone who cannot distinguish the accent. */\n.b316-plan-featured {\n border-color: var(--b316-color-primary);\n box-shadow: 0 0 0 1px var(--b316-color-primary);\n}\n\n.b316-plan-badge {\n display: inline-block;\n background: var(--b316-color-primary);\n color: var(--b316-color-primary-text);\n border-radius: 999px;\n padding: 2px 9px;\n font-size: 0.75em;\n font-weight: 600;\n letter-spacing: .02em;\n margin-bottom: 8px;\n}\n\n/* Occupies the badge's height without drawing anything, so a featured card\n does not push its own price and features out of line with the others. */\n.b316-plan-badge-spacer {\n display: inline-block;\n padding: 2px 9px;\n font-size: 0.75em;\n margin-bottom: 8px;\n visibility: hidden;\n}\n\n.b316-plan-head { padding: calc(var(--b316-spacing) * 1.6); padding-bottom: 0; }\n.b316-plan-name { font-weight: 600; font-size: 1.06em; }\n.b316-plan-desc { color: var(--b316-color-muted); font-size: 0.87em; margin-top: 2px; }\n\n.b316-plan-pricing { padding: 0 calc(var(--b316-spacing) * 1.6) calc(var(--b316-spacing) * 1.4); }\n\n.b316-plan-price {\n font-size: 2.1em;\n font-weight: 640;\n letter-spacing: -.02em;\n margin-top: calc(var(--b316-spacing) * 0.7);\n /* Lining figures of even width, so prices do not shimmer between cards. */\n font-variant-numeric: tabular-nums lining-nums;\n}\n\n.b316-plan-cadence { color: var(--b316-color-muted); font-size: 0.87em; min-height: 1.35em; }\n.b316-plan-trial { color: var(--b316-color-success); font-size: 0.87em; min-height: 1.35em; }\n\n.b316-plan-features {\n list-style: none;\n padding: calc(var(--b316-spacing) * 1.2) calc(var(--b316-spacing) * 1.6);\n margin: 0;\n flex: 1;\n border-top: 1px solid var(--b316-color-border);\n}\n.b316-plan-feature {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding: 5px 0;\n font-size: 0.94em;\n}\n.b316-plan-feature-value { color: var(--b316-color-muted); font-variant-numeric: tabular-nums; }\n\n.b316-plan-action {\n padding: calc(var(--b316-spacing) * 1.2) calc(var(--b316-spacing) * 1.6);\n border-top: 1px solid var(--b316-color-border);\n}\n\n/* The plan already held. A faded primary button reads as broken rather than\n as \"you are here\", so this is a flat, quiet, genuinely inert surface. */\n.b316-button-current,\n.b316-button-current[disabled] {\n background: transparent;\n color: var(--b316-color-muted);\n border: 1px solid var(--b316-color-border);\n font-weight: 500;\n opacity: 1;\n cursor: default;\n}\n\n.b316-row { display: flex; justify-content: space-between; gap: 16px; align-items: center; }\n\n/* Credential lists. A row is a thing plus the actions on it, and the actions\n stay put as names vary in length, so the eye tracks one column not two. */\n.b316-list { list-style: none; margin: 0; padding: 0; }\n\n.b316-list-item {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n padding: 12px 0;\n border-top: 1px solid var(--b316-color-border);\n}\n\n.b316-list-item:first-child { border-top: none; }\n\n/* Carries a secret shown exactly once, so it has to read as different from the\n rest of the card rather than as another paragraph. */\n.b316-notice {\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n background: var(--b316-color-subtle, rgba(0,0,0,0.03));\n padding: 12px;\n font-size: 0.93em;\n}\n\n.b316-checkbox {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 4px 0;\n cursor: pointer;\n}\n\n.b316-checkbox input[disabled] { cursor: default; }\n.b316-checkbox.b316-muted { cursor: default; }\n`;\n\n/** Join the component's own class with any the host passed in. */\nexport function cls(base: string, extra?: string): string {\n\treturn extra ? `${base} ${extra}` : base;\n}\n\n/**\n * Branding and invoice styles.\n *\n * Appended as a second block so the print rules stay next to the invoice they\n * apply to, rather than being buried in the middle of the component styles.\n */\nexport const STYLESHEET_EXTRA = `\n.b316-pay__element { margin-bottom: var(--b316-spacing); min-height: 40px; }\n\n.b316-pay__submit {\n width: 100%;\n padding: 11px 14px;\n border: 0;\n border-radius: calc(var(--b316-radius) / 1.6);\n background: var(--b316-color-primary);\n color: #fff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.b316-pay__submit[disabled] { opacity: 0.55; cursor: progress; }\n\n.b316-pay__error {\n background: var(--b316-color-danger-bg);\n color: var(--b316-color-danger);\n padding: 8px 10px;\n border-radius: calc(var(--b316-radius) / 2);\n font-size: 0.9em;\n margin-bottom: var(--b316-spacing);\n}\n\n.b316-pay__done {\n background: var(--b316-color-success-bg, #f0fdf4);\n color: var(--b316-color-success);\n padding: 12px 14px;\n border-radius: calc(var(--b316-radius) / 2);\n text-align: center;\n margin: 0;\n}\n\n.b316-tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--b316-color-border); }\n.b316-tab {\n flex: 1; padding: 8px 4px; background: none; border: 0; cursor: pointer;\n font: inherit; font-size: .95em; color: var(--b316-color-muted);\n border-bottom: 2px solid transparent; margin-bottom: -1px;\n}\n.b316-tab-on { color: var(--b316-color-text); border-bottom-color: var(--b316-color-primary); }\n.b316-branding { display: flex; flex-direction: column; gap: 4px; }\n.b316-branding-logo { max-height: 40px; width: auto; align-self: flex-start; }\n.b316-branding-name { font-size: 1.5em; font-weight: 650; letter-spacing: -.01em; }\n.b316-branding-tagline { color: var(--b316-color-muted); }\n\n.b316-invoice-table { width: 100%; border-collapse: collapse; font-size: 0.94em; }\n.b316-invoice-table th {\n text-align: left;\n font-weight: 500;\n color: var(--b316-color-muted);\n font-size: 0.85em;\n padding: 0 0 6px;\n border-bottom: 1px solid var(--b316-color-border);\n}\n.b316-invoice-table td { padding: 9px 0; border-bottom: 1px solid var(--b316-color-border); }\n/* Columns need breathing room or the amount runs straight into the action —\n \"$49.00View\" — which is what happens when only the row has padding. */\n.b316-invoice-table th + th,\n.b316-invoice-table td + td { padding-left: 16px; }\n.b316-invoice-table td:last-child,\n.b316-invoice-table th:last-child { text-align: right; width: 1%; white-space: nowrap; }\n.b316-invoice-table tr:last-child td { border-bottom: 0; }\n.b316-num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.b316-invoice-view {\n margin-top: calc(var(--b316-spacing) * 1.4);\n border-top: 1px solid var(--b316-color-border);\n padding-top: calc(var(--b316-spacing) * 1.4);\n}\n.b316-invoice-actions { display: flex; gap: 8px; justify-content: flex-end; margin-bottom: var(--b316-spacing); }\n.b316-invoice-doc { display: flex; flex-direction: column; gap: calc(var(--b316-spacing) * 1.4); }\n.b316-invoice-meta { display: grid; grid-template-columns: 1fr 1fr; gap: var(--b316-spacing); }\n.b316-invoice-totals { display: flex; flex-direction: column; gap: 6px; margin-left: auto; min-width: 240px; }\n.b316-invoice-total { font-weight: 650; border-top: 1px solid var(--b316-color-border); padding-top: 6px; }\n\n/* Printing an invoice emits the invoice alone, and printing anything else is\n none of this package's business.\n\n This used to start with a bare \"body * { visibility: hidden }\", which is the\n usual recipe for printing one element — and it is scoped to the document,\n not to us. The stylesheet is injected into the host page's head the first\n time any Base316 component mounts, so from that moment every print in the\n host application came out blank unless the content happened to sit inside\n .b316-invoice-doc. A customer printing their own page had no way to connect\n it back to us.\n\n Scoped to a root the invoice sets on <html> while it is being printed\n instead, so nothing applies unless an invoice asked for it. */\n@media print {\n [data-b316-printing] body * { visibility: hidden; }\n [data-b316-printing] .b316-invoice-doc,\n [data-b316-printing] .b316-invoice-doc * { visibility: visible; }\n [data-b316-printing] .b316-invoice-doc {\n position: absolute;\n inset: 0 auto auto 0;\n width: 100%;\n padding: 24px;\n }\n .b316-invoice-actions { display: none; }\n}\n\n/* --- Collections: tables, forms and detail views ------------------------- */\n\n.b316-table-wrap { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-table-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); flex-wrap: wrap; }\n.b316-table-actions { display: flex; align-items: center; gap: var(--b316-spacing); }\n\n/* The table scrolls inside its own box rather than pushing the page sideways:\n a collection with twenty fields is normal, and a horizontally scrolling page\n makes every other component on it unreachable. */\n.b316-table-scroll { overflow-x: auto; border: 1px solid var(--b316-color-border); border-radius: var(--b316-radius); }\n.b316-table { width: 100%; border-collapse: collapse; font-size: 0.95em; }\n.b316-table th, .b316-table td { padding: 10px 12px; text-align: left; vertical-align: top; white-space: nowrap; }\n.b316-table thead th { background: var(--b316-color-surface-muted, rgba(0,0,0,.03)); font-weight: 600; font-size: 0.87em; color: var(--b316-color-muted); border-bottom: 1px solid var(--b316-color-border); }\n.b316-table tbody tr + tr td { border-top: 1px solid var(--b316-color-border); }\n.b316-row-clickable { cursor: pointer; }\n.b316-row-clickable:hover td { background: var(--b316-color-surface-muted, rgba(0,0,0,.02)); }\n.b316-table-rowactions { text-align: right; white-space: nowrap; }\n.b316-table-more { display: flex; justify-content: center; }\n\n.b316-sort { background: none; border: 0; padding: 0; font: inherit; color: inherit; cursor: pointer; }\n.b316-sort:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }\n\n.b316-empty { padding: calc(var(--b316-spacing) * 2); text-align: center; color: var(--b316-color-muted); }\n\n.b316-button-quiet {\n background: none;\n border: 0;\n padding: 4px 6px;\n font: inherit;\n font-size: 0.9em;\n color: var(--b316-color-primary);\n cursor: pointer;\n border-radius: calc(var(--b316-radius) / 2);\n}\n.b316-button-quiet:hover:not([disabled]) { background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); }\n.b316-button-quiet:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 1px; }\n.b316-button-quiet[disabled] { opacity: .55; cursor: not-allowed; }\n.b316-danger { color: var(--b316-color-danger, #b42318); }\n\n.b316-chip {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--b316-color-surface-muted, rgba(0,0,0,.05));\n font-size: 0.87em;\n}\n.b316-chips { display: inline-flex; gap: 4px; flex-wrap: wrap; }\n\n.b316-form { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-form-title { margin: 0; font-size: 1.05em; }\n.b316-form-actions { display: flex; justify-content: flex-end; gap: 8px; }\n.b316-field { display: flex; flex-direction: column; gap: 4px; }\n.b316-hint { font-size: 0.82em; color: var(--b316-color-muted); }\n.b316-input-invalid { border-color: var(--b316-color-danger, #b42318); }\n.b316-choices { display: flex; flex-wrap: wrap; gap: 10px; }\n.b316-choice { display: inline-flex; align-items: center; gap: 6px; font-size: 0.95em; }\n.b316-suffixed { display: flex; align-items: center; gap: 8px; }\n.b316-address { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }\n\n.b316-relation-chosen { display: flex; align-items: center; gap: 8px; }\n.b316-relation-results {\n list-style: none;\n margin: 4px 0 0;\n padding: 4px;\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n max-height: 220px;\n overflow-y: auto;\n background: var(--b316-color-surface, #fff);\n}\n.b316-relation-result { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 6px 8px; font: inherit; cursor: pointer; border-radius: calc(var(--b316-radius) / 2); }\n.b316-relation-result:hover, .b316-relation-result:focus-visible { background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); outline: none; }\n.b316-relation-empty { padding: 6px 8px; }\n\n.b316-detail { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--b316-spacing); }\n.b316-detail-title { margin: 0; font-size: 1.1em; }\n.b316-detail-actions { display: flex; gap: 4px; }\n.b316-detail-fields { display: grid; grid-template-columns: minmax(120px, 200px) 1fr; gap: 8px var(--b316-spacing); margin: 0; }\n.b316-detail-row { display: contents; }\n.b316-detail-fields dd { margin: 0; }\n\n/* One column on a narrow screen. A label column of 200px beside a value leaves\n nothing for the value on a phone. */\n/* --- Teams --------------------------------------------------------------- */\n\n.b316-team { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-team-title { margin: 0; font-size: 1em; font-weight: 600; }\n.b316-team-subtitle { margin: 0; font-size: .9em; font-weight: 600; color: var(--b316-color-muted); }\n.b316-team-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }\n.b316-team-member { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); }\n.b316-team-member-side { display: flex; align-items: center; gap: 8px; }\n.b316-team-invite { display: flex; flex-direction: column; gap: 4px; }\n.b316-team-invite-row { display: flex; gap: 8px; }\n.b316-team-invite-row input { flex: 1; }\n/* Selectable and wrapping: this is copied by hand and pasted into an email. */\n.b316-team-link { display: flex; flex-direction: column; gap: 4px; }\n.b316-team-link code { word-break: break-all; user-select: all; padding: 8px; border: 1px solid var(--b316-color-border); border-radius: var(--b316-radius); }\n\n.b316-invitation { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-invitation-actions { display: flex; align-items: center; gap: var(--b316-spacing); }\n\n/* --- Sessions, two-factor and the password flows ------------------------- */\n\n.b316-sessions { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-sessions-head { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); flex-wrap: wrap; }\n.b316-sessions-title, .b316-mfa-title { margin: 0; font-size: 1em; font-weight: 600; }\n.b316-sessions-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }\n.b316-session { display: flex; flex-direction: column; gap: 2px; }\n.b316-session-device { display: flex; align-items: center; gap: 6px; font-size: 0.95em; }\n\n.b316-device { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-device-title { margin: 0; font-size: 1em; font-weight: 600; }\n/* What is being granted, listed rather than run together: somebody is deciding\n on this, and a comma-separated line is read as one thing. */\n.b316-device-scopes { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }\n.b316-device-scopes li { padding: 2px 8px; border-radius: 999px; font-size: 0.85em; background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); }\n.b316-device-actions { display: flex; gap: 8px; }\n\n.b316-privacy { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-privacy-title { margin: 0; font-size: 1em; font-weight: 600; }\n/* Wraps rather than squeezes: the explanation beside each control is the part\n that matters, and on a narrow screen it belongs above the button. */\n.b316-privacy-row { display: flex; flex-wrap: wrap; align-items: start; justify-content: space-between; gap: 10px; }\n.b316-privacy-row p { margin: 0; }\n.b316-privacy-confirm { display: flex; flex-direction: column; gap: 8px; }\n.b316-privacy-actions { display: flex; justify-content: flex-end; gap: 8px; }\n\n.b316-mfa { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-mfa-enrol, .b316-mfa-codes, .b316-mfa-on, .b316-mfa-off { display: flex; flex-direction: column; gap: 10px; }\n.b316-mfa-actions { display: flex; justify-content: flex-end; gap: 8px; }\n/* Selectable and wrapping: this is copied by hand on the device that cannot\n scan its own screen. */\n.b316-mfa-secret code {\n display: block;\n padding: 10px;\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n font-size: 1.05em;\n letter-spacing: .08em;\n word-break: break-all;\n user-select: all;\n}\n.b316-mfa-uri { font-size: 0.9em; }\n.b316-mfa-code-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }\n.b316-mfa-code-list code { user-select: all; }\n/* The enrolment choices: whole-width buttons with their explanation inside,\n so the explanation is part of what a screen reader announces. */\n.b316-mfa-methods { display: flex; flex-direction: column; gap: 8px; border: 0; margin: 0; padding: 0; min-width: 0; }\n.b316-mfa-method { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; text-align: left; }\n.b316-mfa-method .b316-muted { font-weight: 400; }\n/* Always on white with a margin: a QR code on a dark theme does not scan. */\n.b316-mfa-qr { align-self: center; width: 180px; height: 180px; padding: 8px; background: #fff; border-radius: var(--b316-radius); }\n\n@media (max-width: 560px) {\n .b316-mfa-code-list { grid-template-columns: 1fr; }\n .b316-detail-fields { grid-template-columns: 1fr; }\n .b316-detail-row { display: block; margin-bottom: 10px; }\n .b316-address { grid-template-columns: 1fr; }\n}\n\n/* --- Board --------------------------------------------------------------- */\n\n.b316-board-wrap { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n/* The board scrolls sideways inside itself. Six columns is normal and a page\n that scrolls horizontally puts everything else on it out of reach. */\n.b316-board { display: flex; gap: var(--b316-spacing); overflow-x: auto; align-items: flex-start; padding-bottom: 4px; }\n.b316-board-column {\n flex: 0 0 260px;\n background: var(--b316-color-surface-muted, rgba(0,0,0,.03));\n border: 1px solid transparent;\n border-radius: var(--b316-radius);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.b316-board-over { border-color: var(--b316-color-primary); }\n.b316-board-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }\n.b316-board-title { font-weight: 600; font-size: 0.92em; }\n.b316-board-cards { display: flex; flex-direction: column; gap: 8px; min-height: 40px; }\n.b316-board-card {\n background: var(--b316-color-surface, #fff);\n border: 1px solid var(--b316-color-border);\n border-radius: calc(var(--b316-radius) * .8);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 0.9em;\n}\n.b316-board-card[draggable=\"true\"] { cursor: grab; }\n.b316-board-card-title { font-weight: 600; }\n.b316-board-card-field { display: flex; justify-content: space-between; gap: 8px; }\n.b316-board-move { display: flex; align-items: center; gap: 6px; margin-top: 2px; }\n.b316-board-move select { flex: 1; font-size: 0.9em; padding: 2px 4px; }\n.b316-board-empty { color: var(--b316-color-muted); font-size: 0.87em; padding: 6px 2px; }\n\n/* --- Chart --------------------------------------------------------------- */\n\n.b316-chart { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-chart-title { font-weight: 600; font-size: 0.95em; }\n.b316-chart-plot { display: flex; align-items: flex-end; gap: 4px; overflow-x: auto; }\n.b316-chart-col { flex: 1 0 24px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 4px; }\n.b316-chart-bar { width: 100%; background: var(--b316-color-primary); border-radius: 3px 3px 0 0; min-height: 2px; }\n.b316-chart-label { font-size: 0.7em; color: var(--b316-color-muted); white-space: nowrap; transform: rotate(-45deg); transform-origin: top left; height: 1.6em; }\n.b316-chart-data summary { cursor: pointer; font-size: 0.87em; color: var(--b316-color-muted); }\n.b316-chart-data table { margin-top: 8px; }\n\n/* --- Billing portal ------------------------------------------------------ */\n\n.b316-billing-portal { display: grid; gap: var(--b316-spacing); }\n.b316-billing-portal-section-title { font-weight: 600; font-size: 1em; margin: 0 0 8px; }\n.b316-billing-portal .b316-plans { margin: 0; }\n.b316-invoice-row-actions { white-space: nowrap; text-align: right; }\n.b316-invoice-row-actions .b316-button-link + .b316-button-link { margin-left: 8px; }\n.b316-review-table { width: 100%; border-collapse: collapse; font-size: 0.92em; margin: 8px 0; }\n.b316-review-table th, .b316-review-table td { text-align: left; padding: 6px 4px; border-top: 1px solid var(--b316-color-border, #e5e7eb); }\n.b316-review-table th { color: var(--b316-color-muted); font-weight: 500; border-top: 0; }\n.b316-review-gain { color: #065f46; }\n.b316-review-loss { color: var(--b316-color-danger); }\n.b316-review-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }\n@media (max-width: 560px) {\n .b316-invoice-table th:nth-child(2), .b316-invoice-table td:nth-child(2) { display: none; }\n .b316-review-actions .b316-button { flex: 1 1 100%; }\n}\n`;\n","\"use client\";\n\nimport type { CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * The customer's logo, name and tagline, as configured in the dashboard.\n *\n * `brandDisplay` decides which of the logo and the name is shown, so an\n * application's own header matches the Base316-hosted sign-in page without the\n * customer setting their brand up twice. `LOGO` still renders the name as the\n * image's alt text, because a logo that fails to load must not leave the page\n * anonymous.\n */\nexport function Branding({\n\tshowTagline = true,\n\tclassName,\n\tstyle,\n}: {\n\tshowTagline?: boolean;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { branding } = useBase316();\n\n\tif (!branding) {\n\t\treturn null;\n\t}\n\n\tconst showLogo = branding.logoUrl && branding.brandDisplay !== \"NAME\";\n\tconst showName = branding.brandDisplay !== \"LOGO\" || !branding.logoUrl;\n\n\treturn (\n\t\t<div className={cls(\"b316-branding\", className)} style={style}>\n\t\t\t{showLogo ? (\n\t\t\t\t<img className=\"b316-branding-logo\" src={branding.logoUrl!} alt={branding.brandName} />\n\t\t\t) : null}\n\t\t\t{showName ? <div className=\"b316-branding-name\">{branding.brandName}</div> : null}\n\t\t\t{showTagline && branding.tagline ? (\n\t\t\t\t<div className=\"b316-branding-tagline\">{branding.tagline}</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { InvoiceDetail, InvoiceSummary } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\nfunction money(amount: string, currency: string): string {\n\tconst value = Number(amount);\n\n\tif (!Number.isFinite(value)) {\n\t\treturn `${amount} ${currency}`;\n\t}\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\treturn `${value} ${currency}`;\n\t}\n}\n\nfunction day(value: string | null): string {\n\treturn value ? new Date(value).toLocaleDateString() : \"—\";\n}\n\n/** Statuses an invoice can still be paid in: open, or written off and still owed. */\nconst PAYABLE = new Set([\"OPEN\", \"UNCOLLECTIBLE\"]);\n\n/**\n * The signed-in user's invoices: view one, download its PDF, and pay one that\n * is still open.\n *\n * The PDF is the server's own rendering (`/v1/me/invoices/:id/pdf`) — the same\n * document an operator downloads — fetched with the session and handed to the\n * browser as a download, so nothing about it depends on the host page's print\n * stylesheet. Viewing still opens the printable layout in the page.\n *\n * Paying sends the browser to the hosted pay page, minted on demand for that\n * invoice, where Stripe collects the card; the figure charged is read from the\n * invoice there, never from this list.\n *\n * Drafts never appear. They are the rating engine's working state and can still\n * change, so showing one as a bill would be wrong.\n */\nexport function Invoices({ className, style }: { className?: string; style?: CSSProperties }) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [invoices, setInvoices] = useState<InvoiceSummary[] | null>(null);\n\tconst [open, setOpen] = useState<InvoiceDetail | null>(null);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busyId, setBusyId] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (!token) {\n\t\t\tsetInvoices([]);\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.invoices(token)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) setInvoices(result.data);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load invoices\", cause);\n\t\t\t\tif (!cancelled) setError(\"Could not load your invoices.\");\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token]);\n\n\tconst view = useCallback(\n\t\tasync (id: string) => {\n\t\t\tif (!token) return;\n\n\t\t\ttry {\n\t\t\t\tsetOpen(await client.billing.invoice(token, id));\n\t\t\t} catch (cause) {\n\t\t\t\tconsole.error(\"[base316] could not load the invoice\", cause);\n\t\t\t\tsetError(\"Could not open that invoice.\");\n\t\t\t}\n\t\t},\n\t\t[client, token],\n\t);\n\n\tconst download = useCallback(\n\t\tasync (invoice: InvoiceSummary) => {\n\t\t\tif (!token) return;\n\n\t\t\tsetBusyId(invoice.id);\n\n\t\t\ttry {\n\t\t\t\tconst bytes = await client.billing.invoicePdf(token, invoice.id);\n\t\t\t\tconst url = URL.createObjectURL(new Blob([bytes as BlobPart], { type: \"application/pdf\" }));\n\t\t\t\tconst link = document.createElement(\"a\");\n\n\t\t\t\tlink.href = url;\n\t\t\t\tlink.download = `${invoice.number}.pdf`;\n\t\t\t\tdocument.body.appendChild(link);\n\t\t\t\tlink.click();\n\t\t\t\tlink.remove();\n\t\t\t\t// Released after the click has been handled, not before it.\n\t\t\t\tsetTimeout(() => URL.revokeObjectURL(url), 1_000);\n\t\t\t} catch (cause) {\n\t\t\t\tconsole.error(\"[base316] could not download the invoice\", cause);\n\t\t\t\tsetError(\"Could not download that invoice.\");\n\t\t\t} finally {\n\t\t\t\tsetBusyId(null);\n\t\t\t}\n\t\t},\n\t\t[client, token],\n\t);\n\n\tconst pay = useCallback(\n\t\tasync (invoice: InvoiceSummary) => {\n\t\t\tif (!token) return;\n\n\t\t\tsetBusyId(invoice.id);\n\n\t\t\ttry {\n\t\t\t\tconst { url } = await client.billing.invoicePayLink(token, invoice.id);\n\t\t\t\twindow.location.assign(url);\n\t\t\t} catch (cause) {\n\t\t\t\tconsole.error(\"[base316] could not start paying the invoice\", cause);\n\t\t\t\tsetError(\"That invoice cannot be paid online right now.\");\n\t\t\t\tsetBusyId(null);\n\t\t\t}\n\t\t},\n\t\t[client, token],\n\t);\n\n\t/**\n\t * A failure is reported before the loading state swallows it.\n\t *\n\t * `invoices` stays null on both a pending request and a failed one, so this\n\t * guard meant a customer whose fetch failed sat on \"Loading…\" for ever and\n\t * the error div further down was unreachable.\n\t */\n\tif (error) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (sessionLoading || invoices === null) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!token) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tSign in to see your invoices.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (invoices.length === 0) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tNo invoices yet.\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-invoices\", className)} style={style}>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<table className=\"b316-invoice-table\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Invoice</th>\n\t\t\t\t\t\t<th>Period</th>\n\t\t\t\t\t\t<th>Status</th>\n\t\t\t\t\t\t<th className=\"b316-num\">Total</th>\n\t\t\t\t\t\t<th />\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t{invoices.map((invoice) => (\n\t\t\t\t\t\t<tr key={invoice.id}>\n\t\t\t\t\t\t\t<td>{invoice.number}</td>\n\t\t\t\t\t\t\t<td className=\"b316-muted\">\n\t\t\t\t\t\t\t\t{day(invoice.periodStart)} – {day(invoice.periodEnd)}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td className=\"b316-muted\">{invoice.status.toLowerCase()}</td>\n\t\t\t\t\t\t\t<td className=\"b316-num\">{money(invoice.total, invoice.currency)}</td>\n\t\t\t\t\t\t\t<td className=\"b316-invoice-row-actions\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-link\"\n\t\t\t\t\t\t\t\t\tonClick={() => void view(invoice.id)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tView\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-link\"\n\t\t\t\t\t\t\t\t\tdisabled={busyId === invoice.id}\n\t\t\t\t\t\t\t\t\tonClick={() => void download(invoice)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tPDF\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t{PAYABLE.has(invoice.status) &&\n\t\t\t\t\t\t\t\tNumber(invoice.total) - Number(invoice.amountPaid) > 0 ? (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-link\"\n\t\t\t\t\t\t\t\t\t\tdisabled={busyId === invoice.id}\n\t\t\t\t\t\t\t\t\t\tonClick={() => void pay(invoice)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tPay\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t))}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t{open ? <InvoiceView invoice={open} onClose={() => setOpen(null)} /> : null}\n\t\t</div>\n\t);\n}\n\n/**\n * One invoice, laid out to be printed.\n *\n * `b316-print-only` and the print stylesheet mean the browser's print dialog\n * emits just this document rather than the whole application around it.\n */\nfunction InvoiceView({ invoice, onClose }: { invoice: InvoiceDetail; onClose: () => void }) {\n\treturn (\n\t\t<div className=\"b316-invoice-view\">\n\t\t\t<div className=\"b316-invoice-actions\">\n\t\t\t\t<button type=\"button\" className=\"b316-button b316-button-secondary\" onClick={onClose}>\n\t\t\t\t\tClose\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Claim the print stylesheet, print, and give it back.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * The \"print one element\" rule has to hide everything else on\n\t\t\t\t\t\t * the page, so it cannot be left switched on: the stylesheet\n\t\t\t\t\t\t * lives in the host application's `<head>`, and an always-on\n\t\t\t\t\t\t * rule blanked every print the host did for its own reasons.\n\t\t\t\t\t\t * The flag is set only for the moment this button prints.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst root = document.documentElement;\n\n\t\t\t\t\t\troot.setAttribute(\"data-b316-printing\", \"\");\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\twindow.print();\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t// `window.print()` is synchronous in every browser that\n\t\t\t\t\t\t\t// matters, but the attribute must come off even if it throws\n\t\t\t\t\t\t\t// — leaving it set would reinstate exactly the bug this\n\t\t\t\t\t\t\t// replaced.\n\t\t\t\t\t\t\troot.removeAttribute(\"data-b316-printing\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tDownload PDF\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-invoice-doc\">\n\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<div className=\"b316-plan-name\">{invoice.issuer.brandName}</div>\n\t\t\t\t\t\t{invoice.issuer.supportEmail ? (\n\t\t\t\t\t\t\t<div className=\"b316-muted\">{invoice.issuer.supportEmail}</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style={{ textAlign: \"right\" }}>\n\t\t\t\t\t\t<div className=\"b316-plan-name\">{invoice.number}</div>\n\t\t\t\t\t\t<div className=\"b316-muted\">{invoice.status.toLowerCase()}</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div className=\"b316-invoice-meta\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<div className=\"b316-label\">Billed to</div>\n\t\t\t\t\t\t<div>{invoice.customer.name ?? invoice.customer.email ?? \"—\"}</div>\n\t\t\t\t\t\t{invoice.customer.name && invoice.customer.email ? (\n\t\t\t\t\t\t\t<div className=\"b316-muted\">{invoice.customer.email}</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<div className=\"b316-label\">Period</div>\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t{day(invoice.periodStart)} – {day(invoice.periodEnd)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"b316-muted\">Issued {day(invoice.issuedAt)}</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<table className=\"b316-invoice-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th>Description</th>\n\t\t\t\t\t\t\t<th className=\"b316-num\">Qty</th>\n\t\t\t\t\t\t\t<th className=\"b316-num\">Unit</th>\n\t\t\t\t\t\t\t<th className=\"b316-num\">Amount</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{invoice.lineItems.map((line) => (\n\t\t\t\t\t\t\t<tr key={line.id}>\n\t\t\t\t\t\t\t\t<td>{line.description}</td>\n\t\t\t\t\t\t\t\t<td className=\"b316-num b316-muted\">\n\t\t\t\t\t\t\t\t\t{/* Billable, not consumed: the difference is the included\n\t\t\t\t\t\t\t\t\t allowance, and charging it would be wrong. */}\n\t\t\t\t\t\t\t\t\t{line.billable}\n\t\t\t\t\t\t\t\t\t{line.unit ? ` ${line.unit}` : \"\"}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td className=\"b316-num b316-muted\">\n\t\t\t\t\t\t\t\t\t{line.unitAmount === null ? \"—\" : money(line.unitAmount, invoice.currency)}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td className=\"b316-num\">{money(line.amount, invoice.currency)}</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\n\t\t\t\t<div className=\"b316-invoice-totals\">\n\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t<span className=\"b316-muted\">Subtotal</span>\n\t\t\t\t\t\t<span className=\"b316-num\">{money(invoice.subtotal, invoice.currency)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t{Number(invoice.discountTotal) > 0 ? (\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">Discount</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">−{money(invoice.discountTotal, invoice.currency)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{Number(invoice.taxTotal) > 0 ? (\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">Tax</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{money(invoice.taxTotal, invoice.currency)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div className=\"b316-row b316-invoice-total\">\n\t\t\t\t\t\t<span>Total</span>\n\t\t\t\t\t\t<span className=\"b316-num\">{money(invoice.total, invoice.currency)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t{Number(invoice.amountPaid) > 0 ? (\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">Paid</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{money(invoice.amountPaid, invoice.currency)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { UpcomingInvoice as UpcomingInvoiceData } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Formatted for display only. Every figure was computed server-side in decimal\n * arithmetic; nothing here adds amounts together.\n */\nfunction money(amount: string, currency: string): string {\n\tconst value = Number(amount);\n\n\tif (!Number.isFinite(value)) {\n\t\treturn `${amount} ${currency}`;\n\t}\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\treturn `${amount} ${currency}`;\n\t}\n}\n\nconst day = (value: string) => new Date(value).toLocaleDateString();\n\nconst REASON: Record<string, string> = {\n\tRENEWAL: \"Renews\",\n\tFINAL: \"Final invoice\",\n\tTRIAL_END: \"Trial ends\",\n};\n\ntype State =\n\t| { kind: \"loading\" }\n\t| { kind: \"ready\"; invoice: UpcomingInvoiceData }\n\t| { kind: \"none\" }\n\t| { kind: \"managed\" }\n\t| { kind: \"error\" };\n\n/**\n * The signed-in user's next bill: when it arrives, what is on it, and what it\n * comes to.\n *\n * The figures are the billing engine's own — usage so far, the plan fee,\n * addons, one-off charges, discount, tax and wallet balance — computed on\n * request and stored nowhere, so showing this costs the user nothing and can\n * never disagree with the invoice that follows, except by usage that arrives\n * in between.\n *\n * A client company whose plan a firm pays for sees a line saying so rather\n * than the firm's invoice, which lists every other client's usage too.\n */\nexport function UpcomingInvoice({\n\tshowLines = true,\n\tclassName,\n\tstyle,\n}: {\n\t/** Show the breakdown. Off gives one line: the amount and the date. */\n\tshowLines?: boolean;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [state, setState] = useState<State>({ kind: \"loading\" });\n\n\tuseEffect(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.upcomingInvoice(token)\n\t\t\t.then((invoice) => {\n\t\t\t\tif (!cancelled) setState({ kind: \"ready\", invoice });\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\t// Nothing to bill and somebody-else-pays are answers, not failures.\n\t\t\t\t// Read off the status rather than `instanceof`, which fails when the\n\t\t\t\t// host bundles a second copy of the SDK.\n\t\t\t\tconst status = (cause as { status?: unknown } | null)?.status;\n\n\t\t\t\tif (status === 404) {\n\t\t\t\t\tsetState({ kind: \"none\" });\n\t\t\t\t} else if (status === 403) {\n\t\t\t\t\tsetState({ kind: \"managed\" });\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"[base316] could not load the upcoming invoice\", cause);\n\t\t\t\t\tsetState({ kind: \"error\" });\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token]);\n\n\tconst card = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) {\n\t\treturn card(\"Loading…\");\n\t}\n\n\tif (!token) {\n\t\treturn card(\"Sign in to see your next invoice.\");\n\t}\n\n\tswitch (state.kind) {\n\t\tcase \"loading\":\n\t\t\treturn card(\"Loading…\");\n\t\tcase \"error\":\n\t\t\treturn card(\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your next invoice.\n\t\t\t\t</div>,\n\t\t\t);\n\t\tcase \"none\":\n\t\t\treturn card(\"No upcoming invoice.\");\n\t\tcase \"managed\":\n\t\t\treturn card(\"Your plan is provided by the organization that manages your account.\");\n\t}\n\n\tconst { invoice } = state;\n\tconst amount = (value: string) => money(value, invoice.currency);\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-upcoming-invoice\", className)} style={style}>\n\t\t\t<div className=\"b316-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<div className=\"b316-label\">Next invoice</div>\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t{REASON[invoice.reason] ?? \"Issued\"} {day(invoice.issuesAt)}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"b316-plan-name b316-num\">{amount(invoice.amountDue)}</div>\n\t\t\t</div>\n\n\t\t\t{showLines ? (\n\t\t\t\t<>\n\t\t\t\t\t{invoice.lines.length > 0 ? (\n\t\t\t\t\t\t<table className=\"b316-invoice-table\">\n\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t<th>Description</th>\n\t\t\t\t\t\t\t\t\t<th className=\"b316-num\">Amount</th>\n\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t{invoice.lines.map((line, index) => (\n\t\t\t\t\t\t\t\t\t// No ids until an invoice exists; the engine's order is stable.\n\t\t\t\t\t\t\t\t\t<tr key={`${line.kind}-${index}`}>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t{line.description}\n\t\t\t\t\t\t\t\t\t\t\t{line.kind === \"USAGE\" ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{line.billable} billable of {line.quantity}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{line.unit ? ` ${line.unit}` : \"\"}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td className=\"b316-num\">{amount(line.amount)}</td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t</table>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<div className=\"b316-muted\">Nothing to bill yet.</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<div className=\"b316-invoice-totals\">\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">Subtotal</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{amount(invoice.subtotal)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{Number(invoice.discountTotal) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\tDiscount{invoice.discount ? ` (${invoice.discount.code})` : \"\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">−{amount(invoice.discountTotal)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{Number(invoice.taxTotal) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Tax</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">{amount(invoice.taxTotal)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<div className=\"b316-row b316-invoice-total\">\n\t\t\t\t\t\t\t<span>Total</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{amount(invoice.total)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{Number(invoice.walletApplied) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Account balance</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">−{amount(invoice.walletApplied)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{invoice.amountDue !== invoice.total ? (\n\t\t\t\t\t\t\t<div className=\"b316-row b316-invoice-total\">\n\t\t\t\t\t\t\t\t<span>Amount due</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">{amount(invoice.amountDue)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\tUsage up to {day(invoice.issuesAt)} is still added before it is issued.\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { QuantityChangeOutcome, QuantityChangePreview } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Formatted for display only. Every figure was computed server-side in decimal\n * arithmetic; nothing here adds amounts together.\n */\nfunction money(amount: string, currency: string): string {\n\tconst value = Number(amount);\n\n\tif (!Number.isFinite(value)) {\n\t\treturn `${amount} ${currency}`;\n\t}\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\treturn `${amount} ${currency}`;\n\t}\n}\n\nconst day = (value: string) => new Date(value).toLocaleDateString();\n\n/** A fresh key per confirmed change, so a retried click can never charge twice. */\nfunction newIdempotencyKey(): string {\n\tconst random =\n\t\ttypeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\"\n\t\t\t? crypto.randomUUID()\n\t\t\t: `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n\treturn `seats-${random}`;\n}\n\n/** The status off an SDK error, read without `instanceof` (a second SDK copy breaks it). */\nconst statusOf = (cause: unknown) => (cause as { status?: unknown } | null)?.status;\n\ntype Load =\n\t| { kind: \"loading\" }\n\t| { kind: \"ready\"; quantity: number; scheduledQuantity: number | null; limit: string | null }\n\t| { kind: \"none\" }\n\t| { kind: \"managed\"; name: string | null }\n\t| { kind: \"error\" };\n\nexport interface SeatManagerProps {\n\t/** What a unit is called, plural. \"seats\" by default. */\n\tunitLabel?: string;\n\t/** Called after a change is made, with what it did. */\n\tonChange?: (outcome: QuantityChangeOutcome) => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/**\n * Let the signed-in user change how many seats their subscription is for —\n * with the price shown before anything is charged.\n *\n * Preview, then confirm. The preview is the server's own calculation: adding\n * seats is charged now for the part of the period that is left, removing them\n * takes effect at the period end and refunds nothing. The user only chooses the\n * number — how the change is paid for is the application's policy, not theirs.\n *\n * A client company whose plan a firm pays for is told so instead: resizing the\n * firm's subscription would reach every other client it has.\n */\nexport function SeatManager({ unitLabel = \"seats\", onChange, className, style }: SeatManagerProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [load, setLoad] = useState<Load>({ kind: \"loading\" });\n\tconst [target, setTarget] = useState(\"\");\n\tconst [preview, setPreview] = useState<QuantityChangePreview | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst [message, setMessage] = useState<{ tone: \"error\" | \"success\"; text: string } | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst { subscription, managedBy } = await client.billing.subscription(token);\n\n\t\t\tif (managedBy) {\n\t\t\t\tsetLoad({ kind: \"managed\", name: managedBy.name });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!subscription) {\n\t\t\t\tsetLoad({ kind: \"none\" });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// The plan's seat cap, if it has one, comes from a preview of the count\n\t\t\t// already held — it changes nothing and answers what the limit is.\n\t\t\tconst current = await client.billing\n\t\t\t\t.previewQuantity(token, subscription.quantity)\n\t\t\t\t.catch(() => null);\n\n\t\t\tsetLoad({\n\t\t\t\tkind: \"ready\",\n\t\t\t\tquantity: subscription.quantity,\n\t\t\t\tscheduledQuantity: subscription.scheduledQuantity ?? null,\n\t\t\t\tlimit: current?.seatLimit?.limit ?? null,\n\t\t\t});\n\t\t\tsetTarget(String(subscription.quantity));\n\t\t} catch (cause) {\n\t\t\tif (statusOf(cause) === 403) {\n\t\t\t\tsetLoad({ kind: \"managed\", name: null });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconsole.error(\"[base316] could not load the subscription\", cause);\n\t\t\tsetLoad({ kind: \"error\" });\n\t\t}\n\t}, [client, token]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\tconst card = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card b316-seat-manager\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) {\n\t\treturn card(\"Loading…\");\n\t}\n\n\tif (!token) {\n\t\treturn card(`Sign in to manage your ${unitLabel}.`);\n\t}\n\n\tswitch (load.kind) {\n\t\tcase \"loading\":\n\t\t\treturn card(\"Loading…\");\n\t\tcase \"error\":\n\t\t\treturn card(\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your subscription.\n\t\t\t\t</div>,\n\t\t\t);\n\t\tcase \"none\":\n\t\t\treturn card(\"You are not subscribed to a plan.\");\n\t\tcase \"managed\":\n\t\t\treturn card(\n\t\t\t\t`Your plan is provided by ${load.name ?? \"the organization that manages your account\"}. Ask them to change your ${unitLabel}.`,\n\t\t\t);\n\t}\n\n\tconst count = Number(target);\n\tconst valid = Number.isInteger(count) && count >= 1;\n\n\t/** Why a request was refused, in words the user can act on. */\n\tconst refusal = (cause: unknown) => {\n\t\tswitch (statusOf(cause)) {\n\t\t\tcase 400:\n\t\t\t\treturn load.limit !== null\n\t\t\t\t\t? `Your plan allows up to ${load.limit} ${unitLabel}.`\n\t\t\t\t\t: `That number of ${unitLabel} is not available on your plan.`;\n\t\t\tcase 402:\n\t\t\t\treturn \"Add a payment method before adding more.\";\n\t\t\tcase 403:\n\t\t\t\treturn \"Your plan is managed by another organization.\";\n\t\t\tcase 409:\n\t\t\t\treturn \"Your subscription changed in the meantime. Preview again.\";\n\t\t\tdefault:\n\t\t\t\treturn `Could not change your ${unitLabel}.`;\n\t\t}\n\t};\n\n\tconst runPreview = async () => {\n\t\tsetBusy(true);\n\t\tsetMessage(null);\n\n\t\ttry {\n\t\t\tsetPreview(await client.billing.previewQuantity(token, count));\n\t\t} catch (cause) {\n\t\t\tsetPreview(null);\n\t\t\tsetMessage({ tone: \"error\", text: refusal(cause) });\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst confirm = async () => {\n\t\tif (!preview) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetMessage(null);\n\n\t\ttry {\n\t\t\tconst outcome = await client.billing.setQuantity(token, preview.quantity, {\n\t\t\t\tidempotencyKey: newIdempotencyKey(),\n\t\t\t});\n\n\t\t\tsetPreview(null);\n\t\t\tsetMessage({\n\t\t\t\ttone: \"success\",\n\t\t\t\ttext:\n\t\t\t\t\toutcome.effective === \"period_end\" && outcome.direction !== \"unchanged\"\n\t\t\t\t\t\t? `You will have ${outcome.quantity} ${unitLabel} from ${day(outcome.effectiveAt)}.`\n\t\t\t\t\t\t: `You now have ${outcome.quantity} ${unitLabel}.`,\n\t\t\t});\n\t\t\tonChange?.(outcome);\n\t\t\tawait refresh();\n\t\t} catch (cause) {\n\t\t\tsetMessage({ tone: \"error\", text: refusal(cause) });\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst amount = (value: string) => money(value, preview?.currency ?? \"USD\");\n\n\treturn card(\n\t\t<>\n\t\t\t<div className=\"b316-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<div className=\"b316-label\">{unitLabel.charAt(0).toUpperCase() + unitLabel.slice(1)}</div>\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t{load.quantity} now\n\t\t\t\t\t\t{load.scheduledQuantity !== null\n\t\t\t\t\t\t\t? ` · ${load.scheduledQuantity} from the end of this period`\n\t\t\t\t\t\t\t: \"\"}\n\t\t\t\t\t\t{load.limit !== null ? ` · up to ${load.limit} on your plan` : \"\"}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-row\">\n\t\t\t\t<input\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"number\"\n\t\t\t\t\tmin={1}\n\t\t\t\t\tmax={load.limit === null ? undefined : Number(load.limit)}\n\t\t\t\t\tstep={1}\n\t\t\t\t\taria-label={`Number of ${unitLabel}`}\n\t\t\t\t\tvalue={target}\n\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\tsetTarget(event.target.value);\n\t\t\t\t\t\t// A preview is for the number it was asked about. Confirming one\n\t\t\t\t\t\t// computed for a different number would charge the wrong amount.\n\t\t\t\t\t\tsetPreview(null);\n\t\t\t\t\t\tsetMessage(null);\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\tdisabled={!valid || busy || count === load.quantity}\n\t\t\t\t\tonClick={runPreview}\n\t\t\t\t>\n\t\t\t\t\tPreview\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t{preview ? (\n\t\t\t\t<div className=\"b316-invoice-totals\" data-testid=\"seat-preview\">\n\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t\t{preview.direction === \"increase\" ? \"Due now\" : \"Due now (nothing is refunded)\"}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span className=\"b316-num\">{amount(preview.total)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t<span className=\"b316-muted\">Each period from then</span>\n\t\t\t\t\t\t<span className=\"b316-num\">{amount(preview.newRecurringAmount)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t{preview.effective === \"period_end\"\n\t\t\t\t\t\t\t? `Takes effect at the end of this period, ${day(preview.effectiveAt)}.`\n\t\t\t\t\t\t\t: preview.proration === \"invoice_now\"\n\t\t\t\t\t\t\t\t? `Charged for the rest of this period, which ends ${day(preview.currentPeriodEnd)}.`\n\t\t\t\t\t\t\t\t: \"Takes effect now.\"}\n\t\t\t\t\t</div>\n\t\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={confirm}>\n\t\t\t\t\t\t{preview.direction === \"increase\" && Number(preview.total) > 0\n\t\t\t\t\t\t\t? `Pay ${amount(preview.total)} and change to ${preview.quantity}`\n\t\t\t\t\t\t\t: `Change to ${preview.quantity}`}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{message?.tone === \"error\" ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{message.text}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{message?.tone === \"success\" ? (\n\t\t\t\t<output className=\"b316-success\">{message.text}</output>\n\t\t\t) : null}\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { BillingDetails, CustomerAddress, TaxIdInput } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/** The tax id types offered when the application does not choose its own list. */\nconst DEFAULT_TAX_ID_TYPES: { type: string; label: string; example: string }[] = [\n\t{ type: \"eu_vat\", label: \"EU VAT number\", example: \"DE123456789\" },\n\t{ type: \"gb_vat\", label: \"UK VAT number\", example: \"GB123456789\" },\n\t{ type: \"ch_vat\", label: \"Swiss VAT number\", example: \"CHE-123.456.789 MWST\" },\n\t{ type: \"no_vat\", label: \"Norwegian VAT number\", example: \"123456789MVA\" },\n\t{ type: \"au_abn\", label: \"Australian ABN\", example: \"12345678912\" },\n\t{ type: \"nz_gst\", label: \"New Zealand GST number\", example: \"123456789\" },\n\t{ type: \"ca_gst_hst\", label: \"Canadian GST/HST number\", example: \"123456789RT0002\" },\n\t{ type: \"in_gst\", label: \"Indian GSTIN\", example: \"12ABCDE3456FGZH\" },\n\t{ type: \"us_ein\", label: \"US EIN\", example: \"12-3456789\" },\n];\n\nconst STATUS_TEXT: Record<string, string> = {\n\tVERIFIED: \"Verified\",\n\tUNVERIFIED: \"Not checked\",\n\tINVALID: \"Not registered\",\n\tUNAVAILABLE: \"Check pending\",\n};\n\n/** The status off an SDK error, read without `instanceof` (a second SDK copy breaks it). */\nconst statusOf = (cause: unknown) => (cause as { status?: unknown } | null)?.status;\nconst messageOf = (cause: unknown) =>\n\ttypeof (cause as { message?: unknown } | null)?.message === \"string\"\n\t\t? (cause as { message: string }).message\n\t\t: \"Your details could not be saved.\";\n\ntype Load =\n\t| { kind: \"loading\" }\n\t| { kind: \"ready\"; details: BillingDetails }\n\t| { kind: \"none\" }\n\t| { kind: \"managed\" }\n\t| { kind: \"error\" };\n\nconst EMPTY: Record<keyof CustomerAddress, string> = {\n\tline1: \"\",\n\tline2: \"\",\n\tcity: \"\",\n\tstate: \"\",\n\tpostalCode: \"\",\n\tcountry: \"\",\n};\n\nexport interface BillingDetailsFormProps {\n\t/**\n\t * The tax id types to offer, in order. Stripe's type names; the defaults\n\t * cover the EU, UK, Switzerland, Norway, Australia, New Zealand, Canada,\n\t * India and the US.\n\t */\n\ttaxIdTypes?: { type: string; label: string; example: string }[];\n\t/** Called after a save, with the details as stored — tax ids with their check result. */\n\tonSave?: (details: BillingDetails) => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/**\n * The signed-in user's billing address and tax ids.\n *\n * Saved against their own account only — the session decides which, never\n * anything the page sends. An EU VAT number is checked with the EU's VIES\n * service as it is saved, and its result shown: a number VIES does not know is\n * kept and marked, never silently dropped, and one VIES cannot reach right now\n * is checked again later. Invoices are made out to this address, and a valid\n * EU VAT number lets a cross-border business purchase be reverse charged.\n *\n * A client company whose plan a firm pays for is told so instead: the firm's\n * account is the one invoiced.\n */\nexport function BillingDetailsForm({\n\ttaxIdTypes = DEFAULT_TAX_ID_TYPES,\n\tonSave,\n\tclassName,\n\tstyle,\n}: BillingDetailsFormProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [load, setLoad] = useState<Load>({ kind: \"loading\" });\n\tconst [address, setAddress] = useState(EMPTY);\n\tconst [kept, setKept] = useState<TaxIdInput[]>([]);\n\tconst [newType, setNewType] = useState(taxIdTypes[0]?.type ?? \"eu_vat\");\n\tconst [newValue, setNewValue] = useState(\"\");\n\tconst [busy, setBusy] = useState(false);\n\tconst [message, setMessage] = useState<{ tone: \"error\" | \"success\"; text: string } | null>(null);\n\n\tconst show = useCallback((details: BillingDetails) => {\n\t\tsetLoad({ kind: \"ready\", details });\n\t\tsetAddress({\n\t\t\tline1: details.address.line1 ?? \"\",\n\t\t\tline2: details.address.line2 ?? \"\",\n\t\t\tcity: details.address.city ?? \"\",\n\t\t\tstate: details.address.state ?? \"\",\n\t\t\tpostalCode: details.address.postalCode ?? \"\",\n\t\t\tcountry: details.address.country ?? \"\",\n\t\t});\n\t\tsetKept(details.taxIds.map(({ type, value }) => ({ type, value })));\n\t}, []);\n\n\tconst refresh = useCallback(async () => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tshow(await client.billing.billingDetails(token));\n\t\t} catch (cause) {\n\t\t\tconst status = statusOf(cause);\n\n\t\t\tif (status === 403) {\n\t\t\t\tsetLoad({ kind: \"managed\" });\n\t\t\t} else if (status === 404) {\n\t\t\t\tsetLoad({ kind: \"none\" });\n\t\t\t} else {\n\t\t\t\tconsole.error(\"[base316] could not load billing details\", cause);\n\t\t\t\tsetLoad({ kind: \"error\" });\n\t\t\t}\n\t\t}\n\t}, [client, token, show]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\tconst card = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card b316-billing-details\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) {\n\t\treturn card(\"Loading…\");\n\t}\n\n\tif (!token) {\n\t\treturn card(\"Sign in to manage your billing details.\");\n\t}\n\n\tswitch (load.kind) {\n\t\tcase \"loading\":\n\t\t\treturn card(\"Loading…\");\n\t\tcase \"error\":\n\t\t\treturn card(\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your billing details.\n\t\t\t\t</div>,\n\t\t\t);\n\t\tcase \"none\":\n\t\t\treturn card(\"There is no billing account for you yet.\");\n\t\tcase \"managed\":\n\t\t\treturn card(\"Your billing is managed by the organization that provides your plan.\");\n\t}\n\n\tconst { details } = load;\n\n\tconst save = async () => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetMessage(null);\n\n\t\tconst taxIds = newValue.trim() ? [...kept, { type: newType, value: newValue.trim() }] : kept;\n\t\tconst value = (text: string) => text.trim() || null;\n\n\t\ttry {\n\t\t\tconst saved = await client.billing.updateBillingDetails(token, {\n\t\t\t\taddress: {\n\t\t\t\t\tline1: value(address.line1),\n\t\t\t\t\tline2: value(address.line2),\n\t\t\t\t\tcity: value(address.city),\n\t\t\t\t\tstate: value(address.state),\n\t\t\t\t\tpostalCode: value(address.postalCode),\n\t\t\t\t\tcountry: value(address.country)?.toUpperCase() ?? null,\n\t\t\t\t},\n\t\t\t\ttaxIds,\n\t\t\t});\n\n\t\t\tshow(saved);\n\t\t\tsetNewValue(\"\");\n\t\t\tsetMessage({ tone: \"success\", text: \"Billing details saved.\" });\n\t\t\tonSave?.(saved);\n\t\t} catch (cause) {\n\t\t\tsetMessage({ tone: \"error\", text: messageOf(cause) });\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst field = (key: keyof CustomerAddress, label: string, autoComplete: string) => (\n\t\t<label className=\"b316-field\">\n\t\t\t<span className=\"b316-label\">{label}</span>\n\t\t\t<input\n\t\t\t\tclassName=\"b316-input\"\n\t\t\t\tvalue={address[key]}\n\t\t\t\tautoComplete={autoComplete}\n\t\t\t\tmaxLength={key === \"country\" ? 2 : 200}\n\t\t\t\tonChange={(event) => setAddress({ ...address, [key]: event.target.value })}\n\t\t\t/>\n\t\t</label>\n\t);\n\n\tconst labelFor = (type: string) => taxIdTypes.find((entry) => entry.type === type)?.label ?? type;\n\tconst example = taxIdTypes.find((entry) => entry.type === newType)?.example;\n\n\treturn card(\n\t\t<form\n\t\t\tclassName=\"b316-form\"\n\t\t\tonSubmit={(event) => {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tvoid save();\n\t\t\t}}\n\t\t>\n\t\t\t<fieldset className=\"b316-fieldset\">\n\t\t\t\t<legend className=\"b316-legend\">Billing address</legend>\n\t\t\t\t{field(\"line1\", \"Address\", \"address-line1\")}\n\t\t\t\t{field(\"line2\", \"Address line 2\", \"address-line2\")}\n\t\t\t\t{field(\"city\", \"City\", \"address-level2\")}\n\t\t\t\t{field(\"postalCode\", \"Postal code\", \"postal-code\")}\n\t\t\t\t{field(\"state\", \"State, province or region\", \"address-level1\")}\n\t\t\t\t{field(\"country\", \"Country (two-letter code)\", \"country\")}\n\t\t\t</fieldset>\n\n\t\t\t<fieldset className=\"b316-fieldset\">\n\t\t\t\t<legend className=\"b316-legend\">Tax ids</legend>\n\n\t\t\t\t{details.taxIds.length > 0 && (\n\t\t\t\t\t<ul className=\"b316-list\" data-testid=\"tax-ids\">\n\t\t\t\t\t\t{details.taxIds\n\t\t\t\t\t\t\t.filter((taxId) =>\n\t\t\t\t\t\t\t\tkept.some((entry) => entry.type === taxId.type && entry.value === taxId.value),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.map((taxId) => (\n\t\t\t\t\t\t\t\t<li key={taxId.id} className=\"b316-list-item\">\n\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t{labelFor(taxId.type)} <code>{taxId.value}</code>{\" \"}\n\t\t\t\t\t\t\t\t\t\t<span className={`b316-status b316-status-${taxId.status.toLowerCase()}`}>\n\t\t\t\t\t\t\t\t\t\t\t{STATUS_TEXT[taxId.status] ?? taxId.status}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"b316-link\"\n\t\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\t\tsetKept(\n\t\t\t\t\t\t\t\t\t\t\t\tkept.filter(\n\t\t\t\t\t\t\t\t\t\t\t\t\t(entry) => !(entry.type === taxId.type && entry.value === taxId.value),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tRemove\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t)}\n\n\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t<span className=\"b316-label\">Type</span>\n\t\t\t\t\t<select\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tvalue={newType}\n\t\t\t\t\t\tonChange={(event) => setNewType(event.target.value)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{taxIdTypes.map((entry) => (\n\t\t\t\t\t\t\t<option key={entry.type} value={entry.type}>\n\t\t\t\t\t\t\t\t{entry.label}\n\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</select>\n\t\t\t\t</label>\n\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t<span className=\"b316-label\">Tax id</span>\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tvalue={newValue}\n\t\t\t\t\t\tplaceholder={example}\n\t\t\t\t\t\tmaxLength={64}\n\t\t\t\t\t\tonChange={(event) => setNewValue(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t</label>\n\t\t\t</fieldset>\n\n\t\t\t{message?.tone === \"error\" && (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{message.text}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t{message?.tone === \"success\" && (\n\t\t\t\t<div className=\"b316-success\" role=\"status\">\n\t\t\t\t\t{message.text}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy}>\n\t\t\t\t{busy ? \"Saving…\" : \"Save billing details\"}\n\t\t\t</button>\n\t\t</form>,\n\t);\n}\n","\"use client\";\n\nimport {\n\tBase316Error,\n\tisPasskeyAutofillAvailable,\n\tisPasskeySupported,\n\tneedsSecondFactor,\n\ttype SignInPending,\n} from \"@base316/sdk\";\nimport { useEffect, useRef, useState, type CSSProperties, type FormEvent } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\nimport { SecondFactorStep, type SecondFactorLabels } from \"./SecondFactorStep\";\n\n/**\n * Email and password sign-in, and — where the application turns them on — a\n * magic link or a code by text message.\n *\n * Handles the MFA branch, because an account with a second factor gets a\n * challenge instead of a session, and a form that ignores that case appears to\n * fail for exactly the users who most need it to work. That includes the case\n * where the environment requires a factor and the person has none: they enrol\n * one here (`SecondFactorStep`), see their recovery codes, and are signed in.\n */\nexport function SignIn({\n\tonSignedIn,\n\tpasskeys = true,\n\tmagicLinkRedirectUrl,\n\tphone = false,\n\tsecondFactorLabels,\n\tclassName,\n\tstyle,\n}: {\n\tonSignedIn?: () => void;\n\t/** Offer passkeys alongside the password. On by default where supported. */\n\tpasskeys?: boolean;\n\t/**\n\t * Where an emailed sign-in link lands. Offering magic link at all requires\n\t * it, because the link has to point somewhere this application controls —\n\t * and the URL must be registered on the environment's sign-in page, the same\n\t * list that governs redirects.\n\t *\n\t * The page it names should render this component: arriving with `?token=`\n\t * redeems it automatically.\n\t */\n\tmagicLinkRedirectUrl?: string;\n\t/**\n\t * Offer signing in with a code sent by text message.\n\t *\n\t * Off by default, because it needs the environment switched on for it and,\n\t * in production, the environment's own Twilio account.\n\t */\n\tphone?: boolean;\n\t/** Override the second-factor step's wording, for translation. */\n\tsecondFactorLabels?: Partial<SecondFactorLabels>;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { client, setToken } = useBase316();\n\tconst [email, setEmail] = useState(\"\");\n\tconst [password, setPassword] = useState(\"\");\n\tconst [code, setCode] = useState(\"\");\n\t// A sign-in that owes a second factor — a code for one they have, or an\n\t// enrolment when the environment requires one and they have none. The step\n\t// renders from this rather than assuming an authenticator app.\n\tconst [pending, setPending] = useState<SignInPending | null>(null);\n\tconst pendingChallenge = pending?.challengeToken ?? null;\n\tconst [phoneNumber, setPhoneNumber] = useState(\"\");\n\tconst [phoneChallenge, setPhoneChallenge] = useState<{ token: string; hint: string } | null>(\n\t\tnull,\n\t);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\t// Whether to draw a passkey button at all. Resolved in an effect rather than\n\t// during render: it asks the browser, and it is false on the server.\n\tconst [passkeyReady, setPasskeyReady] = useState(false);\n\n\tconst [mode, setMode] = useState<\"password\" | \"magic\" | \"phone\">(\"password\");\n\tconst [linkSent, setLinkSent] = useState(false);\n\tconst abortRef = useRef<AbortController | null>(null);\n\n\tconst signInWithPasskey = async (conditional: boolean, signal?: AbortSignal) => {\n\t\tif (!conditional) {\n\t\t\tsetBusy(true);\n\t\t\tsetError(null);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await client.auth.passkeys.signIn({ conditional, signal });\n\n\t\t\tsetToken(result.token);\n\t\t\tonSignedIn?.();\n\t\t} catch (cause) {\n\t\t\t// Cancelling is an answer, not an error — and a conditional ceremony\n\t\t\t// aborts every time the component unmounts, which must stay silent.\n\t\t\tif (\n\t\t\t\tcause instanceof DOMException &&\n\t\t\t\t(cause.name === \"NotAllowedError\" || cause.name === \"AbortError\")\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// A good passkey on an unconfirmed address is said out loud, even from\n\t\t\t// autofill: it is answered only after the assertion verified, and\n\t\t\t// staying silent would leave somebody pressing a key that works.\n\t\t\tif (cause instanceof Base316Error && cause.reason === \"EMAIL_NOT_VERIFIED\") {\n\t\t\t\tsetError(cause.message);\n\t\t\t} else if (!conditional) {\n\t\t\t\tconsole.error(\"[base316] passkey sign-in failed\", cause);\n\t\t\t\tsetError(\"That passkey did not work.\");\n\t\t\t}\n\t\t} finally {\n\t\t\tif (!conditional) {\n\t\t\t\tsetBusy(false);\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Offer the passkey in the browser's own autofill list.\n\t *\n\t * This is what makes a passkey better than a password rather than merely\n\t * different: the credential appears in the email field's suggestions and one\n\t * tap signs in. The promise stays pending until somebody picks one, so it is\n\t * aborted on unmount.\n\t */\n\tuseEffect(() => {\n\t\tif (!passkeys || !isPasskeySupported() || pendingChallenge) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetPasskeyReady(true);\n\n\t\tconst controller = new AbortController();\n\t\tabortRef.current = controller;\n\n\t\tvoid isPasskeyAutofillAvailable().then((available) => {\n\t\t\tif (available && !controller.signal.aborted) {\n\t\t\t\tvoid signInWithPasskey(true, controller.signal);\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tcontroller.abort();\n\t\t};\n\t\t// Re-running this on every render would start a new ceremony each time,\n\t\t// so it deliberately depends only on what decides whether to run at all.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [passkeys, pendingChallenge]);\n\n\t/**\n\t * Redeem a token the link put in the address bar.\n\t *\n\t * Removed from the URL as soon as it is read: a sign-in token sitting in\n\t * history, or in whatever the page sends to an analytics service, is a\n\t * credential lying around in public.\n\t */\n\tuseEffect(() => {\n\t\tif (typeof window === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(window.location.href);\n\t\tconst token = url.searchParams.get(\"token\");\n\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\turl.searchParams.delete(\"token\");\n\t\twindow.history.replaceState({}, \"\", url.toString());\n\n\t\tlet cancelled = false;\n\n\t\tvoid client.auth.magicLink\n\t\t\t.verify({ token })\n\t\t\t.then((result) => {\n\t\t\t\tif (cancelled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// A link proves the mailbox, not the second factor. Treating the\n\t\t\t\t// challenge as a session used to call setToken(undefined) — which\n\t\t\t\t// looked exactly like being signed out.\n\t\t\t\tif (needsSecondFactor(result)) {\n\t\t\t\t\tsetPending(result);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsetToken(result.token);\n\t\t\t\tonSignedIn?.();\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(\"That sign-in link is no longer valid. Ask for a new one.\");\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t\t// Once, on arrival. Re-running would redeem a token already spent.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, []);\n\n\tasync function sendLink() {\n\t\tif (!magicLinkRedirectUrl) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.magicLink.request({ email, redirectUrl: magicLinkRedirectUrl });\n\n\t\t\t// Shown whether or not the address has an account: a sign-in form is\n\t\t\t// not a place to find out who has registered.\n\t\t\tsetLinkSent(true);\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] magic link request failed\", cause);\n\t\t\tsetError(\"We could not send that link. Try again.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function submit(event: FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tif (mode === \"magic\" && !pendingChallenge) {\n\t\t\t\tawait sendLink();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (mode === \"phone\") {\n\t\t\t\tif (!phoneChallenge) {\n\t\t\t\t\tconst started = await client.auth.phone.start({ phone: phoneNumber });\n\n\t\t\t\t\t// The same answer whether or not the number has an account, so the\n\t\t\t\t\t// next step is always the code box.\n\t\t\t\t\tsetPhoneChallenge({ token: started.challengeToken, hint: started.destinationHint });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst signedIn = await client.auth.phone.verify({\n\t\t\t\t\tchallengeToken: phoneChallenge.token,\n\t\t\t\t\tcode,\n\t\t\t\t});\n\n\t\t\t\tif (needsSecondFactor(signedIn)) {\n\t\t\t\t\tsetPending(signedIn);\n\t\t\t\t\tsetCode(\"\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsetToken(signedIn.token);\n\t\t\t\tonSignedIn?.();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst result = await client.auth.signIn({ email, password });\n\n\t\t\t// `needsSecondFactor` is the SDK's narrowing helper; the response itself\n\t\t\t// carries `mfaRequired`. Testing for a field of the helper's name never\n\t\t\t// matched, so a second-factor account fell through to \"wrong password\".\n\t\t\tif (needsSecondFactor(result)) {\n\t\t\t\tsetPending(result);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetToken(result.token);\n\t\t\tonSignedIn?.();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] sign-in failed\", cause);\n\t\t\tsetError(\n\t\t\t\tmode === \"phone\"\n\t\t\t\t\t? phoneChallenge\n\t\t\t\t\t\t? \"That code did not work. Check it, or ask for a new one.\"\n\t\t\t\t\t\t: // Why a text could not be sent is worth saying — a number in the\n\t\t\t\t\t\t\t// wrong format, or too many requests — and the server words it\n\t\t\t\t\t\t\t// without saying anything about accounts.\n\t\t\t\t\t\t\tcause instanceof Error && cause.message\n\t\t\t\t\t\t\t? cause.message\n\t\t\t\t\t\t\t: \"We could not send a code. Try again.\"\n\t\t\t\t\t: // An unconfirmed address and a throttle are worth naming; the\n\t\t\t\t\t\t// server words both without saying whether an account exists.\n\t\t\t\t\t\tcause instanceof Base316Error &&\n\t\t\t\t\t\t (cause.reason === \"EMAIL_NOT_VERIFIED\" || cause.code === \"RATE_LIMITED\")\n\t\t\t\t\t\t? cause.message\n\t\t\t\t\t\t: \"That email and password did not match.\",\n\t\t\t);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\t// Only where the host gave somewhere for the link to land. A tab that cannot\n\t// work is worse than an absent one.\n\tconst magicAvailable = Boolean(magicLinkRedirectUrl) && !pendingChallenge;\n\tconst tabsShown = (magicAvailable || phone) && !pendingChallenge;\n\n\tif (pending) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<SecondFactorStep\n\t\t\t\t\tpending={pending}\n\t\t\t\t\tlabels={secondFactorLabels}\n\t\t\t\t\tonSignedIn={onSignedIn}\n\t\t\t\t\tonRestart={() => {\n\t\t\t\t\t\tsetPending(null);\n\t\t\t\t\t\tsetPassword(\"\");\n\t\t\t\t\t\tsetCode(\"\");\n\t\t\t\t\t\tsetPhoneChallenge(null);\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (linkSent) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div style={{ fontWeight: 600, marginBottom: 6 }}>Check your email</div>\n\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\tIf an account exists for {email}, a sign-in link is on its way. It expires shortly and can\n\t\t\t\t\tbe used once.\n\t\t\t\t</div>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\tstyle={{ marginTop: 16 }}\n\t\t\t\t\tonClick={() => setLinkSent(false)}\n\t\t\t\t>\n\t\t\t\t\tBack to sign in\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form onSubmit={submit} className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{tabsShown ? (\n\t\t\t\t<div className=\"b316-tabs\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName={cls(\"b316-tab\", mode === \"password\" ? \"b316-tab-on\" : undefined)}\n\t\t\t\t\t\tonClick={() => setMode(\"password\")}\n\t\t\t\t\t>\n\t\t\t\t\t\tPassword\n\t\t\t\t\t</button>\n\t\t\t\t\t{magicAvailable ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={cls(\"b316-tab\", mode === \"magic\" ? \"b316-tab-on\" : undefined)}\n\t\t\t\t\t\t\tonClick={() => setMode(\"magic\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tMagic link\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{phone ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName={cls(\"b316-tab\", mode === \"phone\" ? \"b316-tab-on\" : undefined)}\n\t\t\t\t\t\t\tonClick={() => setMode(\"phone\")}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tText message\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{mode === \"phone\" ? (\n\t\t\t\tphoneChallenge ? (\n\t\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-phone-code\">\n\t\t\t\t\t\t\tCode\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tid=\"b316-phone-code\"\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\tvalue={code}\n\t\t\t\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\t\t\t\tautoComplete=\"one-time-code\"\n\t\t\t\t\t\t\tinputMode=\"numeric\"\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t\tWe sent a code to {phoneChallenge.hint}. It expires in ten minutes.{\" \"}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tsetPhoneChallenge(null);\n\t\t\t\t\t\t\t\t\tsetCode(\"\");\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tUse a different number\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t) : (\n\t\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-phone\">\n\t\t\t\t\t\t\tMobile number\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tid=\"b316-phone\"\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\ttype=\"tel\"\n\t\t\t\t\t\t\tvalue={phoneNumber}\n\t\t\t\t\t\t\tonChange={(event) => setPhoneNumber(event.target.value)}\n\t\t\t\t\t\t\tautoComplete=\"tel\"\n\t\t\t\t\t\t\tplaceholder=\"+14155550123\"\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<span className=\"b316-muted\">Include the country code.</span>\n\t\t\t\t\t</div>\n\t\t\t\t)\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-email\">\n\t\t\t\t\t\t\tEmail\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tid=\"b316-email\"\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\tvalue={email}\n\t\t\t\t\t\t\tonChange={(event) => setEmail(event.target.value)}\n\t\t\t\t\t\t\tautoComplete={passkeyReady ? \"email webauthn\" : \"email\"}\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t{mode === \"password\" ? (\n\t\t\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-password\">\n\t\t\t\t\t\t\t\tPassword\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tid=\"b316-password\"\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\tvalue={password}\n\t\t\t\t\t\t\t\tonChange={(event) => setPassword(event.target.value)}\n\t\t\t\t\t\t\t\tautoComplete=\"current-password\"\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t)}\n\n\t\t\t<button className=\"b316-button\" type=\"submit\" disabled={busy}>\n\t\t\t\t{busy\n\t\t\t\t\t? \"Working…\"\n\t\t\t\t\t: mode === \"magic\"\n\t\t\t\t\t\t? \"Email me a link\"\n\t\t\t\t\t\t: mode === \"phone\" && !phoneChallenge\n\t\t\t\t\t\t\t? \"Text me a code\"\n\t\t\t\t\t\t\t: \"Sign in\"}\n\t\t\t</button>\n\n\t\t\t{passkeyReady && !pendingChallenge ? (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"b316-muted\" style={{ textAlign: \"center\", margin: \"10px 0\" }}>\n\t\t\t\t\t\tor\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t// The conditional ceremony holds the only credential request\n\t\t\t\t\t\t\t// the browser allows at a time; it has to go before a\n\t\t\t\t\t\t\t// deliberate one can start.\n\t\t\t\t\t\t\tabortRef.current?.abort();\n\t\t\t\t\t\t\tvoid signInWithPasskey(false);\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tSign in with a passkey\n\t\t\t\t\t</button>\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport {\n\tBase316Error,\n\ttype RequiredEnrollmentMethod,\n\ttype RequiredEnrollmentStart,\n\ttype SignInPending,\n} from \"@base316/sdk\";\nimport { useEffect, useRef, useState, type CSSProperties, type FormEvent } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * The second half of a sign-in that owes a second factor.\n *\n * Two shapes, decided by the server rather than guessed here:\n *\n * - **A challenge** (`enroll: false`): a code box for the factor the person\n * already has — their authenticator app, or the code just sent to their inbox\n * or phone — or one of their recovery codes.\n * - **An enrolment** (`enroll: true`): the environment requires a second factor\n * and this person has none, so there is nothing a code box could check. They\n * choose one of `enrollMethods`, prove it with its first code, and are shown\n * their recovery codes once before the session is handed over.\n *\n * The enrolment branch is what used to be missing. `SignIn` showed \"from your\n * authenticator app\" to somebody who had never set one up, and `SignUp`\n * silently stopped — so under a required policy nobody new could ever get in.\n *\n * Every visible string comes from `labels`, so a translated application passes\n * its own and nothing here needs forking.\n */\n\nexport interface SecondFactorLabels {\n\tchallengeTitle: string;\n\tcodeLabel: string;\n\t/** Under the code box when the code went to an inbox or phone. */\n\tcodeSentTo: (destinationHint: string) => string;\n\t/** Under the code box when it comes from an authenticator app. */\n\tcodeFromApp: string;\n\tverify: string;\n\tresend: string;\n\tresent: string;\n\tenrollTitle: string;\n\tenrollIntro: string;\n\tmethodTotp: string;\n\tmethodTotpHint: string;\n\tmethodEmail: string;\n\tmethodEmailHint: string;\n\tmethodSms: string;\n\tmethodSmsHint: string;\n\ttotpInstructions: string;\n\tqrAlt: string;\n\tmanualKey: string;\n\topenInApp: string;\n\tsixDigitCode: string;\n\t/** Under the code box while enrolling a factor whose first code was sent. */\n\tenrollCodeSentTo: (destinationHint: string) => string;\n\tconfirm: string;\n\tphoneLabel: string;\n\tphoneHint: string;\n\tsendCode: string;\n\tchooseAnother: string;\n\tcodesTitle: string;\n\tcodesIntro: string;\n\tcopy: string;\n\tcopied: string;\n\tdownload: string;\n\t/** The file the codes download as. */\n\tdownloadName: string;\n\tsavedConfirm: string;\n\tcontinue: string;\n\tworking: string;\n\tstartOver: string;\n\t/** A failure the server did not word. */\n\tgenericError: string;\n}\n\nexport const DEFAULT_SECOND_FACTOR_LABELS: SecondFactorLabels = {\n\tchallengeTitle: \"Two-step verification\",\n\tcodeLabel: \"Authentication code\",\n\tcodeSentTo: (hint) => `We sent a code to ${hint}. Enter it, or one of your recovery codes.`,\n\tcodeFromApp: \"From your authenticator app, or one of your recovery codes.\",\n\tverify: \"Verify\",\n\tresend: \"Send another code\",\n\tresent: \"A new code is on its way.\",\n\tenrollTitle: \"Set up two-step verification\",\n\tenrollIntro:\n\t\t\"This account needs a second step at sign-in. Choose how you want to receive your codes.\",\n\tmethodTotp: \"Authenticator app\",\n\tmethodTotpHint: \"Google Authenticator, 1Password, Authy or similar. The most secure choice.\",\n\tmethodEmail: \"Email me a code\",\n\tmethodEmailHint: \"A code is sent to your inbox each time you sign in.\",\n\tmethodSms: \"Text me a code\",\n\tmethodSmsHint: \"A code is sent to your phone each time you sign in.\",\n\ttotpInstructions:\n\t\t\"Scan this QR code with your authenticator app, or enter the key by hand. Then type the six-digit code it shows.\",\n\tqrAlt: \"QR code to add this account to an authenticator app\",\n\tmanualKey: \"Setup key\",\n\topenInApp: \"Open in an authenticator app\",\n\tsixDigitCode: \"Six-digit code\",\n\tenrollCodeSentTo: (hint) => `We sent a code to ${hint}. Enter it to finish setting this up.`,\n\tconfirm: \"Confirm\",\n\tphoneLabel: \"Mobile number\",\n\tphoneHint: \"Include the country code, for example +14155550123.\",\n\tsendCode: \"Send code\",\n\tchooseAnother: \"Choose another way\",\n\tcodesTitle: \"Save your recovery codes\",\n\tcodesIntro:\n\t\t\"Each code signs you in once if you lose access to your second step. Keep them somewhere safe — they will not be shown again.\",\n\tcopy: \"Copy codes\",\n\tcopied: \"Copied\",\n\tdownload: \"Download\",\n\tdownloadName: \"recovery-codes.txt\",\n\tsavedConfirm: \"I have saved these codes\",\n\tcontinue: \"Continue\",\n\tworking: \"Working…\",\n\tstartOver: \"Start over\",\n\tgenericError: \"Something went wrong. Try again.\",\n};\n\nexport interface SecondFactorStepProps {\n\t/** What `signIn`, `magicLink.verify` or `phone.verify` returned with `mfaRequired`. */\n\tpending: SignInPending;\n\t/** Called once the session has been handed to the provider. */\n\tonSignedIn?: () => void;\n\t/**\n\t * Back to the start of the sign-in, for a challenge that has expired or been\n\t * used up. Without it, no \"Start over\" button is drawn.\n\t */\n\tonRestart?: () => void;\n\tlabels?: Partial<SecondFactorLabels>;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\ntype Stage =\n\t| { name: \"challenge\" }\n\t| { name: \"choose\" }\n\t| { name: \"smsNumber\" }\n\t| { name: \"confirm\"; enrollment: RequiredEnrollmentStart }\n\t| { name: \"codes\"; token: string; recoveryCodes: string[] };\n\n/** The server's sentence where it wrote one; ours where it did not. */\nfunction messageFrom(cause: unknown, fallback: string): string {\n\treturn cause instanceof Base316Error && cause.message ? cause.message : fallback;\n}\n\n/** A challenge that cannot be answered any more — start the sign-in again. */\nfunction challengeGone(cause: unknown): boolean {\n\treturn (\n\t\tcause instanceof Base316Error &&\n\t\t(cause.reason === \"ALREADY_ENROLLED\" ||\n\t\t\t(cause.code === \"INVALID_API_KEY\" && cause.param === \"challengeToken\"))\n\t);\n}\n\nexport function SecondFactorStep({\n\tpending,\n\tonSignedIn,\n\tonRestart,\n\tlabels: overrides,\n\tclassName,\n\tstyle,\n}: SecondFactorStepProps) {\n\tconst labels = { ...DEFAULT_SECOND_FACTOR_LABELS, ...overrides };\n\tconst { client, setToken } = useBase316();\n\tconst [stage, setStage] = useState<Stage>(\n\t\tpending.enroll ? { name: \"choose\" } : { name: \"challenge\" },\n\t);\n\tconst [code, setCode] = useState(\"\");\n\tconst [phone, setPhone] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [gone, setGone] = useState(false);\n\tconst [notice, setNotice] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst [saved, setSaved] = useState(false);\n\tconst [copied, setCopied] = useState(false);\n\tconst headingRef = useRef<HTMLHeadingElement>(null);\n\n\t// Each step is a new screen to a screen reader too: move focus to its\n\t// heading, or the reader stays on a button that no longer exists.\n\tuseEffect(() => {\n\t\theadingRef.current?.focus();\n\t}, [stage.name]);\n\n\tfunction fail(cause: unknown) {\n\t\tconsole.error(\"[base316] second factor failed\", cause);\n\t\tsetError(messageFrom(cause, labels.genericError));\n\t\tsetGone(challengeGone(cause));\n\t}\n\n\tfunction finish(token: string) {\n\t\tsetToken(token);\n\t\tonSignedIn?.();\n\t}\n\n\tasync function verify(event: FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\t\tsetNotice(null);\n\n\t\ttry {\n\t\t\tconst verified = await client.auth.verifyMfa({\n\t\t\t\tchallengeToken: pending.challengeToken,\n\t\t\t\tcode: code.trim(),\n\t\t\t});\n\n\t\t\tfinish(verified.token);\n\t\t} catch (cause) {\n\t\t\tfail(cause);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function resend() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.mfa.resend({ challengeToken: pending.challengeToken });\n\t\t\tsetNotice(labels.resent);\n\t\t} catch (cause) {\n\t\t\tfail(cause);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function start(method: RequiredEnrollmentMethod, again = false) {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\t\tsetNotice(null);\n\n\t\ttry {\n\t\t\tconst enrollment = await client.auth.startRequiredEnrollment({\n\t\t\t\tchallengeToken: pending.challengeToken,\n\t\t\t\tmethod,\n\t\t\t\t...(method === \"SMS_OTP\" && phone.trim() ? { phone: phone.trim() } : {}),\n\t\t\t});\n\n\t\t\tsetCode(\"\");\n\t\t\tsetStage({ name: \"confirm\", enrollment });\n\n\t\t\tif (again) {\n\t\t\t\tsetNotice(labels.resent);\n\t\t\t}\n\t\t} catch (cause) {\n\t\t\tfail(cause);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function confirm(event: FormEvent) {\n\t\tevent.preventDefault();\n\n\t\tif (stage.name !== \"confirm\") {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\t\tsetNotice(null);\n\n\t\ttry {\n\t\t\tconst result = await client.auth.completeRequiredEnrollment({\n\t\t\t\tchallengeToken: pending.challengeToken,\n\t\t\t\tfactorId: stage.enrollment.factorId,\n\t\t\t\tcode: code.trim(),\n\t\t\t});\n\n\t\t\t// Not signed in yet: the codes are shown once, and handing over the\n\t\t\t// session first would let the page navigate away before anybody saw\n\t\t\t// them.\n\t\t\tsetStage({ name: \"codes\", token: result.token, recoveryCodes: result.recoveryCodes });\n\t\t} catch (cause) {\n\t\t\tfail(cause);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function copyCodes(codes: string[]) {\n\t\ttry {\n\t\t\tawait navigator.clipboard.writeText(codes.join(\"\\n\"));\n\t\t\tsetCopied(true);\n\t\t} catch {\n\t\t\t// No clipboard (an insecure origin, or permission refused). The codes\n\t\t\t// are selectable and downloadable, so this is not worth an error.\n\t\t}\n\t}\n\n\tfunction downloadCodes(codes: string[]) {\n\t\tconst url = URL.createObjectURL(new Blob([`${codes.join(\"\\n\")}\\n`], { type: \"text/plain\" }));\n\t\tconst link = document.createElement(\"a\");\n\n\t\tlink.href = url;\n\t\tlink.download = labels.downloadName;\n\t\tdocument.body.appendChild(link);\n\t\tlink.click();\n\t\tlink.remove();\n\t\tURL.revokeObjectURL(url);\n\t}\n\n\tconst deliveredFactor = pending.factors.find((factor) => factor.destinationHint);\n\tconst methods = pending.enrollMethods ?? [];\n\n\tconst banner = (\n\t\t<>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t\t{gone && onRestart ? (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{\" \"}\n\t\t\t\t\t\t\t<button type=\"button\" className=\"b316-button-link\" onClick={onRestart}>\n\t\t\t\t\t\t\t\t{labels.startOver}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{notice ? <output className=\"b316-muted\">{notice}</output> : null}\n\t\t</>\n\t);\n\n\tconst heading = (text: string) => (\n\t\t<h3 className=\"b316-form-title\" tabIndex={-1} ref={headingRef}>\n\t\t\t{text}\n\t\t</h3>\n\t);\n\n\tconst codeInput = (id: string, label: string, describedBy?: string) => (\n\t\t<div className=\"b316-field\">\n\t\t\t<label className=\"b316-label\" htmlFor={id}>\n\t\t\t\t{label}\n\t\t\t</label>\n\t\t\t<input\n\t\t\t\tid={id}\n\t\t\t\tclassName=\"b316-input\"\n\t\t\t\tvalue={code}\n\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\tautoComplete=\"one-time-code\"\n\t\t\t\tinputMode=\"numeric\"\n\t\t\t\taria-describedby={describedBy}\n\t\t\t\trequired\n\t\t\t/>\n\t\t</div>\n\t);\n\n\tlet body;\n\n\tif (stage.name === \"challenge\") {\n\t\tbody = (\n\t\t\t<form onSubmit={verify} className=\"b316-mfa-enrol\">\n\t\t\t\t{heading(labels.challengeTitle)}\n\t\t\t\t{banner}\n\t\t\t\t{codeInput(\"b316-code\", labels.codeLabel, \"b316-code-hint\")}\n\t\t\t\t<span id=\"b316-code-hint\" className=\"b316-muted\">\n\t\t\t\t\t{deliveredFactor?.destinationHint\n\t\t\t\t\t\t? labels.codeSentTo(deliveredFactor.destinationHint)\n\t\t\t\t\t\t: labels.codeFromApp}\n\t\t\t\t</span>\n\t\t\t\t<button className=\"b316-button\" type=\"submit\" disabled={busy}>\n\t\t\t\t\t{busy ? labels.working : labels.verify}\n\t\t\t\t</button>\n\t\t\t\t{deliveredFactor ? (\n\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" disabled={busy} onClick={resend}>\n\t\t\t\t\t\t{labels.resend}\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t</form>\n\t\t);\n\t} else if (stage.name === \"choose\") {\n\t\tconst hint: Record<RequiredEnrollmentMethod, [string, string]> = {\n\t\t\tTOTP: [labels.methodTotp, labels.methodTotpHint],\n\t\t\tEMAIL_OTP: [labels.methodEmail, labels.methodEmailHint],\n\t\t\tSMS_OTP: [labels.methodSms, labels.methodSmsHint],\n\t\t};\n\n\t\tbody = (\n\t\t\t<div className=\"b316-mfa-enrol\">\n\t\t\t\t{heading(labels.enrollTitle)}\n\t\t\t\t{banner}\n\t\t\t\t<p className=\"b316-muted\">{labels.enrollIntro}</p>\n\t\t\t\t<fieldset className=\"b316-mfa-methods\" aria-label={labels.enrollTitle}>\n\t\t\t\t\t{methods.map((method) => (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={method}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary b316-mfa-method\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\taria-describedby={`b316-method-${method}`}\n\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\tmethod === \"SMS_OTP\" ? setStage({ name: \"smsNumber\" }) : void start(method)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span>{hint[method][0]}</span>\n\t\t\t\t\t\t\t<span id={`b316-method-${method}`} className=\"b316-muted\">\n\t\t\t\t\t\t\t\t{hint[method][1]}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</button>\n\t\t\t\t\t))}\n\t\t\t\t</fieldset>\n\t\t\t</div>\n\t\t);\n\t} else if (stage.name === \"smsNumber\") {\n\t\tbody = (\n\t\t\t<form\n\t\t\t\tclassName=\"b316-mfa-enrol\"\n\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tvoid start(\"SMS_OTP\");\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{heading(labels.methodSms)}\n\t\t\t\t{banner}\n\t\t\t\t<div className=\"b316-field\">\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-enrol-phone\">\n\t\t\t\t\t\t{labels.phoneLabel}\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-enrol-phone\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\ttype=\"tel\"\n\t\t\t\t\t\tautoComplete=\"tel\"\n\t\t\t\t\t\tplaceholder=\"+14155550123\"\n\t\t\t\t\t\taria-describedby=\"b316-enrol-phone-hint\"\n\t\t\t\t\t\tvalue={phone}\n\t\t\t\t\t\tonChange={(event) => setPhone(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t\t<span id=\"b316-enrol-phone-hint\" className=\"b316-muted\">\n\t\t\t\t\t\t{labels.phoneHint}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\tonClick={() => setStage({ name: \"choose\" })}\n\t\t\t\t\t>\n\t\t\t\t\t\t{labels.chooseAnother}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy}>\n\t\t\t\t\t\t{busy ? labels.working : labels.sendCode}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</form>\n\t\t);\n\t} else if (stage.name === \"confirm\") {\n\t\tconst { enrollment } = stage;\n\n\t\tbody = (\n\t\t\t<form onSubmit={confirm} className=\"b316-mfa-enrol\">\n\t\t\t\t{heading(enrollment.method === \"TOTP\" ? labels.methodTotp : labels.enrollTitle)}\n\t\t\t\t{banner}\n\t\t\t\t{enrollment.method === \"TOTP\" ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<p className=\"b316-muted\">{labels.totpInstructions}</p>\n\t\t\t\t\t\t{/* An image of the server's SVG, never markup put into the page:\n\t\t\t\t\t\t an <img> cannot run anything the string might contain. */}\n\t\t\t\t\t\t<img\n\t\t\t\t\t\t\tclassName=\"b316-mfa-qr\"\n\t\t\t\t\t\t\tsrc={`data:image/svg+xml;charset=utf-8,${encodeURIComponent(enrollment.qrSvg)}`}\n\t\t\t\t\t\t\talt={labels.qrAlt}\n\t\t\t\t\t\t\twidth={180}\n\t\t\t\t\t\t\theight={180}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{/* The key as text too: a QR code is unreadable on the device\n\t\t\t\t\t\t showing it, which is the case when somebody sets this up on\n\t\t\t\t\t\t their phone. */}\n\t\t\t\t\t\t<div className=\"b316-mfa-secret\">\n\t\t\t\t\t\t\t<span className=\"b316-label\" id=\"b316-manual-key\">\n\t\t\t\t\t\t\t\t{labels.manualKey}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<code aria-labelledby=\"b316-manual-key\">{enrollment.secret}</code>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<a className=\"b316-mfa-uri\" href={enrollment.uri}>\n\t\t\t\t\t\t\t{labels.openInApp}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t{codeInput(\"b316-enrol-code\", labels.sixDigitCode)}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{codeInput(\"b316-enrol-code\", labels.codeLabel, \"b316-enrol-code-hint\")}\n\t\t\t\t\t\t<span id=\"b316-enrol-code-hint\" className=\"b316-muted\">\n\t\t\t\t\t\t\t{labels.enrollCodeSentTo(enrollment.destinationHint)}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t\t<button className=\"b316-button\" type=\"submit\" disabled={busy || !code.trim()}>\n\t\t\t\t\t{busy ? labels.working : labels.confirm}\n\t\t\t\t</button>\n\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t{enrollment.method !== \"TOTP\" ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={() => void start(enrollment.method, true)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{labels.resend}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{methods.length > 1 ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tsetError(null);\n\t\t\t\t\t\t\t\tsetStage({ name: \"choose\" });\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{labels.chooseAnother}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</form>\n\t\t);\n\t} else {\n\t\tconst { recoveryCodes, token } = stage;\n\n\t\tbody = (\n\t\t\t<div className=\"b316-mfa-codes\">\n\t\t\t\t{heading(labels.codesTitle)}\n\t\t\t\t<p>{labels.codesIntro}</p>\n\t\t\t\t<ul className=\"b316-mfa-code-list\">\n\t\t\t\t\t{recoveryCodes.map((recovery) => (\n\t\t\t\t\t\t<li key={recovery}>\n\t\t\t\t\t\t\t<code>{recovery}</code>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\tonClick={() => void copyCodes(recoveryCodes)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{copied ? labels.copied : labels.copy}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\tonClick={() => downloadCodes(recoveryCodes)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{labels.download}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<label className=\"b316-checkbox\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tchecked={saved}\n\t\t\t\t\t\tonChange={(event) => setSaved(event.target.checked)}\n\t\t\t\t\t/>\n\t\t\t\t\t<span>{labels.savedConfirm}</span>\n\t\t\t\t</label>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\tdisabled={!saved}\n\t\t\t\t\tonClick={() => finish(token)}\n\t\t\t\t>\n\t\t\t\t\t{labels.continue}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-mfa\", className)} style={style}>\n\t\t\t{body}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport {\n\tBase316Error,\n\ttype InvitationPreview,\n\tneedsSecondFactor,\n\ttype PasswordPolicy,\n\ttype SignInPending,\n} from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties, type FormEvent } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\nimport { SecondFactorStep, type SecondFactorLabels } from \"./SecondFactorStep\";\n\n/**\n * Create an account.\n *\n * Signing up provisions the billing identity too, so the user this returns can\n * be put on a plan immediately — there is no second step to link them to a\n * customer record.\n *\n * Sign-up does not itself produce a session, since the account still has to\n * verify its email. The form signs in straight afterwards so the common case\n * does not make people type their password twice — and when that sign-in owes\n * a second factor, including enrolling one under a policy that requires it,\n * the form carries on into that step rather than stopping with nothing on\n * screen.\n *\n * The password rules shown are the environment's own, read from the API, and a\n * refusal is the server's sentence for the rule that was missed.\n *\n * On a page reached from an invitation (`?invitation=`, or `invitationToken`)\n * the token rides along with the sign-up. The account is then created straight\n * into the inviting team — no personal workspace — with its address counted as\n * verified, because the token reached that mailbox. The form says which team\n * and fills in the address the invitation went to.\n */\n\nexport interface SignUpLabels {\n\tname: string;\n\temail: string;\n\tpassword: string;\n\tsubmit: string;\n\tworking: string;\n\t/** Rules under the password box, joined by the component. */\n\truleMinLength: (count: number) => string;\n\truleUppercase: string;\n\truleLowercase: string;\n\truleNumber: string;\n\truleSymbol: string;\n\truleBreached: string;\n\t/** Account made, but the environment wants the address confirmed first. */\n\tconfirmEmailTitle: string;\n\tconfirmEmail: (email: string) => string;\n\t/** Account made, but signing in straight after failed for another reason. */\n\tcreatedSignInFailed: (reason: string) => string;\n\t/** A failure the server did not word. */\n\tgenericError: string;\n\t/** Above the form when the page came from an invitation. */\n\tjoining: (organizationName: string, roleName: string) => string;\n}\n\nexport const DEFAULT_SIGN_UP_LABELS: SignUpLabels = {\n\tname: \"Name\",\n\temail: \"Email\",\n\tpassword: \"Password\",\n\tsubmit: \"Create account\",\n\tworking: \"Creating…\",\n\truleMinLength: (count) => `At least ${count} characters`,\n\truleUppercase: \"a capital letter\",\n\truleLowercase: \"a lowercase letter\",\n\truleNumber: \"a number\",\n\truleSymbol: \"a symbol\",\n\truleBreached: \"not one found in a known data breach\",\n\tconfirmEmailTitle: \"Check your email\",\n\tconfirmEmail: (email) =>\n\t\t`Your account is ready. We sent a confirmation link to ${email} — open it, then sign in.`,\n\tcreatedSignInFailed: (reason) =>\n\t\t`Your account was created, but we could not sign you in: ${reason}`,\n\tgenericError: \"We could not create that account. Try again.\",\n\tjoining: (organizationName, roleName) =>\n\t\t`You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`,\n};\n\nexport interface SignUpProps {\n\tonSignedUp?: () => void;\n\t/**\n\t * The invitation this sign-up accepts. Read from `?invitation=` when\n\t * omitted; pass `null` to ignore the URL.\n\t */\n\tinvitationToken?: string | null;\n\t/** Called with the team's id when the sign-up accepted an invitation. */\n\tonJoined?: (organizationId: string) => void;\n\tlabels?: Partial<SignUpLabels>;\n\t/** Override the second-factor step's wording, for translation. */\n\tsecondFactorLabels?: Partial<SecondFactorLabels>;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/** The environment's rules as one line, e.g. \"At least 12 characters, with a symbol.\" */\nfunction describeRules(policy: PasswordPolicy, labels: SignUpLabels): string {\n\tconst extras = [\n\t\tpolicy.requireUppercase ? labels.ruleUppercase : null,\n\t\tpolicy.requireLowercase ? labels.ruleLowercase : null,\n\t\tpolicy.requireNumber ? labels.ruleNumber : null,\n\t\tpolicy.requireSymbol ? labels.ruleSymbol : null,\n\t].filter(Boolean);\n\n\tconst base = labels.ruleMinLength(policy.minLength);\n\tconst withExtras = extras.length > 0 ? `${base}, with ${extras.join(\", \")}` : base;\n\n\treturn `${policy.checkBreached ? `${withExtras}; ${labels.ruleBreached}` : withExtras}.`;\n}\n\nexport function SignUp({\n\tonSignedUp,\n\tinvitationToken: suppliedInvitation,\n\tonJoined,\n\tlabels: overrides,\n\tsecondFactorLabels,\n\tclassName,\n\tstyle,\n}: SignUpProps) {\n\tconst labels = { ...DEFAULT_SIGN_UP_LABELS, ...overrides };\n\tconst { client, setToken } = useBase316();\n\tconst [name, setName] = useState(\"\");\n\tconst [email, setEmail] = useState(\"\");\n\tconst [password, setPassword] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst [policy, setPolicy] = useState<PasswordPolicy | null>(null);\n\tconst [pending, setPending] = useState<SignInPending | null>(null);\n\tconst [confirmEmail, setConfirmEmail] = useState(false);\n\tconst [urlInvitation, setUrlInvitation] = useState<string | null>(null);\n\tconst [loaded, setLoaded] = useState<{ token: string; preview: InvitationPreview } | null>(null);\n\n\t// A supplied token wins; `null` means \"ignore the page's\".\n\tconst invitation = suppliedInvitation === undefined ? urlInvitation : suppliedInvitation;\n\t// Only the preview of the token in force, so a changed prop never shows the\n\t// previous team's name.\n\tconst preview = loaded && loaded.token === invitation ? loaded.preview : null;\n\n\t// The page's own invitation. Read after mount, as `<AcceptInvitation />`\n\t// does, so server rendering never sees it.\n\tuseEffect(() => {\n\t\tif (suppliedInvitation !== undefined || typeof window === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tsetUrlInvitation(new URL(window.location.href).searchParams.get(\"invitation\"));\n\t}, [suppliedInvitation]);\n\n\t// Which team, and which address. A dead token leaves the form as it was:\n\t// the sign-up itself then says the invitation is no longer valid.\n\tuseEffect(() => {\n\t\tif (!invitation) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.teams\n\t\t\t.preview(invitation)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetLoaded({ token: invitation, preview: result });\n\t\t\t\t\tsetEmail((current) => current || result.email);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => undefined);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, invitation]);\n\n\t// The rules in force, so the hint under the box is true. A failure leaves\n\t// the hint off rather than guessing \"8 characters\" under a stricter policy.\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tclient.auth\n\t\t\t.passwordPolicy()\n\t\t\t.then((loaded) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetPolicy(loaded);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => undefined);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client]);\n\n\tasync function submit(event: FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst created = await client.auth.signUp({\n\t\t\t\temail,\n\t\t\t\tpassword,\n\t\t\t\tname: name || undefined,\n\t\t\t\tinvitationToken: invitation ?? undefined,\n\t\t\t});\n\n\t\t\tif (created.invitationAccepted && created.organizationId) {\n\t\t\t\tonJoined?.(created.organizationId);\n\t\t\t}\n\t\t} catch (cause) {\n\t\t\t// The friendly message is what the person sees; the cause goes to the\n\t\t\t// console so a developer integrating this is not left guessing. The\n\t\t\t// server's own sentence is the friendly message where it wrote one:\n\t\t\t// \"That email is already registered\", \"Password needs a symbol\".\n\t\t\tconsole.error(\"[base316] sign-up failed\", cause);\n\t\t\tsetError(\n\t\t\t\tcause instanceof Base316Error &&\n\t\t\t\t\t(cause.code === \"INVALID_REQUEST\" ||\n\t\t\t\t\t\tcause.code === \"RATE_LIMITED\" ||\n\t\t\t\t\t\tcause.code === \"CONFLICT\") &&\n\t\t\t\t\tcause.message\n\t\t\t\t\t? cause.message\n\t\t\t\t\t: labels.genericError,\n\t\t\t);\n\t\t\tsetBusy(false);\n\n\t\t\treturn;\n\t\t}\n\n\t\t// The account exists from here on. Whatever happens next, saying \"we could\n\t\t// not create that account\" would be untrue.\n\t\ttry {\n\t\t\tconst signedIn = await client.auth.signIn({ email, password });\n\n\t\t\tif (needsSecondFactor(signedIn)) {\n\t\t\t\tsetPending(signedIn);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetToken(signedIn.token);\n\t\t\tonSignedUp?.();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] sign-in after sign-up failed\", cause);\n\n\t\t\tif (cause instanceof Base316Error && cause.reason === \"EMAIL_NOT_VERIFIED\") {\n\t\t\t\tsetConfirmEmail(true);\n\t\t\t\tonSignedUp?.();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetError(\n\t\t\t\tlabels.createdSignInFailed(\n\t\t\t\t\tcause instanceof Base316Error && cause.message ? cause.message : labels.genericError,\n\t\t\t\t),\n\t\t\t);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (pending) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<SecondFactorStep pending={pending} labels={secondFactorLabels} onSignedIn={onSignedUp} />\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (confirmEmail) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">{labels.confirmEmailTitle}</h3>\n\t\t\t\t<output className=\"b316-muted\">{labels.confirmEmail(email)}</output>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form onSubmit={submit} className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{preview ? (\n\t\t\t\t<p className=\"b316-muted\">{labels.joining(preview.organizationName, preview.roleName)}</p>\n\t\t\t) : null}\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-name\">\n\t\t\t\t\t{labels.name}\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-name\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\tvalue={name}\n\t\t\t\t\tonChange={(event) => setName(event.target.value)}\n\t\t\t\t\tautoComplete=\"name\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-signup-email\">\n\t\t\t\t\t{labels.email}\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-signup-email\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"email\"\n\t\t\t\t\tvalue={email}\n\t\t\t\t\tonChange={(event) => setEmail(event.target.value)}\n\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\trequired\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-signup-password\">\n\t\t\t\t\t{labels.password}\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-signup-password\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"password\"\n\t\t\t\t\tvalue={password}\n\t\t\t\t\tonChange={(event) => setPassword(event.target.value)}\n\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\tminLength={policy?.minLength}\n\t\t\t\t\tmaxLength={policy?.maxLength}\n\t\t\t\t\taria-describedby={policy ? \"b316-signup-password-rules\" : undefined}\n\t\t\t\t\trequired\n\t\t\t\t/>\n\t\t\t\t{policy ? (\n\t\t\t\t\t<span id=\"b316-signup-password-rules\" className=\"b316-muted\">\n\t\t\t\t\t\t{describeRules(policy, labels)}\n\t\t\t\t\t</span>\n\t\t\t\t) : null}\n\t\t\t</div>\n\n\t\t\t<button className=\"b316-button\" type=\"submit\" disabled={busy}>\n\t\t\t\t{busy ? labels.working : labels.submit}\n\t\t\t</button>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport type { CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Who is signed in, and a way out.\n *\n * Reads the session the provider already resolved rather than fetching again,\n * so a page with several of these components makes one round trip, not several.\n */\nexport function UserProfile({ className, style }: { className?: string; style?: CSSProperties }) {\n\tconst { session, loading, signOut } = useBase316();\n\n\tif (loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!session) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tNot signed in.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst user = (session.user ?? {}) as {\n\t\tname?: string;\n\t\temail?: string;\n\t\temailVerified?: boolean;\n\t};\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t<div className=\"b316-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<div style={{ fontWeight: 600 }}>{user.name || user.email || \"Signed in\"}</div>\n\t\t\t\t\t{user.name && user.email ? <div className=\"b316-muted\">{user.email}</div> : null}\n\t\t\t\t\t{user.emailVerified === false ? (\n\t\t\t\t\t\t<div className=\"b316-muted\">Email not verified</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\tonClick={() => void signOut()}\n\t\t\t\t>\n\t\t\t\t\tSign out\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { isPasskeySupported, type PasskeySummary } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * The signed-in user's passkeys, and a way to add one.\n *\n * Belongs on an account screen next to \"change password\". A passkey is bound to\n * the origin it was created on, so one registered here works on this site and\n * not on the hosted sign-in page — which is why this component exists at all\n * rather than sending people somewhere else to manage them.\n */\nexport function PasskeyManager({\n\tclassName,\n\tstyle,\n\ttitle = \"Passkeys\",\n}: {\n\tclassName?: string;\n\tstyle?: CSSProperties;\n\ttitle?: string;\n}) {\n\tconst { client, token, session } = useBase316();\n\n\tconst [passkeys, setPasskeys] = useState<PasskeySummary[] | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [name, setName] = useState(\"\");\n\n\t/**\n\t * Whether this browser can do WebAuthn at all.\n\t *\n\t * Asked in an effect rather than during render. It is false on a server and\n\t * usually true in the browser, so deciding during render renders one thing on\n\t * the server and another on the client — which React reports as a hydration\n\t * error rather than as the section quietly appearing.\n\t */\n\tconst [supported, setSupported] = useState(false);\n\n\tconst load = useCallback(async () => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await client.auth.passkeys.list(token);\n\t\t\tsetPasskeys(result.data);\n\t\t} catch (cause) {\n\t\t\t// An account screen that cannot list passkeys should still render the\n\t\t\t// rest of itself — but an empty list is not the way to say so. It reads\n\t\t\t// as \"you have no passkeys\", which to somebody with three registered is\n\t\t\t// a claim that their credentials are gone, shown at exactly the moment\n\t\t\t// they are trying to check.\n\t\t\tconsole.error(\"[base316] could not list passkeys\", cause);\n\t\t\tsetError(\"Could not load your passkeys. They have not been changed.\");\n\t\t\tsetPasskeys(null);\n\t\t}\n\t}, [client, token]);\n\n\tuseEffect(() => {\n\t\tif (!isPasskeySupported()) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetSupported(true);\n\t\tvoid load();\n\t}, [load]);\n\n\t// An \"add a passkey\" button in a browser that cannot make one is worse than\n\t// no section at all.\n\tif (!session || !token || !supported) {\n\t\treturn null;\n\t}\n\n\tconst add = async () => {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.passkeys.register(token, { name: name.trim() || undefined });\n\t\t\tsetName(\"\");\n\t\t\tawait load();\n\t\t} catch (caught) {\n\t\t\t// A cancelled ceremony is not a failure worth shouting about: the\n\t\t\t// person closed the dialog, which is an answer.\n\t\t\tif (caught instanceof DOMException && caught.name === \"NotAllowedError\") {\n\t\t\t\tsetError(null);\n\t\t\t} else {\n\t\t\t\tsetError(caught instanceof Error ? caught.message : \"That did not work.\");\n\t\t\t}\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst remove = async (id: string) => {\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.passkeys.remove(token, id);\n\t\t\tawait load();\n\t\t} catch (caught) {\n\t\t\tsetError(caught instanceof Error ? caught.message : \"That did not work.\");\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t<div style={{ fontWeight: 600, marginBottom: 4 }}>{title}</div>\n\t\t\t<div className=\"b316-muted\" style={{ marginBottom: 12 }}>\n\t\t\t\tSign in with your fingerprint, face or a security key — nothing to type and nothing to\n\t\t\t\tremember.\n\t\t\t</div>\n\n\t\t\t{passkeys === null ? (\n\t\t\t\t<div className=\"b316-muted\">Loading…</div>\n\t\t\t) : passkeys.length === 0 ? (\n\t\t\t\t<div className=\"b316-muted\">No passkeys yet.</div>\n\t\t\t) : (\n\t\t\t\t<ul style={{ listStyle: \"none\", margin: 0, padding: 0 }}>\n\t\t\t\t\t{passkeys.map((passkey) => (\n\t\t\t\t\t\t<li key={passkey.id} className=\"b316-row\" style={{ padding: \"8px 0\" }}>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<div>{passkey.name || \"Passkey\"}</div>\n\t\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\t{passkey.lastUsedAt\n\t\t\t\t\t\t\t\t\t\t? `Last used ${formatDate(passkey.lastUsedAt)}`\n\t\t\t\t\t\t\t\t\t\t: `Added ${formatDate(passkey.createdAt)}`}\n\t\t\t\t\t\t\t\t\t{/* A passkey that is not backed up lives on one device, and\n\t\t\t\t\t\t\t\t\t losing that device loses the passkey. Worth saying. */}\n\t\t\t\t\t\t\t\t\t{passkey.backedUp ? \"\" : \" · this device only\"}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{/*\n\t\t\t\t\t\t\t * On a passwordless account, removing the last passkey locks the\n\t\t\t\t\t\t\t * person out of their own account — so it asks. In the page, not\n\t\t\t\t\t\t\t * in a dialog the embedding iframe will suppress.\n\t\t\t\t\t\t\t */}\n\t\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\t\tconfirmLabel={`Remove ${passkey.name ?? \"this passkey\"} for good`}\n\t\t\t\t\t\t\t\tonConfirm={() => remove(passkey.id)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tRemove\n\t\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t)}\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\" style={{ marginTop: 12 }}>\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-row\" style={{ marginTop: 12, gap: 8 }}>\n\t\t\t\t<input\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\tplaceholder=\"Name this passkey (optional)\"\n\t\t\t\t\tvalue={name}\n\t\t\t\t\tonChange={(event) => setName(event.target.value)}\n\t\t\t\t/>\n\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={() => void add()}>\n\t\t\t\t\t{busy ? \"Waiting…\" : \"Add a passkey\"}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction formatDate(value: string): string {\n\tconst date = new Date(value);\n\n\treturn Number.isNaN(date.getTime()) ? \"\" : date.toLocaleDateString();\n}\n","import { useEffect, useRef, useState, type ReactNode } from \"react\";\n\n/**\n * Asking \"are you sure\" without `window.confirm`.\n *\n * These components are embedded in the customer's own page, and a page that\n * embeds them in a sandboxed iframe — which is the recommended way to embed\n * anything — does not get modal dialogs unless `allow-modals` is set. Chrome\n * and Firefox both block the call and return `false`.\n *\n * So `window.confirm` in this package was not a confirmation. It was a silent\n * no: somebody clicked Revoke, the browser suppressed the dialog, the function\n * returned false, and the component did nothing at all. No error, no dialog,\n * nothing — the worst failure shape there is, because the user's next move is\n * to click it again.\n *\n * The replacement asks in the page itself. One click arms it, a second\n * confirms, and anywhere else cancels. No portal, no modal, no dependency on\n * what the embedding page allows.\n */\n\nexport interface ConfirmButtonProps {\n\t/** What the button says at rest. */\n\tchildren: ReactNode;\n\t/** What it says once armed. Make it name the consequence. */\n\tconfirmLabel: string;\n\tonConfirm: () => void | Promise<void>;\n\tclassName?: string;\n\tdisabled?: boolean;\n\t/** How long the armed state survives without an answer. */\n\ttimeoutMs?: number;\n}\n\n/**\n * Long enough to read the question, short enough that an armed button is never\n * a surprise on a page somebody came back to.\n */\nconst DEFAULT_TIMEOUT_MS = 5_000;\n\nexport function ConfirmButton({\n\tchildren,\n\tconfirmLabel,\n\tonConfirm,\n\tclassName,\n\tdisabled,\n\ttimeoutMs = DEFAULT_TIMEOUT_MS,\n}: ConfirmButtonProps) {\n\tconst [armed, setArmed] = useState(false);\n\tconst confirmRef = useRef<HTMLButtonElement>(null);\n\n\tuseEffect(() => {\n\t\tif (!armed) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Focus moves to the confirmation, so a keyboard user answers the question\n\t\t// rather than tabbing past it, and a screen reader reads it aloud.\n\t\tconfirmRef.current?.focus();\n\n\t\tconst timer = setTimeout(() => setArmed(false), timeoutMs);\n\n\t\treturn () => clearTimeout(timer);\n\t}, [armed, timeoutMs]);\n\n\tif (!armed) {\n\t\treturn (\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={className}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonClick={() => setArmed(true)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</button>\n\t\t);\n\t}\n\n\treturn (\n\t\t// No `role=\"group\"`: both buttons already say what they do, and the\n\t\t// grouping would only repeat the question a screen reader has just read.\n\t\t<span className=\"b316-confirm\">\n\t\t\t<button\n\t\t\t\tref={confirmRef}\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={className}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tonClick={async () => {\n\t\t\t\t\tsetArmed(false);\n\t\t\t\t\tawait onConfirm();\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{confirmLabel}\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\tonClick={() => setArmed(false)}\n\t\t\t>\n\t\t\t\tCancel\n\t\t\t</button>\n\t\t</span>\n\t);\n}\n","\"use client\";\n\nimport type { SessionSummary } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Where this account is signed in, and a way to end the rest.\n *\n * The panel somebody opens when they think they have been compromised, which\n * is why the copy is plain and the button does not hedge. It shows where and\n * when rather than anything identifying the session itself: the token digest is\n * the value the database authenticates against and never reaches the browser.\n *\n * Revoking keeps the caller's own session. Signing somebody out of the device\n * they are holding, in response to a button about their *other* devices, would\n * be a surprise at the worst possible moment.\n */\n\nexport interface ActiveSessionsProps {\n\t/** Called after other sessions are ended, with how many went. */\n\tonRevoked?: (count: number) => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/** \"Chrome on macOS\" out of a user-agent string, or null when it says nothing useful. */\nfunction describeDevice(userAgent: string | null): string | null {\n\tif (!userAgent) {\n\t\treturn null;\n\t}\n\n\tconst browser = /Edg\\//.test(userAgent)\n\t\t? \"Edge\"\n\t\t: /OPR\\//.test(userAgent)\n\t\t\t? \"Opera\"\n\t\t\t: /Chrome\\//.test(userAgent)\n\t\t\t\t? \"Chrome\"\n\t\t\t\t: /Safari\\//.test(userAgent)\n\t\t\t\t\t? \"Safari\"\n\t\t\t\t\t: /Firefox\\//.test(userAgent)\n\t\t\t\t\t\t? \"Firefox\"\n\t\t\t\t\t\t: null;\n\n\tconst platform = /iPhone|iPad/.test(userAgent)\n\t\t? \"iOS\"\n\t\t: /Android/.test(userAgent)\n\t\t\t? \"Android\"\n\t\t\t: /Mac OS X/.test(userAgent)\n\t\t\t\t? \"macOS\"\n\t\t\t\t: /Windows/.test(userAgent)\n\t\t\t\t\t? \"Windows\"\n\t\t\t\t\t: /Linux/.test(userAgent)\n\t\t\t\t\t\t? \"Linux\"\n\t\t\t\t\t\t: null;\n\n\tif (!browser && !platform) {\n\t\t// Better to show the raw string than to claim knowledge: somebody chasing a\n\t\t// session they do not recognise needs whatever there is.\n\t\treturn userAgent.slice(0, 60);\n\t}\n\n\treturn [browser, platform].filter(Boolean).join(\" on \");\n}\n\nfunction when(value: string): string {\n\tconst date = new Date(value);\n\n\treturn Number.isNaN(date.getTime()) ? \"\" : date.toLocaleString();\n}\n\nexport function ActiveSessions({ onRevoked, className, style }: ActiveSessionsProps) {\n\tconst { client, token } = useBase316();\n\tconst [sessions, setSessions] = useState<SessionSummary[] | null>(null);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\tconst load = useCallback(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tclient.auth\n\t\t\t.sessions(token)\n\t\t\t.then((result) => {\n\t\t\t\t// Revoked ones are history, not devices somebody is signed in on.\n\t\t\t\tsetSessions(result.data.filter((session) => !session.revokedAt));\n\t\t\t\tsetError(null);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not load your sessions.\");\n\t\t\t});\n\t}, [client, token]);\n\n\tuseEffect(load, [load]);\n\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!sessions) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tasync function revokeOthers() {\n\t\tsetBusy(true);\n\n\t\ttry {\n\t\t\tconst result = await client.auth.revokeOtherSessions(token as string);\n\n\t\t\tonRevoked?.(result.revoked);\n\t\t\tload();\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not end those sessions.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-sessions\", className)} style={style}>\n\t\t\t<div className=\"b316-sessions-head\">\n\t\t\t\t<h3 className=\"b316-sessions-title\">Where you are signed in</h3>\n\t\t\t\t{sessions.length > 1 ? (\n\t\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={revokeOthers}>\n\t\t\t\t\t\t{busy ? \"Ending…\" : \"Sign out other devices\"}\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t</div>\n\n\t\t\t<ul className=\"b316-sessions-list\">\n\t\t\t\t{sessions.map((session) => (\n\t\t\t\t\t<li key={session.id} className=\"b316-session\">\n\t\t\t\t\t\t<div className=\"b316-session-device\">\n\t\t\t\t\t\t\t{describeDevice(session.userAgent) ?? \"Unknown device\"}\n\t\t\t\t\t\t\t{session.impersonatedBy ? (\n\t\t\t\t\t\t\t\t// Worth saying loudly: somebody is acting as this account.\n\t\t\t\t\t\t\t\t<span className=\"b316-chip\"> Support access</span>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t{session.ipAddress ? `${session.ipAddress} · ` : \"\"}\n\t\t\t\t\t\t\tlast used {when(session.lastSeenAt)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ul>\n\n\t\t\t{sessions.length === 0 ? <div className=\"b316-muted\">No active sessions.</div> : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { DeviceRequest } from \"@base316/sdk\";\nimport { useState, type CSSProperties, type FormEvent } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Approving a sign-in that started somewhere with no browser.\n *\n * Drop this on a page in your own application — `/device` is the convention —\n * and point your device's verification URI at it. The person is already signed\n * in here, which is the whole reason this belongs in your app rather than on a\n * page of ours: there is nothing to log into, and the page looks like yours.\n *\n * Two steps, deliberately. The code is checked first so that what is being\n * approved can be named before anybody presses Approve; a single button that\n * takes a code and grants access in one motion is a button people press without\n * reading.\n */\n\nexport interface DeviceApprovalProps {\n\t/**\n\t * The code, when your page already has it.\n\t *\n\t * A device that can show a link or a QR code puts the code in the URL, which\n\t * saves exactly the typing this flow exists to avoid. Read it off your router\n\t * and pass it here; the entry step is skipped.\n\t */\n\tuserCode?: string;\n\t/** Called after the person answers, with what they chose. */\n\tonDecided?: (approved: boolean) => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function DeviceApproval({\n\tuserCode = \"\",\n\tonDecided,\n\tclassName,\n\tstyle,\n}: DeviceApprovalProps) {\n\tconst { client, token } = useBase316();\n\tconst [code, setCode] = useState(userCode);\n\tconst [request, setRequest] = useState<DeviceRequest | null>(null);\n\tconst [decided, setDecided] = useState<boolean | null>(null);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\t// Without a signed-in user there is nobody to approve *as*. Rendering a code\n\t// box anyway would collect a code and then fail at the one step that matters.\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tasync function lookUp(event: FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tsetRequest(await client.device.lookup(code));\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"We could not check that code.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function decide(approve: boolean) {\n\t\tif (!request) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.device.decide(token as string, { id: request.id, approve });\n\t\t\tsetDecided(approve);\n\t\t\tonDecided?.(approve);\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"We could not record that.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (decided !== null) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card b316-device\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-device-title\">{decided ? \"You're all set\" : \"Not approved\"}</h3>\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t{decided\n\t\t\t\t\t\t? \"You can close this page and go back to your device.\"\n\t\t\t\t\t\t: \"Nothing was granted. You can close this page.\"}\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (request) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card b316-device\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-device-title\">Sign in to {request.clientName}</h3>\n\t\t\t\t<p className=\"b316-muted\">{request.clientName} is asking to sign in as you.</p>\n\n\t\t\t\t{request.scopes.length > 0 ? (\n\t\t\t\t\t<ul className=\"b316-device-scopes\">\n\t\t\t\t\t\t{request.scopes.map((scope) => (\n\t\t\t\t\t\t\t<li key={scope}>{scope}</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t) : null}\n\n\t\t\t\t{error ? (\n\t\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t\t{error}\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\n\t\t\t\t<div className=\"b316-device-actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => decide(true)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{busy ? \"Approving…\" : \"Approve\"}\n\t\t\t\t\t</button>\n\t\t\t\t\t{/* A real refusal, not just closing the tab: it tells the device to\n\t\t\t\t\t stop polling instead of leaving it to time out. */}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-quiet\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => decide(false)}\n\t\t\t\t\t>\n\t\t\t\t\t\tDeny\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-card b316-device\", className)} style={style} onSubmit={lookUp}>\n\t\t\t<h3 className=\"b316-device-title\">Connect your device</h3>\n\t\t\t<p className=\"b316-muted\">Enter the code shown on your device.</p>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<input\n\t\t\t\tclassName=\"b316-input\"\n\t\t\t\tvalue={code}\n\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\t// Not `one-time-code`: that invites the browser to offer an SMS\n\t\t\t\t// passcode, which this is not.\n\t\t\t\tautoComplete=\"off\"\n\t\t\t\tautoCapitalize=\"characters\"\n\t\t\t\tspellCheck={false}\n\t\t\t\tplaceholder=\"XXXX-XXXX\"\n\t\t\t\taria-label=\"Device code\"\n\t\t\t/>\n\n\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy || code.trim().length < 4}>\n\t\t\t\t{busy ? \"Checking…\" : \"Continue\"}\n\t\t\t</button>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport { useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Download my data, and delete my account.\n *\n * The two things a privacy notice promises and most products never build, so\n * the promise gets kept by an inbox and a person doing it by hand. Both here\n * take the signed-in user's own session, so neither needs your server to be\n * trusted with somebody else's account.\n *\n * Deletion asks twice, and the second time it asks the person to type. That is\n * not friction for its own sake: this is the one control on the page that\n * cannot be undone, and a misplaced click should not be able to reach it.\n */\n\nexport interface PrivacyControlsProps {\n\t/**\n\t * What must be typed to confirm deletion.\n\t *\n\t * Defaults to the English word, which is wrong in every other language —\n\t * pass the one your interface is written in.\n\t */\n\tconfirmWord?: string;\n\t/** Called after the account is gone. Sign them out and send them somewhere. */\n\tonErased?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function PrivacyControls({\n\tconfirmWord = \"DELETE\",\n\tonErased,\n\tclassName,\n\tstyle,\n}: PrivacyControlsProps) {\n\tconst { client, token } = useBase316();\n\tconst [confirming, setConfirming] = useState(false);\n\tconst [typed, setTyped] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tasync function download() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst data = await client.auth.privacy.export(token as string);\n\n\t\t\t// A file, because the useful outcome is a copy they keep — not\n\t\t\t// something on screen they have to select and paste.\n\t\t\tconst url = URL.createObjectURL(\n\t\t\t\tnew Blob([JSON.stringify(data, null, 2)], { type: \"application/json\" }),\n\t\t\t);\n\t\t\tconst link = document.createElement(\"a\");\n\n\t\t\tlink.href = url;\n\t\t\tlink.download = \"my-data.json\";\n\t\t\tlink.click();\n\t\t\tURL.revokeObjectURL(url);\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not build your export.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function erase() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.privacy.erase(token as string);\n\t\t\tonErased?.();\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not delete your account.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-privacy\", className)} style={style}>\n\t\t\t<h3 className=\"b316-privacy-title\">Your data</h3>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-privacy-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<p>Download a copy</p>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tEverything we hold about you, as a file. Passwords and security keys are not included —\n\t\t\t\t\t\tthey are what protect the account rather than anything you can use.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" disabled={busy} onClick={download}>\n\t\t\t\t\t{busy ? \"Preparing…\" : \"Download\"}\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-privacy-row\">\n\t\t\t\t<div>\n\t\t\t\t\t<p>Delete your account</p>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tPermanent. Invoices already raised are kept, because the law requires it; everything\n\t\t\t\t\t\tthat identifies you is removed from them.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\n\t\t\t\t{confirming ? null : (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => setConfirming(true)}\n\t\t\t\t\t>\n\t\t\t\t\t\tDelete\n\t\t\t\t\t</button>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{confirming ? (\n\t\t\t\t<div className=\"b316-privacy-confirm\">\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-privacy-confirm\">\n\t\t\t\t\t\tType {confirmWord} to confirm\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-privacy-confirm\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tvalue={typed}\n\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\tonChange={(event) => setTyped(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t\t<div className=\"b316-privacy-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tsetConfirming(false);\n\t\t\t\t\t\t\t\tsetTyped(\"\");\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button b316-danger\"\n\t\t\t\t\t\t\t// Trimmed but not case-folded: typing it exactly is the point.\n\t\t\t\t\t\t\tdisabled={busy || typed.trim() !== confirmWord}\n\t\t\t\t\t\t\tonClick={erase}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{busy ? \"Deleting…\" : \"Delete my account\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { useBase316 } from \"./provider\";\nimport { QrCode } from \"./QrCode\";\n\n/**\n * Turning on two-factor authentication.\n *\n * Three ways in: an authenticator app, a code to the inbox, and — where the\n * application turns it on — a code by text message. The app is the strongest\n * and is offered first; the other two are the ones people who will not install\n * anything actually use, and a factor somebody turns on beats a stronger one\n * they decline.\n *\n * Three steps, kept separate because the middle one is what stops people\n * locking themselves out: enrolling produces a secret that is useless until a\n * code proves the app actually holds it. Activating on enrolment would mean a\n * QR code that failed to scan leaves somebody unable to sign in, with no way\n * back.\n *\n * The recovery codes are shown once. They are password equivalents, so nothing\n * stores them anywhere they can be read back — which makes \"I have saved these\"\n * a real step rather than a formality, and the dialog says so.\n */\n\nexport interface TwoFactorManagerProps {\n\t/** Whether this account already has a factor. Drives which side is shown. */\n\tenabled?: boolean;\n\t/**\n\t * Offer a code by text message.\n\t *\n\t * Off by default, because it only works once the environment can send one —\n\t * its own Twilio account in production — and a button that can only fail is\n\t * worse than no button.\n\t */\n\tallowSms?: boolean;\n\tonEnabled?: () => void;\n\tonDisabled?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/** `JBSWY3DPEHPK3PXP` as `JBSW Y3DP EHPK 3PXP`: easier to read off one screen and type into another. */\nfunction groupKey(secret: string): string {\n\treturn secret.replace(/\\s+/g, \"\").replace(/(.{4})(?=.)/g, \"$1 \");\n}\n\ntype Stage =\n\t| { name: \"idle\" }\n\t| { name: \"enrolling\"; factorId: string; secret: string; uri: string }\n\t/** The same confirm step, with a code that was sent rather than derived. */\n\t| { name: \"enrollingEmail\"; factorId: string; destinationHint: string }\n\t/** Which number a text-message factor should use, before anything is sent. */\n\t| { name: \"smsNumber\" }\n\t| { name: \"saved\"; recoveryCodes: string[] };\n\nexport function TwoFactorManager({\n\tenabled = false,\n\tallowSms = false,\n\tonEnabled,\n\tonDisabled,\n\tclassName,\n\tstyle,\n}: TwoFactorManagerProps) {\n\tconst { client, token } = useBase316();\n\tconst [stage, setStage] = useState<Stage>({ name: \"idle\" });\n\tconst [on, setOn] = useState(enabled);\n\tconst [code, setCode] = useState(\"\");\n\tconst [phone, setPhone] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tasync function begin() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst enrollment = await client.auth.mfa.enroll(token as string);\n\n\t\t\tsetStage({ name: \"enrolling\", ...enrollment });\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not start setup.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function beginEmail() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst enrollment = await client.auth.mfa.enrollEmail(token as string);\n\n\t\t\tsetStage({ name: \"enrollingEmail\", ...enrollment });\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not send a code.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function beginSms() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\t// Blank means the account's own number, which the server looks up.\n\t\t\tconst enrollment = await client.auth.mfa.enrollSms(\n\t\t\t\ttoken as string,\n\t\t\t\tphone.trim() ? { phone: phone.trim() } : {},\n\t\t\t);\n\n\t\t\tsetStage({ name: \"enrollingEmail\", ...enrollment });\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not send a code.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function confirm() {\n\t\tif (stage.name !== \"enrolling\" && stage.name !== \"enrollingEmail\") {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.auth.mfa.confirm(token as string, {\n\t\t\t\tfactorId: stage.factorId,\n\t\t\t\tcode: code.trim(),\n\t\t\t});\n\n\t\t\tsetStage({ name: \"saved\", recoveryCodes: result.recoveryCodes });\n\t\t\tsetOn(true);\n\t\t\tsetCode(\"\");\n\t\t\tonEnabled?.();\n\t\t} catch (cause) {\n\t\t\t// The common case by far is a mistyped or expired code, and the server\n\t\t\t// deliberately says no more than that.\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That code did not match.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function disable() {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.mfa.disable(token as string);\n\n\t\t\tsetOn(false);\n\t\t\tsetStage({ name: \"idle\" });\n\t\t\tonDisabled?.();\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not turn it off.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-mfa\", className)} style={style}>\n\t\t\t<h3 className=\"b316-mfa-title\">Two-factor authentication</h3>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{stage.name === \"saved\" ? (\n\t\t\t\t<div className=\"b316-mfa-codes\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\tSave these recovery codes somewhere safe. Each one signs you in once if you lose your\n\t\t\t\t\t\tauthenticator, and they are not shown again.\n\t\t\t\t\t</p>\n\t\t\t\t\t<ul className=\"b316-mfa-code-list\">\n\t\t\t\t\t\t{stage.recoveryCodes.map((recovery) => (\n\t\t\t\t\t\t\t<li key={recovery}>\n\t\t\t\t\t\t\t\t<code>{recovery}</code>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t\t<button type=\"button\" className=\"b316-button\" onClick={() => setStage({ name: \"idle\" })}>\n\t\t\t\t\t\tI have saved them\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : stage.name === \"smsNumber\" ? (\n\t\t\t\t<div className=\"b316-mfa-enrol\">\n\t\t\t\t\t<p>We will text a code to this number now, and each time you sign in.</p>\n\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-mfa-phone\">\n\t\t\t\t\t\tMobile number\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-mfa-phone\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\ttype=\"tel\"\n\t\t\t\t\t\tautoComplete=\"tel\"\n\t\t\t\t\t\tplaceholder=\"+14155550123\"\n\t\t\t\t\t\tvalue={phone}\n\t\t\t\t\t\tonChange={(event) => setPhone(event.target.value)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => setStage({ name: \"idle\" })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={beginSms}>\n\t\t\t\t\t\t\t{busy ? \"Sending…\" : \"Send code\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : stage.name === \"enrollingEmail\" ? (\n\t\t\t\t<div className=\"b316-mfa-enrol\">\n\t\t\t\t\t<p>We sent a code to {stage.destinationHint}. Enter it below to turn this on.</p>\n\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-mfa-code\">\n\t\t\t\t\t\tCode\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-mfa-code\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tinputMode=\"numeric\"\n\t\t\t\t\t\tautoComplete=\"one-time-code\"\n\t\t\t\t\t\tvalue={code}\n\t\t\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => setStage({ name: \"idle\" })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\t\tdisabled={busy || !code}\n\t\t\t\t\t\t\tonClick={confirm}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{busy ? \"Checking…\" : \"Turn on\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : stage.name === \"enrolling\" ? (\n\t\t\t\t<div className=\"b316-mfa-enrol\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\tScan this with your authenticator app (Google Authenticator, 1Password, Authy…), then\n\t\t\t\t\t\tenter the six-digit code it shows.\n\t\t\t\t\t</p>\n\t\t\t\t\t<QrCode\n\t\t\t\t\t\tclassName=\"b316-mfa-qr\"\n\t\t\t\t\t\tvalue={stage.uri}\n\t\t\t\t\t\tlabel=\"QR code for your authenticator app\"\n\t\t\t\t\t/>\n\t\t\t\t\t{/* The secret in text as well as the QR code: a QR code is unreadable\n\t\t\t\t\t on the device that is displaying it, which is exactly the case when\n\t\t\t\t\t somebody sets this up on a phone. */}\n\t\t\t\t\t<div className=\"b316-mfa-secret\">\n\t\t\t\t\t\t<span className=\"b316-label\" id=\"b316-mfa-manual-key\">\n\t\t\t\t\t\t\tCan't scan? Enter this key\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t{/* In groups of four, as authenticator apps print them; every app\n\t\t\t\t\t\t ignores the spaces when the key is typed or pasted. */}\n\t\t\t\t\t\t<code aria-labelledby=\"b316-mfa-manual-key\">{groupKey(stage.secret)}</code>\n\t\t\t\t\t</div>\n\t\t\t\t\t<a className=\"b316-mfa-uri\" href={stage.uri}>\n\t\t\t\t\t\tOpen in an authenticator app\n\t\t\t\t\t</a>\n\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-mfa-code\">\n\t\t\t\t\t\tCode\n\t\t\t\t\t</label>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid=\"b316-mfa-code\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tinputMode=\"numeric\"\n\t\t\t\t\t\tautoComplete=\"one-time-code\"\n\t\t\t\t\t\tvalue={code}\n\t\t\t\t\t\tonChange={(event) => setCode(event.target.value)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => setStage({ name: \"idle\" })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\t\tdisabled={busy || !code}\n\t\t\t\t\t\t\tonClick={confirm}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{busy ? \"Checking…\" : \"Turn on\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : on ? (\n\t\t\t\t<div className=\"b316-mfa-on\">\n\t\t\t\t\t<p className=\"b316-muted\">On. You will be asked for a code when you sign in.</p>\n\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tconfirmLabel=\"Turn off two-factor authentication\"\n\t\t\t\t\t\tonConfirm={disable}\n\t\t\t\t\t>\n\t\t\t\t\t\tTurn off\n\t\t\t\t\t</ConfirmButton>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-mfa-off\">\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tOff. Turning it on means a code as well as your password, every time you sign in.\n\t\t\t\t\t</p>\n\t\t\t\t\t<div className=\"b316-mfa-actions\">\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={begin}>\n\t\t\t\t\t\t\t{busy ? \"Starting…\" : \"Use an authenticator app\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t{/* Offered second, and described honestly: it is only as strong as\n\t\t\t\t\t\t the mailbox. Still far better than nothing, which is what the\n\t\t\t\t\t\t people who decline an app otherwise have. */}\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={beginEmail}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tEmail me a code\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t{allowSms ? (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\tonClick={() => setStage({ name: \"smsNumber\" })}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tText me a code\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import qrcode from \"qrcode-generator\";\nimport { useMemo } from \"react\";\n\n/**\n * A QR code, drawn here as SVG.\n *\n * Drawn in the browser rather than fetched as an image: what this encodes is an\n * authenticator secret, and sending it to a QR service — or anywhere at all —\n * would hand the second factor to whoever runs it. The library is pure\n * JavaScript with no dependencies and makes no requests.\n *\n * Rendered as React elements, never as a markup string, so nothing in the\n * value can become anything other than the modules of the code.\n */\n\n/** The four-module margin the QR specification asks for. Readers miss codes without it. */\nconst QUIET_ZONE = 4;\n\nexport interface QrCodeProps {\n\tvalue: string;\n\t/** What a screen reader announces in place of the picture. */\n\tlabel: string;\n\t/** Rendered width and height in pixels. */\n\tsize?: number;\n\tclassName?: string;\n}\n\n/**\n * The library maps each UTF-16 unit to one byte, which mangles anything outside\n * Latin-1. Handing it the UTF-8 bytes as a binary string encodes them exactly,\n * so an account name with an accent still scans as itself.\n */\nfunction utf8Binary(value: string): string {\n\tlet binary = \"\";\n\n\tfor (const byte of new TextEncoder().encode(value)) {\n\t\tbinary += String.fromCharCode(byte);\n\t}\n\n\treturn binary;\n}\n\n/** One path of unit squares: a few kilobytes for a TOTP URI, and crisp at any size. */\nexport function qrPath(value: string): { path: string; modules: number } {\n\t// Type 0 picks the smallest version that fits; M recovers from ~15% damage,\n\t// which is plenty for a screen and keeps the grid coarse enough to scan.\n\tconst code = qrcode(0, \"M\");\n\n\tcode.addData(utf8Binary(value), \"Byte\");\n\tcode.make();\n\n\tconst modules = code.getModuleCount();\n\tlet path = \"\";\n\n\tfor (let row = 0; row < modules; row += 1) {\n\t\tfor (let col = 0; col < modules; col += 1) {\n\t\t\tif (code.isDark(row, col)) {\n\t\t\t\tpath += `M${col + QUIET_ZONE} ${row + QUIET_ZONE}h1v1h-1z`;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { path, modules };\n}\n\nexport function QrCode({ value, label, size = 180, className }: QrCodeProps) {\n\tconst { path, modules } = useMemo(() => qrPath(value), [value]);\n\tconst extent = modules + QUIET_ZONE * 2;\n\n\treturn (\n\t\t<svg\n\t\t\tclassName={className}\n\t\t\t// An <svg> is announced as an image only with this role; an <img> would\n\t\t\t// need the markup as a string, which is what this component avoids.\n\t\t\t// oxlint-disable-next-line jsx-a11y/prefer-tag-over-role\n\t\t\trole=\"img\"\n\t\t\taria-label={label}\n\t\t\twidth={size}\n\t\t\theight={size}\n\t\t\tviewBox={`0 0 ${extent} ${extent}`}\n\t\t\tshapeRendering=\"crispEdges\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t>\n\t\t\t{/* Dark on white in every theme: inverted codes do not scan in many readers. */}\n\t\t\t<rect width={extent} height={extent} fill=\"#ffffff\" />\n\t\t\t<path d={path} fill=\"#000000\" />\n\t\t</svg>\n\t);\n}\n","\"use client\";\n\nimport { useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Asking for a reset link.\n *\n * The screen always says the same thing afterwards, whether or not the address\n * has an account. That is not politeness: a form that said \"no account with\n * that address\" is a way to discover who has registered, one address at a time,\n * and the API already refuses to distinguish them — so a component that showed\n * a different message for each would be inventing information the server\n * deliberately withheld.\n *\n * There is no prop for where the link lands. That URL is configured on the\n * environment, for the same reason a checkout return URL is — a form that could\n * name it would be a way to have a sign-in link emailed to somewhere else.\n */\n\nexport interface ForgotPasswordProps {\n\tonSent?: (email: string) => void;\n\t/** Back to sign-in. Rendered as a link when given. */\n\tsignInUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function ForgotPassword({ onSent, signInUrl, className, style }: ForgotPasswordProps) {\n\tconst { client } = useBase316();\n\tconst [email, setEmail] = useState(\"\");\n\tconst [sent, setSent] = useState(false);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tasync function submit(event: React.FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.requestPasswordReset({ email: email.trim() });\n\n\t\t\tsetSent(true);\n\t\t\tonSent?.(email.trim());\n\t\t} catch (cause) {\n\t\t\t// Only a transport failure reaches here — the endpoint resolves for an\n\t\t\t// unknown address on purpose.\n\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not send the link.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (sent) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">Check your email</h3>\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tIf there is an account for {email.trim()}, a link to set a new password is on its way.\n\t\t\t\t</p>\n\t\t\t\t{signInUrl ? (\n\t\t\t\t\t<a className=\"b316-button-link\" href={signInUrl}>\n\t\t\t\t\t\tBack to sign in\n\t\t\t\t\t</a>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-card b316-form\", className)} style={style} onSubmit={submit}>\n\t\t\t<h3 className=\"b316-form-title\">Reset your password</h3>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-forgot-email\">\n\t\t\t\t\tEmail\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-forgot-email\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"email\"\n\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\trequired\n\t\t\t\t\tvalue={email}\n\t\t\t\t\tonChange={(event) => setEmail(event.target.value)}\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy || !email}>\n\t\t\t\t{busy ? \"Sending…\" : \"Send reset link\"}\n\t\t\t</button>\n\n\t\t\t{signInUrl ? (\n\t\t\t\t<a className=\"b316-button-link\" href={signInUrl}>\n\t\t\t\t\tBack to sign in\n\t\t\t\t</a>\n\t\t\t) : null}\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport { useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Setting a new password from an emailed link.\n *\n * The page the link lands on renders this; the token comes from `?token=` and\n * is removed from the address bar as soon as it is read. A reset token sitting\n * in browser history, in a referrer header or in a shared screenshot is a way\n * into the account for as long as it is unspent.\n *\n * The confirmation field is checked here rather than by the server, because it\n * is the one thing the server cannot help with: two different strings are both\n * valid passwords, and only the person typing knows which they meant.\n */\n\nexport interface ResetPasswordProps {\n\t/** Supply the token directly. Read from `?token=` when omitted. */\n\ttoken?: string;\n\tonReset?: () => void;\n\t/** Where to go afterwards. Rendered as a link when given. */\n\tsignInUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function ResetPassword({\n\ttoken: supplied,\n\tonReset,\n\tsignInUrl,\n\tclassName,\n\tstyle,\n}: ResetPasswordProps) {\n\tconst { client } = useBase316();\n\tconst [token, setToken] = useState<string | null>(supplied ?? null);\n\tconst [password, setPassword] = useState(\"\");\n\tconst [confirmation, setConfirmation] = useState(\"\");\n\tconst [done, setDone] = useState(false);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\t// Read once, on arrival, and scrub it from the URL. `replaceState` rather\n\t// than a navigation so the page does not reload and lose what was typed.\n\tuseEffect(() => {\n\t\tif (supplied || typeof window === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst url = new URL(window.location.href);\n\t\tconst found = url.searchParams.get(\"token\");\n\n\t\tif (!found) {\n\t\t\treturn;\n\t\t}\n\n\t\turl.searchParams.delete(\"token\");\n\t\twindow.history.replaceState({}, \"\", url.toString());\n\t\tsetToken(found);\n\t}, [supplied]);\n\n\tasync function submit(event: React.FormEvent) {\n\t\tevent.preventDefault();\n\n\t\tif (password !== confirmation) {\n\t\t\tsetError(\"Those do not match.\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.auth.completePasswordReset({ token, password });\n\n\t\t\tsetDone(true);\n\t\t\tonReset?.();\n\t\t} catch (cause) {\n\t\t\t// Covers expired, already used and never valid. The server does not\n\t\t\t// distinguish them and neither should this.\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That link is no longer valid.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (done) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">Password changed</h3>\n\t\t\t\t<p className=\"b316-muted\">You can sign in with your new password.</p>\n\t\t\t\t{signInUrl ? (\n\t\t\t\t\t<a className=\"b316-button-link\" href={signInUrl}>\n\t\t\t\t\t\tSign in\n\t\t\t\t\t</a>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!token) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">Nothing to reset</h3>\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tThis page needs the link from your email. Request a new one if yours has expired.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-card b316-form\", className)} style={style} onSubmit={submit}>\n\t\t\t<h3 className=\"b316-form-title\">Choose a new password</h3>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-reset-password\">\n\t\t\t\t\tNew password\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-reset-password\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"password\"\n\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\trequired\n\t\t\t\t\tvalue={password}\n\t\t\t\t\tonChange={(event) => setPassword(event.target.value)}\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-field\">\n\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-reset-confirm\">\n\t\t\t\t\tRepeat it\n\t\t\t\t</label>\n\t\t\t\t<input\n\t\t\t\t\tid=\"b316-reset-confirm\"\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\ttype=\"password\"\n\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\trequired\n\t\t\t\t\tvalue={confirmation}\n\t\t\t\t\tonChange={(event) => setConfirmation(event.target.value)}\n\t\t\t\t/>\n\t\t\t</div>\n\n\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy || !password}>\n\t\t\t\t{busy ? \"Saving…\" : \"Set password\"}\n\t\t\t</button>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Confirming an address from an emailed link.\n *\n * The whole component is one effect: read `?token=`, spend it, say what\n * happened. Two details carry it.\n *\n * The token is removed from the URL before it is spent, so it does not sit in\n * browser history or leak through a referrer. And the effect runs exactly once\n * — the token is single-use, so a re-run in development's double-invoked\n * effects would spend it and then report that it was invalid, which looks like\n * a broken link to everybody who sees it.\n */\n\nexport interface VerifyEmailProps {\n\t/** Supply the token directly. Read from `?token=` when omitted. */\n\ttoken?: string;\n\tonVerified?: () => void;\n\t/** Where to go next. Rendered as a link when given. */\n\tcontinueUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\ntype State = \"waiting\" | \"verifying\" | \"verified\" | \"failed\" | \"missing\";\n\nexport function VerifyEmail({\n\ttoken: supplied,\n\tonVerified,\n\tcontinueUrl,\n\tclassName,\n\tstyle,\n}: VerifyEmailProps) {\n\tconst { client } = useBase316();\n\tconst [state, setState] = useState<State>(\"waiting\");\n\tconst spent = useRef(false);\n\n\tuseEffect(() => {\n\t\t// Once. A single-use token spent twice reports failure the second time,\n\t\t// and React invokes effects twice in development.\n\t\t//\n\t\t// Not covered by a test: deleting this guard fails nothing, even under\n\t\t// StrictMode, because the test harness does not reproduce the\n\t\t// double-invocation for this component. Kept because it is correct, and\n\t\t// flagged because an untested guard is exactly what a later cleanup\n\t\t// removes as dead code.\n\t\tif (spent.current) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet token = supplied ?? null;\n\n\t\tif (!token && typeof window !== \"undefined\") {\n\t\t\tconst url = new URL(window.location.href);\n\n\t\t\ttoken = url.searchParams.get(\"token\");\n\n\t\t\tif (token) {\n\t\t\t\turl.searchParams.delete(\"token\");\n\t\t\t\twindow.history.replaceState({}, \"\", url.toString());\n\t\t\t}\n\t\t}\n\n\t\tif (!token) {\n\t\t\tsetState(\"missing\");\n\t\t\treturn;\n\t\t}\n\n\t\tspent.current = true;\n\t\tsetState(\"verifying\");\n\n\t\tclient.auth\n\t\t\t.verifyEmail({ token })\n\t\t\t.then(() => {\n\t\t\t\tsetState(\"verified\");\n\t\t\t\tonVerified?.();\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t// Expired, already used, or never valid — the server does not say\n\t\t\t\t// which, and guessing would be worse than the honest sentence below.\n\t\t\t\tsetState(\"failed\");\n\t\t\t});\n\t}, [client, supplied, onVerified]);\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{state === \"verified\" ? (\n\t\t\t\t<>\n\t\t\t\t\t<h3 className=\"b316-form-title\">Email confirmed</h3>\n\t\t\t\t\t<p className=\"b316-muted\">Thanks — your address is verified.</p>\n\t\t\t\t\t{continueUrl ? (\n\t\t\t\t\t\t<a className=\"b316-button-link\" href={continueUrl}>\n\t\t\t\t\t\t\tContinue\n\t\t\t\t\t\t</a>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t) : state === \"failed\" ? (\n\t\t\t\t<>\n\t\t\t\t\t<h3 className=\"b316-form-title\">That link did not work</h3>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tIt may have expired or already been used. Ask for a new one and try again.\n\t\t\t\t\t</p>\n\t\t\t\t</>\n\t\t\t) : state === \"missing\" ? (\n\t\t\t\t<>\n\t\t\t\t\t<h3 className=\"b316-form-title\">Nothing to confirm</h3>\n\t\t\t\t\t<p className=\"b316-muted\">This page needs the link from your email.</p>\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<p className=\"b316-muted\">Confirming your email…</p>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { TeamInvitation, TeamMember, TeamSummary } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Who is in a team, who has been invited, and the way in and out.\n *\n * One component rather than four, because these are one screen everywhere they\n * appear: a list of people, a list of people who have not arrived yet, a box to\n * add another, and a way to leave. Splitting them would make the common case —\n * a Team settings page — four imports and some layout, which is exactly the\n * assembly work the catalogue exists to remove.\n *\n * What it offers depends on what the viewer may do, and that is the server's\n * answer rather than this component's guess: inviting and removing are gated on\n * a permission the customer's own roles grant, so a member who cannot manage\n * the team simply is not shown those controls.\n *\n * Sending the invitation email is the application's job. The token comes back\n * once from the API and is never recoverable, so `onInvited` is where it goes —\n * without a handler, the link is shown on screen to be copied, which is honest\n * rather than silently losing it.\n */\n\nexport interface TeamMembersProps {\n\t/**\n\t * Which team. Defaults to the only one this person is in.\n\t *\n\t * Left out with several, the component says which is which rather than\n\t * guessing — picking one at random is how somebody invites a colleague into\n\t * the wrong company.\n\t */\n\torganizationId?: string;\n\t/**\n\t * Called with the invitation link after inviting.\n\t *\n\t * Where an application sends the email. Without it the link is shown on\n\t * screen instead, because the token is returned once and cannot be fetched\n\t * again.\n\t */\n\tonInvited?: (invitation: { email: string; token: string; url?: string }) => void;\n\t/** Where an invitation link should point. Used to build the URL for `onInvited`. */\n\tacceptUrl?: string;\n\tonLeft?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function TeamMembers({\n\torganizationId,\n\tonInvited,\n\tacceptUrl,\n\tonLeft,\n\tclassName,\n\tstyle,\n}: TeamMembersProps) {\n\tconst { client, token, session } = useBase316();\n\n\tconst [teams, setTeams] = useState<TeamSummary[] | null>(null);\n\tconst [members, setMembers] = useState<TeamMember[] | null>(null);\n\tconst [invitations, setInvitations] = useState<TeamInvitation[] | null>(null);\n\tconst [email, setEmail] = useState(\"\");\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [copied, setCopied] = useState<string | null>(null);\n\n\tconst chosen = organizationId ?? (teams?.length === 1 ? teams[0]!.id : null);\n\tconst team = teams?.find((candidate) => candidate.id === chosen) ?? null;\n\n\tconst load = useCallback(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tclient.teams\n\t\t\t.list(token)\n\t\t\t.then((result) => setTeams(result.data))\n\t\t\t.catch((cause) =>\n\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not load your teams.\"),\n\t\t\t);\n\t}, [client, token]);\n\n\tuseEffect(load, [load]);\n\n\tuseEffect(() => {\n\t\tif (!token || !chosen) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.teams\n\t\t\t.members(token, chosen)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetMembers(result.data);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not load the members.\");\n\t\t\t\t}\n\t\t\t});\n\n\t\t// Managers only, and a refusal here is not an error worth showing: it is\n\t\t// simply how the screen looks for somebody who cannot manage the team.\n\t\tclient.teams\n\t\t\t.invitations(token, chosen)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetInvitations(result.data);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetInvitations(null);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, chosen]);\n\n\tif (!token) {\n\t\treturn null;\n\t}\n\n\tif (!teams) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{error ?? \"Loading…\"}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!chosen) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{teams.length === 0\n\t\t\t\t\t? \"You are not in a team yet.\"\n\t\t\t\t\t: \"You are in more than one team. Name which with the organizationId prop.\"}\n\t\t\t</div>\n\t\t);\n\t}\n\n\t/** Managers get the pending list; everybody else gets null from that call. */\n\tconst canManage = invitations !== null;\n\n\tasync function invite(event: React.FormEvent) {\n\t\tevent.preventDefault();\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.teams.invite(token as string, chosen as string, {\n\t\t\t\temail: email.trim(),\n\t\t\t});\n\n\t\t\tconst url = acceptUrl\n\t\t\t\t? `${acceptUrl}${acceptUrl.includes(\"?\") ? \"&\" : \"?\"}invitation=${encodeURIComponent(result.token)}`\n\t\t\t\t: undefined;\n\n\t\t\tonInvited?.({ email: email.trim(), token: result.token, url });\n\n\t\t\tif (!onInvited) {\n\t\t\t\t// Shown rather than lost. The token is returned once and only a digest\n\t\t\t\t// is stored, so there is no second chance to fetch it.\n\t\t\t\tsetCopied(url ?? result.token);\n\t\t\t}\n\n\t\t\tsetEmail(\"\");\n\t\t\tsetInvitations((current) => [result.invitation, ...(current ?? [])]);\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That invitation could not be sent.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function remove(userId: string) {\n\t\tconst leaving = userId === session?.userId;\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait client.teams.removeMember(token as string, chosen as string, userId);\n\n\t\t\tif (leaving) {\n\t\t\t\tonLeft?.();\n\t\t\t\tload();\n\t\t\t} else {\n\t\t\t\tsetMembers((current) => (current ?? []).filter((member) => member.user.id !== userId));\n\t\t\t}\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That did not work.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tasync function withdraw(invitationId: string) {\n\t\ttry {\n\t\t\tawait client.teams.revokeInvitation(token as string, chosen as string, invitationId);\n\t\t\tsetInvitations((current) => (current ?? []).filter((one) => one.id !== invitationId));\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That invitation could not be withdrawn.\");\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-team\", className)} style={style}>\n\t\t\t<h3 className=\"b316-team-title\">{team?.name ?? \"Team\"}</h3>\n\n\t\t\t{team?.inherited ? (\n\t\t\t\t// Not a member of this team, so not in the list below and with nothing\n\t\t\t\t// to leave: access comes from the team that manages it, and ends there.\n\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\tYou have access through{\" \"}\n\t\t\t\t\t{teams.find((candidate) => candidate.id === team.via)?.name ??\n\t\t\t\t\t\t\"the organization that manages this team\"}\n\t\t\t\t\t.\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<ul className=\"b316-team-list\">\n\t\t\t\t{(members ?? []).map((member) => (\n\t\t\t\t\t<li key={member.id} className=\"b316-team-member\">\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<div>{member.user.name ?? member.user.email ?? \"Someone\"}</div>\n\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t{member.user.email}\n\t\t\t\t\t\t\t\t{member.user.id === session?.userId ? \" · you\" : \"\"}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"b316-team-member-side\">\n\t\t\t\t\t\t\t<span className=\"b316-chip\">{member.role.name}</span>\n\t\t\t\t\t\t\t{canManage || member.user.id === session?.userId ? (\n\t\t\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tconfirmLabel={\n\t\t\t\t\t\t\t\t\t\tmember.user.id === session?.userId\n\t\t\t\t\t\t\t\t\t\t\t? \"Leave this team\"\n\t\t\t\t\t\t\t\t\t\t\t: `Remove ${member.user.name ?? member.user.email ?? \"them\"}`\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tonConfirm={() => remove(member.user.id)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{member.user.id === session?.userId ? \"Leave\" : \"Remove\"}\n\t\t\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</li>\n\t\t\t\t))}\n\t\t\t</ul>\n\n\t\t\t{canManage && (invitations ?? []).length > 0 ? (\n\t\t\t\t<>\n\t\t\t\t\t<h4 className=\"b316-team-subtitle\">Invited</h4>\n\t\t\t\t\t<ul className=\"b316-team-list\">\n\t\t\t\t\t\t{(invitations ?? []).map((invitation) => (\n\t\t\t\t\t\t\t<li key={invitation.id} className=\"b316-team-member\">\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<div>{invitation.email}</div>\n\t\t\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\t\t{invitation.role.name} · expires{\" \"}\n\t\t\t\t\t\t\t\t\t\t{new Date(invitation.expiresAt).toLocaleDateString()}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\t\t\tonClick={() => void withdraw(invitation.id)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tWithdraw\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</>\n\t\t\t) : null}\n\n\t\t\t{canManage ? (\n\t\t\t\t<form className=\"b316-team-invite\" onSubmit={invite}>\n\t\t\t\t\t<label className=\"b316-label\" htmlFor=\"b316-invite-email\">\n\t\t\t\t\t\tInvite by email\n\t\t\t\t\t</label>\n\t\t\t\t\t<div className=\"b316-team-invite-row\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\tid=\"b316-invite-email\"\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\tplaceholder=\"colleague@example.com\"\n\t\t\t\t\t\t\tvalue={email}\n\t\t\t\t\t\t\tonChange={(event) => setEmail(event.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy || !email}>\n\t\t\t\t\t\t\t{busy ? \"Sending…\" : \"Invite\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t) : null}\n\n\t\t\t{copied ? (\n\t\t\t\t<div className=\"b316-team-link\">\n\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\tSend them this link. It is shown once and cannot be fetched again.\n\t\t\t\t\t</div>\n\t\t\t\t\t<code>{copied}</code>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { InvitationPreview } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * The other end of an invitation.\n *\n * Reads the token from the URL and says what it is for *before* asking anybody\n * to sign in, because \"join Acme as a Member\" is a reason to create an account\n * and \"accept invitation\" is not. That preview is the one call here that needs\n * no session — the person holding the link may have no account at all, which is\n * the entire reason invitations exist.\n *\n * The token is not scrubbed from the URL, unlike a password reset. It is\n * useless to anybody but the address it was sent to, and leaving it in place\n * means the page survives a sign-in round trip that navigates away and back —\n * which is the normal path for somebody who has just created an account.\n */\n\n/**\n * The sign-up link, carrying the invitation.\n *\n * `<SignUp />` reads `?invitation=` and sends it with the sign-up, which is\n * what creates the account inside this team instead of in a personal\n * workspace nobody asked for. A link the caller already gave a token is left\n * alone; a fragment stays at the end, where it belongs.\n */\nexport function signUpUrlWithInvitation(url: string, token: string): string {\n\tconst [beforeHash, ...hash] = url.split(\"#\");\n\tconst base = beforeHash ?? \"\";\n\n\tif (/[?&]invitation=/.test(base)) {\n\t\treturn url;\n\t}\n\n\tconst joined = `${base}${base.includes(\"?\") ? \"&\" : \"?\"}invitation=${encodeURIComponent(token)}`;\n\n\treturn hash.length > 0 ? `${joined}#${hash.join(\"#\")}` : joined;\n}\n\nexport interface AcceptInvitationProps {\n\t/** Supply the token directly. Read from `?invitation=` when omitted. */\n\ttoken?: string;\n\tonAccepted?: (organizationId: string) => void;\n\t/**\n\t * Where to send somebody who needs an account first — a page with\n\t * `<SignUp />`. The invitation is appended as `?invitation=`, so the\n\t * account is created inside this team rather than in a workspace of its\n\t * own.\n\t */\n\tsignUpUrl?: string;\n\tsignInUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function AcceptInvitation({\n\ttoken: supplied,\n\tonAccepted,\n\tsignUpUrl,\n\tsignInUrl,\n\tclassName,\n\tstyle,\n}: AcceptInvitationProps) {\n\tconst { client, token: session, session: user } = useBase316();\n\tconst [invitationToken, setInvitationToken] = useState<string | null>(supplied ?? null);\n\tconst [preview, setPreview] = useState<InvitationPreview | null>(null);\n\tconst [state, setState] = useState<\"loading\" | \"ready\" | \"invalid\" | \"accepted\">(\"loading\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [busy, setBusy] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (supplied || typeof window === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tsetInvitationToken(new URL(window.location.href).searchParams.get(\"invitation\"));\n\t}, [supplied]);\n\n\tuseEffect(() => {\n\t\tif (!invitationToken) {\n\t\t\tsetState(supplied === undefined ? \"loading\" : \"invalid\");\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.teams\n\t\t\t.preview(invitationToken)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetPreview(result);\n\t\t\t\t\tsetState(\"ready\");\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t// One answer for missing, expired, spent and withdrawn — the API does\n\t\t\t\t// not distinguish them, so that somebody cannot probe for live tokens.\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetState(\"invalid\");\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, invitationToken, supplied]);\n\n\tasync function accept() {\n\t\tif (!session || !invitationToken) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.teams.accept(session, invitationToken);\n\n\t\t\tsetState(\"accepted\");\n\t\t\tonAccepted?.(result.organizationId);\n\t\t} catch (cause) {\n\t\t\tsetError(cause instanceof Error ? cause.message : \"That invitation could not be accepted.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}\n\n\tif (state === \"loading\") {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (state === \"invalid\") {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">That invitation is no longer valid</h3>\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tIt may have expired, been withdrawn, or already been used. Ask for a new one.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (state === \"accepted\") {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<h3 className=\"b316-form-title\">You have joined {preview?.organizationName}</h3>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst matches = !user || (user.user.email ?? \"\").toLowerCase() === preview?.email.toLowerCase();\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-invitation\", className)} style={style}>\n\t\t\t<h3 className=\"b316-form-title\">Join {preview?.organizationName}</h3>\n\t\t\t<p className=\"b316-muted\">\n\t\t\t\tInvited as {preview?.email} · {preview?.roleName}\n\t\t\t</p>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{!session ? (\n\t\t\t\t<>\n\t\t\t\t\t<p>Sign in as {preview?.email} to accept.</p>\n\t\t\t\t\t<div className=\"b316-invitation-actions\">\n\t\t\t\t\t\t{signInUrl ? (\n\t\t\t\t\t\t\t<a className=\"b316-button\" href={signInUrl}>\n\t\t\t\t\t\t\t\tSign in\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{signUpUrl ? (\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\tclassName=\"b316-button-link\"\n\t\t\t\t\t\t\t\thref={\n\t\t\t\t\t\t\t\t\tinvitationToken ? signUpUrlWithInvitation(signUpUrl, invitationToken) : signUpUrl\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tCreate an account\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t) : !matches ? (\n\t\t\t\t// Said before they press anything. The server refuses this, but\n\t\t\t\t// finding out after a click reads as a broken invitation rather than\n\t\t\t\t// as being signed in as the wrong person.\n\t\t\t\t<p>\n\t\t\t\t\tYou are signed in as {user?.user.email}. This invitation was sent to {preview?.email} —\n\t\t\t\t\tsign in as that address to accept it.\n\t\t\t\t</p>\n\t\t\t) : (\n\t\t\t\t<button type=\"button\" className=\"b316-button\" disabled={busy} onClick={accept}>\n\t\t\t\t\t{busy ? \"Joining…\" : `Join ${preview?.organizationName}`}\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/**\n * Pay an invoice, inside the host application's own page.\n *\n * The Base316-hosted pay page exists for the case where there is nowhere else to\n * send somebody — a scanned QR code, a link in an email. This is the other case:\n * a customer who already has their own portal and wants the payment step to\n * happen there, under their own navigation, without a redirect.\n *\n * It takes a payment-link token rather than an invoice id on purpose. The token\n * is a capability — it says *this* invoice may be paid by whoever holds it — and\n * that is what makes the component usable on a page the payer reached from an\n * email, where there is no session to check them against.\n *\n * Stripe.js is loaded by injecting a script tag rather than by depending on\n * `@stripe/stripe-js`. This package has exactly one dependency today and the\n * card field has to be a cross-origin iframe either way, so a hard dependency\n * would buy nothing but weight in every bundle that imports anything from here.\n */\n\nconst STRIPE_SRC = \"https://js.stripe.com/v3/\";\n\ninterface StripeElements {\n\tcreate(type: string): { mount(selector: string | HTMLElement): void };\n}\n\ninterface StripeLike {\n\telements(options: { clientSecret: string }): StripeElements;\n\tconfirmPayment(options: {\n\t\telements: StripeElements;\n\t\tconfirmParams: { return_url: string };\n\t\tredirect: \"if_required\";\n\t}): Promise<{ error?: { message?: string } }>;\n}\n\ndeclare global {\n\tinterface Window {\n\t\tStripe?: (key: string, options?: { stripeAccount: string }) => StripeLike;\n\t}\n}\n\n/** Resolves once Stripe.js is on the page, loading it if nobody else has. */\nfunction loadStripeScript(): Promise<void> {\n\tif (typeof window === \"undefined\") {\n\t\treturn Promise.reject(new Error(\"Stripe.js cannot load during server rendering.\"));\n\t}\n\n\tif (window.Stripe) {\n\t\treturn Promise.resolve();\n\t}\n\n\treturn new Promise((resolve, reject) => {\n\t\t// Reused rather than appended again: two copies of Stripe.js on one page\n\t\t// is a support case nobody enjoys, and a host app may already have it.\n\t\tconst existing = document.querySelector<HTMLScriptElement>(`script[src=\"${STRIPE_SRC}\"]`);\n\n\t\tif (existing) {\n\t\t\texisting.addEventListener(\"load\", () => resolve());\n\t\t\texisting.addEventListener(\"error\", () => reject(new Error(\"Stripe.js failed to load.\")));\n\t\t\treturn;\n\t\t}\n\n\t\tconst script = document.createElement(\"script\");\n\t\tscript.src = STRIPE_SRC;\n\t\tscript.async = true;\n\t\tscript.onload = () => resolve();\n\t\tscript.onerror = () => reject(new Error(\"Stripe.js failed to load.\"));\n\t\tdocument.head.appendChild(script);\n\t});\n}\n\nexport function PayInvoice({\n\ttoken,\n\tenvironmentId,\n\tonPaid,\n\tclassName,\n\tstyle,\n}: {\n\t/** From `invoices.createPaymentLink` on your server. */\n\ttoken: string;\n\t/** The environment the link belongs to; it is in the link URL too. */\n\tenvironmentId: string;\n\t/** Runs once the payment is complete. */\n\tonPaid?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { client } = useBase316();\n\tconst mountRef = useRef<HTMLDivElement | null>(null);\n\tconst stripeRef = useRef<StripeLike | null>(null);\n\tconst elementsRef = useRef<StripeElements | null>(null);\n\n\tconst [ready, setReady] = useState(false);\n\tconst [paying, setPaying] = useState(false);\n\tconst [done, setDone] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tasync function start() {\n\t\t\t// The pay routes sit outside /v1 and take no API key: the token in the\n\t\t\t// path is the whole credential, which is what lets this work on a page\n\t\t\t// the payer reached from an email with no session at all.\n\t\t\tconst base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;\n\t\t\tconst response = await fetch(`${base}/intent`, { method: \"POST\" });\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(\"This payment link is no longer valid.\");\n\t\t\t}\n\n\t\t\tconst intent = (await response.json()) as {\n\t\t\t\tclientSecret: string;\n\t\t\t\tpublishableKey: string;\n\t\t\t\taccountId: string | null;\n\t\t\t};\n\n\t\t\tawait loadStripeScript();\n\n\t\t\tif (cancelled || !window.Stripe || !mountRef.current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst stripe = window.Stripe(\n\t\t\t\tintent.publishableKey,\n\t\t\t\tintent.accountId ? { stripeAccount: intent.accountId } : undefined,\n\t\t\t);\n\t\t\tconst elements = stripe.elements({ clientSecret: intent.clientSecret });\n\n\t\t\telements.create(\"payment\").mount(mountRef.current);\n\t\t\tstripeRef.current = stripe;\n\t\t\telementsRef.current = elements;\n\t\t\tsetReady(true);\n\t\t}\n\n\t\tstart().catch((cause: unknown) => {\n\t\t\tif (!cancelled) {\n\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not prepare this payment.\");\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, environmentId, token]);\n\n\tconst submit = async (event: React.FormEvent) => {\n\t\tevent.preventDefault();\n\n\t\tif (!stripeRef.current || !elementsRef.current) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetPaying(true);\n\t\tsetError(null);\n\n\t\t// \"if_required\" keeps an ordinary card payment on this page and leaves it\n\t\t// only when the method genuinely needs a redirect — a 3-D Secure\n\t\t// challenge, or a bank's own app.\n\t\tconst result = await stripeRef.current.confirmPayment({\n\t\t\telements: elementsRef.current,\n\t\t\tconfirmParams: { return_url: window.location.href },\n\t\t\tredirect: \"if_required\",\n\t\t});\n\n\t\tif (result.error) {\n\t\t\tsetError(result.error.message ?? \"That payment could not be completed.\");\n\t\t\tsetPaying(false);\n\t\t\treturn;\n\t\t}\n\n\t\tsetDone(true);\n\t\tonPaid?.();\n\t};\n\n\tif (done) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-pay\", className)} style={style}>\n\t\t\t\t<p className=\"b316-pay__done\">Paid — thank you.</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-pay\", className)} style={style} onSubmit={submit}>\n\t\t\t{error ? (\n\t\t\t\t<p className=\"b316-pay__error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t<div ref={mountRef} className=\"b316-pay__element\" />\n\t\t\t<button className=\"b316-pay__submit\" type=\"submit\" disabled={!ready || paying}>\n\t\t\t\t{paying ? \"Paying…\" : \"Pay\"}\n\t\t\t</button>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { useBase316 } from \"./provider\";\n\n/**\n * Watch a payment link until it is paid.\n *\n * For the merchant's *screen*, not their server. A webhook tells a backend that\n * a walk-up customer paid; it cannot tell the tablet propped on the counter with\n * the QR code on it. This is what flips that screen over.\n *\n * A poll rather than a socket, matching the rest of the platform: there is no\n * streaming endpoint, and a poll is what survives a tablet sleeping and a phone\n * hopping between wifi and cellular mid-payment.\n *\n * Use it with the token you got back from `invoices.createPaymentLink` on your\n * server. Polling stops on its own once the invoice settles, so a forgotten\n * component does not keep asking for ever.\n */\n\nexport type PaymentLinkStatus =\n\t| { state: \"loading\" }\n\t| { state: \"payable\"; number: string; due: string; currency: string }\n\t| { state: \"settled\"; number: string }\n\t/** Unknown, expired, or withdrawn — the API does not say which. */\n\t| { state: \"invalid\" };\n\nexport function usePaymentLink({\n\ttoken,\n\tenvironmentId,\n\tintervalMs = 2000,\n\tonPaid,\n}: {\n\ttoken: string;\n\tenvironmentId: string;\n\t/**\n\t * How often to ask. The default is chosen against the thing being waited for\n\t * — somebody tapping a phone a metre away — rather than against server load.\n\t */\n\tintervalMs?: number;\n\tonPaid?: () => void;\n}): PaymentLinkStatus {\n\tconst { client } = useBase316();\n\tconst [status, setStatus] = useState<PaymentLinkStatus>({ state: \"loading\" });\n\n\t// Held in a ref so that passing a new inline function on every render does\n\t// not tear down and restart the poll.\n\tconst onPaidRef = useRef(onPaid);\n\tonPaidRef.current = onPaid;\n\n\tuseEffect(() => {\n\t\tlet stopped = false;\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\t\tconst statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;\n\n\t\tasync function check() {\n\t\t\ttry {\n\t\t\t\tconst response = await fetch(statusUrl, { cache: \"no-store\" });\n\n\t\t\t\tif (stopped) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (response.status === 404) {\n\t\t\t\t\tsetStatus({ state: \"invalid\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (response.ok) {\n\t\t\t\t\tconst body = (await response.json()) as {\n\t\t\t\t\t\tstate: \"payable\" | \"settled\";\n\t\t\t\t\t\tnumber: string;\n\t\t\t\t\t\tdue: string | null;\n\t\t\t\t\t\tcurrency: string | null;\n\t\t\t\t\t};\n\n\t\t\t\t\tif (stopped) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (body.state === \"settled\") {\n\t\t\t\t\t\tsetStatus({ state: \"settled\", number: body.number });\n\t\t\t\t\t\tonPaidRef.current?.();\n\t\t\t\t\t\t// Deliberately no reschedule: this is terminal.\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tsetStatus({\n\t\t\t\t\t\tstate: \"payable\",\n\t\t\t\t\t\tnumber: body.number,\n\t\t\t\t\t\tdue: body.due ?? \"0\",\n\t\t\t\t\t\tcurrency: body.currency ?? \"USD\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// A dropped request is ordinary — a phone changing network does this.\n\t\t\t\t// The next tick asks again rather than showing an error to somebody\n\t\t\t\t// whose customer is probably mid-payment.\n\t\t\t}\n\n\t\t\tif (!stopped) {\n\t\t\t\t// Scheduled after the response rather than on a fixed interval, so a\n\t\t\t\t// slow network cannot stack requests on top of each other.\n\t\t\t\ttimer = setTimeout(check, intervalMs);\n\t\t\t}\n\t\t}\n\n\t\tvoid check();\n\n\t\treturn () => {\n\t\t\tstopped = true;\n\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t};\n\t}, [client, environmentId, token, intervalMs]);\n\n\treturn status;\n}\n","\"use client\";\n\nimport type { PublicPlan } from \"@base316/sdk\";\nimport { type CSSProperties, useState } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { usePlans } from \"./usePlans\";\n\nfunction formatAmount(amount: string | null, currency: string): string {\n\tif (amount === null) return \"Free\";\n\n\tconst value = Number(amount);\n\tif (!Number.isFinite(value)) return \"Free\";\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\t// An unknown currency code should not blank the price.\n\t\treturn `${value} ${currency}`;\n\t}\n}\n\nfunction cadence(plan: PublicPlan, amount: string | null): string {\n\tif (amount === null) {\n\t\treturn \"\\u00a0\";\n\t}\n\n\tconst unit = plan.interval.toLowerCase();\n\treturn plan.intervalCount === 1 ? `per ${unit}` : `every ${plan.intervalCount} ${unit}s`;\n}\n\n/**\n * What a plan's trial says on the card, or null when it has none.\n *\n * A `CONVERT` trial is the familiar \"14-day free trial\": it bills when it\n * ends. A `DOWNGRADE` trial — the reverse trial — does not bill a subscriber\n * who never added a card; it moves them to `trialDowngradePlanVersionId`. The\n * card has to say so, or a visitor reads \"free trial\" as \"then I'm charged\"\n * and never starts one. The target is named when it is among the published\n * plans (it usually is: the Free plan); otherwise the label says what keeps\n * the plan instead of guessing at a name.\n */\nexport function describeTrial(plan: PublicPlan, plans: readonly PublicPlan[]): string | null {\n\tif (!plan.trialDays) {\n\t\treturn null;\n\t}\n\n\tconst trial = `${plan.trialDays}-day free trial`;\n\n\tif (plan.trialEndAction !== \"DOWNGRADE\") {\n\t\treturn trial;\n\t}\n\n\tconst target = plans.find(\n\t\t(candidate) => candidate.planVersionId === plan.trialDowngradePlanVersionId,\n\t);\n\n\treturn target\n\t\t? `${trial}, then ${target.name} unless you add a card`\n\t\t: `${trial}, no card needed. Add one to keep ${plan.name}`;\n}\n\n/**\n * The plans, as an end user picks them.\n *\n * Drop it in with no props and it works: it loads the published plans, marks\n * the one the signed-in user is on, and completes the purchase.\n *\n * Choosing a plan used to be the caller's job, because minting a checkout\n * session needs a secret key that cannot live in a browser. That is still\n * true — but it is an argument about *key custody*, not about who names the\n * plan. `POST /v1/me/checkout/sessions` resolves the customer from the session\n * and reads the price from the database against the plan id, so a browser\n * naming a cheaper plan subscribes to a cheaper plan rather than paying less\n * for an expensive one. That is what makes this droppable.\n *\n * Two routes, because a subscriber and a newcomer need different things:\n *\n * - Already subscribed, card on file → change plan in place, prorated, no\n * card re-entry and no second subscription beside the first.\n * - Otherwise → a checkout session, which is the thing that collects a card.\n *\n * `onSelectPlan` remains as an override for an application that wants to run\n * its own flow — a quote, an approval step, its own backend route.\n */\nexport function PricingTable({\n\tonSelectPlan,\n\tcurrentPlanVersionId,\n\tfeaturedPlanKey,\n\tsignInUrl,\n\tclassName,\n\tstyle,\n}: {\n\t/**\n\t * Take over what \"Choose\" does.\n\t *\n\t * Optional. Without it the component completes the purchase itself, which\n\t * is what most applications want.\n\t */\n\tonSelectPlan?: (planVersionId: string, plan: PublicPlan) => void | Promise<void>;\n\t/**\n\t * Marks the plan the viewer is already on.\n\t *\n\t * Discovered from the signed-in user's subscription when not given. Pass it\n\t * to override — on a marketing page rendering someone else's plan, say.\n\t */\n\tcurrentPlanVersionId?: string | null;\n\t/** The plan to present as the default choice, by its key. */\n\tfeaturedPlanKey?: string;\n\t/**\n\t * Where to send a signed-out visitor who picks a plan.\n\t *\n\t * Checkout needs a session, so without a signed-in user there is nobody to\n\t * bill. Given a URL the button goes there; without one it says so rather\n\t * than failing on click.\n\t */\n\tsignInUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\t// Every decision worth getting right lives in the hook. What remains here is\n\t// markup — which is the point: an application that wants a different table\n\t// calls `usePlans()` and writes its own rather than forking this one.\n\tconst {\n\t\tplans,\n\t\terror,\n\t\tcurrentPlanVersionId: current,\n\t\tbusyPlanVersionId: busy,\n\t\tlastError,\n\t\tsignedIn,\n\t\tmanagedBy,\n\t\tselectPlan,\n\t} = usePlans({ currentPlanVersionId });\n\t// Said after a downgrade, which waits for the renewal: without it the click\n\t// appears to do nothing, because the current plan rightly stays current.\n\tconst [scheduled, setScheduled] = useState<string | null>(null);\n\n\tasync function choose(plan: PublicPlan) {\n\t\tif (onSelectPlan) {\n\t\t\tawait onSelectPlan(plan.planVersionId, plan);\n\t\t\treturn;\n\t\t}\n\n\t\tsetScheduled(null);\n\t\tconst outcome = await selectPlan(plan);\n\n\t\tif (outcome.status === \"scheduled\") {\n\t\t\tconst on = outcome.effectiveAt\n\t\t\t\t? new Date(outcome.effectiveAt).toLocaleDateString()\n\t\t\t\t: \"your next renewal\";\n\t\t\tsetScheduled(`${plan.name} starts on ${on}. You keep your current plan until then.`);\n\t\t}\n\n\t\t// The hook reports rather than navigates for this one, because where a\n\t\t// signed-out visitor should go is the application's decision.\n\t\tif (outcome.status === \"needs-sign-in\" && signInUrl && typeof window !== \"undefined\") {\n\t\t\twindow.location.assign(signInUrl);\n\t\t}\n\t}\n\n\tif (error) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tPlans are unavailable right now.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!plans) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading plans…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (plans.length === 0) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tNo plans are published yet.\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Whether a slot is rendered is a property of the table, not of one plan:\n\t// reserving space on every card is what keeps the rows aligned.\n\tconst anyTrial = plans.some((plan) => Boolean(plan.trialDays));\n\tconst anyDescription = plans.some((plan) => Boolean(plan.description));\n\tconst anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);\n\n\treturn (\n\t\t<div className={cls(\"b316-plans\", className)} style={style}>\n\t\t\t{/* A failed upgrade is silent otherwise: the button stops spinning and\n\t\t\t nothing about the page says why the plan did not change. */}\n\t\t\t{managedBy ? (\n\t\t\t\t// A client company's plan comes from the firm that runs it. The table\n\t\t\t\t// still shows what is on offer, with the current plan marked, but\n\t\t\t\t// nothing here can be bought: it would grant this account nothing.\n\t\t\t\t<div className=\"b316-plans-managed b316-muted\">\n\t\t\t\t\tYour plan is provided by {managedBy.name ?? \"the organization that manages your account\"}.\n\t\t\t\t\tAsk them to change it.\n\t\t\t\t</div>\n\t\t\t) : lastError ? (\n\t\t\t\t<div className=\"b316-plans-error\" role=\"alert\">\n\t\t\t\t\t{lastError}\n\t\t\t\t</div>\n\t\t\t) : scheduled ? (\n\t\t\t\t<div className=\"b316-plans-managed b316-muted\" role=\"status\">\n\t\t\t\t\t{scheduled}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{plans.map((plan) => {\n\t\t\t\tconst base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];\n\t\t\t\tconst isCurrent = current === plan.planVersionId;\n\t\t\t\tconst featured = featuredPlanKey === plan.key;\n\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={plan.id}\n\t\t\t\t\t\tclassName={featured ? \"b316-card b316-plan b316-plan-featured\" : \"b316-card b316-plan\"}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div className=\"b316-plan-head\">\n\t\t\t\t\t\t\t{anyFeatured ? (\n\t\t\t\t\t\t\t\t<div className={featured ? \"b316-plan-badge\" : \"b316-plan-badge-spacer\"}>\n\t\t\t\t\t\t\t\t\t{featured ? \"Recommended\" : \"\\u00a0\"}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<div className=\"b316-plan-name\">{plan.name}</div>\n\t\t\t\t\t\t\t{anyDescription ? (\n\t\t\t\t\t\t\t\t<div className=\"b316-plan-desc\">{plan.description ?? \"\\u00a0\"}</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div className=\"b316-plan-pricing\">\n\t\t\t\t\t\t\t<div className=\"b316-plan-price\">\n\t\t\t\t\t\t\t\t{formatAmount(base?.amount ?? null, plan.currency)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{/* Rendered even when empty so every card's feature list starts\n\t\t\t\t\t\t\t at the same height — otherwise a free plan pulls its rows up\n\t\t\t\t\t\t\t and nothing lines up across the table. */}\n\t\t\t\t\t\t\t<div className=\"b316-plan-cadence\">{cadence(plan, base?.amount ?? null)}</div>\n\t\t\t\t\t\t\t{anyTrial ? (\n\t\t\t\t\t\t\t\t<div className=\"b316-plan-trial\">{describeTrial(plan, plans) ?? \"\\u00a0\"}</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<ul className=\"b316-plan-features\">\n\t\t\t\t\t\t\t{plan.entitlements\n\t\t\t\t\t\t\t\t.filter((entitlement) => entitlement.enabled)\n\t\t\t\t\t\t\t\t.map((entitlement) => (\n\t\t\t\t\t\t\t\t\t<li key={entitlement.featureId} className=\"b316-plan-feature\">\n\t\t\t\t\t\t\t\t\t\t<span>{entitlement.featureName}</span>\n\t\t\t\t\t\t\t\t\t\t<span className=\"b316-plan-feature-value\">\n\t\t\t\t\t\t\t\t\t\t\t{entitlement.limit === null\n\t\t\t\t\t\t\t\t\t\t\t\t? \"Unlimited\"\n\t\t\t\t\t\t\t\t\t\t\t\t: // A usage price on the feature makes the limit an\n\t\t\t\t\t\t\t\t\t\t\t\t\t// allowance billed past, not a ceiling — the same\n\t\t\t\t\t\t\t\t\t\t\t\t\t// rule `check()` applies (any non-FLAT price).\n\t\t\t\t\t\t\t\t\t\t\t\t\tplan.prices.some(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(price) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprice.featureId === entitlement.featureId && price.model !== \"FLAT\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t\t\t\t\t\t\t? `${entitlement.limit} included`\n\t\t\t\t\t\t\t\t\t\t\t\t\t: entitlement.limit}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</ul>\n\n\t\t\t\t\t\t<div className=\"b316-plan-action\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName={isCurrent ? \"b316-button b316-button-current\" : \"b316-button\"}\n\t\t\t\t\t\t\t\t// Signed out with nowhere to send them is the one case with no\n\t\t\t\t\t\t\t\t// useful action, so the button says so instead of failing on\n\t\t\t\t\t\t\t\t// click. An override is assumed to handle it itself.\n\t\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\t\tisCurrent ||\n\t\t\t\t\t\t\t\t\tmanagedBy !== null ||\n\t\t\t\t\t\t\t\t\tbusy !== null ||\n\t\t\t\t\t\t\t\t\t(!signedIn && !signInUrl && !onSelectPlan)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tvoid choose(plan);\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{isCurrent\n\t\t\t\t\t\t\t\t\t? \"Current plan\"\n\t\t\t\t\t\t\t\t\t: busy === plan.planVersionId\n\t\t\t\t\t\t\t\t\t\t? \"Working…\"\n\t\t\t\t\t\t\t\t\t\t: !signedIn && !signInUrl && !onSelectPlan\n\t\t\t\t\t\t\t\t\t\t\t? \"Sign in to choose\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Choose\"}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { PublicPlan } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport { useBase316 } from \"./provider\";\n\n/**\n * The plans, and what happens when somebody picks one — without any markup.\n *\n * This is the escape hatch that keeps a component library from being forked.\n * `PricingTable` is a few dozen lines of JSX over this hook; an application\n * with its own design system calls the hook directly, renders whatever it\n * likes, and still gets the part that is easy to get wrong:\n *\n * - which plan the signed-in user is actually on,\n * - whether picking one should prorate in place or collect a card,\n * - resolving the customer from the session rather than trusting the browser.\n *\n * The rule the whole library follows: logic lives in a hook, presentation\n * lives in a component, and the component is thin enough to be worth\n * replacing. Fusing the two is what forces a fork the first time somebody\n * wants a different table.\n */\n\n/** What picking a plan did. Returned so a custom UI can respond in kind. */\nexport type SelectPlanOutcome =\n\t| { status: \"changed\"; planVersionId: string }\n\t/**\n\t * A downgrade, scheduled for the renewal rather than made now: the user\n\t * keeps the plan they paid for until `effectiveAt`, so it stays current.\n\t */\n\t| { status: \"scheduled\"; planVersionId: string; effectiveAt: string | null }\n\t| { status: \"checkout\"; url: string }\n\t| { status: \"needs-sign-in\" }\n\t| { status: \"failed\"; reason: string };\n\nexport interface UsePlansOptions {\n\t/**\n\t * Override the plan shown as current.\n\t *\n\t * Discovered from the signed-in user's subscription when omitted.\n\t */\n\tcurrentPlanVersionId?: string | null;\n\t/**\n\t * Where a checkout URL should send the browser.\n\t *\n\t * Defaults to navigating. Pass `false` to keep `selectPlan` free of side\n\t * effects and handle the URL from the outcome — a modal checkout, a native\n\t * shell, or a test.\n\t */\n\tnavigate?: boolean | ((url: string) => void);\n}\n\nexport interface UsePlansResult {\n\t/** Null until loaded. Empty means nothing is published yet. */\n\tplans: PublicPlan[] | null;\n\tloading: boolean;\n\t/** True when the catalog could not be read at all. */\n\terror: boolean;\n\t/** The plan the viewer is on, discovered or supplied. */\n\tcurrentPlanVersionId: string | null;\n\t/** The plan version currently being acted on, for a pending state. */\n\tbusyPlanVersionId: string | null;\n\t/** Why the last selection failed, if it did. Cleared on the next attempt. */\n\tlastError: string | null;\n\t/** Whether there is a session to bill. */\n\tsignedIn: boolean;\n\t/**\n\t * Who provides this account's plan, when it is not the account itself — a\n\t * client company billed through the firm that manages it. Plans cannot be\n\t * bought or changed from here then; `selectPlan` refuses without calling.\n\t */\n\tmanagedBy: { name: string | null } | null;\n\tselectPlan: (plan: PublicPlan) => Promise<SelectPlanOutcome>;\n\treload: () => void;\n}\n\n/**\n * Statuses that mean \"this account cannot be changed in place, send it to\n * checkout\".\n *\n * The API says so explicitly with `useCheckout: true` on the body, but the SDK\n * error carries the status rather than the body. These two codes are exactly\n * and only that case — 409 for no subscription, 402 for no stored card — so\n * branching on them loses nothing.\n */\nconst CHECKOUT_STATUSES = new Set([402, 409]);\n\nexport function usePlans(options: UsePlansOptions = {}): UsePlansResult {\n\tconst { client, token } = useBase316();\n\tconst [plans, setPlans] = useState<PublicPlan[] | null>(null);\n\tconst [error, setError] = useState(false);\n\tconst [busyPlanVersionId, setBusy] = useState<string | null>(null);\n\tconst [lastError, setLastError] = useState<string | null>(null);\n\tconst [ownPlanVersionId, setOwnPlanVersionId] = useState<string | null>(null);\n\tconst [managedBy, setManagedBy] = useState<{ name: string | null } | null>(null);\n\tconst [reloadCount, setReloadCount] = useState(0);\n\n\tconst supplied = options.currentPlanVersionId;\n\tconst discover = supplied === undefined;\n\n\tuseEffect(() => {\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.plans()\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetPlans(result.data);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load plans\", cause);\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(true);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, reloadCount]);\n\n\t// Marking the current plan is what turns a price list into an account\n\t// screen, and asking the caller to supply it means every caller has to\n\t// fetch the subscription themselves before they can render a table.\n\tuseEffect(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.subscription(token)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetManagedBy(result.managedBy ?? null);\n\t\t\t\t\t// A caller-supplied current plan still wins for the marker.\n\t\t\t\t\tif (discover) {\n\t\t\t\t\t\tsetOwnPlanVersionId(result.subscription?.planVersion.id ?? null);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t\t// Not an error worth surfacing: a signed-in user with no subscription\n\t\t\t// is the normal case on a pricing page, and the table still renders.\n\t\t\t.catch(() => null);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, discover, reloadCount]);\n\n\tconst reload = useCallback(() => {\n\t\tsetError(false);\n\t\tsetReloadCount((count) => count + 1);\n\t}, []);\n\n\tconst selectPlan = useCallback(\n\t\tasync (plan: PublicPlan): Promise<SelectPlanOutcome> => {\n\t\t\tsetLastError(null);\n\n\t\t\tif (managedBy) {\n\t\t\t\t// Refused here rather than by the API, so nobody is sent to a checkout\n\t\t\t\t// for a plan that would grant them nothing.\n\t\t\t\tconst reason = `Your plan is provided by ${managedBy.name ?? \"the organization that manages your account\"}.`;\n\t\t\t\tsetLastError(reason);\n\n\t\t\t\treturn { status: \"failed\", reason };\n\t\t\t}\n\n\t\t\tif (!token) {\n\t\t\t\t// Checkout resolves the customer from the session, so without one\n\t\t\t\t// there is nobody to bill. Reported rather than thrown: a signed-out\n\t\t\t\t// visitor on a marketing page is expected, not broken.\n\t\t\t\treturn { status: \"needs-sign-in\" };\n\t\t\t}\n\n\t\t\tsetBusy(plan.planVersionId);\n\n\t\t\tconst go = (url: string) => {\n\t\t\t\tconst navigate = options.navigate ?? true;\n\n\t\t\t\tif (typeof navigate === \"function\") {\n\t\t\t\t\tnavigate(url);\n\t\t\t\t} else if (navigate && typeof window !== \"undefined\") {\n\t\t\t\t\twindow.location.assign(url);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\t// The cheaper path, and the one a subscriber wants: no card re-entry\n\t\t\t\t// and no second subscription opened beside the first.\n\t\t\t\tconst result = await client.billing.changePlan(token, plan.planVersionId);\n\n\t\t\t\t// A downgrade waits for the renewal by default. Marking the new plan\n\t\t\t\t// current now would tell the user they had already lost what they\n\t\t\t\t// paid for this period.\n\t\t\t\tif (result.scheduled) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tstatus: \"scheduled\",\n\t\t\t\t\t\tplanVersionId: plan.planVersionId,\n\t\t\t\t\t\teffectiveAt: result.effectiveAt ?? null,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tsetOwnPlanVersionId(plan.planVersionId);\n\n\t\t\t\treturn { status: \"changed\", planVersionId: plan.planVersionId };\n\t\t\t} catch (cause) {\n\t\t\t\tconst status = (cause as { status?: number | null }).status ?? null;\n\n\t\t\t\tif (status === null || !CHECKOUT_STATUSES.has(status)) {\n\t\t\t\t\tconst reason = cause instanceof Error ? cause.message : \"Could not change plan.\";\n\t\t\t\t\tsetLastError(reason);\n\n\t\t\t\t\treturn { status: \"failed\", reason };\n\t\t\t\t}\n\n\t\t\t\t// No subscription or no card on file — both mean the account needs\n\t\t\t\t// the thing checkout exists to do.\n\t\t\t\ttry {\n\t\t\t\t\tconst session = await client.billing.checkout(token, plan.planVersionId);\n\t\t\t\t\tgo(session.url);\n\n\t\t\t\t\treturn { status: \"checkout\", url: session.url };\n\t\t\t\t} catch (checkoutCause) {\n\t\t\t\t\tconst reason =\n\t\t\t\t\t\tcheckoutCause instanceof Error ? checkoutCause.message : \"Could not start checkout.\";\n\t\t\t\t\tsetLastError(reason);\n\n\t\t\t\t\treturn { status: \"failed\", reason };\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tsetBusy(null);\n\t\t\t}\n\t\t},\n\t\t[client, token, options.navigate, managedBy],\n\t);\n\n\treturn {\n\t\tplans,\n\t\tloading: plans === null && !error,\n\t\terror,\n\t\tcurrentPlanVersionId: discover ? ownPlanVersionId : (supplied ?? null),\n\t\tbusyPlanVersionId,\n\t\tlastError,\n\t\tsignedIn: token !== null,\n\t\tmanagedBy,\n\t\tselectPlan,\n\t\treload,\n\t};\n}\n","\"use client\";\n\nimport { type CollectionRecord, type FieldDescriptor, specFor } from \"@base316/sdk\";\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { FieldCell } from \"./fields\";\nimport { RecordForm } from \"./RecordForm\";\nimport { useCollection, type UseCollectionOptions } from \"./useCollection\";\n\n/**\n * A table of data nobody wrote a table for.\n *\n * Drop it in with a collection key and it works: it reads the schema, derives\n * its columns from the field types, sorts on the fields that can be sorted,\n * searches the ones that can be searched, and offers editing only if this\n * viewer may write.\n *\n * <DataTable collection=\"jobs\" />\n *\n * It never names a field type. Every cell goes through the renderer registry,\n * so a type added later works here without this file being touched — which is\n * the same reason a board or a calendar can be built against the same schema.\n *\n * Wants a different table? Call `useCollection()` and write one. You keep the\n * schema loading, the paging, the permission handling and the write errors,\n * and lose only the markup, which is the part worth replacing.\n */\n\nexport interface DataTableProps extends UseCollectionOptions {\n\t/** The collection key, as the schema defines it. */\n\tcollection: string;\n\t/**\n\t * Which fields to show, in order.\n\t *\n\t * Defaults to every field in its declared position. Name them to trim a wide\n\t * collection down to what this screen is about.\n\t */\n\tcolumns?: string[];\n\t/** Replace the cell for one field. Everything else keeps the default. */\n\trenderCell?: (record: CollectionRecord, field: FieldDescriptor) => ReactNode | undefined;\n\t/** Row click. Without it, rows are not interactive. */\n\tonSelect?: (record: CollectionRecord) => void;\n\t/**\n\t * Called after this table creates, edits or deletes a record.\n\t *\n\t * The table refreshes itself; this is for anything else on the page bound to\n\t * the same collection. Each component holds its own data and they share no\n\t * cache, so without this a `<Chart>` beside a table silently lags by every\n\t * record added through it — which is exactly what an agent building against\n\t * this hit, with no event to hook.\n\t */\n\tonChanged?: () => void;\n\t/** Hide the search box even when the collection has searchable fields. */\n\thideSearch?: boolean;\n\t/** Hide New, Edit and Delete even for a viewer who may write. */\n\treadOnly?: boolean;\n\t/** Shown when there is nothing to list. */\n\temptyState?: ReactNode;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function DataTable({\n\tcollection,\n\tcolumns,\n\trenderCell,\n\tonSelect,\n\tonChanged,\n\thideSearch,\n\treadOnly,\n\temptyState,\n\tclassName,\n\tstyle,\n\t...options\n}: DataTableProps) {\n\tconst {\n\t\tschema,\n\t\trecords,\n\t\tloading,\n\t\terror,\n\t\ttotal,\n\t\thasMore,\n\t\tcanWrite,\n\t\tsearch,\n\t\tsetSearch,\n\t\tsort,\n\t\ttoggleSort,\n\t\tloadMore,\n\t\tremove,\n\t} = useCollection(collection, options);\n\n\t/** The record being edited, or \"new\". Null when the form is closed. */\n\tconst [editing, setEditing] = useState<CollectionRecord | \"new\" | null>(null);\n\n\t/**\n\t * A delete that did not happen.\n\t *\n\t * `remove` returns false on failure and routes the reason into the hook's\n\t * `fieldErrors`, which only `RecordForm` reads — so this table discarded the\n\t * result and called `onChanged` regardless. The row stayed, nothing was\n\t * said, and the reasonable next move was to press Delete again.\n\t *\n\t * Shown above the table rather than replacing it: the data is still good,\n\t * and swapping the whole table for a message would lose the reader's place.\n\t */\n\tconst [removeFailed, setRemoveFailed] = useState<string | null>(null);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst shown = columns\n\t\t? // Ordered by what was asked for, not by the schema: a caller naming\n\t\t\t// columns means that order.\n\t\t\tcolumns\n\t\t\t\t.map((key) => schema.fields.find((field) => field.key === key))\n\t\t\t\t.filter((field): field is FieldDescriptor => Boolean(field))\n\t\t: schema.fields;\n\n\tconst searchable = schema.fields.some((field) => specFor(field).capabilities.searchable);\n\tconst writable = canWrite && !readOnly;\n\n\treturn (\n\t\t<div className={cls(\"b316-table-wrap\", className)} style={style}>\n\t\t\t{removeFailed ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{removeFailed}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-table-bar\">\n\t\t\t\t{searchable && !hideSearch ? (\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"search\"\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tplaceholder={`Search ${schema.namePlural.toLowerCase()}`}\n\t\t\t\t\t\taria-label={`Search ${schema.namePlural}`}\n\t\t\t\t\t\tvalue={search}\n\t\t\t\t\t\tonChange={(event) => setSearch(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<span />\n\t\t\t\t)}\n\n\t\t\t\t<div className=\"b316-table-actions\">\n\t\t\t\t\t{/* Counted from the server rather than from the rows on screen,\n\t\t\t\t\t which are one page of them. */}\n\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t{total} {total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()}\n\t\t\t\t\t</span>\n\t\t\t\t\t{writable ? (\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button\" onClick={() => setEditing(\"new\")}>\n\t\t\t\t\t\t\tNew {schema.name.toLowerCase()}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div className=\"b316-table-scroll\">\n\t\t\t\t<table className=\"b316-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t{shown.map((field) => {\n\t\t\t\t\t\t\t\tconst sortable = specFor(field).capabilities.sortable;\n\t\t\t\t\t\t\t\tconst active = sort?.field === field.key;\n\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<th key={field.key} scope=\"col\" aria-sort={ariaSort(active, sort?.direction)}>\n\t\t\t\t\t\t\t\t\t\t{sortable ? (\n\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-sort\"\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => toggleSort(field.key)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{field.label}\n\t\t\t\t\t\t\t\t\t\t\t\t<span aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t{active ? (sort?.direction === \"desc\" ? \" ↓\" : \" ↑\") : \" ↕\"}\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\tfield.label\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t{writable ? <th scope=\"col\" className=\"b316-table-rowactions\" /> : null}\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{records.map((record) => (\n\t\t\t\t\t\t\t<tr\n\t\t\t\t\t\t\t\tkey={record.id}\n\t\t\t\t\t\t\t\tclassName={onSelect ? \"b316-row-clickable\" : undefined}\n\t\t\t\t\t\t\t\tonClick={onSelect ? () => onSelect(record) : undefined}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{shown.map((field) => (\n\t\t\t\t\t\t\t\t\t<td key={field.key}>\n\t\t\t\t\t\t\t\t\t\t{renderCell?.(record, field) ?? (\n\t\t\t\t\t\t\t\t\t\t\t<FieldCell\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={record.fields[field.key] ?? null}\n\t\t\t\t\t\t\t\t\t\t\t\tfield={field}\n\t\t\t\t\t\t\t\t\t\t\t\trelated={record.related[field.key]}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t{writable ? (\n\t\t\t\t\t\t\t\t\t<td className=\"b316-table-rowactions\">\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t// The row may itself be clickable, and editing is not\n\t\t\t\t\t\t\t\t\t\t\t\t// what a click on the row means.\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\tsetEditing(record);\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tEdit\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\t\t\t\t\t\tconfirmLabel={`Delete ${record.title ?? \"this record\"} for good`}\n\t\t\t\t\t\t\t\t\t\t\t// Deleting is not undoable and the button sits beside\n\t\t\t\t\t\t\t\t\t\t\t// one that is harmless.\n\t\t\t\t\t\t\t\t\t\t\tonConfirm={() =>\n\t\t\t\t\t\t\t\t\t\t\t\tremove(record.id).then((ok) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (ok) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetRemoveFailed(null);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonChanged?.();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\t\tsetRemoveFailed(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t`${record.title ?? \"That record\"} could not be deleted. It is still here.`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t</div>\n\n\t\t\t{records.length === 0 && !loading ? (\n\t\t\t\t<div className=\"b316-empty\">\n\t\t\t\t\t{emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.`}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{loading ? <div className=\"b316-empty\">Loading…</div> : null}\n\n\t\t\t{hasMore ? (\n\t\t\t\t<div className=\"b316-table-more\">\n\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={loadMore} disabled={loading}>\n\t\t\t\t\t\tLoad more\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{editing ? (\n\t\t\t\t<RecordForm\n\t\t\t\t\tcollection={collection}\n\t\t\t\t\trecordId={editing === \"new\" ? undefined : editing.id}\n\t\t\t\t\ttenant={options.tenant}\n\t\t\t\t\tonSaved={() => {\n\t\t\t\t\t\tsetEditing(null);\n\t\t\t\t\t\tonChanged?.();\n\t\t\t\t\t}}\n\t\t\t\t\tonCancel={() => setEditing(null)}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\n/** What a screen reader announces about a sorted column. */\nfunction ariaSort(\n\tactive: boolean,\n\tdirection?: \"asc\" | \"desc\",\n): \"ascending\" | \"descending\" | \"none\" | undefined {\n\tif (!active) {\n\t\treturn undefined;\n\t}\n\n\treturn direction === \"desc\" ? \"descending\" : \"ascending\";\n}\n","\"use client\";\n\nimport {\n\ttype AddressValue,\n\ttype FieldDescriptor,\n\ttype FieldValue,\n\tformatAddress,\n\tspecFor,\n} from \"@base316/sdk\";\nimport type { ReactNode } from \"react\";\n\n/**\n * How each field type looks, and how each is edited.\n *\n * The other half of the registry. `@base316/sdk`'s `fields.ts` says what a\n * field *is* — groupable, summable, searchable — and this says what it looks\n * like. They are split because the server needs the first and must never\n * import React, and because a customer replacing the rendering should not have\n * to restate the semantics.\n *\n * Every component goes through here rather than switching on types itself.\n * That is what makes a new field type cheap: one entry in the SDK registry,\n * one here, and the table, the form, the detail view and anything built later\n * all understand it without being touched.\n */\n\nexport interface CellProps {\n\tvalue: FieldValue;\n\tfield: FieldDescriptor;\n\t/** A relation's resolved label, when this field is one. */\n\trelated?: { id: string; title: string | null };\n}\n\nexport interface InputProps {\n\tvalue: FieldValue;\n\tfield: FieldDescriptor;\n\tonChange: (value: FieldValue) => void;\n\t/** Rendered under the input. Set when the server rejected this field. */\n\terror?: string | null;\n\tdisabled?: boolean;\n}\n\nfunction formatNumber(value: FieldValue, fraction = 0): string {\n\tconst number = Number(value);\n\n\treturn Number.isFinite(number)\n\t\t? new Intl.NumberFormat(undefined, {\n\t\t\t\tminimumFractionDigits: fraction,\n\t\t\t\tmaximumFractionDigits: 2,\n\t\t\t}).format(number)\n\t\t: \"\";\n}\n\n/**\n * Seconds as something a person reads.\n *\n * Durations are stored in seconds so they can be summed; nobody wants to read\n * 5400 on a timesheet.\n */\nfunction formatDuration(value: FieldValue): string {\n\tconst total = Number(value);\n\n\tif (!Number.isFinite(total)) {\n\t\treturn \"\";\n\t}\n\n\tconst hours = Math.floor(total / 3600);\n\tconst minutes = Math.round((total % 3600) / 60);\n\n\tif (hours === 0) {\n\t\treturn `${minutes}m`;\n\t}\n\n\treturn minutes === 0 ? `${hours}h` : `${hours}h ${minutes}m`;\n}\n\n/** The cell for one field. Null and empty render as a dash, never as \"null\". */\nexport function FieldCell({ value, field, related }: CellProps): ReactNode {\n\tif (field.type === \"RELATION\") {\n\t\t// The label if it resolved, the id if it did not — which happens when the\n\t\t// record was deleted or belongs to a tenant this viewer cannot see.\n\t\treturn related?.title ?? (related?.id ? <code className=\"b316-muted\">{related.id}</code> : \"—\");\n\t}\n\n\tif (value === null || value === undefined || value === \"\") {\n\t\treturn <span className=\"b316-muted\">—</span>;\n\t}\n\n\tswitch (field.type) {\n\t\tcase \"BOOLEAN\":\n\t\t\treturn value ? \"Yes\" : \"No\";\n\n\t\tcase \"MONEY\":\n\t\t\treturn formatNumber(value, 2);\n\n\t\tcase \"PERCENT\":\n\t\t\treturn `${formatNumber(value)}%`;\n\n\t\tcase \"DURATION\":\n\t\t\treturn formatDuration(value);\n\n\t\tcase \"RATING\": {\n\t\t\tconst stars = Math.round(Number(value));\n\n\t\t\treturn (\n\t\t\t\t<span aria-label={`${stars} out of 5`}>\n\t\t\t\t\t{\"★\".repeat(stars)}\n\t\t\t\t\t<span className=\"b316-muted\">{\"★\".repeat(Math.max(0, 5 - stars))}</span>\n\t\t\t\t</span>\n\t\t\t);\n\t\t}\n\n\t\tcase \"DATE\":\n\t\t\t// Parsed as a plain date rather than through the Date constructor's\n\t\t\t// timezone handling: \"2026-03-01\" must not display as February 28th\n\t\t\t// west of Greenwich.\n\t\t\treturn String(value).split(\"T\")[0];\n\n\t\tcase \"DATETIME\":\n\t\t\treturn new Date(String(value)).toLocaleString();\n\n\t\tcase \"SELECT\":\n\t\t\treturn <span className=\"b316-chip\">{String(value)}</span>;\n\n\t\tcase \"MULTISELECT\":\n\t\t\treturn (\n\t\t\t\t<span className=\"b316-chips\">\n\t\t\t\t\t{(Array.isArray(value) ? value : [value]).map((item) => (\n\t\t\t\t\t\t<span key={String(item)} className=\"b316-chip\">\n\t\t\t\t\t\t\t{String(item)}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t))}\n\t\t\t\t</span>\n\t\t\t);\n\n\t\tcase \"URL\":\n\t\t\treturn (\n\t\t\t\t<a href={String(value)} target=\"_blank\" rel=\"noreferrer noopener\">\n\t\t\t\t\t{String(value)}\n\t\t\t\t</a>\n\t\t\t);\n\n\t\tcase \"EMAIL\":\n\t\t\treturn <a href={`mailto:${String(value)}`}>{String(value)}</a>;\n\n\t\tcase \"PHONE\":\n\t\t\treturn <a href={`tel:${String(value)}`}>{String(value)}</a>;\n\n\t\tcase \"ADDRESS\":\n\t\t\treturn formatAddress(value as AddressValue);\n\n\t\tcase \"ATTACHMENT\": {\n\t\t\tconst files = Array.isArray(value) ? value : [value];\n\n\t\t\treturn `${files.length} file${files.length === 1 ? \"\" : \"s\"}`;\n\t\t}\n\n\t\tcase \"LONGTEXT\": {\n\t\t\tconst text = String(value);\n\n\t\t\t// Truncated in a cell, whole in the detail view. A paragraph in a table\n\t\t\t// row pushes every other column out of sight.\n\t\t\treturn text.length > 80 ? `${text.slice(0, 80)}…` : text;\n\t\t}\n\n\t\tcase \"JSON\":\n\t\t\treturn <code className=\"b316-muted\">{JSON.stringify(value).slice(0, 60)}</code>;\n\n\t\tdefault:\n\t\t\treturn String(value);\n\t}\n}\n\n/**\n * The input for one field.\n *\n * Returns null for a computed field: an AUTONUMBER, LOOKUP or ROLLUP is\n * produced by the server, and offering an input for one invites somebody to\n * type a value that will be silently discarded.\n */\nexport function FieldInput({ value, field, onChange, error, disabled }: InputProps): ReactNode {\n\tif (specFor(field).computed) {\n\t\treturn null;\n\t}\n\n\tconst id = `b316-field-${field.key}`;\n\tconst described = error ? `${id}-error` : undefined;\n\tconst common = {\n\t\tid,\n\t\tdisabled,\n\t\t\"aria-invalid\": error ? true : undefined,\n\t\t\"aria-describedby\": described,\n\t\tclassName: error ? \"b316-input b316-input-invalid\" : \"b316-input\",\n\t};\n\n\tfunction control(): ReactNode {\n\t\tswitch (field.type) {\n\t\t\tcase \"LONGTEXT\":\n\t\t\t\treturn (\n\t\t\t\t\t<textarea\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\trows={4}\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"BOOLEAN\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\tclassName=\"b316-checkbox\"\n\t\t\t\t\t\tchecked={Boolean(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.checked)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"SELECT\":\n\t\t\t\treturn (\n\t\t\t\t\t<select\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value === \"\" ? null : event.target.value)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{/* Present unless the field is required: without it there is no\n\t\t\t\t\t\t way to clear a choice once one has been made. */}\n\t\t\t\t\t\t{field.required ? null : <option value=\"\">—</option>}\n\t\t\t\t\t\t{(field.options ?? []).map((option) => (\n\t\t\t\t\t\t\t<option key={option} value={option}>\n\t\t\t\t\t\t\t\t{option}\n\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</select>\n\t\t\t\t);\n\n\t\t\tcase \"MULTISELECT\": {\n\t\t\t\tconst selected = new Set(Array.isArray(value) ? value.map(String) : []);\n\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"b316-choices\">\n\t\t\t\t\t\t{(field.options ?? []).map((option) => (\n\t\t\t\t\t\t\t<label key={option} className=\"b316-choice\">\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tchecked={selected.has(option)}\n\t\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\t\tconst next = new Set(selected);\n\n\t\t\t\t\t\t\t\t\t\tif (event.target.checked) {\n\t\t\t\t\t\t\t\t\t\t\tnext.add(option);\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tnext.delete(option);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tonChange([...next]);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{option}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"NUMBER\":\n\t\t\tcase \"MONEY\":\n\t\t\tcase \"PERCENT\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tstep={field.type === \"NUMBER\" ? 1 : 0.01}\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\t// Empty means cleared, not zero. Coercing \"\" to 0 writes a number\n\t\t\t\t\t\t// nobody typed.\n\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\tonChange(event.target.value === \"\" ? null : Number(event.target.value))\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"RATING\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tmin={0}\n\t\t\t\t\t\tmax={5}\n\t\t\t\t\t\tstep={1}\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\tonChange(event.target.value === \"\" ? null : Number(event.target.value))\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"DURATION\": {\n\t\t\t\t// Entered in minutes, stored in seconds. Asking for seconds is how a\n\t\t\t\t// timesheet ends up with someone typing 5400.\n\t\t\t\tconst minutes = value === null || value === undefined ? \"\" : String(Number(value) / 60);\n\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"b316-suffixed\">\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t{...common}\n\t\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\t\tmin={0}\n\t\t\t\t\t\t\tvalue={minutes}\n\t\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\t\tonChange(event.target.value === \"\" ? null : Number(event.target.value) * 60)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<span className=\"b316-muted\">minutes</span>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"DATE\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"date\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value).slice(0, 10)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value === \"\" ? null : event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"DATETIME\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"datetime-local\"\n\t\t\t\t\t\t// `datetime-local` will not accept an offset or trailing Z, and\n\t\t\t\t\t\t// silently shows nothing rather than complaining.\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value).slice(0, 16)}\n\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\tonChange(\n\t\t\t\t\t\t\t\tevent.target.value === \"\" ? null : new Date(event.target.value).toISOString(),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"ADDRESS\": {\n\t\t\t\tconst address = (value ?? {}) as AddressValue;\n\t\t\t\tconst part = (key: keyof AddressValue, label: string) => (\n\t\t\t\t\t<input\n\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tplaceholder={label}\n\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\tvalue={(address[key] as string) ?? \"\"}\n\t\t\t\t\t\tonChange={(event) => onChange({ ...address, [key]: event.target.value })}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\t\treturn (\n\t\t\t\t\t<div className=\"b316-address\">\n\t\t\t\t\t\t{part(\"line1\", \"Address line 1\")}\n\t\t\t\t\t\t{part(\"line2\", \"Address line 2\")}\n\t\t\t\t\t\t{part(\"city\", \"City\")}\n\t\t\t\t\t\t{part(\"region\", \"Region\")}\n\t\t\t\t\t\t{part(\"postalCode\", \"Postal code\")}\n\t\t\t\t\t\t{part(\"country\", \"Country\")}\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"EMAIL\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"URL\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"url\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"PHONE\":\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"tel\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tdefault:\n\t\t\t\treturn (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...common}\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tvalue={value === null || value === undefined ? \"\" : String(value)}\n\t\t\t\t\t\tonChange={(event) => onChange(event.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t}\n\t}\n\n\treturn (\n\t\t<div className=\"b316-field\">\n\t\t\t<label className=\"b316-label\" htmlFor={id}>\n\t\t\t\t{field.label}\n\t\t\t\t{field.required ? <span aria-hidden=\"true\"> *</span> : null}\n\t\t\t</label>\n\t\t\t{control()}\n\t\t\t{field.description ? <div className=\"b316-hint\">{field.description}</div> : null}\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" id={described} role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport { type FieldValue, specFor } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { FieldInput } from \"./fields\";\nimport { RelationPicker } from \"./RelationPicker\";\nimport { useCollection } from \"./useCollection\";\n\n/**\n * Creating or editing one record, with the form derived from the schema.\n *\n * Nobody writes the inputs. The field types decide which control each value\n * gets, which ones are required, and which are not editable at all — an\n * AUTONUMBER, a LOOKUP and a ROLLUP are produced by the server, so offering an\n * input for one would invite somebody to type a value that is discarded.\n *\n * <RecordForm collection=\"jobs\" /> // create\n * <RecordForm collection=\"jobs\" recordId={id} /> // edit\n *\n * Errors come back per field and land under the input that caused them.\n * Validation is not repeated here: the same `validateRecord` the server uses\n * would have to be kept in step, and a second implementation that drifts is\n * worse than one round trip.\n */\n\nexport interface RecordFormProps {\n\tcollection: string;\n\t/** Omit to create. */\n\trecordId?: string;\n\ttenant?: string;\n\tonSaved?: (id: string) => void;\n\tonCancel?: () => void;\n\t/** Start with these values filled in. Ignored when editing. */\n\tdefaults?: Record<string, FieldValue>;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function RecordForm({\n\tcollection,\n\trecordId,\n\ttenant,\n\tonSaved,\n\tonCancel,\n\tdefaults,\n\tclassName,\n\tstyle,\n}: RecordFormProps) {\n\tconst { schema, records, create, update, saving, fieldErrors, error } = useCollection(\n\t\tcollection,\n\t\t{\n\t\t\ttenant,\n\t\t\t// Fetched by id, not filtered for: `id` is not a schema field, so a filter\n\t\t\t// naming it is dropped and the form would quietly load the first page and\n\t\t\t// hope the record was on it.\n\t\t\trecordId,\n\t\t},\n\t);\n\n\tconst [values, setValues] = useState<Record<string, FieldValue>>(defaults ?? {});\n\tconst [loaded, setLoaded] = useState(!recordId);\n\n\tconst existing = recordId ? records.find((record) => record.id === recordId) : undefined;\n\n\t// Fill the form once, when the record arrives. Re-running would discard\n\t// whatever the person had typed since.\n\tuseEffect(() => {\n\t\tif (existing && !loaded) {\n\t\t\tsetValues(existing.fields);\n\t\t\tsetLoaded(true);\n\t\t}\n\t}, [existing, loaded]);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema || !loaded) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Computed fields have nothing to edit, so they are left out of the form\n\t// rather than rendered disabled — a row of greyed inputs is noise.\n\tconst editable = schema.fields.filter((field) => !specFor(field).computed);\n\n\tasync function submit(event: React.FormEvent) {\n\t\tevent.preventDefault();\n\n\t\tconst saved = recordId ? await update(recordId, values) : await create(values);\n\n\t\tif (saved) {\n\t\t\tonSaved?.(saved.id);\n\t\t}\n\t}\n\n\treturn (\n\t\t<form className={cls(\"b316-card b316-form\", className)} style={style} onSubmit={submit}>\n\t\t\t<h3 className=\"b316-form-title\">\n\t\t\t\t{recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}`}\n\t\t\t</h3>\n\n\t\t\t{/* A failure with no field attached — a permission or a network problem.\n\t\t\t Without this the form just stops saving and says nothing. */}\n\t\t\t{fieldErrors._ ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{fieldErrors._}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{editable.map((field) =>\n\t\t\t\tfield.type === \"RELATION\" ? (\n\t\t\t\t\t<RelationPicker\n\t\t\t\t\t\tkey={field.key}\n\t\t\t\t\t\tfield={field}\n\t\t\t\t\t\ttenant={tenant}\n\t\t\t\t\t\tdisabled={saving}\n\t\t\t\t\t\terror={fieldErrors[field.key]}\n\t\t\t\t\t\tvalue={(values[field.key] as string | null) ?? null}\n\t\t\t\t\t\tonChange={(next) => setValues((current) => ({ ...current, [field.key]: next }))}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<FieldInput\n\t\t\t\t\t\tkey={field.key}\n\t\t\t\t\t\tfield={field}\n\t\t\t\t\t\tdisabled={saving}\n\t\t\t\t\t\terror={fieldErrors[field.key]}\n\t\t\t\t\t\tvalue={values[field.key] ?? null}\n\t\t\t\t\t\tonChange={(next) => setValues((current) => ({ ...current, [field.key]: next }))}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t)}\n\n\t\t\t<div className=\"b316-form-actions\">\n\t\t\t\t{onCancel ? (\n\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={onCancel} disabled={saving}>\n\t\t\t\t\t\tCancel\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={saving}>\n\t\t\t\t\t{saving ? \"Saving…\" : \"Save\"}\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</form>\n\t);\n}\n","\"use client\";\n\nimport type { FieldDescriptor } from \"@base316/sdk\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { useBase316 } from \"./provider\";\n\n/**\n * Choosing a record in another collection, by typing its name.\n *\n * The alternative is a text box holding an id, which nobody can fill in\n * without going to look one up — so a relation field without this is a\n * relation field nobody uses.\n *\n * Two fetches, and they answer different questions. The title of what is\n * already chosen has to be known before anybody types, or an existing record\n * opens showing an id. The search results are what typing produces. Conflating\n * them means an edit form that looks empty until the user searches for the\n * value it already has.\n */\n\nexport function RelationPicker({\n\tfield,\n\tvalue,\n\tonChange,\n\terror,\n\tdisabled,\n\ttenant,\n}: {\n\tfield: FieldDescriptor;\n\tvalue: string | null;\n\tonChange: (value: string | null) => void;\n\terror?: string | null;\n\tdisabled?: boolean;\n\ttenant?: string;\n}) {\n\tconst { client, token } = useBase316();\n\tconst [query, setQuery] = useState(\"\");\n\tconst [results, setResults] = useState<{ id: string; title: string | null }[]>([]);\n\tconst [chosenTitle, setChosenTitle] = useState<string | null>(null);\n\tconst [open, setOpen] = useState(false);\n\tconst id = `b316-field-${field.key}`;\n\tconst box = useRef<HTMLDivElement>(null);\n\n\t// What is already chosen, named. Runs on the id rather than on the query, so\n\t// an edit form shows \"Acme\" the moment it opens.\n\tuseEffect(() => {\n\t\tif (!token || !value || !field.relationTo) {\n\t\t\tsetChosenTitle(null);\n\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.collections\n\t\t\t.titles(token, field.relationTo, [value], tenant ? { tenant } : undefined)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetChosenTitle(result.titles[value] ?? null);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => null);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, value, field.relationTo, tenant]);\n\n\t// The search itself, debounced. Without the delay every keystroke is a\n\t// request, and the answers arrive out of order.\n\tuseEffect(() => {\n\t\tif (!token || !field.relationTo || !open) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\t\tconst timer = setTimeout(() => {\n\t\t\tclient.collections\n\t\t\t\t.list(\n\t\t\t\t\ttoken,\n\t\t\t\t\tfield.relationTo as string,\n\t\t\t\t\t{ search: query || undefined, limit: 10 },\n\t\t\t\t\ttenant ? { tenant } : undefined,\n\t\t\t\t)\n\t\t\t\t.then((page) => {\n\t\t\t\t\tif (!cancelled) {\n\t\t\t\t\t\tsetResults(page.data.map((record) => ({ id: record.id, title: record.title })));\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(() => {\n\t\t\t\t\tif (!cancelled) {\n\t\t\t\t\t\tsetResults([]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t}, 200);\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t\tclearTimeout(timer);\n\t\t};\n\t}, [client, token, field.relationTo, query, open, tenant]);\n\n\t// Clicking away closes the list. Without this it stays open over whatever the\n\t// user moved on to.\n\tuseEffect(() => {\n\t\tif (!open || typeof document === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\n\t\tconst onDocumentClick = (event: MouseEvent) => {\n\t\t\tif (box.current && !box.current.contains(event.target as Node)) {\n\t\t\t\tsetOpen(false);\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener(\"mousedown\", onDocumentClick);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"mousedown\", onDocumentClick);\n\t\t};\n\t}, [open]);\n\n\treturn (\n\t\t<div className=\"b316-field\" ref={box}>\n\t\t\t<label className=\"b316-label\" htmlFor={id}>\n\t\t\t\t{field.label}\n\t\t\t\t{field.required ? <span aria-hidden=\"true\"> *</span> : null}\n\t\t\t</label>\n\n\t\t\t{value && !open ? (\n\t\t\t\t<div className=\"b316-relation-chosen\">\n\t\t\t\t\t{/* The id when the title did not resolve: the record was deleted, or\n\t\t\t\t\t belongs to a tenant this viewer cannot see. Showing nothing would\n\t\t\t\t\t look like the field was empty. */}\n\t\t\t\t\t<span>{chosenTitle ?? value}</span>\n\t\t\t\t\t{disabled ? null : (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tsetQuery(\"\");\n\t\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tChange\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t\t{disabled || field.required ? null : (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet\"\n\t\t\t\t\t\t\tonClick={() => onChange(null)}\n\t\t\t\t\t\t\taria-label={`Clear ${field.label}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tClear\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<input\n\t\t\t\t\t\tid={id}\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\taria-expanded={open}\n\t\t\t\t\t\taria-controls={`${id}-results`}\n\t\t\t\t\t\taria-autocomplete=\"list\"\n\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tclassName={error ? \"b316-input b316-input-invalid\" : \"b316-input\"}\n\t\t\t\t\t\tplaceholder={`Search ${field.label.toLowerCase()}`}\n\t\t\t\t\t\tvalue={query}\n\t\t\t\t\t\tonFocus={() => setOpen(true)}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tsetQuery(event.target.value);\n\t\t\t\t\t\t\tsetOpen(true);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{open ? (\n\t\t\t\t\t\t<ul className=\"b316-relation-results\" id={`${id}-results`} role=\"listbox\">\n\t\t\t\t\t\t\t{results.length === 0 ? (\n\t\t\t\t\t\t\t\t<li className=\"b316-muted b316-relation-empty\">No matches</li>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\tresults.map((result) => (\n\t\t\t\t\t\t\t\t\t<li key={result.id}>\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\t\t\taria-selected={result.id === value}\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-relation-result\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\t\t\tonChange(result.id);\n\t\t\t\t\t\t\t\t\t\t\t\tsetChosenTitle(result.title);\n\t\t\t\t\t\t\t\t\t\t\t\tsetOpen(false);\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{result.title ?? result.id}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t))\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t) : null}\n\t\t\t\t</>\n\t\t\t)}\n\n\t\t\t{field.description ? <div className=\"b316-hint\">{field.description}</div> : null}\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type {\n\tCollectionRecord,\n\tCollectionSchema,\n\tFieldValue,\n\tRecordFilterInput,\n} from \"@base316/sdk\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport { useBase316 } from \"./provider\";\n\n/**\n * One collection: its shape, its rows, and how to change them.\n *\n * The headless half of every data component. `DataTable`, `RecordForm` and\n * `RecordDetail` are markup over this, and an application with its own design\n * system calls it directly and writes its own — which is the escape hatch that\n * stops a component library from being forked the first time somebody wants a\n * different table.\n *\n * What it does that is worth not rewriting:\n *\n * - loads the schema before the rows, because nothing can render a column\n * without knowing the field types;\n * - keeps filters, sort, search and paging in one place, so they compose\n * instead of fighting;\n * - refetches after a write, so a saved row appears where it belongs rather\n * than where it was;\n * - keeps per-field errors from the server, so a form can put each message\n * under the input that caused it.\n */\n\nexport interface UseCollectionOptions {\n\t/** Applied on top of whatever the UI sets. For a fixed view of one tenant's data. */\n\tfilters?: RecordFilterInput[];\n\tsort?: { field: string; direction?: \"asc\" | \"desc\" };\n\tlimit?: number;\n\t/**\n\t * Load one record instead of a page.\n\t *\n\t * Fetched by id rather than filtered for. `id` is not a schema field, so a\n\t * filter naming it is dropped on the server and the caller quietly gets the\n\t * first page instead — which works until the record is not on it.\n\t */\n\trecordId?: string;\n\t/**\n\t * Which tenant to read and write as.\n\t *\n\t * Only needed when somebody belongs to several organizations. A user in one\n\t * is scoped to it automatically.\n\t */\n\ttenant?: string;\n}\n\nexport interface UseCollectionResult {\n\t/** Null until loaded. */\n\tschema: CollectionSchema | null;\n\trecords: CollectionRecord[];\n\tloading: boolean;\n\t/** Set when the collection could not be read at all — missing, or forbidden. */\n\terror: string | null;\n\t/** Total matching rows, for \"1–25 of 340\". */\n\ttotal: number;\n\t/** Whether a further page exists. */\n\thasMore: boolean;\n\t/** Whether this viewer may create, edit and delete. False until the schema loads. */\n\tcanWrite: boolean;\n\n\tsearch: string;\n\tsetSearch: (search: string) => void;\n\tfilters: RecordFilterInput[];\n\tsetFilters: (filters: RecordFilterInput[]) => void;\n\tsort: { field: string; direction?: \"asc\" | \"desc\" } | null;\n\t/** Ascending, then descending, then off — the order a table header cycles. */\n\ttoggleSort: (field: string) => void;\n\n\tloadMore: () => void;\n\treload: () => void;\n\n\t/** Per-field messages from the last rejected write. */\n\tfieldErrors: Record<string, string>;\n\tsaving: boolean;\n\tcreate: (fields: Record<string, FieldValue>) => Promise<CollectionRecord | null>;\n\tupdate: (id: string, fields: Record<string, FieldValue>) => Promise<CollectionRecord | null>;\n\tremove: (id: string) => Promise<boolean>;\n}\n\n/** Pull the per-field messages out of a rejected write. */\nfunction fieldErrorFrom(cause: unknown): Record<string, string> {\n\tconst param = (cause as { param?: string | null })?.param;\n\tconst message = cause instanceof Error ? cause.message : \"That value was not accepted.\";\n\n\t// The API names one offending field at a time. Keyed anyway, so a form puts\n\t// the message under the right input rather than in a banner above them all.\n\treturn param ? { [param]: message } : { _: message };\n}\n\nexport function useCollection(\n\tcollection: string,\n\toptions: UseCollectionOptions = {},\n): UseCollectionResult {\n\tconst { client, token } = useBase316();\n\n\tconst [schema, setSchema] = useState<CollectionSchema | null>(null);\n\tconst [records, setRecords] = useState<CollectionRecord[]>([]);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [loading, setLoading] = useState(true);\n\tconst [total, setTotal] = useState(0);\n\tconst [cursor, setCursor] = useState<string | null>(null);\n\tconst [reloadCount, setReloadCount] = useState(0);\n\n\tconst [search, setSearch] = useState(\"\");\n\tconst [filters, setFilters] = useState<RecordFilterInput[]>([]);\n\tconst [sort, setSort] = useState<{ field: string; direction?: \"asc\" | \"desc\" } | null>(\n\t\toptions.sort ?? null,\n\t);\n\n\tconst [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});\n\tconst [saving, setSaving] = useState(false);\n\n\tconst { tenant, limit, recordId } = options;\n\t// Serialised, so a caller passing a fresh array literal every render does not\n\t// restart the query on every render.\n\tconst fixedFilters = JSON.stringify(options.filters ?? []);\n\n\tconst scope = useMemo(() => (tenant ? { tenant } : undefined), [tenant]);\n\n\t// --- The schema, first ----------------------------------------------------\n\n\tuseEffect(() => {\n\t\tif (!token) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tclient.collections\n\t\t\t.schema(token, collection, scope)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetSchema(result);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\t// Fatal, unlike a failed row fetch: without the field types there is\n\t\t\t\t\t// nothing to render, not even an empty table with headings.\n\t\t\t\t\tsetError(cause instanceof Error ? cause.message : \"This collection is unavailable.\");\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, collection, scope]);\n\n\t// --- Then the rows --------------------------------------------------------\n\n\tuseEffect(() => {\n\t\tif (!token || !schema) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet cancelled = false;\n\n\t\tsetLoading(true);\n\n\t\tif (recordId) {\n\t\t\tclient.collections\n\t\t\t\t.get(token, collection, recordId, scope)\n\t\t\t\t.then((record) => {\n\t\t\t\t\tif (cancelled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tsetRecords([record]);\n\t\t\t\t\tsetCursor(null);\n\t\t\t\t\tsetTotal(1);\n\t\t\t\t\tsetError(null);\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t})\n\t\t\t\t.catch((cause) => {\n\t\t\t\t\tif (!cancelled) {\n\t\t\t\t\t\t// Not found covers another tenant's record too, which is the point:\n\t\t\t\t\t\t// an id belonging to somebody else is indistinguishable from one\n\t\t\t\t\t\t// belonging to nobody.\n\t\t\t\t\t\tsetRecords([]);\n\t\t\t\t\t\tsetTotal(0);\n\t\t\t\t\t\tsetError(cause instanceof Error ? cause.message : \"That record is not available.\");\n\t\t\t\t\t\tsetLoading(false);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tcancelled = true;\n\t\t\t};\n\t\t}\n\n\t\tclient.collections\n\t\t\t.list(\n\t\t\t\ttoken,\n\t\t\t\tcollection,\n\t\t\t\t{\n\t\t\t\t\tfilters: [...(JSON.parse(fixedFilters) as RecordFilterInput[]), ...filters],\n\t\t\t\t\tsearch: search || undefined,\n\t\t\t\t\tsort: sort ?? undefined,\n\t\t\t\t\tlimit,\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t)\n\t\t\t.then((page) => {\n\t\t\t\tif (cancelled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Replaces rather than appends: this effect runs when the query\n\t\t\t\t// changed, and appending would stack the old filter's rows under the\n\t\t\t\t// new one's. `loadMore` is what appends.\n\t\t\t\tsetRecords(page.data);\n\t\t\t\tsetCursor(page.cursor);\n\t\t\t\tsetTotal(page.total);\n\t\t\t\tsetError(null);\n\t\t\t\tsetLoading(false);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(cause instanceof Error ? cause.message : \"Could not load these records.\");\n\t\t\t\t\tsetLoading(false);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [\n\t\tclient,\n\t\ttoken,\n\t\tcollection,\n\t\tschema,\n\t\trecordId,\n\t\tfixedFilters,\n\t\tfilters,\n\t\tsearch,\n\t\tsort,\n\t\tlimit,\n\t\tscope,\n\t\treloadCount,\n\t]);\n\n\tconst reload = useCallback(() => {\n\t\tsetReloadCount((count) => count + 1);\n\t}, []);\n\n\tconst loadMore = useCallback(() => {\n\t\tif (!token || !cursor) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetLoading(true);\n\n\t\tclient.collections\n\t\t\t.list(\n\t\t\t\ttoken,\n\t\t\t\tcollection,\n\t\t\t\t{\n\t\t\t\t\tfilters: [...(JSON.parse(fixedFilters) as RecordFilterInput[]), ...filters],\n\t\t\t\t\tsearch: search || undefined,\n\t\t\t\t\tsort: sort ?? undefined,\n\t\t\t\t\tlimit,\n\t\t\t\t\tcursor,\n\t\t\t\t},\n\t\t\t\tscope,\n\t\t\t)\n\t\t\t.then((page) => {\n\t\t\t\tsetRecords((existing) => [...existing, ...page.data]);\n\t\t\t\tsetCursor(page.cursor);\n\t\t\t\tsetLoading(false);\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tsetLoading(false);\n\t\t\t});\n\t}, [client, token, collection, cursor, fixedFilters, filters, search, sort, limit, scope]);\n\n\tconst toggleSort = useCallback((field: string) => {\n\t\tsetSort((current) => {\n\t\t\tif (current?.field !== field) {\n\t\t\t\treturn { field, direction: \"asc\" };\n\t\t\t}\n\n\t\t\t// Third press clears it rather than sticking on descending, so there is\n\t\t\t// a way back to the collection's own order.\n\t\t\treturn current.direction === \"asc\" ? { field, direction: \"desc\" } : null;\n\t\t});\n\t}, []);\n\n\t// --- Writing --------------------------------------------------------------\n\n\tconst create = useCallback(\n\t\tasync (fields: Record<string, FieldValue>) => {\n\t\t\tif (!token) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tsetSaving(true);\n\t\t\tsetFieldErrors({});\n\n\t\t\ttry {\n\t\t\t\tconst record = await client.collections.create(token, collection, fields, scope);\n\n\t\t\t\t// Refetched rather than pushed onto the list: the new row belongs\n\t\t\t\t// wherever the current sort and filters put it, which is not\n\t\t\t\t// necessarily at the top and may be on another page entirely.\n\t\t\t\treload();\n\n\t\t\t\treturn record;\n\t\t\t} catch (cause) {\n\t\t\t\tsetFieldErrors(fieldErrorFrom(cause));\n\n\t\t\t\treturn null;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t},\n\t\t[client, token, collection, scope, reload],\n\t);\n\n\tconst update = useCallback(\n\t\tasync (id: string, fields: Record<string, FieldValue>) => {\n\t\t\tif (!token) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tsetSaving(true);\n\t\t\tsetFieldErrors({});\n\n\t\t\ttry {\n\t\t\t\tconst record = await client.collections.update(token, collection, id, fields, scope);\n\n\t\t\t\t// Replaced in place: an edit that did not move the row should not\n\t\t\t\t// cost a round trip for everything else on the page.\n\t\t\t\tsetRecords((existing) =>\n\t\t\t\t\texisting.map((candidate) => (candidate.id === id ? record : candidate)),\n\t\t\t\t);\n\n\t\t\t\treturn record;\n\t\t\t} catch (cause) {\n\t\t\t\tsetFieldErrors(fieldErrorFrom(cause));\n\n\t\t\t\treturn null;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t},\n\t\t[client, token, collection, scope],\n\t);\n\n\tconst remove = useCallback(\n\t\tasync (id: string) => {\n\t\t\tif (!token) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tsetSaving(true);\n\n\t\t\ttry {\n\t\t\t\tawait client.collections.remove(token, collection, id, scope);\n\n\t\t\t\tsetRecords((existing) => existing.filter((candidate) => candidate.id !== id));\n\t\t\t\tsetTotal((count) => Math.max(0, count - 1));\n\n\t\t\t\treturn true;\n\t\t\t} catch (cause) {\n\t\t\t\tsetFieldErrors(fieldErrorFrom(cause));\n\n\t\t\t\treturn false;\n\t\t\t} finally {\n\t\t\t\tsetSaving(false);\n\t\t\t}\n\t\t},\n\t\t[client, token, collection, scope],\n\t);\n\n\treturn {\n\t\tschema,\n\t\trecords,\n\t\tloading,\n\t\terror,\n\t\ttotal,\n\t\thasMore: cursor !== null,\n\t\tcanWrite: schema?.canWrite ?? false,\n\t\tsearch,\n\t\tsetSearch,\n\t\tfilters,\n\t\tsetFilters,\n\t\tsort,\n\t\ttoggleSort,\n\t\tloadMore,\n\t\treload,\n\t\tfieldErrors,\n\t\tsaving,\n\t\tcreate,\n\t\tupdate,\n\t\tremove,\n\t};\n}\n","\"use client\";\n\nimport {\n\ttype CollectionRecord,\n\ttype FieldDescriptor,\n\tdefaultGroupFieldOf,\n\tspecFor,\n\ttitleFieldOf,\n} from \"@base316/sdk\";\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { FieldCell } from \"./fields\";\nimport { useCollection, type UseCollectionOptions } from \"./useCollection\";\n\n/**\n * A board, over a collection that was never designed to have one.\n *\n * This component is the proof of the whole design. It was written after the\n * schema and the table, it knows nothing about jobs or tickets or deals, and it\n * asks the schema one question:\n *\n * defaultGroupFieldOf(schema.fields) // \"which field makes columns?\"\n *\n * The registry answers with the SELECT field, because a status or a stage is\n * what somebody means by grouping — and so `<Kanban collection=\"jobs\" />`\n * works with no props at all. Had fields been described in rendering terms\n * (\"this column is right-aligned\"), there would have been nothing here to ask,\n * and every board would need its own configuration naming its own columns.\n *\n * Moving a card writes the grouping field. That is the only mutation a board\n * makes, and it is why the field has to be one with a fixed set of values: a\n * column header has to be a value somebody can drop onto.\n */\n\nexport interface KanbanProps extends UseCollectionOptions {\n\tcollection: string;\n\t/**\n\t * Which field makes the columns.\n\t *\n\t * Discovered when omitted. Name it when a collection has several groupable\n\t * fields and the first choice is not the one this board is about.\n\t */\n\tgroupBy?: string;\n\t/** Fields to show on a card, in order. Defaults to the title and the next two. */\n\tcardFields?: string[];\n\tonSelect?: (record: CollectionRecord) => void;\n\temptyState?: ReactNode;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function Kanban({\n\tcollection,\n\tgroupBy,\n\tcardFields,\n\tonSelect,\n\temptyState,\n\tclassName,\n\tstyle,\n\t...options\n}: KanbanProps) {\n\tconst { schema, records, loading, error, canWrite, update, total, hasMore, loadMore } =\n\t\tuseCollection(collection, {\n\t\t\t// A board shows everything at once by its nature — a column holding the\n\t\t\t// first twenty-five of two hundred is misleading rather than partial.\n\t\t\tlimit: options.limit ?? 100,\n\t\t\t...options,\n\t\t});\n\n\tconst [dragging, setDragging] = useState<string | null>(null);\n\tconst [over, setOver] = useState<string | null>(null);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst field = groupBy\n\t\t? (schema.fields.find((candidate) => candidate.key === groupBy) ?? null)\n\t\t: defaultGroupFieldOf(schema.fields);\n\n\t// Said plainly rather than rendered as one empty column. A board over a\n\t// collection with nothing to group by is a mistake in the schema or in the\n\t// choice of component, and both are worth naming.\n\tif (!field || !specFor(field).capabilities.groupable) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{groupBy\n\t\t\t\t\t? `\"${groupBy}\" cannot make columns. A board groups by a choice, a yes/no or a date.`\n\t\t\t\t\t: `${schema.namePlural} have no field to group by. Add a choice field — a status or a stage — and this board will use it.`}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst columns = columnsFor(field);\n\tconst shown = cardFields\n\t\t? cardFields\n\t\t\t\t.map((key) => schema.fields.find((candidate) => candidate.key === key))\n\t\t\t\t.filter((candidate): candidate is FieldDescriptor => Boolean(candidate))\n\t\t: // The first few fields that are neither the grouping one nor the title.\n\t\t\t// The grouping field is already the column heading and the title is\n\t\t\t// already the card heading, so both would be printed twice on every card.\n\t\t\tschema.fields\n\t\t\t\t.filter(\n\t\t\t\t\t(candidate) =>\n\t\t\t\t\t\tcandidate.key !== field.key && candidate.key !== titleFieldOf(schema.fields)?.key,\n\t\t\t\t)\n\t\t\t\t.slice(0, 3);\n\n\tasync function move(record: CollectionRecord, value: string | boolean | null) {\n\t\tif (!canWrite || record.fields[field!.key] === value) {\n\t\t\treturn;\n\t\t}\n\n\t\tawait update(record.id, { [field!.key]: value });\n\t}\n\n\treturn (\n\t\t<div className={cls(\"b316-board-wrap\", className)} style={style}>\n\t\t\t<div className=\"b316-board\" role=\"list\">\n\t\t\t\t{columns.map((column) => {\n\t\t\t\t\tconst inColumn = records.filter(\n\t\t\t\t\t\t(record) => String(record.fields[field.key] ?? \"\") === String(column.value ?? \"\"),\n\t\t\t\t\t);\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<section\n\t\t\t\t\t\t\tkey={String(column.value)}\n\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\tover === String(column.value)\n\t\t\t\t\t\t\t\t\t? \"b316-board-column b316-board-over\"\n\t\t\t\t\t\t\t\t\t: \"b316-board-column\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trole=\"listitem\"\n\t\t\t\t\t\t\taria-label={column.label}\n\t\t\t\t\t\t\tonDragOver={(event) => {\n\t\t\t\t\t\t\t\tif (!canWrite || !dragging) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Without this the drop never fires: the default is to refuse.\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tsetOver(String(column.value));\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonDragLeave={() => setOver(null)}\n\t\t\t\t\t\t\tonDrop={(event) => {\n\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\tsetOver(null);\n\n\t\t\t\t\t\t\t\tconst record = records.find((candidate) => candidate.id === dragging);\n\n\t\t\t\t\t\t\t\tif (record) {\n\t\t\t\t\t\t\t\t\tvoid move(record, column.value);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsetDragging(null);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<header className=\"b316-board-head\">\n\t\t\t\t\t\t\t\t<span className=\"b316-board-title\">{column.label}</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">{inColumn.length}</span>\n\t\t\t\t\t\t\t</header>\n\n\t\t\t\t\t\t\t<div className=\"b316-board-cards\">\n\t\t\t\t\t\t\t\t{inColumn.map((record) => (\n\t\t\t\t\t\t\t\t\t<article\n\t\t\t\t\t\t\t\t\t\tkey={record.id}\n\t\t\t\t\t\t\t\t\t\tclassName=\"b316-board-card\"\n\t\t\t\t\t\t\t\t\t\tdraggable={canWrite}\n\t\t\t\t\t\t\t\t\t\tonDragStart={() => setDragging(record.id)}\n\t\t\t\t\t\t\t\t\t\tonDragEnd={() => {\n\t\t\t\t\t\t\t\t\t\t\tsetDragging(null);\n\t\t\t\t\t\t\t\t\t\t\tsetOver(null);\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tonClick={onSelect ? () => onSelect(record) : undefined}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<div className=\"b316-board-card-title\">{record.title ?? \"Untitled\"}</div>\n\n\t\t\t\t\t\t\t\t\t\t{shown.map((candidate) => (\n\t\t\t\t\t\t\t\t\t\t\t<div key={candidate.key} className=\"b316-board-card-field\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"b316-muted\">{candidate.label}</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<FieldCell\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue={record.fields[candidate.key] ?? null}\n\t\t\t\t\t\t\t\t\t\t\t\t\tfield={candidate}\n\t\t\t\t\t\t\t\t\t\t\t\t\trelated={record.related[candidate.key]}\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t\t\t\t\t{canWrite ? (\n\t\t\t\t\t\t\t\t\t\t\t// Dragging is not reachable by keyboard and is awkward on a\n\t\t\t\t\t\t\t\t\t\t\t// phone. This is the same action by other means, not a\n\t\t\t\t\t\t\t\t\t\t\t// lesser fallback.\n\t\t\t\t\t\t\t\t\t\t\t<label className=\"b316-board-move\">\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Move to</span>\n\t\t\t\t\t\t\t\t\t\t\t\t<select\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tvalue={String(record.fields[field.key] ?? \"\")}\n\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => event.stopPropagation()}\n\t\t\t\t\t\t\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst chosen = columns.find(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(candidate) => String(candidate.value) === event.target.value,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvoid move(record, chosen?.value ?? null);\n\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{columns.map((candidate) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<option key={String(candidate.value)} value={String(candidate.value)}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{candidate.label}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t</article>\n\t\t\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t\t\t{inColumn.length === 0 ? (\n\t\t\t\t\t\t\t\t\t<div className=\"b316-board-empty\">{emptyState ?? \"Nothing here\"}</div>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</section>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\n\t\t\t{hasMore ? (\n\t\t\t\t<div className=\"b316-table-more\">\n\t\t\t\t\t{/* Named, because a board silently showing a hundred of two hundred\n\t\t\t\t\t cards is worse than a table doing the same: the columns look\n\t\t\t\t\t complete. */}\n\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={loadMore} disabled={loading}>\n\t\t\t\t\t\tShowing {records.length} of {total} — load more\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n\n/**\n * The columns a field makes.\n *\n * A SELECT has its options. A BOOLEAN has two. A date does not have a fixed\n * set, which is why the registry marks it groupable for a chart but a board\n * over one would invent a column per day.\n */\nfunction columnsFor(field: FieldDescriptor): { value: string | boolean | null; label: string }[] {\n\tif (field.type === \"BOOLEAN\") {\n\t\treturn [\n\t\t\t{ value: true, label: \"Yes\" },\n\t\t\t{ value: false, label: \"No\" },\n\t\t];\n\t}\n\n\tconst options = (field.options ?? []).map((option) => ({ value: option, label: option }));\n\n\t// A column for records with no value, so nothing is invisible. A card that\n\t// exists but appears nowhere is the worst thing a board can do.\n\treturn [...options, { value: null, label: \"None\" }];\n}\n","\"use client\";\n\nimport {\n\ttype AggregateKind,\n\ttype FieldDescriptor,\n\tfieldsAggregatableBy,\n\tfieldsFor,\n\tspecFor,\n} from \"@base316/sdk\";\nimport { useMemo, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useCollection, type UseCollectionOptions } from \"./useCollection\";\n\n/**\n * A chart, over a collection that was never designed to have one.\n *\n * The second proof, and it asks the schema different questions from the board:\n *\n * fieldsFor(fields, \"timeAxis\") // \"what can be an x-axis?\"\n * fieldsAggregatableBy(fields, \"sum\") // \"what can be added up?\"\n *\n * Neither question mentions a field type, and this file names none. That is the\n * point: the board found a SELECT, this finds a date and a number, and both did\n * it by describing what they needed rather than by being configured.\n *\n * Drawn as SVG rather than with a charting library. Artifacts and customer\n * pages both restrict which scripts may load, a charting dependency is larger\n * than everything else in this package put together, and bars with a baseline\n * are not the hard part of charting.\n */\n\nexport interface ChartProps extends UseCollectionOptions {\n\tcollection: string;\n\t/** The date field along the bottom. Discovered when omitted. */\n\tx?: string;\n\t/**\n\t * What to measure.\n\t *\n\t * Omitted means count the records, which is the question that always has an\n\t * answer: a collection may have no numeric field, but it always has rows.\n\t */\n\ty?: string;\n\t/** How to combine. Ignored when counting. */\n\taggregate?: Exclude<AggregateKind, \"count\">;\n\t/** How wide a bar is in time. */\n\tbucket?: \"day\" | \"week\" | \"month\";\n\ttitle?: string;\n\theight?: number;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\ninterface Bucket {\n\tkey: string;\n\tlabel: string;\n\tvalue: number;\n}\n\nexport function Chart({\n\tcollection,\n\tx,\n\ty,\n\taggregate = \"sum\",\n\tbucket = \"day\",\n\ttitle,\n\theight = 220,\n\tclassName,\n\tstyle,\n\t...options\n}: ChartProps) {\n\tconst { schema, records, error, loading } = useCollection(collection, {\n\t\t// A chart of one page is a chart of an arbitrary subset, which is worse\n\t\t// than no chart: it looks like an answer.\n\t\tlimit: options.limit ?? 200,\n\t\t...options,\n\t});\n\n\tconst axis = useMemo(() => {\n\t\tif (!schema) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst timeFields = fieldsFor(schema.fields, \"timeAxis\");\n\t\tconst chosen = x\n\t\t\t? (schema.fields.find((field) => field.key === x) ?? null)\n\t\t\t: (timeFields[0] ?? null);\n\n\t\treturn chosen && specFor(chosen).capabilities.timeAxis ? chosen : null;\n\t}, [schema, x]);\n\n\tconst measure = useMemo(() => {\n\t\tif (!schema || !y) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst candidates = fieldsAggregatableBy(schema.fields, aggregate);\n\n\t\treturn candidates.find((field) => field.key === y) ?? null;\n\t}, [schema, y, aggregate]);\n\n\tconst buckets = useMemo(\n\t\t() => (axis ? bucketise(records, axis, measure, y ? aggregate : \"count\", bucket) : []),\n\t\t[records, axis, measure, aggregate, bucket, y],\n\t);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema || loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!axis) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{x\n\t\t\t\t\t? `\"${x}\" is not a date, so it cannot be a time axis.`\n\t\t\t\t\t: `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.`}\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Named rather than silently counting instead: a chart labelled \"total value\"\n\t// that is quietly showing a row count is a wrong answer presented confidently.\n\tif (y && !measure) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t{`\"${y}\" cannot be ${aggregate === \"avg\" ? \"averaged\" : `combined with ${aggregate}`}.`}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst peak = Math.max(...buckets.map((entry) => entry.value), 0);\n\tconst heading =\n\t\ttitle ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;\n\n\treturn (\n\t\t<figure className={cls(\"b316-card b316-chart\", className)} style={style}>\n\t\t\t<figcaption className=\"b316-chart-title\">{heading}</figcaption>\n\n\t\t\t{buckets.length === 0 || peak === 0 ? (\n\t\t\t\t<div className=\"b316-empty\">Nothing to chart yet.</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-chart-plot\" style={{ height }}>\n\t\t\t\t\t{buckets.map((entry) => (\n\t\t\t\t\t\t<div className=\"b316-chart-col\" key={entry.key}>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"b316-chart-bar\"\n\t\t\t\t\t\t\t\t// A minimum height so a small non-zero value is still visible:\n\t\t\t\t\t\t\t\t// a bar of one pixel reads as nothing at all.\n\t\t\t\t\t\t\t\tstyle={{ height: `${Math.max(2, (entry.value / peak) * 100)}%` }}\n\t\t\t\t\t\t\t\ttitle={`${entry.label}: ${format(entry.value)}`}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<span className=\"b316-chart-label\">{entry.label}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{/* The table is not decoration. An SVG of bars is unreadable to a screen\n\t\t\t reader and unusable to anybody who needs the numbers, and the data is\n\t\t\t already here. */}\n\t\t\t<details className=\"b316-chart-data\">\n\t\t\t\t<summary>Values</summary>\n\t\t\t\t<table className=\"b316-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th scope=\"col\">{axis.label}</th>\n\t\t\t\t\t\t\t<th scope=\"col\">{measure ? measure.label : \"Count\"}</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{buckets.map((entry) => (\n\t\t\t\t\t\t\t<tr key={entry.key}>\n\t\t\t\t\t\t\t\t<td>{entry.label}</td>\n\t\t\t\t\t\t\t\t<td>{format(entry.value)}</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t</details>\n\t\t</figure>\n\t);\n}\n\nfunction format(value: number): string {\n\treturn new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(value);\n}\n\n/** The bucket a date falls in, as a sortable key. */\nfunction keyFor(date: Date, bucket: \"day\" | \"week\" | \"month\"): string {\n\tif (bucket === \"month\") {\n\t\treturn `${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(2, \"0\")}`;\n\t}\n\n\tif (bucket === \"week\") {\n\t\t// Monday of that week. Sunday is day 0, which would otherwise start the\n\t\t// week on the day most people consider its end.\n\t\tconst monday = new Date(date);\n\t\tconst offset = (date.getUTCDay() + 6) % 7;\n\n\t\tmonday.setUTCDate(date.getUTCDate() - offset);\n\n\t\treturn monday.toISOString().slice(0, 10);\n\t}\n\n\treturn date.toISOString().slice(0, 10);\n}\n\nfunction bucketise(\n\trecords: readonly { fields: Record<string, unknown> }[],\n\taxis: FieldDescriptor,\n\tmeasure: FieldDescriptor | null,\n\taggregate: AggregateKind,\n\tbucket: \"day\" | \"week\" | \"month\",\n): Bucket[] {\n\tconst groups = new Map<string, number[]>();\n\n\tfor (const record of records) {\n\t\tconst raw = record.fields[axis.key];\n\n\t\tif (raw === null || raw === undefined || raw === \"\") {\n\t\t\t// A record with no date has no place on a time axis. Dropped rather than\n\t\t\t// bucketed under today, which would invent a spike that is not there.\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst date = new Date(String(raw));\n\n\t\tif (Number.isNaN(date.getTime())) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst key = keyFor(date, bucket);\n\t\tconst value = measure ? Number(record.fields[measure.key]) : 1;\n\n\t\tgroups.set(key, [...(groups.get(key) ?? []), Number.isFinite(value) ? value : 0]);\n\t}\n\n\treturn (\n\t\t[...groups.entries()]\n\t\t\t// Keys are ISO, so lexical order is chronological order.\n\t\t\t.sort(([left], [right]) => left.localeCompare(right))\n\t\t\t.map(([key, values]) => ({\n\t\t\t\tkey,\n\t\t\t\tlabel: key,\n\t\t\t\tvalue: combine(values, aggregate),\n\t\t\t}))\n\t);\n}\n\nfunction combine(values: number[], aggregate: AggregateKind): number {\n\tswitch (aggregate) {\n\t\tcase \"count\":\n\t\t\treturn values.length;\n\t\tcase \"avg\":\n\t\t\treturn values.length === 0\n\t\t\t\t? 0\n\t\t\t\t: values.reduce((total, value) => total + value, 0) / values.length;\n\t\tcase \"min\":\n\t\t\treturn values.length === 0 ? 0 : Math.min(...values);\n\t\tcase \"max\":\n\t\t\treturn values.length === 0 ? 0 : Math.max(...values);\n\t\tdefault:\n\t\t\treturn values.reduce((total, value) => total + value, 0);\n\t}\n}\n","\"use client\";\n\nimport { specFor } from \"@base316/sdk\";\nimport { useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { FieldCell } from \"./fields\";\nimport { RecordForm } from \"./RecordForm\";\nimport { useCollection } from \"./useCollection\";\n\n/**\n * One record, read.\n *\n * The other half of a table: a row shows what fits in a column, and this shows\n * everything — including the fields a table deliberately truncates, like a\n * paragraph of notes, and the derived ones a form leaves out because they\n * cannot be typed.\n *\n * <RecordDetail collection=\"jobs\" recordId={id} />\n *\n * Edit is offered only when the viewer may write, which the schema already\n * says. There is no second permission check here and there should not be: the\n * server decides, and a component that decided for itself would eventually\n * disagree with it.\n */\n\nexport interface RecordDetailProps {\n\tcollection: string;\n\trecordId: string;\n\ttenant?: string;\n\t/** Hide Edit and Delete even for a viewer who may write. */\n\treadOnly?: boolean;\n\tonDeleted?: () => void;\n\tonClose?: () => void;\n\t/** Rendered under the fields — related lists, actions, anything. */\n\tchildren?: ReactNode;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nexport function RecordDetail({\n\tcollection,\n\trecordId,\n\ttenant,\n\treadOnly,\n\tonDeleted,\n\tonClose,\n\tchildren,\n\tclassName,\n\tstyle,\n}: RecordDetailProps) {\n\tconst { schema, records, canWrite, remove, loading, error } = useCollection(collection, {\n\t\ttenant,\n\t\trecordId,\n\t});\n\n\tconst [editing, setEditing] = useState(false);\n\tconst record = records.find((candidate) => candidate.id === recordId);\n\n\tif (error) {\n\t\t// `role=\"alert\"` and the error styling both: without the first a screen\n\t\t// reader is told nothing, and without the second a failed load renders as\n\t\t// a card with some text in it, which reads as content rather than as a\n\t\t// failure.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!schema || loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!record) {\n\t\t// Also what another tenant's record looks like: not found rather than\n\t\t// forbidden, because an id belonging to somebody else is indistinguishable\n\t\t// from one belonging to nobody.\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tThat {schema.name.toLowerCase()} is not available.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (editing) {\n\t\treturn (\n\t\t\t<RecordForm\n\t\t\t\tcollection={collection}\n\t\t\t\trecordId={recordId}\n\t\t\t\ttenant={tenant}\n\t\t\t\tclassName={className}\n\t\t\t\tstyle={style}\n\t\t\t\tonSaved={() => setEditing(false)}\n\t\t\t\tonCancel={() => setEditing(false)}\n\t\t\t/>\n\t\t);\n\t}\n\n\tconst writable = canWrite && !readOnly;\n\n\treturn (\n\t\t<div className={cls(\"b316-card b316-detail\", className)} style={style}>\n\t\t\t<div className=\"b316-detail-head\">\n\t\t\t\t<h3 className=\"b316-detail-title\">\n\t\t\t\t\t{/* The title field, or the type. A heading reading `rec_01J…` tells\n\t\t\t\t\t somebody looking at a record nothing about it. */}\n\t\t\t\t\t{record.title ?? schema.name}\n\t\t\t\t</h3>\n\n\t\t\t\t<div className=\"b316-detail-actions\">\n\t\t\t\t\t{writable ? (\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={() => setEditing(true)}>\n\t\t\t\t\t\t\tEdit\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{writable ? (\n\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\tclassName=\"b316-button-quiet b316-danger\"\n\t\t\t\t\t\t\tconfirmLabel={`Delete ${record.title ?? \"this record\"} for good`}\n\t\t\t\t\t\t\tonConfirm={async () => {\n\t\t\t\t\t\t\t\tif (await remove(recordId)) {\n\t\t\t\t\t\t\t\t\tonDeleted?.();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{onClose ? (\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button-quiet\" onClick={onClose}>\n\t\t\t\t\t\t\tClose\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<dl className=\"b316-detail-fields\">\n\t\t\t\t{schema.fields.map((field) => (\n\t\t\t\t\t<div className=\"b316-detail-row\" key={field.key}>\n\t\t\t\t\t\t<dt className=\"b316-label\">\n\t\t\t\t\t\t\t{field.label}\n\t\t\t\t\t\t\t{/* Named as computed, because a reader who cannot find it in the\n\t\t\t\t\t\t\t edit form should know why rather than assume it is broken. */}\n\t\t\t\t\t\t\t{specFor(field).computed ? <span className=\"b316-muted\"> (calculated)</span> : null}\n\t\t\t\t\t\t</dt>\n\t\t\t\t\t\t<dd>\n\t\t\t\t\t\t\t<FieldCell\n\t\t\t\t\t\t\t\tvalue={record.fields[field.key] ?? null}\n\t\t\t\t\t\t\t\tfield={field}\n\t\t\t\t\t\t\t\trelated={record.related[field.key]}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</dd>\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</dl>\n\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type {\n\tBillingSubscription,\n\tCancellation,\n\tCancellationReason,\n\tRetentionOffer,\n\tSubscriptionPhase,\n} from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\nfunction statusLabel(status: string): string {\n\tconst words = status.toLowerCase().split(\"_\");\n\treturn words.map((w, i) => (i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w)).join(\" \");\n}\n\n/** The reasons offered, in the order the API lists them. Answering is optional. */\nconst REASONS: { value: CancellationReason; label: string }[] = [\n\t{ value: \"TOO_EXPENSIVE\", label: \"It costs too much\" },\n\t{ value: \"NOT_USING\", label: \"I am not using it enough\" },\n\t{ value: \"MISSING_FEATURES\", label: \"It is missing something I need\" },\n\t{ value: \"SWITCHING\", label: \"I am switching to something else\" },\n\t{ value: \"TECHNICAL_ISSUES\", label: \"It did not work well for me\" },\n\t{ value: \"TEMPORARY\", label: \"I only needed it for a while\" },\n\t{ value: \"OTHER\", label: \"Something else\" },\n];\n\n/** \"50% off your next 3 invoices\", from the offer's terms rather than the coupon's name. */\nexport function describeRetentionOffer(offer: RetentionOffer, currency: string): string {\n\tlet amount: string;\n\n\tif (offer.type === \"PERCENTAGE\") {\n\t\tamount = `${Number(offer.percentOff ?? \"0\")}% off`;\n\t} else {\n\t\ttry {\n\t\t\tamount = `${new Intl.NumberFormat(undefined, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency: offer.currency ?? currency,\n\t\t\t}).format(Number(offer.amountOff ?? \"0\"))} off`;\n\t\t} catch {\n\t\t\tamount = `${offer.amountOff} ${offer.currency ?? currency} off`;\n\t\t}\n\t}\n\n\tif (offer.duration === \"FOREVER\") {\n\t\treturn `${amount} for as long as you stay subscribed`;\n\t}\n\n\tconst periods = offer.duration === \"ONCE\" ? 1 : (offer.durationInPeriods ?? 1);\n\n\treturn periods === 1 ? `${amount} your next invoice` : `${amount} your next ${periods} invoices`;\n}\n\ntype CancelStep =\n\t| { kind: \"idle\" }\n\t| { kind: \"survey\" }\n\t| { kind: \"offer\"; cancellation: Cancellation & { offer: RetentionOffer } };\n\n/**\n * The signed-in user's own subscription.\n *\n * Reads through the session, never a customer id from props: the account is\n * whoever the session says it is, so one user cannot be pointed at another's\n * billing by changing a prop.\n */\nexport function SubscriptionManager({\n\tonChange,\n\tclassName,\n\tstyle,\n}: {\n\t/**\n\t * Called after a cancel, a resume or an undone plan change, so a sibling\n\t * showing the same subscription — an upcoming invoice, a plan picker — can\n\t * refresh. `BillingPortal` uses it to keep its pieces in step.\n\t */\n\tonChange?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [subscription, setSubscription] = useState<BillingSubscription | null>(null);\n\tconst [loading, setLoading] = useState(true);\n\t// Set when the plan is provided by the organization that manages this\n\t// account. It is shown, but changing or cancelling it is theirs to do.\n\tconst [managedBy, setManagedBy] = useState<{ name: string | null } | null>(null);\n\t// A downgrade scheduled for the renewal, or a ramp: said plainly, with the\n\t// undo beside it, because \"why is my plan changing next month\" is the\n\t// question it answers.\n\tconst [schedule, setSchedule] = useState<SubscriptionPhase[]>([]);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\t// Cancelling is a short flow: why, then the retention offer if the\n\t// environment makes one, then done. Leaving is never more than one click\n\t// from any step.\n\tconst [step, setStep] = useState<CancelStep>({ kind: \"idle\" });\n\tconst [reason, setReason] = useState<CancellationReason | null>(null);\n\tconst [comment, setComment] = useState(\"\");\n\n\tconst load = useCallback(async () => {\n\t\tif (!token) {\n\t\t\tsetSubscription(null);\n\t\t\tsetLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await client.billing.subscription(token);\n\t\t\tsetSubscription(result.subscription);\n\t\t\tsetManagedBy(result.managedBy ?? null);\n\t\t\tsetSchedule(result.schedule ?? []);\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not load the subscription\", cause);\n\t\t\tsetError(\"Could not load your subscription.\");\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, [client, token]);\n\n\tuseEffect(() => {\n\t\tvoid load();\n\t}, [load]);\n\n\t/** Run a change, then re-read the subscription and tell the host. */\n\tconst act = async (change: () => Promise<unknown>, failure: string) => {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait change();\n\t\t\tawait load();\n\t\t\tonChange?.();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] subscription change failed\", cause);\n\t\t\tsetError(failure);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tif (sessionLoading || loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!token) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tSign in to manage your subscription.\n\t\t\t</div>\n\t\t);\n\t}\n\n\t/**\n\t * A failure is reported before anything is claimed about the account.\n\t *\n\t * The error was stored and then never reached: this guard ran first, so a\n\t * customer whose request failed was told \"You are not subscribed to a plan\"\n\t * — a confident, wrong statement to make to somebody who is paying. The\n\t * error div further down was unreachable for the whole life of the file.\n\t *\n\t * `ActiveSessions` has the ordering right; this is the same.\n\t */\n\tif (error) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!subscription) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tYou are not subscribed to a plan.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();\n\tconst next = schedule[0] ?? null;\n\tconst nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<div className=\"b316-plan-name\">{subscription.planVersion.plan.name}</div>\n\t\t\t<div className=\"b316-muted\">\n\t\t\t\t{/* PAST_DUE reads as \"Past due\", not \"past_due\". */}\n\t\t\t\t{statusLabel(subscription.status)}\n\t\t\t\t{\" · \"}\n\t\t\t\t{subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`}\n\t\t\t</div>\n\n\t\t\t{next && !managedBy ? (\n\t\t\t\t<div className=\"b316-muted\" role=\"status\" style={{ marginTop: 10 }}>\n\t\t\t\t\tMoves to {next.plan.name} on {nextOn}. You keep {subscription.planVersion.plan.name} until\n\t\t\t\t\tthen.\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\tstyle={{ marginTop: 10 }}\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={async () => {\n\t\t\t\t\t\t\t\tsetBusy(true);\n\t\t\t\t\t\t\t\tsetError(null);\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait client.billing.cancelScheduledChange(token);\n\t\t\t\t\t\t\t\t\tawait load();\n\t\t\t\t\t\t\t\t\tonChange?.();\n\t\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t\tconsole.error(\"[base316] could not undo the scheduled change\", cause);\n\t\t\t\t\t\t\t\t\tsetError(\"Could not keep your current plan. Try again.\");\n\t\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{busy ? \"Working…\" : `Keep ${subscription.planVersion.plan.name}`}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{managedBy ? (\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tProvided by {managedBy.name ?? \"the organization that manages your account\"}. Ask them to\n\t\t\t\t\tchange or cancel it.\n\t\t\t\t</p>\n\t\t\t) : subscription.cancelAtPeriodEnd ? (\n\t\t\t\t<div>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tThis subscription will not renew. You keep access until {renews}.\n\t\t\t\t\t</p>\n\t\t\t\t\t{/* The undo for a cancel, offered for as long as it can be taken:\n\t\t\t\t\t until the period actually ends. */}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\tvoid act(() => client.billing.resume(token), \"Could not resume. Try again.\")\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t{busy ? \"Working…\" : \"Resume subscription\"}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : step.kind === \"offer\" ? (\n\t\t\t\t<section style={{ marginTop: 14 }} aria-label=\"Retention offer\">\n\t\t\t\t\t<div className=\"b316-plan-name\">\n\t\t\t\t\t\t{step.cancellation.offer.headline ?? \"Before you go\"}\n\t\t\t\t\t</div>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\t{step.cancellation.offer.message ??\n\t\t\t\t\t\t\t`Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(\n\t\t\t\t\t\t\t\tstep.cancellation.offer,\n\t\t\t\t\t\t\t\tstep.cancellation.currency,\n\t\t\t\t\t\t\t)}.`}\n\t\t\t\t\t</p>\n\t\t\t\t\t<div style={{ display: \"flex\", gap: 8, flexWrap: \"wrap\" }}>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\tvoid act(async () => {\n\t\t\t\t\t\t\t\t\tawait client.billing.acceptRetentionOffer(token, step.cancellation.id);\n\t\t\t\t\t\t\t\t\tsetStep({ kind: \"idle\" });\n\t\t\t\t\t\t\t\t}, \"Could not apply the offer. Try again.\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{busy ? \"Working…\" : \"Accept offer and stay\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\tvoid act(async () => {\n\t\t\t\t\t\t\t\t\tawait client.billing.confirmCancellation(token, step.cancellation.id);\n\t\t\t\t\t\t\t\t\tsetStep({ kind: \"idle\" });\n\t\t\t\t\t\t\t\t}, \"Could not cancel. Try again.\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tNo thanks, cancel\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<p className=\"b316-muted\">If you cancel, you keep access until {renews}.</p>\n\t\t\t\t</section>\n\t\t\t) : step.kind === \"survey\" ? (\n\t\t\t\t<form\n\t\t\t\t\tstyle={{ marginTop: 14 }}\n\t\t\t\t\tonSubmit={(event) => {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tvoid act(async () => {\n\t\t\t\t\t\t\tconst started = await client.billing.startCancellation(token, {\n\t\t\t\t\t\t\t\treason,\n\t\t\t\t\t\t\t\tcomment: comment.trim() || null,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (started.offer) {\n\t\t\t\t\t\t\t\tsetStep({ kind: \"offer\", cancellation: { ...started, offer: started.offer } });\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// No offer: the user already chose to leave on this step.\n\t\t\t\t\t\t\tawait client.billing.confirmCancellation(token, started.id);\n\t\t\t\t\t\t\tsetStep({ kind: \"idle\" });\n\t\t\t\t\t\t}, \"Could not cancel. Try again.\");\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\t\tYou keep access until {renews}. It will not renew after that.\n\t\t\t\t\t</p>\n\t\t\t\t\t<fieldset className=\"b316-fieldset\">\n\t\t\t\t\t\t<legend className=\"b316-label\">Why are you leaving? (optional)</legend>\n\t\t\t\t\t\t{REASONS.map((option) => (\n\t\t\t\t\t\t\t<label key={option.value} style={{ display: \"flex\", gap: 8, alignItems: \"center\" }}>\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\t\t\t\t\tname=\"b316-cancel-reason\"\n\t\t\t\t\t\t\t\t\tvalue={option.value}\n\t\t\t\t\t\t\t\t\tchecked={reason === option.value}\n\t\t\t\t\t\t\t\t\tonChange={() => setReason(option.value)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<span>{option.label}</span>\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</fieldset>\n\t\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t\t<span className=\"b316-label\">Anything else? (optional)</span>\n\t\t\t\t\t\t<textarea\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\trows={3}\n\t\t\t\t\t\t\tmaxLength={2000}\n\t\t\t\t\t\t\tvalue={comment}\n\t\t\t\t\t\t\tonChange={(event) => setComment(event.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</label>\n\t\t\t\t\t<div style={{ display: \"flex\", gap: 8, flexWrap: \"wrap\" }}>\n\t\t\t\t\t\t<button type=\"submit\" className=\"b316-button b316-button-secondary\" disabled={busy}>\n\t\t\t\t\t\t\t{busy ? \"Working…\" : \"Cancel subscription\"}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={() => setStep({ kind: \"idle\" })}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tKeep {subscription.planVersion.plan.name}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t) : (\n\t\t\t\t<div style={{ marginTop: 14 }}>\n\t\t\t\t\t{/* Asked in the page rather than with `window.confirm`, which a\n\t\t\t\t\t sandboxed embed silently answers \"no\". The next step says\n\t\t\t\t\t when access ends and asks why, before anything changes. */}\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\tsetReason(null);\n\t\t\t\t\t\t\tsetComment(\"\");\n\t\t\t\t\t\t\tsetStep({ kind: \"survey\" });\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tCancel subscription\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport type { BillingCustomer, BillingSubscription } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { BillingDetailsForm } from \"./BillingDetailsForm\";\nimport { CreditBalances } from \"./CreditBalances\";\nimport { Invoices } from \"./Invoices\";\nimport { PaymentMethod } from \"./PaymentMethod\";\nimport { PlanChangeReview } from \"./PlanChangeReview\";\nimport { PricingTable } from \"./PricingTable\";\nimport { useBase316 } from \"./provider\";\nimport { SeatManager } from \"./SeatManager\";\nimport { SubscriptionManager } from \"./SubscriptionManager\";\nimport { UpcomingInvoice } from \"./UpcomingInvoice\";\n\nexport interface BillingPortalProps {\n\t/**\n\t * Where the browser comes back to after updating the card on Stripe's page.\n\t * Must be one of the environment's redirect URIs. Defaults to the current\n\t * page.\n\t */\n\treturnUrl?: string;\n\t/** The plan to present as the default choice in the plan picker, by key. */\n\tfeaturedPlanKey?: string;\n\t/** What a seat is called, plural. \"seats\" by default. */\n\tunitLabel?: string;\n\t/**\n\t * The \"Billing details\" section: the billing address and tax IDs.\n\t *\n\t * Replace it with your own form, or pass `null` to leave it out. By default\n\t * it is `<BillingDetailsForm />`: the address invoices are made out to and\n\t * the tax IDs on them, EU VAT numbers checked with VIES as they are saved.\n\t */\n\tbillingDetails?: ReactNode;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\ninterface Overview {\n\tcustomer: BillingCustomer | null;\n\tsubscription: BillingSubscription | null;\n\tmanagedBy: { name: string | null } | null;\n\tquantityPriced: boolean;\n}\n\n/**\n * A whole billing page for the signed-in user, in one component.\n *\n * The embeddable counterpart to the hosted billing portal: plan and status,\n * the next invoice, a scheduled change with its undo, a plan picker whose\n * choice opens a review step, seats when the plan is priced per seat, credit\n * balances with buying and auto-recharge when the product sells credit packs,\n * the saved cards, invoices with their PDFs and a way to pay an open one, and cancel\n * and resume. Everything goes through the signed-in user's session and the\n * `/v1/me` routes, which apply the same rules as the hosted page.\n *\n * It is the existing pieces composed — `SubscriptionManager`,\n * `UpcomingInvoice`, `PricingTable`, `PlanChangeReview`, `SeatManager`,\n * `CreditBalances`, `PaymentMethod` and `Invoices` — so a page that wants a different layout\n * uses those directly. After any change the pieces are re-read together, so\n * the invoice preview never disagrees with the plan above it.\n *\n * A client company billed by the firm that manages it sees the firm's plan,\n * read-only and named, and its own invoices — nothing it could change.\n */\nexport function BillingPortal({\n\treturnUrl,\n\tfeaturedPlanKey,\n\tunitLabel,\n\tbillingDetails,\n\tclassName,\n\tstyle,\n}: BillingPortalProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [overview, setOverview] = useState<Overview | null>(null);\n\tconst [failed, setFailed] = useState(false);\n\t// Bumped after any change: every piece is keyed on it, so they all re-read.\n\tconst [version, setVersion] = useState(0);\n\tconst [reviewing, setReviewing] = useState<string | null>(null);\n\tconst [notice, setNotice] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tif (!token) return;\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.subscription(token)\n\t\t\t.then((result) => {\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\tsetOverview({\n\t\t\t\t\tcustomer: result.customer,\n\t\t\t\t\tsubscription: result.subscription,\n\t\t\t\t\tmanagedBy: result.managedBy ?? null,\n\t\t\t\t\tquantityPriced: result.quantityPriced ?? false,\n\t\t\t\t});\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load billing\", cause);\n\t\t\t\tif (!cancelled) setFailed(true);\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, version]);\n\n\t// A notice describes the last change; any later one makes it stale.\n\tconst refresh = useCallback(() => {\n\t\tsetNotice(null);\n\t\tsetVersion((value) => value + 1);\n\t}, []);\n\n\tconst shell = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-billing-portal\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) return shell(<div className=\"b316-card\">Loading…</div>);\n\tif (!token) return shell(<div className=\"b316-card\">Sign in to manage your billing.</div>);\n\n\tif (failed) {\n\t\treturn shell(\n\t\t\t<div className=\"b316-card\">\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your billing.\n\t\t\t\t</div>\n\t\t\t</div>,\n\t\t);\n\t}\n\n\tif (!overview) return shell(<div className=\"b316-card\">Loading…</div>);\n\n\tconst { subscription, managedBy, quantityPriced } = overview;\n\tconst canChange = Boolean(subscription) && !managedBy;\n\n\treturn shell(\n\t\t<>\n\t\t\t{notice ? (\n\t\t\t\t<div className=\"b316-card b316-notice\" role=\"status\">\n\t\t\t\t\t{notice}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<SubscriptionManager key={`plan-${version}`} onChange={refresh} />\n\n\t\t\t{canChange ? <UpcomingInvoice key={`next-${version}`} /> : null}\n\n\t\t\t{canChange && quantityPriced ? (\n\t\t\t\t<SeatManager key={`seats-${version}`} unitLabel={unitLabel} onChange={refresh} />\n\t\t\t) : null}\n\n\t\t\t{reviewing ? (\n\t\t\t\t<PlanChangeReview\n\t\t\t\t\tplanVersionId={reviewing}\n\t\t\t\t\tonCancel={() => setReviewing(null)}\n\t\t\t\t\tonDone={({ scheduled }) => {\n\t\t\t\t\t\tsetReviewing(null);\n\t\t\t\t\t\trefresh();\n\t\t\t\t\t\tsetNotice(\n\t\t\t\t\t\t\tscheduled\n\t\t\t\t\t\t\t\t? \"Your plan change is scheduled for the end of this billing period.\"\n\t\t\t\t\t\t\t\t: \"Your plan has been changed.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<section>\n\t\t\t\t\t<h2 className=\"b316-billing-portal-section-title\">\n\t\t\t\t\t\t{subscription ? \"Change plan\" : \"Choose a plan\"}\n\t\t\t\t\t</h2>\n\t\t\t\t\t<PricingTable\n\t\t\t\t\t\tkey={`plans-${version}`}\n\t\t\t\t\t\tfeaturedPlanKey={featuredPlanKey}\n\t\t\t\t\t\t// A subscriber reviews a change before making it. Without a\n\t\t\t\t\t\t// subscription the table's own checkout is the right route.\n\t\t\t\t\t\tonSelectPlan={\n\t\t\t\t\t\t\tcanChange\n\t\t\t\t\t\t\t\t? (planVersionId) => {\n\t\t\t\t\t\t\t\t\t\tsetNotice(null);\n\t\t\t\t\t\t\t\t\t\tsetReviewing(planVersionId);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t</section>\n\t\t\t)}\n\n\t\t\t<CreditBalances key={`credits-${version}`} />\n\n\t\t\t{managedBy ? null : <PaymentMethod key={`card-${version}`} returnUrl={returnUrl} />}\n\n\t\t\t<Invoices key={`invoices-${version}`} />\n\n\t\t\t{/* The billing address and tax IDs, through `/v1/me/billing-details` —\n\t\t\t the same self-service rules as the hosted portal's form, including\n\t\t\t the refusal for a managed tenant. A host can pass its own. */}\n\t\t\t{billingDetails === undefined ? (\n\t\t\t\t<BillingDetailsForm key={`details-${version}`} />\n\t\t\t) : (\n\t\t\t\tbillingDetails\n\t\t\t)}\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { MyCreditFeature, MyCredits } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties, type FormEvent, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\ntype State = { kind: \"loading\" } | { kind: \"ready\"; credits: MyCredits } | { kind: \"error\" };\n\nexport interface CreditBalancesProps {\n\t/** Called after auto-recharge is saved. */\n\tonChange?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nfunction units(value: number | string | null): string {\n\treturn value === null ? \"Unlimited\" : Number(value).toLocaleString(\"en\");\n}\n\nfunction money(amount: string, currency: string): string {\n\ttry {\n\t\treturn new Intl.NumberFormat(\"en\", { style: \"currency\", currency }).format(Number(amount));\n\t} catch {\n\t\treturn `${currency} ${amount}`;\n\t}\n}\n\n/** What the user needs to know about their auto-recharge right now, if anything. */\nfunction status(feature: MyCreditFeature): string | null {\n\tconst setting = feature.autoRecharge;\n\n\tif (!setting) return null;\n\tif (setting.disabledAt && setting.disabledReason === \"PAYMENT_FAILED\") {\n\t\treturn \"Auto-recharge was turned off because your card was declined twice. Update your card, then turn it back on.\";\n\t}\n\tif (setting.disabledAt && setting.disabledReason === \"PACK_UNAVAILABLE\") {\n\t\treturn \"Auto-recharge was turned off because the pack it bought is no longer available. Choose another pack.\";\n\t}\n\tif (setting.enabled && setting.needsPaymentMethod) {\n\t\treturn \"Auto-recharge is on, but there is no card on file to charge. Add a card and it will recharge next time.\";\n\t}\n\tif (setting.enabled && setting.inFlight) {\n\t\treturn \"A recharge is being processed. Your credits appear as soon as the payment clears.\";\n\t}\n\n\treturn null;\n}\n\nfunction Feature({\n\tfeature,\n\tmanaged,\n\tonSaved,\n}: {\n\tfeature: MyCreditFeature;\n\tmanaged: boolean;\n\tonSaved: () => void;\n}) {\n\tconst { client, token } = useBase316();\n\tconst setting = feature.autoRecharge;\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [saved, setSaved] = useState<string | null>(null);\n\tconst [pack, setPack] = useState(feature.packs[0]?.id ?? \"\");\n\tconst unit = feature.unit ? ` ${feature.unit}` : \"\";\n\tconst warning = status(feature);\n\n\tconst buy = async () => {\n\t\tif (!token || !pack) return;\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.billing.buyCredits(token, pack);\n\n\t\t\tif (result.url) {\n\t\t\t\twindow.location.assign(result.url);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetSaved(\"Paid from your account balance. Your credits are ready.\");\n\t\t\tonSaved();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not buy credits\", cause);\n\t\t\tsetError(\"That pack could not be bought. Try another.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\tconst save = async (event: FormEvent<HTMLFormElement>) => {\n\t\tevent.preventDefault();\n\t\tif (!token) return;\n\n\t\tconst form = new FormData(event.currentTarget);\n\t\tconst text = (name: string) => {\n\t\t\tconst value = form.get(name);\n\n\t\t\treturn typeof value === \"string\" ? value.trim() : \"\";\n\t\t};\n\t\tconst count = text(\"monthlyMaxCount\");\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\t\tsetSaved(null);\n\n\t\ttry {\n\t\t\tconst result = await client.billing.setAutoRecharge(token, {\n\t\t\t\tfeatureId: feature.featureId,\n\t\t\t\tenabled: form.get(\"enabled\") === \"on\",\n\t\t\t\tthreshold: text(\"threshold\"),\n\t\t\t\tcreditPackId: text(\"creditPackId\") || null,\n\t\t\t\tmonthlyMaxCount: count ? Number.parseInt(count, 10) : null,\n\t\t\t\tmonthlyMaxAmount: text(\"monthlyMaxAmount\") || null,\n\t\t\t});\n\n\t\t\tsetSaved(result.enabled ? \"Auto-recharge is on.\" : \"Auto-recharge is off.\");\n\t\t\tonSaved();\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not save auto-recharge\", cause);\n\t\t\tsetError(\n\t\t\t\t\"Auto-recharge was not saved. Check the threshold and set a monthly maximum: a number of purchases, an amount, or both.\",\n\t\t\t);\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className=\"b316-card b316-credit-balance\">\n\t\t\t<div className=\"b316-label\">{feature.featureName}</div>\n\t\t\t<div>\n\t\t\t\t<strong>{units(feature.remaining)}</strong>\n\t\t\t\t{unit} left\n\t\t\t</div>\n\t\t\t<div className=\"b316-muted\">\n\t\t\t\t{feature.allowance === null\n\t\t\t\t\t? \"Unlimited allowance\"\n\t\t\t\t\t: `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`}{\" \"}\n\t\t\t\t· {units(feature.purchasedRemaining)} purchased\n\t\t\t</div>\n\n\t\t\t{warning && !managed ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{warning}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t{saved ? (\n\t\t\t\t<div className=\"b316-notice\" role=\"status\">\n\t\t\t\t\t{saved}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{managed || feature.packs.length === 0 ? null : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"b316-row\" style={{ marginTop: 12 }}>\n\t\t\t\t\t\t<select\n\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\taria-label=\"Pack to buy\"\n\t\t\t\t\t\t\tvalue={pack}\n\t\t\t\t\t\t\tonChange={(event) => setPack(event.target.value)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{feature.packs.map((option) => (\n\t\t\t\t\t\t\t\t<option key={option.id} value={option.id}>\n\t\t\t\t\t\t\t\t\t{option.name} — {units(option.units)} for {money(option.amount, option.currency)}\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</select>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\tonClick={buy}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tBuy now\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<form onSubmit={save} style={{ marginTop: 16 }}>\n\t\t\t\t\t\t<label className=\"b316-checkbox\">\n\t\t\t\t\t\t\t<input type=\"checkbox\" name=\"enabled\" defaultChecked={setting?.enabled ?? false} />{\" \"}\n\t\t\t\t\t\t\tBuy credits automatically when my balance runs low\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t\t\t<span className=\"b316-label\">When fewer than this many{unit} are left</span>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\tname=\"threshold\"\n\t\t\t\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\t\t\t\trequired\n\t\t\t\t\t\t\t\tdefaultValue={setting?.threshold ?? \"\"}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t\t\t<span className=\"b316-label\">Buy</span>\n\t\t\t\t\t\t\t<select\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\tname=\"creditPackId\"\n\t\t\t\t\t\t\t\tdefaultValue={setting?.creditPackId ?? feature.packs[0]?.id}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{feature.packs.map((option) => (\n\t\t\t\t\t\t\t\t\t<option key={option.id} value={option.id}>\n\t\t\t\t\t\t\t\t\t\t{option.name}\n\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</select>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t\t\t<span className=\"b316-label\">At most this many times a month</span>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\tname=\"monthlyMaxCount\"\n\t\t\t\t\t\t\t\tinputMode=\"numeric\"\n\t\t\t\t\t\t\t\tdefaultValue={setting ? String(setting.monthlyMaxCount ?? \"\") : \"3\"}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<label className=\"b316-field\">\n\t\t\t\t\t\t\t<span className=\"b316-label\">\n\t\t\t\t\t\t\t\tSpending at most ({setting?.currency ?? feature.packs[0]?.currency ?? \"USD\"}) a\n\t\t\t\t\t\t\t\tmonth\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\t\t\tname=\"monthlyMaxAmount\"\n\t\t\t\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\t\t\t\tdefaultValue={setting?.monthlyMaxAmount ?? \"\"}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</label>\n\t\t\t\t\t\t<button type=\"submit\" className=\"b316-button\" disabled={busy}>\n\t\t\t\t\t\t\tSave auto-recharge\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</form>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\n/**\n * The signed-in user's credit balances: what is left of each metered feature\n * sold in packs, a way to buy a pack now, and auto-recharge — a threshold, the\n * pack to buy, and a monthly maximum.\n *\n * Buying goes to the hosted pay page; auto-recharge charges the card on file\n * (`PaymentMethod`). A client company whose credits a firm pays for sees the\n * pool it spends, with nothing to change. Renders nothing when the product\n * sells no credit packs.\n */\nexport function CreditBalances({ onChange, className, style }: CreditBalancesProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [state, setState] = useState<State>({ kind: \"loading\" });\n\tconst [version, setVersion] = useState(0);\n\n\tuseEffect(() => {\n\t\tif (!token) return;\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.credits(token)\n\t\t\t.then((credits) => {\n\t\t\t\tif (!cancelled) setState({ kind: \"ready\", credits });\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load credits\", cause);\n\t\t\t\tif (!cancelled) setState({ kind: \"error\" });\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, version]);\n\n\tconst wrap = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-credit-balances\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading || !token || state.kind === \"loading\") return null;\n\n\tif (state.kind === \"error\") {\n\t\treturn wrap(\n\t\t\t<div className=\"b316-card\">\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your credits.\n\t\t\t\t</div>\n\t\t\t</div>,\n\t\t);\n\t}\n\n\tconst { credits } = state;\n\n\tif (credits.features.length === 0) return null;\n\n\treturn wrap(\n\t\t<>\n\t\t\t{credits.managedBy ? (\n\t\t\t\t<p className=\"b316-muted\">\n\t\t\t\t\tCredits for this account come from{\" \"}\n\t\t\t\t\t{credits.managedBy.name ?? \"the organization that manages it\"}, which manages them.\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t{credits.features.map((feature) => (\n\t\t\t\t<Feature\n\t\t\t\t\tkey={feature.featureId}\n\t\t\t\t\tfeature={feature}\n\t\t\t\t\tmanaged={Boolean(credits.managedBy)}\n\t\t\t\t\tonSaved={() => {\n\t\t\t\t\t\tsetVersion((value) => value + 1);\n\t\t\t\t\t\tonChange?.();\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { SavedCard } from \"@base316/sdk\";\nimport { useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\ntype State =\n\t| { kind: \"loading\" }\n\t| { kind: \"ready\"; cards: SavedCard[] }\n\t| { kind: \"managed\" }\n\t| { kind: \"error\" };\n\nexport interface PaymentMethodProps {\n\t/**\n\t * Where the browser comes back to once the new card is stored. Must be one\n\t * of the environment's redirect URIs. Defaults to the current page.\n\t */\n\treturnUrl?: string;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\nfunction brandName(brand: string | null): string {\n\tif (!brand) return \"Card\";\n\n\treturn brand.charAt(0).toUpperCase() + brand.slice(1);\n}\n\n/**\n * The card the signed-in user's invoices are charged against, and a way to\n * replace it — plus any other saved cards, each of which can be made the\n * default or removed.\n *\n * Replacing it goes to a page hosted by Stripe, on the application's connected\n * account: the card is never typed into this component, the host page or\n * Base316, so adding this to an application adds nothing to its PCI scope.\n * The browser returns to `returnUrl` once the card is stored.\n *\n * A client company whose plan a firm pays for is told so instead — the firm's\n * card is the one charged.\n */\nexport function PaymentMethod({ returnUrl, className, style }: PaymentMethodProps) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\tconst [state, setState] = useState<State>({ kind: \"loading\" });\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\t// Bumped after a card is made default or removed, to re-read the list.\n\tconst [version, setVersion] = useState(0);\n\n\tuseEffect(() => {\n\t\tif (!token) return;\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.paymentMethods(token)\n\t\t\t.then((result) => {\n\t\t\t\tif (cancelled) return;\n\n\t\t\t\tsetState(\n\t\t\t\t\tresult.billedByParent ? { kind: \"managed\" } : { kind: \"ready\", cards: result.data },\n\t\t\t\t);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not load the payment method\", cause);\n\t\t\t\tif (!cancelled) setState({ kind: \"error\" });\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, version]);\n\n\tconst wrap = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card b316-payment-method\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (sessionLoading) return wrap(\"Loading…\");\n\tif (!token) return wrap(\"Sign in to manage your payment method.\");\n\n\tswitch (state.kind) {\n\t\tcase \"loading\":\n\t\t\treturn wrap(\"Loading…\");\n\t\tcase \"error\":\n\t\t\treturn wrap(\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\tCould not load your payment method.\n\t\t\t\t</div>,\n\t\t\t);\n\t\tcase \"managed\":\n\t\t\treturn wrap(\n\t\t\t\t<p className=\"b316-muted\">Your plan is paid for by the organization that manages it.</p>,\n\t\t\t);\n\t}\n\n\tconst card = state.cards.find((saved) => saved.isDefault) ?? null;\n\tconst others = state.cards.filter((saved) => !saved.isDefault);\n\n\tconst act = async (label: string, run: () => Promise<unknown>) => {\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tawait run();\n\t\t\tsetVersion((value) => value + 1);\n\t\t} catch (cause) {\n\t\t\tconsole.error(`[base316] could not ${label}`, cause);\n\t\t\tsetError(\"That card could not be changed. Try again.\");\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t};\n\n\treturn wrap(\n\t\t<>\n\t\t\t<div className=\"b316-label\">Payment method</div>\n\t\t\t{card ? (\n\t\t\t\t<div>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{brandName(card.brand)} ending {card.last4 ?? \"????\"}\n\t\t\t\t\t</div>\n\t\t\t\t\t{card.expMonth && card.expYear ? (\n\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\tExpires {String(card.expMonth).padStart(2, \"0\")}/{card.expYear}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<p className=\"b316-muted\">No card on file.</p>\n\t\t\t)}\n\n\t\t\t{others.length > 0 ? (\n\t\t\t\t<div style={{ marginTop: 12 }}>\n\t\t\t\t\t<div className=\"b316-label\">Other saved cards</div>\n\t\t\t\t\t{others.map((saved) => (\n\t\t\t\t\t\t<div key={saved.id} className=\"b316-row\" style={{ marginTop: 6 }}>\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t{brandName(saved.brand)} ending {saved.last4 ?? \"????\"}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button-link\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\tact(\"make the card the default\", () =>\n\t\t\t\t\t\t\t\t\t\t\tclient.billing.setDefaultPaymentMethod(token, saved.id),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tMake default\n\t\t\t\t\t\t\t\t</button>{\" \"}\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button-link\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t\t\t\tact(\"remove the card\", () =>\n\t\t\t\t\t\t\t\t\t\t\tclient.billing.removePaymentMethod(token, saved.id),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRemove\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\tstyle={{ marginTop: 12 }}\n\t\t\t\tdisabled={busy}\n\t\t\t\tonClick={async () => {\n\t\t\t\t\tsetBusy(true);\n\t\t\t\t\tsetError(null);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst { url } = await client.billing.updatePaymentMethod(token, {\n\t\t\t\t\t\t\t...(returnUrl ? { returnUrl } : {}),\n\t\t\t\t\t\t});\n\t\t\t\t\t\twindow.location.assign(url);\n\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\tconsole.error(\"[base316] could not start a card update\", cause);\n\t\t\t\t\t\tsetError(\"Cards cannot be updated here right now.\");\n\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{busy ? \"Opening Stripe…\" : card ? \"Update card\" : \"Add a card\"}\n\t\t\t</button>\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { PlanChangePreview, PlanChangeTiming } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties, type ReactNode } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { useBase316 } from \"./provider\";\n\n/** Display only: every figure was computed server-side in decimal arithmetic. */\nfunction money(amount: string | null, currency: string): string {\n\tif (amount === null) return \"—\";\n\n\tconst value = Number(amount);\n\n\tif (!Number.isFinite(value)) return `${amount} ${currency}`;\n\n\ttry {\n\t\treturn new Intl.NumberFormat(undefined, { style: \"currency\", currency }).format(value);\n\t} catch {\n\t\treturn `${amount} ${currency}`;\n\t}\n}\n\nconst day = (value: string | null) => (value ? new Date(value).toLocaleDateString() : \"—\");\n\n/** A feature's grant in words: a switch is included or not; a quantity has a number. */\nfunction limitText(terms: { enabled: boolean; limit: string | null } | null, type: string): string {\n\tif (!terms || !terms.enabled || terms.limit === \"0\") return \"Not included\";\n\tif (type === \"BOOLEAN\") return \"Included\";\n\n\treturn terms.limit === null ? \"Unlimited\" : terms.limit;\n}\n\nconst statusOf = (cause: unknown) => (cause as { status?: unknown } | null)?.status;\n\nconst TIMING_CLOSED: Record<string, string> = {\n\tTRIALING: \"During a trial a change happens now, and costs nothing until the trial ends.\",\n\tCANCELLATION_PENDING: \"Resume your subscription to schedule a change for the period end.\",\n\tCURRENCY_MISMATCH: \"This plan is billed in a different currency, so it can only start now.\",\n\tNOT_RENEWING: \"This subscription is not renewing, so nothing can wait for the period end.\",\n};\n\nexport interface PlanChangeReviewProps {\n\t/** The plan version being moved to — a `PublicPlan`'s `planVersionId`. */\n\tplanVersionId: string;\n\t/** Called once the change is made or scheduled. */\n\tonDone?: (outcome: { scheduled: boolean }) => void;\n\t/** Called when the user backs out. Without it there is no back button. */\n\tonCancel?: () => void;\n\t/**\n\t * Called when a change now needs a card the account does not have. Without\n\t * it the review offers to start a card update itself.\n\t */\n\tonNeedsCard?: () => void;\n\tclassName?: string;\n\tstyle?: CSSProperties;\n}\n\n/**\n * The review step before a plan change: what is gained and lost, what it\n * costs, and when it happens — then confirm.\n *\n * The figures are `previewPlanChange`'s, the same function the change runs, so\n * the amount shown is the amount charged. The default timing is the server's\n * (an upgrade now, a downgrade at the renewal); the other is offered when it is\n * open, and the reason is said when it is not.\n */\nexport function PlanChangeReview({\n\tplanVersionId,\n\tonDone,\n\tonCancel,\n\tonNeedsCard,\n\tclassName,\n\tstyle,\n}: PlanChangeReviewProps) {\n\tconst { client, token } = useBase316();\n\tconst [timing, setTiming] = useState<PlanChangeTiming | undefined>(undefined);\n\tconst [preview, setPreview] = useState<PlanChangePreview | null>(null);\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [needsCard, setNeedsCard] = useState(false);\n\tconst [busy, setBusy] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (!token) return;\n\n\t\tlet cancelled = false;\n\n\t\tclient.billing\n\t\t\t.previewPlanChange(token, planVersionId, timing)\n\t\t\t.then((result) => {\n\t\t\t\tif (!cancelled) setPreview(result);\n\t\t\t})\n\t\t\t.catch((cause) => {\n\t\t\t\tconsole.error(\"[base316] could not preview the plan change\", cause);\n\t\t\t\tif (!cancelled) {\n\t\t\t\t\tsetError(\n\t\t\t\t\t\tstatusOf(cause) === 403\n\t\t\t\t\t\t\t? \"Your plan is provided by the organization that manages your account.\"\n\t\t\t\t\t\t\t: \"That plan change is not available.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [client, token, planVersionId, timing]);\n\n\tconst confirm = useCallback(async () => {\n\t\tif (!token || !preview) return;\n\n\t\tsetBusy(true);\n\t\tsetError(null);\n\n\t\ttry {\n\t\t\tconst result = await client.billing.changePlan(token, {\n\t\t\t\tplanVersionId,\n\t\t\t\ttiming: preview.timing,\n\t\t\t});\n\n\t\t\tonDone?.({ scheduled: result.scheduled });\n\t\t} catch (cause) {\n\t\t\tif (statusOf(cause) === 402) {\n\t\t\t\tsetNeedsCard(true);\n\t\t\t} else {\n\t\t\t\tconsole.error(\"[base316] plan change failed\", cause);\n\t\t\t\tsetError(\"Could not change your plan. Try again.\");\n\t\t\t}\n\t\t} finally {\n\t\t\tsetBusy(false);\n\t\t}\n\t}, [client, token, preview, planVersionId, onDone]);\n\n\tconst addCard = useCallback(async () => {\n\t\tif (onNeedsCard) {\n\t\t\tonNeedsCard();\n\t\t\treturn;\n\t\t}\n\n\t\tif (!token) return;\n\n\t\ttry {\n\t\t\tconst { url } = await client.billing.updatePaymentMethod(token);\n\t\t\twindow.location.assign(url);\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not start a card update\", cause);\n\t\t\tsetError(\"Cards cannot be added here right now.\");\n\t\t}\n\t}, [client, token, onNeedsCard]);\n\n\tconst card = (content: ReactNode) => (\n\t\t<div className={cls(\"b316-card b316-plan-review\", className)} style={style}>\n\t\t\t{content}\n\t\t</div>\n\t);\n\n\tif (error && !preview) {\n\t\treturn card(\n\t\t\t<>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t\t{onCancel ? (\n\t\t\t\t\t<button type=\"button\" className=\"b316-button b316-button-secondary\" onClick={onCancel}>\n\t\t\t\t\t\tBack\n\t\t\t\t\t</button>\n\t\t\t\t) : null}\n\t\t\t</>,\n\t\t);\n\t}\n\n\tif (!preview) {\n\t\treturn card(\"Loading…\");\n\t}\n\n\tconst { from, to, now } = preview;\n\tconst other: PlanChangeTiming = preview.timing === \"NOW\" ? \"PERIOD_END\" : \"NOW\";\n\tconst otherOpen = preview.timings[other]?.available ?? false;\n\tconst otherReason = preview.timings[other]?.reason ?? null;\n\tconst changes = preview.entitlements.filter((change) => change.change !== \"UNCHANGED\");\n\n\treturn card(\n\t\t<>\n\t\t\t<div className=\"b316-plan-name\">Change to {to.planName}</div>\n\t\t\t<div className=\"b316-muted\">From {from.planName}</div>\n\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{changes.length === 0 ? (\n\t\t\t\t<p className=\"b316-muted\">Every feature stays the same.</p>\n\t\t\t) : (\n\t\t\t\t<table className=\"b316-review-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th>Feature</th>\n\t\t\t\t\t\t\t<th>{from.planName}</th>\n\t\t\t\t\t\t\t<th>{to.planName}</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{changes.map((change) => (\n\t\t\t\t\t\t\t<tr key={change.featureId}>\n\t\t\t\t\t\t\t\t<td>{change.featureName}</td>\n\t\t\t\t\t\t\t\t<td>{limitText(change.before, change.type)}</td>\n\t\t\t\t\t\t\t\t<td\n\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\tchange.change === \"GAINED\" || change.change === \"INCREASED\"\n\t\t\t\t\t\t\t\t\t\t\t? \"b316-review-gain\"\n\t\t\t\t\t\t\t\t\t\t\t: \"b316-review-loss\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{limitText(change.after, change.type)}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t)}\n\n\t\t\t{preview.timing === \"NOW\" ? (\n\t\t\t\tnow.trialing ? (\n\t\t\t\t\t<p>\n\t\t\t\t\t\tThe change happens now. Your trial carries on until {day(now.trialEndsAt)}, and nothing\n\t\t\t\t\t\tis charged before then.\n\t\t\t\t\t</p>\n\t\t\t\t) : (\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{Number(now.credit) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Credit for the unused part of {from.planName}</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">−{money(now.credit, from.currency)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{Number(now.closingUsage) > 0 ? (\n\t\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t\t<span className=\"b316-muted\">Usage so far this period</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">{money(now.closingUsage, from.currency)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<div className=\"b316-row\">\n\t\t\t\t\t\t\t<span className=\"b316-muted\">\n\t\t\t\t\t\t\t\t{to.planName}, {day(now.newPeriod.start)} – {day(now.newPeriod.end)}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span className=\"b316-num\">{money(now.newPeriodCharge, to.currency)}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{now.net !== null ? (\n\t\t\t\t\t\t\t<div className=\"b316-row b316-invoice-total\">\n\t\t\t\t\t\t\t\t<span>Due now</span>\n\t\t\t\t\t\t\t\t<span className=\"b316-num\">{money(now.net, to.currency)}</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t)\n\t\t\t) : (\n\t\t\t\t<p>\n\t\t\t\t\tYou keep {from.planName} until {day(preview.atPeriodEnd?.effectiveAt ?? null)}, then move\n\t\t\t\t\tto {to.planName}. Nothing is charged now.\n\t\t\t\t\t{preview.atPeriodEnd?.nextInvoice\n\t\t\t\t\t\t? ` Your first invoice on ${to.planName} is ${money(\n\t\t\t\t\t\t\t\tpreview.atPeriodEnd.nextInvoice.amountDue,\n\t\t\t\t\t\t\t\tpreview.atPeriodEnd.nextInvoice.currency,\n\t\t\t\t\t\t\t)}.`\n\t\t\t\t\t\t: \"\"}\n\t\t\t\t</p>\n\t\t\t)}\n\n\t\t\t{otherOpen ? (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button b316-button-link\"\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t// Back to loading until the other timing's figures arrive.\n\t\t\t\t\t\tsetPreview(null);\n\t\t\t\t\t\tsetTiming(other);\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{other === \"NOW\" ? \"Change now instead\" : \"Wait until the end of the period instead\"}\n\t\t\t\t</button>\n\t\t\t) : otherReason && TIMING_CLOSED[otherReason] ? (\n\t\t\t\t<p className=\"b316-muted\">{TIMING_CLOSED[otherReason]}</p>\n\t\t\t) : null}\n\n\t\t\t{needsCard ? (\n\t\t\t\t<div className=\"b316-notice\" role=\"status\">\n\t\t\t\t\tA card is needed for a change that is charged now.\n\t\t\t\t\t<div className=\"b316-review-actions\">\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button\" onClick={() => void addCard()}>\n\t\t\t\t\t\t\tAdd a card\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-review-actions\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\tonClick={() => void confirm()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{busy\n\t\t\t\t\t\t\t? \"Working…\"\n\t\t\t\t\t\t\t: preview.timing === \"NOW\"\n\t\t\t\t\t\t\t\t? `Change to ${to.planName} now`\n\t\t\t\t\t\t\t\t: `Schedule ${to.planName}`}\n\t\t\t\t\t</button>\n\t\t\t\t\t{onCancel ? (\n\t\t\t\t\t\t<button type=\"button\" className=\"b316-button b316-button-secondary\" onClick={onCancel}>\n\t\t\t\t\t\t\tKeep {from.planName}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</>,\n\t);\n}\n","\"use client\";\n\nimport type { ApiCredential, CustomerApiResource } from \"@base316/sdk\";\nimport { useCallback, useEffect, useState, type CSSProperties } from \"react\";\n\nimport { cls } from \"./appearance\";\nimport { ConfirmButton } from \"./confirm\";\nimport { useBase316 } from \"./provider\";\n\n/** `900` reads as nothing; `15m` reads as a decision somebody made. */\nfunction duration(seconds: number): string {\n\tif (seconds % 3600 === 0) {\n\t\treturn `${seconds / 3600}h`;\n\t}\n\n\tif (seconds % 60 === 0) {\n\t\treturn `${seconds / 60}m`;\n\t}\n\n\treturn `${seconds}s`;\n}\n\n/**\n * The signed-in user's credentials for this application's API.\n *\n * Drop this on an account or developer-settings page and the account manages\n * its own keys: issue, rotate, revoke. Reads through the session, never a\n * customer id from props — the account is whoever the session says it is, so\n * one user cannot be pointed at another's keys by changing a prop.\n *\n * What it deliberately does *not* offer is changing the rate limit. A caller\n * who can raise their own ceiling does not have one. The limit is shown, and so\n * are the scopes the plan withholds, which is an upgrade prompt arriving at the\n * moment somebody actually wants the capability.\n */\nexport function ApiKeyManager({\n\tclassName,\n\tstyle,\n\t/** Restrict to one API. Omit to show every one the account can reach. */\n\taudience,\n}: {\n\tclassName?: string;\n\tstyle?: CSSProperties;\n\taudience?: string;\n}) {\n\tconst { client, token, loading: sessionLoading } = useBase316();\n\n\tconst [resources, setResources] = useState<CustomerApiResource[]>([]);\n\tconst [credentials, setCredentials] = useState<ApiCredential[]>([]);\n\tconst [loading, setLoading] = useState(true);\n\tconst [busy, setBusy] = useState(false);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tconst [creating, setCreating] = useState(false);\n\tconst [name, setName] = useState(\"\");\n\tconst [chosen, setChosen] = useState<string[]>([]);\n\tconst [resourceId, setResourceId] = useState<string | null>(null);\n\t// Held only until dismissed: the secret exists here and nowhere else.\n\tconst [issued, setIssued] = useState<{ clientId: string; secret: string } | null>(null);\n\n\tconst load = useCallback(async () => {\n\t\tif (!token) {\n\t\t\tsetLoading(false);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst [available, held] = await Promise.all([\n\t\t\t\tclient.apiCredentials.resources(token),\n\t\t\t\tclient.apiCredentials.list(token),\n\t\t\t]);\n\n\t\t\tconst visible = audience\n\t\t\t\t? available.data.filter((resource) => resource.audience === audience)\n\t\t\t\t: available.data;\n\n\t\t\tsetResources(visible);\n\t\t\tsetCredentials(audience ? held.data.filter((item) => item.audience === audience) : held.data);\n\t\t\tsetResourceId((current) => current ?? visible[0]?.id ?? null);\n\t\t} catch (cause) {\n\t\t\tconsole.error(\"[base316] could not load API credentials\", cause);\n\t\t\tsetError(\"Could not load your API keys.\");\n\t\t} finally {\n\t\t\tsetLoading(false);\n\t\t}\n\t}, [client, token, audience]);\n\n\tuseEffect(() => {\n\t\tvoid load();\n\t}, [load]);\n\n\tif (sessionLoading || loading) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tLoading…\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (!token) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tSign in to manage your API keys.\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Before the empty state, which is otherwise what a failed load looks like:\n\t// \"There are no APIs available to your account\" is a claim, and the request\n\t// simply not arriving is not evidence for it.\n\tif (error) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (resources.length === 0) {\n\t\treturn (\n\t\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t\tThere are no APIs available to your account.\n\t\t\t</div>\n\t\t);\n\t}\n\n\tconst resource = resources.find((item) => item.id === resourceId) ?? resources[0]!;\n\n\tconst reset = () => {\n\t\tsetCreating(false);\n\t\tsetName(\"\");\n\t\tsetChosen([]);\n\t\tsetIssued(null);\n\t};\n\n\treturn (\n\t\t<div className={cls(\"b316-card\", className)} style={style}>\n\t\t\t{error ? (\n\t\t\t\t<div className=\"b316-error\" role=\"alert\">\n\t\t\t\t\t{error}\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{resources.length > 1 ? (\n\t\t\t\t<select\n\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\tvalue={resource.id}\n\t\t\t\t\tonChange={(event) => setResourceId(event.target.value)}\n\t\t\t\t\tstyle={{ marginBottom: 14 }}\n\t\t\t\t>\n\t\t\t\t\t{resources.map((item) => (\n\t\t\t\t\t\t<option key={item.id} value={item.id}>\n\t\t\t\t\t\t\t{item.name}\n\t\t\t\t\t\t</option>\n\t\t\t\t\t))}\n\t\t\t\t</select>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-plan-name\">{resource.name}</div>\n\t\t\t)}\n\n\t\t\t{resource.rateLimit ? (\n\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t{resource.rateLimit.requestsPerWindow} requests per{\" \"}\n\t\t\t\t\t{duration(resource.rateLimit.windowSeconds)}\n\t\t\t\t\t{resource.rateLimit.burst > resource.rateLimit.requestsPerWindow\n\t\t\t\t\t\t? `, bursting to ${resource.rateLimit.burst}`\n\t\t\t\t\t\t: null}\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div className=\"b316-muted\">No rate limit.</div>\n\t\t\t)}\n\n\t\t\t{/* --- What they hold --- */}\n\n\t\t\t{credentials.length === 0 ? (\n\t\t\t\t<p className=\"b316-muted\" style={{ marginTop: 14 }}>\n\t\t\t\t\tYou have no API keys yet.\n\t\t\t\t</p>\n\t\t\t) : (\n\t\t\t\t<ul className=\"b316-list\" style={{ marginTop: 14 }}>\n\t\t\t\t\t{credentials.map((credential) => (\n\t\t\t\t\t\t<li key={credential.clientId} className=\"b316-list-item\">\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t<div className=\"b316-plan-name\">{credential.name}</div>\n\t\t\t\t\t\t\t\t<div className=\"b316-muted\">\n\t\t\t\t\t\t\t\t\t<code>{credential.clientId}</code>\n\t\t\t\t\t\t\t\t\t{credential.secretLastFour ? ` · …${credential.secretLastFour}` : null}\n\t\t\t\t\t\t\t\t\t{credential.disabled ? \" · Disabled\" : null}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<div className=\"b316-muted\">{credential.scopes.join(\", \")}</div>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t<div style={{ display: \"flex\", gap: 8 }}>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tonClick={async () => {\n\t\t\t\t\t\t\t\t\t\tsetBusy(true);\n\t\t\t\t\t\t\t\t\t\tsetError(null);\n\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tconst rotated = await client.apiCredentials.rotate(\n\t\t\t\t\t\t\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t\t\t\t\t\t\tcredential.clientId,\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\t// Same client id, new secret — so the surface shows it\n\t\t\t\t\t\t\t\t\t\t\t// once, exactly as it does on creation.\n\t\t\t\t\t\t\t\t\t\t\tsetIssued({\n\t\t\t\t\t\t\t\t\t\t\t\tclientId: credential.clientId,\n\t\t\t\t\t\t\t\t\t\t\t\tsecret: rotated.issuedSecret,\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\tawait load();\n\t\t\t\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.error(\"[base316] rotate failed\", cause);\n\t\t\t\t\t\t\t\t\t\t\tsetError(\"Could not rotate that key.\");\n\t\t\t\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRotate\n\t\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t\t{/*\n\t\t\t\t\t\t\t\t * Irreversible, and the caller's integration stops as soon as\n\t\t\t\t\t\t\t\t * its current token expires. Worth one confirmation — asked in\n\t\t\t\t\t\t\t\t * the page, because `window.confirm` is suppressed in the\n\t\t\t\t\t\t\t\t * sandboxed iframe these are meant to be embedded in.\n\t\t\t\t\t\t\t\t */}\n\t\t\t\t\t\t\t\t<ConfirmButton\n\t\t\t\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={busy}\n\t\t\t\t\t\t\t\t\tconfirmLabel={`Revoke ${credential.name} for good`}\n\t\t\t\t\t\t\t\t\tonConfirm={async () => {\n\t\t\t\t\t\t\t\t\t\tsetBusy(true);\n\t\t\t\t\t\t\t\t\t\tsetError(null);\n\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tawait client.apiCredentials.revoke(token, credential.clientId);\n\t\t\t\t\t\t\t\t\t\t\tawait load();\n\t\t\t\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.error(\"[base316] revoke failed\", cause);\n\t\t\t\t\t\t\t\t\t\t\tsetError(\"Could not revoke that key.\");\n\t\t\t\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tRevoke\n\t\t\t\t\t\t\t\t</ConfirmButton>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t))}\n\t\t\t\t</ul>\n\t\t\t)}\n\n\t\t\t{/* --- The secret, shown once --- */}\n\n\t\t\t{issued ? (\n\t\t\t\t<div className=\"b316-notice\" style={{ marginTop: 14 }}>\n\t\t\t\t\t<strong>Copy this now.</strong> It is shown once and cannot be retrieved again.\n\t\t\t\t\t<div style={{ marginTop: 8 }}>\n\t\t\t\t\t\t<code style={{ wordBreak: \"break-all\" }}>{issued.secret}</code>\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tstyle={{ marginTop: 10 }}\n\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t// Clipboard access can be refused — an insecure origin, a denied\n\t\t\t\t\t\t\t// permission. The value is on screen either way, so a failure is\n\t\t\t\t\t\t\t// not worth interrupting for.\n\t\t\t\t\t\t\tvoid navigator.clipboard?.writeText(issued.secret).catch(() => {});\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tCopy\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tstyle={{ marginTop: 10, marginLeft: 8 }}\n\t\t\t\t\t\tonClick={reset}\n\t\t\t\t\t>\n\t\t\t\t\t\tDone\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{/* --- Issue a new one --- */}\n\n\t\t\t{creating && !issued ? (\n\t\t\t\t<div style={{ marginTop: 14 }}>\n\t\t\t\t\t<input\n\t\t\t\t\t\tclassName=\"b316-input\"\n\t\t\t\t\t\tplaceholder=\"What is this key for?\"\n\t\t\t\t\t\tvalue={name}\n\t\t\t\t\t\tonChange={(event) => setName(event.target.value)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div style={{ marginTop: 10 }}>\n\t\t\t\t\t\t{resource.availableScopes.map((scope) => (\n\t\t\t\t\t\t\t<label key={scope.key} className=\"b316-checkbox\">\n\t\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\t\t\t\t\tchecked={chosen.includes(scope.key)}\n\t\t\t\t\t\t\t\t\tonChange={(event) =>\n\t\t\t\t\t\t\t\t\t\tsetChosen((current) =>\n\t\t\t\t\t\t\t\t\t\t\tevent.target.checked\n\t\t\t\t\t\t\t\t\t\t\t\t? [...current, scope.key]\n\t\t\t\t\t\t\t\t\t\t\t\t: current.filter((key) => key !== scope.key),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<code>{scope.key}</code>\n\t\t\t\t\t\t\t\t{scope.description ? (\n\t\t\t\t\t\t\t\t\t<span className=\"b316-muted\"> — {scope.description}</span>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t{/* Shown rather than hidden: somebody who cannot see the capability\n\t\t\t\t\t\t cannot know an upgrade would give it to them. */}\n\t\t\t\t\t\t{resource.lockedScopes.map((scope) => (\n\t\t\t\t\t\t\t<label key={scope.key} className=\"b316-checkbox b316-muted\">\n\t\t\t\t\t\t\t\t<input type=\"checkbox\" disabled />\n\t\t\t\t\t\t\t\t<code>{scope.key}</code>\n\t\t\t\t\t\t\t\t<span> — not included in your plan</span>\n\t\t\t\t\t\t\t</label>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\t\tstyle={{ marginTop: 12 }}\n\t\t\t\t\t\tdisabled={busy || !name.trim() || chosen.length === 0}\n\t\t\t\t\t\tonClick={async () => {\n\t\t\t\t\t\t\tsetBusy(true);\n\t\t\t\t\t\t\tsetError(null);\n\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst created = await client.apiCredentials.create(token, {\n\t\t\t\t\t\t\t\t\tapiResourceId: resource.id,\n\t\t\t\t\t\t\t\t\tname: name.trim(),\n\t\t\t\t\t\t\t\t\tscopes: chosen,\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tif (created.issuedSecret) {\n\t\t\t\t\t\t\t\t\tsetIssued({ clientId: created.clientId, secret: created.issuedSecret });\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsetCreating(false);\n\t\t\t\t\t\t\t\tsetName(\"\");\n\t\t\t\t\t\t\t\tsetChosen([]);\n\t\t\t\t\t\t\t\tawait load();\n\t\t\t\t\t\t\t} catch (cause) {\n\t\t\t\t\t\t\t\t// The API names the scope a plan withholds, which is more\n\t\t\t\t\t\t\t\t// useful than anything generic written here.\n\t\t\t\t\t\t\t\tconst message =\n\t\t\t\t\t\t\t\t\tcause instanceof Error ? cause.message : \"Could not create that key.\";\n\n\t\t\t\t\t\t\t\tconsole.error(\"[base316] create failed\", cause);\n\t\t\t\t\t\t\t\tsetError(message);\n\t\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\t\tsetBusy(false);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\tCreate key\n\t\t\t\t\t</button>\n\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"b316-button b316-button-secondary\"\n\t\t\t\t\t\tstyle={{ marginTop: 12, marginLeft: 8 }}\n\t\t\t\t\t\tonClick={reset}\n\t\t\t\t\t>\n\t\t\t\t\t\tCancel\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t) : null}\n\n\t\t\t{!creating && !issued ? (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName=\"b316-button\"\n\t\t\t\t\tstyle={{ marginTop: 14 }}\n\t\t\t\t\tdisabled={resource.availableScopes.length === 0}\n\t\t\t\t\tonClick={() => setCreating(true)}\n\t\t\t\t>\n\t\t\t\t\t{resource.availableScopes.length === 0\n\t\t\t\t\t\t? \"No scopes available on your plan\"\n\t\t\t\t\t\t: \"New API key\"}\n\t\t\t\t</button>\n\t\t\t) : null}\n\t\t</div>\n\t);\n}\n","/**\n * What is in this package, described so that something assembling a page does\n * not have to guess.\n *\n * The audience is an agent building an application, and a drag-and-drop canvas\n * later. Both need the same four answers, and none of them can be had by\n * reading a type definition:\n *\n * 1. **What exists.** Otherwise a component gets invented, and the failure is a\n * build error nobody can act on.\n * 2. **What it needs before it works.** This is the big one. Almost everything\n * here renders nothing without a signed-in user — which looks like a broken\n * component rather than a missing precondition, and is the single most\n * expensive way to lose an hour with this package.\n * 3. **Which sibling to reach for.** A table, a board and a chart all bind to a\n * collection and answer different questions.\n * 4. **What the props actually are.** Not their types — TypeScript has those —\n * but what they mean and what happens when they are left out.\n *\n * Every component here takes no required props. That is a rule rather than a\n * coincidence: a thing that cannot be dropped in as `<Thing />` is a thing an\n * agent has to be taught, and the whole point is that it does not.\n *\n * **This file drifts if nobody stops it**, so `manifest.test.ts` fails when an\n * export is added or removed without a matching entry. A manifest that lies is\n * worse than no manifest, because both an agent and a person will believe it.\n */\n\n/**\n * What must already be true, or the component renders nothing useful.\n *\n * Ordered by how often each one is the answer to \"why is this blank\".\n */\nexport type Requirement =\n\t/** A signed-in end user. Without one, most of these render nothing at all. */\n\t| \"session\"\n\t/** A collection defined in this environment, named by the `collection` prop. */\n\t| \"collection\"\n\t/** At least one published plan in the catalog. */\n\t| \"plans\"\n\t/** A connected payment account, or checkout refuses before a card is asked for. */\n\t| \"paymentAccount\"\n\t/** An API resource defined, so there are credentials to manage. */\n\t| \"apiResource\";\n\nexport interface PropEntry {\n\tname: string;\n\t/** What it does, and what happens without it. */\n\tsummary: string;\n\t/** True for none of them, by design. Present so the rule is machine-checkable. */\n\trequired: boolean;\n}\n\nexport interface ManifestEntry {\n\tname: string;\n\tkind: \"component\" | \"hook\" | \"provider\";\n\t/** One line: what this is. */\n\tsummary: string;\n\t/** When to reach for this one rather than a sibling. */\n\tuseWhen: string;\n\trequires: Requirement[];\n\t/** Parameterised by a collection defined at runtime. */\n\tbindsToCollection?: boolean;\n\tprops: PropEntry[];\n\t/** What appears when a requirement is not met. The answer to \"why is it blank\". */\n\twhenUnmet?: string;\n\tseeAlso?: string[];\n}\n\nconst appearance: PropEntry[] = [\n\t{ name: \"className\", summary: \"Your own classes on the wrapper.\", required: false },\n\t{ name: \"style\", summary: \"Inline styles on the wrapper.\", required: false },\n];\n\nexport const MANIFEST: ManifestEntry[] = [\n\t// --- Setup ---------------------------------------------------------------\n\t{\n\t\tname: \"Base316Provider\",\n\t\tkind: \"provider\",\n\t\tsummary: \"Holds the client, the session and the theme. Everything else must be inside it.\",\n\t\tuseWhen: \"Once, around the part of the application that uses any other export here.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"publishableKey\", summary: \"The environment's publishable key.\", required: true },\n\t\t\t{ name: \"baseUrl\", summary: \"Where the API lives. Defaults to production.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"token\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Supply to own session storage yourself. Left out, the session is kept in localStorage.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onTokenChange\",\n\t\t\t\tsummary: \"Called when the session changes. Pair with `token` for an httpOnly cookie.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"appearance\",\n\t\t\t\tsummary: \"Colours, radius and font as tokens. Restyles everything at once.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"tenant\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"White-label everything inside for one tenant — `{ organizationId }` or `{ organizationExternalId }`. A firm's name, logo and colours on the screens it runs its clients on; its own branding, then its parent's, then the environment's. Change it when the user switches team.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"useBase316\", \"useSession\"],\n\t},\n\t{\n\t\tname: \"useBase316\",\n\t\tkind: \"hook\",\n\t\tsummary: \"The client, the session token and the branding, from inside the provider.\",\n\t\tuseWhen: \"Writing a component of your own that needs to call the API directly.\",\n\t\trequires: [],\n\t\tprops: [],\n\t\tseeAlso: [\"Base316Provider\"],\n\t},\n\t{\n\t\tname: \"useSession\",\n\t\tkind: \"hook\",\n\t\tsummary:\n\t\t\t\"The resolved session, or null. Carries `userId`, `user` (id, email, name, image, and the customer's own declared fields) and `tenants` — every team this person is in, each with their role.\",\n\t\tuseWhen: \"Deciding what to render for a signed-in versus a signed-out visitor.\",\n\t\trequires: [],\n\t\tprops: [],\n\t},\n\n\t// --- Signing in ----------------------------------------------------------\n\t{\n\t\tname: \"SignIn\",\n\t\tkind: \"component\",\n\t\tsummary: \"Password, passkey, magic-link and text-message sign-in in one form.\",\n\t\tuseWhen: \"The application renders its own sign-in rather than redirecting to the hosted page.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"onSignedIn\", summary: \"Called once a session exists.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"passkeys\",\n\t\t\t\tsummary: \"Offer passkeys where supported. On by default.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"magicLinkRedirectUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Where an emailed link lands, which must be registered on the environment. Without it, magic link is not offered at all.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"phone\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"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.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"secondFactorLabels\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"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.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"SignUp\", \"ForgotPassword\", \"SecondFactorStep\"],\n\t},\n\t{\n\t\tname: \"SignUp\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"Create an account with an email and a password, showing the environment's password rules, then sign in — through the second-factor step when one is owed or must be enrolled.\",\n\t\tuseWhen: \"Alongside SignIn, on a page that registers new users.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"onSignedUp\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called once the account is created and signed in, or created and waiting on email confirmation.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"invitationToken\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The invitation this sign-up accepts; read from `?invitation=` when omitted, `null` to ignore the URL. The account joins the inviting team instead of getting a personal workspace, and its address counts as verified.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onJoined\",\n\t\t\t\tsummary: \"Called with the team's organizationId when the sign-up accepted an invitation.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"labels\", summary: \"Wording for the form, for translation.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"secondFactorLabels\",\n\t\t\t\tsummary: \"Wording for the second-factor step, for translation.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"SignIn\", \"VerifyEmail\", \"SecondFactorStep\"],\n\t},\n\t{\n\t\tname: \"SecondFactorStep\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The second half of a sign-in that returned `mfaRequired`: a code box for an existing factor, or — when the environment requires a factor and the user has none — choosing an authenticator app (QR code and key), an emailed code or a text, confirming it, and showing the recovery codes once.\",\n\t\tuseWhen:\n\t\t\t\"Your own first step (a custom form, a magic-link landing) got a `SignInPending` back. SignIn and SignUp already include it.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"pending\",\n\t\t\t\tsummary: \"The `SignInPending` from signIn, magicLink.verify or phone.verify.\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onSignedIn\",\n\t\t\t\tsummary: \"Called once the session is handed to the provider.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onRestart\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Back to the start, for a challenge that expired or ran out of attempts. Without it no Start over button is drawn.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"labels\",\n\t\t\t\tsummary: \"Wording, for translation. English when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"SignIn\", \"TwoFactorManager\"],\n\t},\n\t{\n\t\tname: \"ForgotPassword\",\n\t\tkind: \"component\",\n\t\tsummary: \"Ask for a reset link by email.\",\n\t\tuseWhen: \"Linked from a sign-in form.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"onSent\", summary: \"Called with the address after the request.\", required: false },\n\t\t\t{ name: \"signInUrl\", summary: \"Renders a link back to sign-in.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"ResetPassword\"],\n\t},\n\t{\n\t\tname: \"ResetPassword\",\n\t\tkind: \"component\",\n\t\tsummary: \"Set a new password from an emailed link.\",\n\t\tuseWhen: \"On the page the reset link lands on.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"token\",\n\t\t\t\tsummary: \"Read from `?token=` when omitted, and removed from the URL.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onReset\", summary: \"Called once the password is changed.\", required: false },\n\t\t\t{ name: \"signInUrl\", summary: \"Renders a link onward to sign-in.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"With no token in the URL or props, explains that the link is needed.\",\n\t\tseeAlso: [\"ForgotPassword\"],\n\t},\n\t{\n\t\tname: \"VerifyEmail\",\n\t\tkind: \"component\",\n\t\tsummary: \"Confirm an address from an emailed link.\",\n\t\tuseWhen: \"On the page the verification link lands on.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"token\",\n\t\t\t\tsummary: \"Read from `?token=` when omitted, and removed from the URL.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onVerified\", summary: \"Called once confirmed.\", required: false },\n\t\t\t{ name: \"continueUrl\", summary: \"Renders a link onward.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"SignUp\"],\n\t},\n\n\t// --- The account ---------------------------------------------------------\n\t{\n\t\tname: \"UserProfile\",\n\t\tkind: \"component\",\n\t\tsummary: \"Name, email and the customer's own declared fields.\",\n\t\tuseWhen: \"An account settings page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"ActiveSessions\", \"TwoFactorManager\", \"PasskeyManager\"],\n\t},\n\t{\n\t\tname: \"ActiveSessions\",\n\t\tkind: \"component\",\n\t\tsummary: \"Where the account is signed in, and a button to end the other devices.\",\n\t\tuseWhen: \"A security settings page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{ name: \"onRevoked\", summary: \"Called with the number of sessions ended.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"TwoFactorManager\"],\n\t},\n\t{\n\t\tname: \"DeviceApproval\",\n\t\tkind: \"component\",\n\t\tsummary: \"Approve a sign-in that started on a CLI, a TV, or anything with no browser.\",\n\t\tuseWhen:\n\t\t\t\"You point a device's verification URI at a page in your own app. Put this on that page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"userCode\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The code, when the URL already carries it. Skips the entry step; without it the person types the code.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onDecided\", summary: \"Called with whether they approved.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Renders nothing without a session — there is nobody to approve as, and collecting a code first would fail at the step that matters.\",\n\t\tseeAlso: [\"SignIn\", \"ActiveSessions\"],\n\t},\n\t{\n\t\tname: \"PrivacyControls\",\n\t\tkind: \"component\",\n\t\tsummary: \"Download a copy of everything held about you, or delete your account.\",\n\t\tuseWhen:\n\t\t\t\"An account settings page. These are the two things a privacy notice promises and most products never build.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"confirmWord\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"What must be typed to confirm deletion. Defaults to the English word, which is wrong in every other language.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onErased\",\n\t\t\t\tsummary: \"Called once the account is gone. Sign them out and send them somewhere.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"UserProfile\", \"ActiveSessions\"],\n\t},\n\t{\n\t\tname: \"TwoFactorManager\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"Turn two-factor authentication on or off, by authenticator app (QR code and key), a code to the inbox or a code by text message.\",\n\t\tuseWhen:\n\t\t\t\"A security settings page. The app is strongest; the emailed or texted code is the one people who will not install an app actually use.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"enabled\",\n\t\t\t\tsummary: \"Whether a factor already exists, which decides which side is shown.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"allowSms\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Offer a code by text message. Off by default: it only works once the environment can send one.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onEnabled\", summary: \"Called once a factor is confirmed.\", required: false },\n\t\t\t{ name: \"onDisabled\", summary: \"Called once it is removed.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"ActiveSessions\", \"PasskeyManager\"],\n\t},\n\t{\n\t\tname: \"PasskeyManager\",\n\t\tkind: \"component\",\n\t\tsummary: \"Add and remove passkeys.\",\n\t\tuseWhen: \"A security settings page, beside two-factor.\",\n\t\trequires: [\"session\"],\n\t\tprops: [{ name: \"title\", summary: \"Heading text.\", required: false }, ...appearance],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"TwoFactorManager\"],\n\t},\n\t{\n\t\tname: \"Branding\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The logo, name and tagline — the environment's, or the tenant's when the provider is given a `tenant`.\",\n\t\tuseWhen: \"Above a sign-in form, so your pages match the hosted ones.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"showTagline\", summary: \"Include the tagline under the name.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t},\n\n\t// --- Teams ---------------------------------------------------------------\n\t{\n\t\tname: \"TeamMembers\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"Who is in a team, who has been invited, and the way in and out. A team reached only through the organization that manages it says so, and offers nothing to leave.\",\n\t\tuseWhen:\n\t\t\t\"A Team or Members settings page. One component covers the list, the pending invitations, the invite box and leaving.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"organizationId\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Which team. Defaults to the only one this person is in; with several it says so rather than guessing.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onInvited\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called with `{ email, token, url }` — the address invited, the raw token, and the accept URL when `acceptUrl` was given. This is where your application sends the email. Without a handler the link is shown on screen instead, because the token is returned once and cannot be fetched again.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"acceptUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The page hosting AcceptInvitation. The component appends `?invitation=<token>` and hands the finished link back as `url` on onInvited; without it, onInvited gets the raw token and you build the link yourself.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onLeft\", summary: \"Called after the viewer leaves the team.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Renders nothing without a session. Inviting and removing appear only for somebody whose role grants team.manage, and are refused for a role granting anything the viewer does not hold. Addresses are shown only to such a viewer.\",\n\t\tseeAlso: [\"AcceptInvitation\"],\n\t},\n\t{\n\t\tname: \"AcceptInvitation\",\n\t\tkind: \"component\",\n\t\tsummary: \"The other end of an invitation: what it is for, and joining.\",\n\t\tuseWhen: \"On the page an invitation link lands on.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"token\",\n\t\t\t\tsummary: \"Read from `?invitation=` when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onAccepted\",\n\t\t\t\tsummary: \"Called with the organizationId once they have joined.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"signUpUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"For somebody with no account yet: a page with SignUp. The link carries `?invitation=`, so the account is created inside this team without a personal workspace.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"signInUrl\", summary: \"For somebody who has one.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Says what the invitation is for without a session, since the point is that they may have no account. Names the address to sign in as when the signed-in one does not match.\",\n\t\tseeAlso: [\"TeamMembers\", \"SignUp\"],\n\t},\n\n\t// --- Money ---------------------------------------------------------------\n\t{\n\t\tname: \"PricingTable\",\n\t\tkind: \"component\",\n\t\tsummary: \"The published plans, and completing the purchase.\",\n\t\tuseWhen: \"A pricing page, or an upgrade screen.\",\n\t\trequires: [\"plans\", \"paymentAccount\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"onSelectPlan\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Take over what Choose does. Left out, the component changes the plan or starts a checkout itself.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"currentPlanVersionId\",\n\t\t\t\tsummary: \"Marks the current plan. Discovered from the session when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"featuredPlanKey\",\n\t\t\t\tsummary: \"Which plan to present as the default.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"signInUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Where a signed-out visitor goes on choosing. Without it the button says so rather than failing.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Says plans are unavailable when the catalog is empty.\",\n\t\tseeAlso: [\"SubscriptionManager\", \"usePlans\"],\n\t},\n\t{\n\t\tname: \"usePlans\",\n\t\tkind: \"hook\",\n\t\tsummary: \"The plans, the current one, and the prorate-or-checkout branch — without markup.\",\n\t\tuseWhen: \"You want your own pricing table but not your own billing logic.\",\n\t\trequires: [\"plans\"],\n\t\tprops: [],\n\t\tseeAlso: [\"PricingTable\"],\n\t},\n\t{\n\t\tname: \"SubscriptionManager\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The current plan, its renewal date, a scheduled plan change with its undo, cancelling at the period end — asking why, and showing the environment's retention offer when it makes one — and resuming a cancelled one.\",\n\t\tuseWhen: \"A billing settings page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"onChange\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called after a cancel, a resume or an undone plan change, so a sibling showing the same subscription can refresh.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"BillingPortal\", \"PricingTable\", \"Invoices\"],\n\t},\n\t{\n\t\tname: \"Invoices\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The signed-in user's invoices, newest first: view one, download its PDF, and pay one that is still open on the hosted pay page.\",\n\t\tuseWhen: \"A billing settings page.\",\n\t\trequires: [\"session\"],\n\t\tprops: [...appearance],\n\t\twhenUnmet: \"Renders nothing without a session.\",\n\t\tseeAlso: [\"BillingPortal\", \"SubscriptionManager\", \"UpcomingInvoice\"],\n\t},\n\t{\n\t\tname: \"BillingPortal\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"A whole billing page for the signed-in user: plan and status, next invoice, scheduled change with undo, plan change with a review step, seats, credit balances with auto-recharge, saved cards, invoices with PDFs and pay, cancel and resume, and a Billing details slot.\",\n\t\tuseWhen:\n\t\t\t\"You want a complete self-service billing screen inside your own application. For a page you do not host at all, mint a hosted billing portal session from your server instead (`billingPortal.createSession`). For a different layout, compose the pieces it is made of.\",\n\t\trequires: [\"session\", \"plans\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"returnUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Where the browser comes back to after updating the card on Stripe's page. Must be an environment redirect URI. The current page when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"featuredPlanKey\",\n\t\t\t\tsummary: \"The plan to present as the default choice in the plan picker.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"unitLabel\",\n\t\t\t\tsummary: 'What a seat is called, plural. \"seats\" by default.',\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"billingDetails\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Your own Billing details section (address, tax IDs). By default it is BillingDetailsForm — the address and tax IDs, EU VAT numbers checked with VIES; pass null to leave it out.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session. With no subscription it offers the plans through checkout. A managed tenant sees the firm's plan read-only and its own invoices.\",\n\t\tseeAlso: [\n\t\t\t\"SubscriptionManager\",\n\t\t\t\"UpcomingInvoice\",\n\t\t\t\"PlanChangeReview\",\n\t\t\t\"SeatManager\",\n\t\t\t\"CreditBalances\",\n\t\t\t\"PaymentMethod\",\n\t\t\t\"Invoices\",\n\t\t],\n\t},\n\t{\n\t\tname: \"CreditBalances\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The signed-in user's credit balances: what is left of each metered feature sold in packs, buying a pack now, and auto-recharge (threshold, pack, monthly maximum).\",\n\t\tuseWhen:\n\t\t\t\"A billing or usage page in a product that sells credit packs. `BillingPortal` includes it. Buying goes to the hosted pay page; auto-recharge charges the card on file.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{ name: \"onChange\", summary: \"Called after auto-recharge is saved.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Renders nothing without a session or when no credit packs are on sale. A managed tenant sees the balance it spends, read-only.\",\n\t\tseeAlso: [\"BillingPortal\", \"PaymentMethod\"],\n\t},\n\t{\n\t\tname: \"PlanChangeReview\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The review step before a plan change: features gained and lost, the prorated credit and charge or the date it waits for, then confirm.\",\n\t\tuseWhen:\n\t\t\t\"Your own plan picker, between choosing a plan and changing to it. `BillingPortal` opens it when a subscriber picks a plan.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"planVersionId\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The plan version to move to — a PublicPlan's planVersionId. Required in practice.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onDone\", summary: \"Called once the change is made or scheduled.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"onCancel\",\n\t\t\t\tsummary: \"Called when the user keeps their plan. Without it there is no back button.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onNeedsCard\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called when a change now needs a card the account lacks. Without it the review starts a card update itself.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Says the change is not available when the plan cannot be moved to, and that the plan is provided by their organization for a managed tenant.\",\n\t\tseeAlso: [\"BillingPortal\", \"PricingTable\", \"usePlans\"],\n\t},\n\t{\n\t\tname: \"PaymentMethod\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The card the signed-in user's invoices are charged against, a button that replaces it on a Stripe-hosted page, and their other saved cards to make default or remove.\",\n\t\tuseWhen:\n\t\t\t\"A billing page. The card is entered on Stripe's page on your connected account, never in your page or Base316, so it adds nothing to your PCI scope.\",\n\t\trequires: [\"session\", \"paymentAccount\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"returnUrl\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Where the browser comes back to once the card is stored. Must be an environment redirect URI. The current page when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session; says cards cannot be updated when the environment has no connected payment account; says the plan is paid for by their organization for a managed tenant.\",\n\t\tseeAlso: [\"BillingPortal\", \"Invoices\"],\n\t},\n\t{\n\t\tname: \"UpcomingInvoice\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The signed-in user's next bill: when it is issued, its lines, discount, tax, wallet balance and the amount due.\",\n\t\tuseWhen:\n\t\t\t\"A billing or account page that answers 'what will I be charged next'. Computed on request and stored nowhere, so it is safe to show on every visit.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"showLines\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Show the breakdown. Off gives one line: the amount due and the date. On by default.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session; says there is no upcoming invoice when nothing will bill them; says the plan is provided by their organization for a managed tenant.\",\n\t\tseeAlso: [\"Invoices\", \"SubscriptionManager\"],\n\t},\n\t{\n\t\tname: \"BillingDetailsForm\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"The signed-in user's billing address and tax ids, with EU VAT numbers checked against VIES as they are saved.\",\n\t\tuseWhen:\n\t\t\t\"A billing or account page where a business customer enters the address its invoices are made out to and its VAT, GST or similar number. Saved against the session's own account only.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"taxIdTypes\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"The tax id types to offer, as Stripe type names with a label and example. Defaults to the EU, UK, Switzerland, Norway, Australia, New Zealand, Canada, India and the US.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onSave\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called after a save, with the details as stored — each tax id with its check result.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session; says there is no billing account when the user has none; says billing is managed by their organization for a managed tenant, and offers nothing to change.\",\n\t\tseeAlso: [\"Invoices\", \"UpcomingInvoice\", \"SubscriptionManager\"],\n\t},\n\t{\n\t\tname: \"SeatManager\",\n\t\tkind: \"component\",\n\t\tsummary:\n\t\t\t\"Change how many seats the signed-in user's subscription is for, with the prorated price previewed before anything is charged.\",\n\t\tuseWhen:\n\t\t\t\"A billing or team page on a plan sold per seat. Adding seats is charged now for the rest of the period; removing them takes effect at the period end with no refund. The user picks only the number.\",\n\t\trequires: [\"session\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"unitLabel\",\n\t\t\t\tsummary: 'What a unit is called, plural. \"seats\" by default.',\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"onChange\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called after a change is made, with what it did (amount, invoice, when it applies).\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Asks the user to sign in without a session; says there is no plan when they have no subscription; says the plan is provided by their organization for a managed tenant, and offers no change.\",\n\t\tseeAlso: [\"SubscriptionManager\", \"UpcomingInvoice\", \"TeamMembers\"],\n\t},\n\t{\n\t\tname: \"PayInvoice\",\n\t\tkind: \"component\",\n\t\tsummary: \"Pay one invoice from a link, with no account needed.\",\n\t\tuseWhen: \"A page reached from a payment link or a QR code — a walk-up customer.\",\n\t\trequires: [\"paymentAccount\"],\n\t\tprops: [\n\t\t\t{ name: \"token\", summary: \"The link token, from the URL.\", required: false },\n\t\t\t{ name: \"environmentId\", summary: \"Which environment the link belongs to.\", required: false },\n\t\t\t{ name: \"onPaid\", summary: \"Called once payment succeeds.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"usePaymentLink\"],\n\t},\n\t{\n\t\tname: \"usePaymentLink\",\n\t\tkind: \"hook\",\n\t\tsummary: \"Watches a payment link and reports when it is paid.\",\n\t\tuseWhen: \"Showing your own waiting screen beside a QR code.\",\n\t\trequires: [],\n\t\tprops: [],\n\t\tseeAlso: [\"PayInvoice\"],\n\t},\n\t{\n\t\tname: \"ApiKeyManager\",\n\t\tkind: \"component\",\n\t\tsummary: \"A customer managing their own API credentials and seeing their rate limits.\",\n\t\tuseWhen: \"A developer-settings page inside your application.\",\n\t\trequires: [\"session\", \"apiResource\"],\n\t\tprops: [\n\t\t\t{\n\t\t\t\tname: \"audience\",\n\t\t\t\tsummary: \"Limit to one protected API. All of them when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Renders nothing without a session; says so when no API resource is defined.\",\n\t},\n\n\t// --- The application's own data ------------------------------------------\n\t{\n\t\tname: \"DataTable\",\n\t\tkind: \"component\",\n\t\tsummary: \"A table of a collection's records, with columns derived from its fields.\",\n\t\tuseWhen:\n\t\t\t\"Listing records. Reach for Kanban instead to group them by a status, or Chart to count or total them over time.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"columns\",\n\t\t\t\tsummary: \"Which fields to show, in order. Every field when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"renderCell\", summary: \"Replace the cell for one field.\", required: false },\n\t\t\t{ name: \"onSelect\", summary: \"Row click. Rows are inert without it.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"onChanged\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called after this table creates, edits or deletes a record. The table refreshes itself; use this to refresh anything else on the page bound to the same collection, such as a Chart.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"hideSearch\", summary: \"Hide the search box.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"readOnly\",\n\t\t\t\tsummary: \"Hide New, Edit and Delete even for a writer.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"emptyState\", summary: \"Shown when there is nothing to list.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"Without the read permission it says which permission is missing, rather than showing an empty table.\",\n\t\tseeAlso: [\"Kanban\", \"Chart\", \"RecordDetail\", \"RecordForm\", \"useCollection\"],\n\t},\n\t{\n\t\tname: \"Kanban\",\n\t\tkind: \"component\",\n\t\tsummary: \"A board, grouped by a choice field it finds on its own.\",\n\t\tuseWhen: \"The records move through stages — a status, a pipeline.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"groupBy\",\n\t\t\t\tsummary: \"Which field makes the columns. Discovered when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"cardFields\", summary: \"What to show on a card.\", required: false },\n\t\t\t{ name: \"onSelect\", summary: \"Card click.\", required: false },\n\t\t\t{ name: \"emptyState\", summary: \"Shown in a column with nothing in it.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"A collection with no groupable field says to add a choice field, rather than drawing one column.\",\n\t\tseeAlso: [\"DataTable\", \"Chart\"],\n\t},\n\t{\n\t\tname: \"Chart\",\n\t\tkind: \"component\",\n\t\tsummary: \"Records over time, counted or totalled.\",\n\t\tuseWhen: \"The question is how many or how much, by day, week or month.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{ name: \"x\", summary: \"The date field. Discovered when omitted.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"y\",\n\t\t\t\tsummary: \"What to measure. Counts the records when omitted.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"aggregate\", summary: \"sum, avg, min or max. Defaults to sum.\", required: false },\n\t\t\t{ name: \"bucket\", summary: \"day, week or month. Defaults to day.\", required: false },\n\t\t\t{ name: \"title\", summary: \"Overrides the derived caption.\", required: false },\n\t\t\t{ name: \"height\", summary: \"Plot height in pixels.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet:\n\t\t\t\"A collection with no date field says so. A field that cannot be summed is refused rather than quietly counted.\",\n\t\tseeAlso: [\"DataTable\", \"Kanban\"],\n\t},\n\t{\n\t\tname: \"RecordDetail\",\n\t\tkind: \"component\",\n\t\tsummary: \"One record in full, including the fields a table truncates.\",\n\t\tuseWhen: \"After a row or card is clicked.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{ name: \"recordId\", summary: \"Which record. Required in practice.\", required: false },\n\t\t\t{ name: \"tenant\", summary: \"Only when the user is in several.\", required: false },\n\t\t\t{ name: \"readOnly\", summary: \"Hide Edit and Delete.\", required: false },\n\t\t\t{ name: \"onDeleted\", summary: \"Called after deletion.\", required: false },\n\t\t\t{ name: \"onClose\", summary: \"Renders a Close button when given.\", required: false },\n\t\t\t{ name: \"children\", summary: \"Rendered under the fields.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\tseeAlso: [\"DataTable\", \"RecordForm\"],\n\t},\n\t{\n\t\tname: \"RecordForm\",\n\t\tkind: \"component\",\n\t\tsummary: \"Create or edit a record, with inputs derived from the field types.\",\n\t\tuseWhen: \"Adding a record, or editing one outside the detail view.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [\n\t\t\t{ name: \"collection\", summary: \"The collection key. Required in practice.\", required: false },\n\t\t\t{ name: \"recordId\", summary: \"Omit to create, supply to edit.\", required: false },\n\t\t\t{ name: \"tenant\", summary: \"Only when the user is in several.\", required: false },\n\t\t\t{\n\t\t\t\tname: \"onSaved\",\n\t\t\t\tsummary:\n\t\t\t\t\t\"Called with the record id. Does not refresh a sibling table — see the composition rules.\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t\t{ name: \"onCancel\", summary: \"Renders a Cancel button when given.\", required: false },\n\t\t\t{ name: \"defaults\", summary: \"Values to start with. Ignored when editing.\", required: false },\n\t\t\t...appearance,\n\t\t],\n\t\twhenUnmet: \"Computed fields get no input at all, because the server produces them.\",\n\t\tseeAlso: [\"RecordDetail\", \"RelationPicker\"],\n\t},\n\t{\n\t\tname: \"RelationPicker\",\n\t\tkind: \"component\",\n\t\tsummary: \"Choose a record in another collection by typing its name.\",\n\t\tuseWhen: \"Building your own form. RecordForm uses this for relation fields already.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tprops: [\n\t\t\t{ name: \"field\", summary: \"The relation field descriptor.\", required: true },\n\t\t\t{ name: \"value\", summary: \"The chosen record id, or null.\", required: true },\n\t\t\t{ name: \"onChange\", summary: \"Called with the new id.\", required: true },\n\t\t\t{ name: \"error\", summary: \"Message shown under the input.\", required: false },\n\t\t\t{ name: \"disabled\", summary: \"Read-only.\", required: false },\n\t\t\t{ name: \"tenant\", summary: \"Only when the user is in several.\", required: false },\n\t\t],\n\t\tseeAlso: [\"RecordForm\"],\n\t},\n\t{\n\t\tname: \"useCollection\",\n\t\tkind: \"hook\",\n\t\tsummary:\n\t\t\t\"A collection's schema, records, filters, paging, permissions and writes — without markup.\",\n\t\tuseWhen: \"You want your own table, board or form but not your own data layer.\",\n\t\trequires: [\"session\", \"collection\"],\n\t\tbindsToCollection: true,\n\t\tprops: [],\n\t\tseeAlso: [\"DataTable\", \"FieldCell\", \"FieldInput\"],\n\t},\n\t{\n\t\tname: \"FieldCell\",\n\t\tkind: \"component\",\n\t\tsummary: \"One field value, rendered the way the tables render it.\",\n\t\tuseWhen: \"Building your own table over useCollection.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"value\", summary: \"The stored value.\", required: true },\n\t\t\t{ name: \"field\", summary: \"The field descriptor.\", required: true },\n\t\t\t{ name: \"related\", summary: \"A relation's resolved label.\", required: false },\n\t\t],\n\t\tseeAlso: [\"FieldInput\", \"useCollection\"],\n\t},\n\t{\n\t\tname: \"FieldInput\",\n\t\tkind: \"component\",\n\t\tsummary: \"The input for one field, chosen by its type.\",\n\t\tuseWhen: \"Building your own form over useCollection.\",\n\t\trequires: [],\n\t\tprops: [\n\t\t\t{ name: \"value\", summary: \"The current value.\", required: true },\n\t\t\t{ name: \"field\", summary: \"The field descriptor.\", required: true },\n\t\t\t{ name: \"onChange\", summary: \"Called with the new value.\", required: true },\n\t\t\t{ name: \"error\", summary: \"Message shown under the input.\", required: false },\n\t\t\t{ name: \"disabled\", summary: \"Read-only.\", required: false },\n\t\t],\n\t\twhenUnmet: \"Renders nothing for a computed field — the server produces those.\",\n\t\tseeAlso: [\"FieldCell\", \"RecordForm\"],\n\t},\n];\n\n/**\n * How the pieces go together.\n *\n * Listed separately from the entries because it is not a fact about any one of\n * them, and it is the thing most often got wrong: a component dropped outside\n * the provider throws, and one dropped on a page with no signed-in user renders\n * nothing and reads as broken. Neither is discoverable from a prop list.\n */\nexport const COMPOSITION = {\n\trules: [\n\t\t\"Everything must be inside Base316Provider. Outside it, hooks throw.\",\n\t\t\"Most components need a signed-in user. Gate on useSession and render SignIn when there is none — see `requires: session` on each entry.\",\n\t\t\"A collection must exist before anything can bind to it. Define one in the dashboard under Collections, or through POST /v1/collections with a secret key.\",\n\t\t\"No component takes a prop you must supply to make it behave. Naming the subject is different: a collection component needs `collection` and a detail view needs `recordId`, because those say *what* to show rather than patch *how* it works. Everything else has a default.\",\n\t\t\"Each component bound to a collection holds its own data — DataTable, Kanban, Chart, RecordForm, RecordDetail, every one. None of them share a cache, so a write in one leaves the others showing what they already had. Put the form inside the table, where New and Edit refresh it; pass `onChanged` to refresh a sibling such as a Chart; or lift `useCollection` and render your own, which is what the hook is for.\",\n\t\t\"Next.js App Router: put Base316Provider in a Client Component wrapper used by the root layout. Every component here is a Client Component; none of them run on the server.\",\n\t],\n\t/** The shape almost every application ends up with. */\n\texample: `\nimport { Base316Provider, DataTable, RecordForm, SignIn, useSession } from \"@base316/react\";\n\nfunction Jobs() {\n const session = useSession();\n\n // Without this the table renders nothing and looks broken.\n if (!session) return <SignIn />;\n\n return (\n <>\n <DataTable collection=\"jobs\" onSelect={(record) => console.log(record.id)} />\n <RecordForm collection=\"jobs\" />\n </>\n );\n}\n\nexport function App() {\n return (\n <Base316Provider publishableKey={process.env.NEXT_PUBLIC_BASE316_PUBLISHABLE_KEY!}>\n <Jobs />\n </Base316Provider>\n );\n}\n`.trim(),\n} as const;\n\n/** Look one up by name. */\nexport function describeComponent(name: string): ManifestEntry | undefined {\n\treturn MANIFEST.find((entry) => entry.name === name);\n}\n\n/** Everything that needs a particular precondition — the \"why is this blank\" list. */\nexport function componentsRequiring(requirement: Requirement): ManifestEntry[] {\n\treturn MANIFEST.filter((entry) => entry.requires.includes(requirement));\n}\n"],"mappings":"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","names":["appearance","appearance","jsx","useCallback","useEffect","useState","jsx","jsxs","useState","useEffect","useCallback","useEffect","useState","jsx","jsxs","money","day","useState","useEffect","invoice","status","useCallback","useEffect","useState","Fragment","jsx","jsxs","money","day","useState","useCallback","useEffect","useCallback","useEffect","useState","jsx","jsxs","statusOf","useState","useCallback","details","status","useEffect","Base316Error","useEffect","useRef","useState","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","Fragment","jsx","jsxs","useState","useRef","Base316Error","useEffect","Base316Error","needsSecondFactor","useEffect","useState","jsx","jsxs","useState","useEffect","loaded","Base316Error","needsSecondFactor","jsx","jsxs","isPasskeySupported","useCallback","useEffect","useState","useEffect","useRef","useState","jsx","jsxs","jsx","jsxs","useState","useCallback","useEffect","isPasskeySupported","useCallback","useEffect","useState","jsx","jsxs","useState","useCallback","useEffect","useState","jsx","jsxs","useState","useState","jsx","jsxs","useState","useState","useMemo","jsx","jsxs","jsx","jsxs","useState","useState","jsx","jsxs","useState","useEffect","useState","jsx","jsxs","useState","useEffect","useEffect","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","useEffect","useState","Fragment","jsx","jsxs","useState","useCallback","useEffect","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","useEffect","useRef","useState","jsx","jsxs","useRef","useState","useEffect","useEffect","useRef","useState","status","useState","useRef","useEffect","useState","useCallback","useEffect","useState","useState","useEffect","useCallback","status","jsx","jsxs","useState","specFor","useState","jsx","jsxs","specFor","useEffect","useState","useEffect","useRef","useState","Fragment","jsx","jsxs","useState","useRef","useEffect","useCallback","useEffect","useMemo","useState","useState","useMemo","useEffect","useCallback","jsx","jsxs","useState","useEffect","specFor","jsx","jsxs","useState","specFor","specFor","useState","jsx","jsxs","useState","specFor","specFor","useMemo","jsx","jsxs","useMemo","specFor","specFor","useState","jsx","jsxs","useState","specFor","useCallback","useEffect","useState","jsx","jsxs","status","useState","useCallback","useEffect","useCallback","useEffect","useState","useEffect","useState","Fragment","jsx","jsxs","money","useState","useEffect","credits","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","useCallback","useEffect","useState","Fragment","jsx","jsxs","money","day","statusOf","useState","useEffect","useCallback","Fragment","jsx","jsxs","useState","useEffect","useCallback","useCallback","useEffect","useState","jsx","jsxs","useState","useCallback","resource","useEffect"]}