@usethrottle/auth 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -44,7 +44,7 @@ type ThrottleVariables = Partial<Record<keyof typeof VARIABLE_PROPERTY, string>>
44
44
  * rendered element without adding its key here ships something a merchant
45
45
  * cannot restyle, which the drift test in Task 15 catches.
46
46
  */
47
- declare const THROTTLE_ELEMENT_KEYS: readonly ["card", "card.header", "card.title", "card.description", "card.body", "card.footer", "card.logo", "field", "field.label", "field.input", "field.hint", "field.error", "field.group", "button", "alert", "spinner", "skeleton", "avatar", "badge", "emptyState", "emptyState.title", "emptyState.description", "modal.overlay", "modal.container", "modal.closeButton", "dropdown.trigger", "dropdown.menu", "dropdown.item", "dropdown.separator", "tabs.list", "tabs.tab", "table", "table.head", "table.row", "table.cell", "signIn.root", "signIn.title", "signIn.logo", "signIn.emailField", "signIn.passwordField", "signIn.submitButton", "signIn.forgotLink", "signIn.switchLink", "signUp.root", "signUp.title", "signUp.logo", "signUp.emailField", "signUp.passwordField", "signUp.submitButton", "signUp.switchLink", "forgotPassword.root", "forgotPassword.title", "forgotPassword.logo", "forgotPassword.emailField", "forgotPassword.submitButton", "forgotPassword.backLink", "resetPassword.root", "resetPassword.title", "resetPassword.logo", "resetPassword.passwordField", "resetPassword.submitButton", "verifyEmail.root", "verifyEmail.title", "verifyEmail.logo", "verifyEmail.resendButton", "authFlow.root", "authModal.overlay", "authModal.container", "signInButton.root", "signUpButton.root", "signOutButton.root", "stepUp.root", "stepUp.title", "stepUp.passwordField", "stepUp.submitButton", "stepUp.cancelButton", "signInPage.root", "signInPage.logo", "signInPage.footer", "signUpPage.root", "signUpPage.logo", "signUpPage.footer", "userButton.root", "userButton.trigger", "userButton.menu", "userButton.identity", "userButton.email", "userButton.badge", "userButton.item", "userButton.manageButton", "userButton.signOutButton", "userButton.signOutAllButton", "accountDashboard.root", "accountDashboard.tabs", "accountDashboard.sidebar", "accountDashboard.panel", "accountModal.overlay", "accountModal.container", "accountModal.header", "accountModal.title", "accountModal.body", "verifyBanner.root", "verifyBanner.message", "verifyBanner.resendButton", "verifyBanner.dismissButton", "profilePanel.root", "profilePanel.form", "profilePanel.submitButton", "addressesPanel.root", "addressesPanel.list", "addressesPanel.item", "addressesPanel.addButton", "addressesPanel.form", "addressesPanel.defaultButton", "addressesPanel.editButton", "addressesPanel.deleteButton", "addressesPanel.table", "addressesPanel.row", "paymentMethodsPanel.root", "paymentMethodsPanel.list", "paymentMethodsPanel.item", "paymentMethodsPanel.defaultButton", "paymentMethodsPanel.deleteButton", "paymentMethodsPanel.addButton", "paymentMethodsPanel.addDialog", "orderDetail.addresses", "orderDetail.shippingAddress", "orderDetail.billingAddress", "orderDetail.timeline", "orderDetail.payButton", "orderDetail.trackButton", "orderDetail.reorderButton", "fieldRow", "confirm.header", "confirm.title", "confirm.body", "confirm.confirmButton", "confirm.cancelButton", "paymentMethodsPanel.table", "paymentMethodsPanel.row", "ordersPanel.root", "ordersPanel.table", "ordersPanel.row", "ordersPanel.list", "ordersPanel.item", "ordersPanel.viewButton", "orderDetail.root", "orderDetail.backButton", "orderDetail.lineItems", "orderDetail.lineItem", "orderDetail.totals", "invoicesPanel.root", "invoicesPanel.table", "invoicesPanel.row", "invoicesPanel.list", "invoicesPanel.item", "invoicesPanel.viewButton", "invoiceDetail.root", "invoiceDetail.backButton", "invoiceDetail.downloadButton", "invoiceDetail.totals", "subscriptionsPanel.root", "subscriptionsPanel.list", "subscriptionsPanel.item", "subscriptionsPanel.cancelButton", "subscriptionsPanel.cancelNowButton", "subscriptionsPanel.pauseButton", "subscriptionsPanel.resumeButton", "subscriptionsPanel.table", "subscriptionsPanel.row", "securityPanel.root", "securityPanel.passwordForm", "securityPanel.passwordButton", "securityPanel.sessionList", "securityPanel.sessionItem", "securityPanel.revokeButton", "securityPanel.revokeAllButton", "securityPanel.table", "securityPanel.row"];
47
+ declare const THROTTLE_ELEMENT_KEYS: readonly ["card", "card.header", "card.title", "card.description", "card.body", "card.footer", "card.logo", "field", "field.label", "field.input", "field.hint", "field.error", "field.group", "button", "alert", "spinner", "skeleton", "avatar", "badge", "emptyState", "emptyState.title", "emptyState.description", "modal.overlay", "modal.container", "modal.closeButton", "dropdown.trigger", "dropdown.menu", "dropdown.item", "dropdown.separator", "tabs.list", "tabs.tab", "table", "table.head", "table.row", "table.cell", "signIn.root", "signIn.title", "signIn.logo", "signIn.emailField", "signIn.passwordField", "signIn.submitButton", "signIn.forgotLink", "signIn.switchLink", "signUp.root", "signUp.title", "signUp.logo", "signUp.emailField", "signUp.passwordField", "signUp.submitButton", "signUp.switchLink", "forgotPassword.root", "forgotPassword.title", "forgotPassword.logo", "forgotPassword.emailField", "forgotPassword.submitButton", "forgotPassword.backLink", "resetPassword.root", "resetPassword.title", "resetPassword.logo", "resetPassword.passwordField", "resetPassword.submitButton", "verifyEmail.root", "verifyEmail.title", "verifyEmail.logo", "verifyEmail.resendButton", "authFlow.root", "authModal.overlay", "authModal.container", "signInButton.root", "signUpButton.root", "signOutButton.root", "stepUp.root", "stepUp.title", "stepUp.passwordField", "stepUp.submitButton", "stepUp.cancelButton", "signInPage.root", "signInPage.logo", "signInPage.footer", "signUpPage.root", "signUpPage.logo", "signUpPage.footer", "userButton.root", "userButton.trigger", "userButton.menu", "userButton.identity", "userButton.email", "userButton.badge", "userButton.item", "userButton.manageButton", "userButton.signOutButton", "userButton.signOutAllButton", "accountDashboard.root", "accountDashboard.tabs", "accountDashboard.sidebar", "accountDashboard.panel", "accountModal.overlay", "accountModal.container", "accountModal.header", "accountModal.title", "accountModal.body", "verifyBanner.root", "verifyBanner.message", "verifyBanner.resendButton", "verifyBanner.dismissButton", "profilePanel.root", "profilePanel.form", "profilePanel.submitButton", "addressesPanel.root", "addressesPanel.list", "addressesPanel.item", "addressesPanel.addButton", "addressesPanel.form", "addressesPanel.defaultButton", "addressesPanel.editButton", "addressesPanel.deleteButton", "addressesPanel.table", "addressesPanel.row", "paymentMethodsPanel.root", "paymentMethodsPanel.list", "paymentMethodsPanel.item", "paymentMethodsPanel.defaultButton", "paymentMethodsPanel.deleteButton", "paymentMethodsPanel.addButton", "paymentMethodsPanel.addDialog", "orderDetail.addresses", "orderDetail.shippingAddress", "orderDetail.billingAddress", "orderDetail.timeline", "orderDetail.payButton", "orderDetail.trackButton", "orderDetail.reorderButton", "orderDetail.layout", "orderDetail.main", "orderDetail.rail", "orderDetail.cancelButton", "orderDetail.returnButton", "orderDetail.invoiceButton", "orderDetail.actions", "invoiceDetail.layout", "invoiceDetail.main", "invoiceDetail.rail", "invoiceDetail.lineItems", "invoiceDetail.lineItem", "invoiceDetail.orderLink", "invoiceDetail.subscriptionLink", "invoiceDetail.payButton", "invoiceDetail.actions", "fieldRow", "confirm.header", "confirm.title", "confirm.body", "confirm.confirmButton", "confirm.cancelButton", "paymentMethodsPanel.table", "paymentMethodsPanel.row", "ordersPanel.root", "ordersPanel.table", "ordersPanel.row", "ordersPanel.list", "ordersPanel.item", "ordersPanel.viewButton", "orderDetail.root", "orderDetail.backButton", "orderDetail.lineItems", "orderDetail.lineItem", "orderDetail.totals", "invoicesPanel.root", "invoicesPanel.table", "invoicesPanel.row", "invoicesPanel.list", "invoicesPanel.item", "invoicesPanel.viewButton", "invoiceDetail.root", "invoiceDetail.backButton", "invoiceDetail.downloadButton", "invoiceDetail.totals", "subscriptionsPanel.root", "subscriptionsPanel.list", "subscriptionsPanel.item", "subscriptionsPanel.cancelButton", "subscriptionsPanel.cancelNowButton", "subscriptionsPanel.pauseButton", "subscriptionsPanel.resumeButton", "subscriptionsPanel.table", "subscriptionsPanel.row", "securityPanel.root", "securityPanel.passwordForm", "securityPanel.passwordButton", "securityPanel.sessionList", "securityPanel.sessionItem", "securityPanel.revokeButton", "securityPanel.revokeAllButton", "securityPanel.table", "securityPanel.row"];
48
48
  type ThrottleElementKey = (typeof THROTTLE_ELEMENT_KEYS)[number];
49
49
  interface ThrottleSlots {
50
50
  Spinner?: ComponentType<{
@@ -222,6 +222,17 @@ declare const enUS: {
222
222
  payNow: string;
223
223
  track: string;
224
224
  reorder: string;
225
+ cancelOrder: string;
226
+ cancelOrderConfirm: string;
227
+ cancelOrderBody: string;
228
+ cancelOrderAction: string;
229
+ requestReturn: string;
230
+ requestReturnConfirm: string;
231
+ requestReturnBody: string;
232
+ requestReturnAction: string;
233
+ returnRequested: string;
234
+ downloadInvoice: string;
235
+ summary: string;
225
236
  empty: string;
226
237
  emptyDescription: string;
227
238
  gatedDescription: string;
@@ -285,6 +296,12 @@ declare const enUS: {
285
296
  refunded: string;
286
297
  period: string;
287
298
  downloadButton: string;
299
+ items: string;
300
+ summary: string;
301
+ viewOrder: string;
302
+ viewSubscription: string;
303
+ payButton: string;
304
+ billedTo: string;
288
305
  /** Display copy for `invoice.status` — the wire values are paid|open|void. */
289
306
  statusLabels: {
290
307
  paid: string;
@@ -393,6 +410,11 @@ declare function OrdersPanel(props: OrderActionHandlers & {
393
410
  localization?: ThrottleLocalization;
394
411
  variant?: AccountPanelVariant;
395
412
  onViewSubscription?(id: string): void;
413
+ /** Forwarded to `OrderDetail`, where both default to on. */
414
+ allowCancel?: boolean;
415
+ allowReturn?: boolean;
416
+ /** Opens straight to this order. Set by the dashboard on cross-panel navigation. */
417
+ initialOpenId?: string | null;
396
418
  }): react_jsx_runtime.JSX.Element;
397
419
 
398
420
  type AccountTab = 'profile' | 'addresses' | 'paymentMethods' | 'orders' | 'invoices' | 'subscriptions' | 'security';
@@ -486,7 +508,7 @@ declare const THROTTLE_STYLE_ID = "throttle-auth-styles";
486
508
  * specificity plus source order is what lets them win. A descendant selector
487
509
  * here would silently outrank them.
488
510
  */
489
- declare const THROTTLE_STYLES = "\n.throttle-root {\n --throttle-color-primary: #18181b;\n --throttle-color-primary-foreground: #ffffff;\n --throttle-color-background: #ffffff;\n --throttle-color-surface: #f8fafc;\n --throttle-color-foreground: #0e1116;\n --throttle-color-muted: #eceef2;\n --throttle-color-muted-foreground: #5b6472;\n --throttle-color-border: #e2e8f0;\n /* The boundary of an INTERACTIVE control, which WCAG 1.4.11 requires to\n reach 3:1 against its adjacent colour \u2014 an input identified only by a\n 1.23:1 hairline is not identifiable at all. Decorative separators (card\n edges, table rules, dividers) keep --throttle-color-border: they do not\n identify a control, so the requirement does not apply and darkening\n them would only add noise. */\n /* The account dashboard paints nothing by default so it can drop into a\n merchant's page without fighting their background. The accountSurface and\n accountPadding appearance variables opt back into a card.\n No backticks in this comment: the sheet is a TS template literal. */\n --throttle-card-width: 400px;\n --throttle-color-account-surface: transparent;\n --throttle-account-padding: 0;\n --throttle-color-border-control: #8b93a1;\n --throttle-color-danger: #c2321f;\n --throttle-color-danger-surface: #fef2f2;\n --throttle-color-danger-border: #fecaca;\n --throttle-color-success: #127a4a;\n --throttle-color-success-surface: #ecfdf5;\n --throttle-color-success-border: #a7f3d0;\n --throttle-color-warning: #92400e;\n --throttle-color-warning-surface: #fffbeb;\n --throttle-color-warning-border: #fde68a;\n --throttle-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n --throttle-font-size: 16px;\n --throttle-font-size-xs: 12px;\n --throttle-font-size-sm: 14px;\n --throttle-font-size-lg: 20px;\n --throttle-font-size-xl: 24px;\n --throttle-line-height: 1.5;\n --throttle-line-height-tight: 1.25;\n --throttle-radius: 12px;\n --throttle-radius-sm: 8px;\n --throttle-radius-full: 999px;\n --throttle-border-width: 1px;\n --throttle-spacing: 8px;\n --throttle-space-1: 4px;\n --throttle-space-2: var(--throttle-spacing);\n --throttle-space-3: 12px;\n --throttle-space-4: 16px;\n --throttle-space-5: 24px;\n --throttle-space-6: 32px;\n --throttle-control-height: 48px;\n --throttle-control-padding-x: 16px;\n --throttle-shadow-card: 0 1px 3px rgba(15,23,42,.08), 0 1px 2px rgba(15,23,42,.04);\n --throttle-shadow-popover: 0 10px 24px rgba(15,23,42,.12), 0 2px 6px rgba(15,23,42,.06);\n --throttle-transition: 150ms cubic-bezier(.2,0,.2,1);\n --throttle-z-modal: 2147483000;\n --throttle-z-popover: 2147482000;\n font-family: var(--throttle-font-family);\n font-size: var(--throttle-font-size);\n line-height: var(--throttle-line-height);\n color: var(--throttle-color-foreground);\n box-sizing: border-box;\n}\n.throttle-root *, .throttle-root *::before, .throttle-root *::after { box-sizing: inherit; }\n\n.throttle-root[data-throttle-theme=\"dark\"] {\n --throttle-color-primary: #e6edf3;\n --throttle-color-primary-foreground: #0d1117;\n --throttle-color-background: #0d1117;\n --throttle-color-surface: #1c2129;\n --throttle-color-foreground: #e6edf3;\n --throttle-color-muted: #21262d;\n --throttle-color-muted-foreground: #9aa4b2;\n --throttle-color-border: #30363d;\n --throttle-color-border-control: #5c6570;\n --throttle-color-danger: #ff6b58;\n --throttle-color-danger-surface: #2a1513;\n --throttle-color-danger-border: #5c2b25;\n --throttle-color-success: #45c08a;\n --throttle-color-success-surface: #0f2419;\n --throttle-color-success-border: #1f4d36;\n --throttle-color-warning: #e0a53a;\n --throttle-color-warning-surface: #2a2113;\n --throttle-color-warning-border: #5c4a25;\n --throttle-shadow-card: 0 1px 3px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.4);\n --throttle-shadow-popover: 0 10px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.35);\n}\n@media (prefers-color-scheme: dark) {\n .throttle-root[data-throttle-theme=\"auto\"] {\n --throttle-color-primary: #e6edf3;\n --throttle-color-primary-foreground: #0d1117;\n --throttle-color-background: #0d1117;\n --throttle-color-surface: #1c2129;\n --throttle-color-foreground: #e6edf3;\n --throttle-color-muted: #21262d;\n --throttle-color-muted-foreground: #9aa4b2;\n --throttle-color-border: #30363d;\n --throttle-color-border-control: #5c6570;\n --throttle-color-danger: #ff6b58;\n --throttle-color-danger-surface: #2a1513;\n --throttle-color-danger-border: #5c2b25;\n --throttle-color-success: #45c08a;\n --throttle-color-success-surface: #0f2419;\n --throttle-color-success-border: #1f4d36;\n --throttle-color-warning: #e0a53a;\n --throttle-color-warning-surface: #2a2113;\n --throttle-color-warning-border: #5c4a25;\n --throttle-shadow-card: 0 1px 3px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.4);\n --throttle-shadow-popover: 0 10px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.35);\n }\n}\n\n.throttle-card {\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-card);\n padding: var(--throttle-space-5);\n width: 100%;\n max-width: var(--throttle-card-width);\n margin-inline: auto;\n}\n/* Inside a Modal the dialog already provides the surface \u2014 background, radius\n and elevation. A card that draws its own on top is the \"box inside a box\":\n two shadowed rounded rectangles nested, with the card's max-width stranding\n it in the middle of a much wider dialog. */\n.throttle-card--bare { border: none; box-shadow: none; background: none; max-width: none; }\n.throttle-card__header { margin-bottom: var(--throttle-space-4); }\n.throttle-card__header--branded { text-align: center; }\n.throttle-card__logo { display: flex; justify-content: center; margin-bottom: var(--throttle-space-3); }\n.throttle-card__title { font-size: var(--throttle-font-size-xl); line-height: var(--throttle-line-height-tight); font-weight: 600; letter-spacing: -0.02em; margin: 0; }\n.throttle-card__title--branded { font-size: var(--throttle-font-size-xl); }\n.throttle-card__description { color: var(--throttle-color-muted-foreground); margin: var(--throttle-space-1) 0 0; }\n.throttle-card__body { display: flex; flex-direction: column; gap: var(--throttle-space-3); }\n.throttle-card__footer { margin-top: var(--throttle-space-4); text-align: center; }\n.throttle-card__footer--ruled { border-top: var(--throttle-border-width) solid var(--throttle-color-border); padding-top: var(--throttle-space-4); }\n\n.throttle-field { display: flex; flex-direction: column; gap: var(--throttle-space-1); }\n.throttle-field__labelrow { display: flex; align-items: baseline; justify-content: space-between; gap: var(--throttle-space-2); }\n.throttle-field__label { font-weight: 500; }\n.throttle-field__input {\n font: inherit;\n font-size: var(--throttle-font-size);\n color: var(--throttle-color-foreground);\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border-control);\n border-radius: var(--throttle-radius-sm);\n /* padding-block stays 0 so min-height alone owns the height, exactly as\n .throttle-button does. With 12px vertical padding the box computed to\n 50px against the button's 48px \u2014 a 2px mismatch, measured in a browser\n across 19 controls. An input element centres its own text vertically. */\n padding-block: 0;\n padding-inline: var(--throttle-control-padding-x);\n min-height: var(--throttle-control-height);\n width: 100%;\n transition: border-color var(--throttle-transition), box-shadow var(--throttle-transition);\n}\n.throttle-field__input:focus-visible {\n outline: none;\n border-color: var(--throttle-color-primary);\n box-shadow: 0 0 0 2px var(--throttle-color-background), 0 0 0 4px var(--throttle-color-primary);\n}\n.throttle-field__input:disabled { background: var(--throttle-color-muted); color: var(--throttle-color-muted-foreground); cursor: not-allowed; }\n.throttle-field__input::placeholder { color: var(--throttle-color-muted-foreground); opacity: 1; }\n.throttle-field__input--grouped { border: none; border-radius: 0; padding-inline: 0; }\n.throttle-field__hint { color: var(--throttle-color-muted-foreground); font-size: var(--throttle-font-size-xs); }\n/* Always mounted, so it reserves its line whether or not there is an error:\n an error appearing on submit must not push the submit button out from\n under the buyer's pointer. */\n.throttle-field__error { color: var(--throttle-color-danger); font-size: var(--throttle-font-size-xs); line-height: 1rem; }\n/* Reserved a full line under EVERY input even with nothing to say, which\n with the stack gap put 28px of dead space beneath each field, on every\n form and all seven account panels. The element stays mounted when empty\n because role=alert only announces changes to a live region that was\n already there; it just stops occupying a line. */\n.throttle-field__error:empty { display: none; }\n\n.throttle-field-group {\n display: flex;\n flex-direction: column;\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-sm);\n overflow: hidden;\n}\n.throttle-field-group__item { padding: var(--throttle-space-3) var(--throttle-control-padding-x); }\n.throttle-field-group__divider { height: var(--throttle-border-width); background: var(--throttle-color-border); }\n.throttle-field-group__forgot { margin-left: auto; }\n\n.throttle-button {\n font: inherit;\n font-weight: 500;\n border-radius: var(--throttle-radius-sm);\n border: var(--throttle-border-width) solid transparent;\n padding-inline: var(--throttle-control-padding-x);\n padding-block: 0;\n min-height: var(--throttle-control-height);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: opacity var(--throttle-transition), background-color var(--throttle-transition), border-color var(--throttle-transition), filter var(--throttle-transition), box-shadow var(--throttle-transition);\n}\n.throttle-button:disabled { opacity: .55; cursor: not-allowed; }\n.throttle-button:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--throttle-color-background), 0 0 0 4px var(--throttle-color-primary); }\n.throttle-button--primary { background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground); width: 100%; }\n.throttle-button--primary:hover:not(:disabled) { filter: brightness(0.92); }\n.throttle-button--secondary { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); border-color: var(--throttle-color-border-control); }\n.throttle-button--secondary:hover:not(:disabled) { background: var(--throttle-color-muted); }\n.throttle-button--danger { background: transparent; color: var(--throttle-color-danger); border-color: var(--throttle-color-border); }\n.throttle-button--danger:hover:not(:disabled) { background: color-mix(in srgb, var(--throttle-color-danger) 10%, transparent); }\n/* Link-style actions are the rows panel default, and they carry Delete,\n Remove, Cancel and Sign out. Zero padding with min-height 0 made those\n roughly 20px tall and ~8px apart \u2014 a mis-tap on a phone lands on something\n irreversible. The target is expanded with vertical padding and pulled back\n with an equal negative margin, so the hit box clears 44px while the text\n sits exactly where it did. Collapsing this back to zero padding shrinks the\n target again. */\n.throttle-button--link { background: none; border: none; color: var(--throttle-color-primary); padding-inline: 0; padding-block: var(--throttle-space-3); margin-block: calc(var(--throttle-space-3) * -1); min-height: 0; text-decoration: underline; width: auto; }\n.throttle-button--link:hover:not(:disabled) { opacity: .8; }\n.throttle-button--linkDanger { background: none; border: none; color: var(--throttle-color-danger); padding-inline: 0; padding-block: var(--throttle-space-3); margin-block: calc(var(--throttle-space-3) * -1); min-height: 0; text-decoration: underline; width: auto; }\n.throttle-button--linkDanger:hover:not(:disabled) { opacity: .8; }\n.throttle-button--xs { font-size: var(--throttle-font-size-xs); }\n\n.throttle-alert { border-radius: var(--throttle-radius-sm); padding: var(--throttle-space-3); font-size: var(--throttle-font-size-sm); }\n.throttle-alert--error { background: var(--throttle-color-danger-surface); border: var(--throttle-border-width) solid var(--throttle-color-danger-border); color: var(--throttle-color-danger); }\n.throttle-alert--success { background: var(--throttle-color-success-surface); border: var(--throttle-border-width) solid var(--throttle-color-success-border); color: var(--throttle-color-success); }\n.throttle-alert--info { background: var(--throttle-color-surface); color: var(--throttle-color-muted-foreground); }\n\n.throttle-spinner {\n display: inline-block; width: 1em; height: 1em;\n border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;\n animation: throttle-spin 700ms linear infinite;\n}\n@keyframes throttle-spin { to { transform: rotate(360deg); } }\n.throttle-button--loading { position: relative; }\n.throttle-button__label { display: inline-flex; align-items: center; justify-content: center; gap: var(--throttle-space-2); }\n.throttle-button__label--hidden { visibility: hidden; }\n.throttle-spinner--centred { position: absolute; top: 50%; left: 50%; margin: -0.5em 0 0 -0.5em; }\n\n@media (prefers-reduced-motion: reduce) { .throttle-spinner { animation-duration: 2.4s; } }\n\n.throttle-skeleton {\n background: var(--throttle-color-muted);\n border-radius: var(--throttle-radius-sm);\n animation: throttle-pulse 1.4s ease-in-out infinite; height: 2.5em; }\n@keyframes throttle-pulse { 50% { opacity: .5; } }\n@media (prefers-reduced-motion: reduce) { .throttle-skeleton { animation: none; } }\n\n.throttle-modal__overlay {\n position: fixed; inset: 0; z-index: var(--throttle-z-modal);\n background: rgba(14,17,22,.45);\n display: flex; align-items: center; justify-content: center;\n padding: var(--throttle-space-4);\n overflow-y: auto;\n}\n.throttle-modal__container {\n background: var(--throttle-color-background);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-popover);\n max-width: 720px; width: 100%; max-height: 90vh; overflow-y: auto;\n position: relative;\n}\n/* After the base rule on purpose: both are single-class, so equal specificity\n means source order decides. Declared before it, this silently lost. */\n.throttle-modal__container--compact { max-width: 440px; }\n.throttle-modal__close {\n position: absolute; top: var(--throttle-space-3); right: var(--throttle-space-3);\n background: none; border: none; cursor: pointer; font-size: var(--throttle-font-size-lg);\n color: var(--throttle-color-muted-foreground);\n transition: color var(--throttle-transition);\n}\n.throttle-modal__close:hover { color: var(--throttle-color-foreground); }\n.throttle-modal__header { padding: var(--throttle-space-4) var(--throttle-space-4) 0; }\n.throttle-modal__title { font-size: var(--throttle-font-size-lg); line-height: var(--throttle-line-height-tight); font-weight: 600; margin: 0; }\n.throttle-modal__body { padding: var(--throttle-space-4); }\n\n.throttle-dropdown__trigger { background: none; border: none; cursor: pointer; padding: 0; border-radius: var(--throttle-radius-full); transition: background-color var(--throttle-transition); }\n.throttle-dropdown__trigger:hover { background: var(--throttle-color-surface); }\n.throttle-dropdown__trigger:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: 2px; }\n.throttle-dropdown__menu {\n position: absolute; right: 0; top: calc(100% + var(--throttle-space-2));\n z-index: var(--throttle-z-popover);\n min-width: 260px;\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-popover);\n padding: var(--throttle-space-1);\n}\n.throttle-dropdown__item {\n display: flex; align-items: center; gap: var(--throttle-space-2);\n width: 100%; text-align: left; font: inherit; color: inherit;\n background: none; border: none; cursor: pointer;\n padding: var(--throttle-space-3);\n border-radius: var(--throttle-radius-sm);\n text-decoration: none;\n transition: background-color var(--throttle-transition);\n}\n.throttle-dropdown__item:hover { background: var(--throttle-color-surface); }\n.throttle-dropdown__item:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-dropdown__separator { height: 1px; background: var(--throttle-color-border); margin: var(--throttle-space-1) 0; border: 0; }\n\n.throttle-tabs__list {\n display: flex; gap: var(--throttle-space-1);\n border-bottom: var(--throttle-border-width) solid var(--throttle-color-border);\n overflow-x: auto; scrollbar-width: thin;\n}\n.throttle-tabs__tab {\n font: inherit; background: none; border: none; cursor: pointer; white-space: nowrap;\n padding: var(--throttle-space-3);\n color: var(--throttle-color-muted-foreground);\n border-bottom: 2px solid transparent;\n transition: color var(--throttle-transition), border-color var(--throttle-transition);\n}\n.throttle-tabs__tab:hover { color: var(--throttle-color-foreground); }\n.throttle-tabs__tab--active { color: var(--throttle-color-foreground); border-bottom-color: var(--throttle-color-primary); }\n.throttle-tabs__panel { padding-top: var(--throttle-space-4); }\n\n/* Paints its own ground. A UserButton in a navbar should stay transparent, but\n the dashboard is a large surface of themed text: in dark theme its foreground\n is near-white, so on a light host page it was rendering white-on-white. */\n.throttle-cardframe { width: 100%; min-height: 420px; border: 0; display: block; }\n.throttle-centre { display: flex; align-items: center; justify-content: center; min-height: 160px; }\n.throttle-fieldrow { display: grid; grid-template-columns: 1fr 1fr; gap: var(--throttle-space-4); align-items: start; }\n.throttle-section__title { font-size: var(--throttle-font-size-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--throttle-color-muted-foreground); margin: 0 0 var(--throttle-space-2); font-weight: 600; }\n.throttle-addresses { display: grid; grid-template-columns: 1fr 1fr; gap: var(--throttle-space-5); }\n.throttle-addressblock__line { margin: 0 0 2px; }\n.throttle-timeline { display: flex; flex-direction: column; gap: var(--throttle-space-2); }\n.throttle-timeline__row { display: flex; align-items: center; gap: var(--throttle-space-2); }\n.throttle-timeline__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--throttle-color-border-control); flex: none; }\n.throttle-timeline__label { flex: 1; }\n.throttle-account-root { container-type: inline-size; background: var(--throttle-color-account-surface); color: var(--throttle-color-foreground); padding: var(--throttle-account-padding); }\n.throttle-account { display: flex; gap: var(--throttle-space-5); align-items: flex-start; }\n.throttle-account__content { flex: 1; min-width: 0; }\n.throttle-tabs__rail { flex: none; width: 220px; display: flex; flex-direction: column; gap: 2px; }\n.throttle-tabs__railitem {\n font: inherit;\n font-size: var(--throttle-font-size-sm);\n display: flex;\n align-items: center;\n gap: var(--throttle-space-3);\n width: 100%;\n text-align: left;\n background: none;\n border: none;\n border-radius: var(--throttle-radius-sm);\n padding: 0 var(--throttle-space-3);\n min-height: var(--throttle-control-height);\n color: var(--throttle-color-muted-foreground);\n cursor: pointer;\n transition: background var(--throttle-transition), color var(--throttle-transition);\n}\n.throttle-tabs__railitem:hover { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); }\n.throttle-tabs__railitem:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-tabs__tab:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-tabs__railitem--active { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); font-weight: 500; }\n.throttle-tabs__railicon { flex: none; opacity: .75; }\n\n/* A CONTAINER query, not a viewport one: these components render inside a\n merchant's page, so the viewport says nothing about how much room the\n dashboard actually has \u2014 it could sit in a 400px column on a 1920px screen.\n Below ~560px of container the rail becomes a full-width list above the\n panel: all seven still visible, each still a 44px target. */\n@container (max-width: 560px) {\n /* align-items: flex-start is right in row direction and wrong in column \u2014\n it shrinks the rail to its content width, so width:100% alone cannot make\n it span. Stretch it explicitly when stacked. */\n .throttle-account { flex-direction: column; align-items: stretch; gap: var(--throttle-space-4); }\n .throttle-addresses { grid-template-columns: 1fr; }\n .throttle-fieldrow { grid-template-columns: 1fr; }\n .throttle-tabs__rail { width: 100%; }\n}\n\n.throttle-table { width: 100%; border-collapse: collapse; text-align: left; }\n.throttle-table__head { color: var(--throttle-color-muted-foreground); font-weight: 500; font-size: var(--throttle-font-size-sm); }\n.throttle-table__row { border-top: var(--throttle-border-width) solid var(--throttle-color-border); cursor: pointer; transition: background-color var(--throttle-transition); }\n.throttle-table__row:hover { background: var(--throttle-color-surface); }\n.throttle-table__row:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-table__cell { padding: var(--throttle-space-3) var(--throttle-space-2); height: 56px; box-sizing: border-box; }\n.throttle-table__scroll { overflow-x: auto; }\n\n.throttle-empty { text-align: center; padding: var(--throttle-space-6) var(--throttle-space-4); }\n.throttle-empty__title { font-weight: 600; margin: 0 0 var(--throttle-space-1); }\n.throttle-empty__description { color: var(--throttle-color-muted-foreground); margin: 0; }\n\n.throttle-avatar {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; border-radius: var(--throttle-radius-full);\n background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground);\n font-size: var(--throttle-font-size-xs); font-weight: 600; text-transform: uppercase;\n}\n\n.throttle-badge {\n display: inline-block; font-size: var(--throttle-font-size-xs); font-weight: 500;\n padding: 2px var(--throttle-space-2); border-radius: var(--throttle-radius-full);\n background: var(--throttle-color-muted); color: var(--throttle-color-muted-foreground);\n}\n.throttle-badge--muted { background: none; border: var(--throttle-border-width) solid var(--throttle-color-border); color: var(--throttle-color-muted-foreground); font-weight: 400; padding: 1px calc(var(--throttle-space-2) - 1px); }\n.throttle-badge--success { background: color-mix(in srgb, var(--throttle-color-success) 15%, transparent); color: var(--throttle-color-success); }\n.throttle-badge--warning { background: color-mix(in srgb, var(--throttle-color-warning) 15%, transparent); color: var(--throttle-color-warning); }\n.throttle-badge--danger { background: color-mix(in srgb, var(--throttle-color-danger) 15%, transparent); color: var(--throttle-color-danger); }\n\n.throttle-stack { display: flex; flex-direction: column; gap: var(--throttle-space-3); }\n.throttle-row { display: flex; align-items: center; justify-content: space-between; gap: var(--throttle-space-2); flex-wrap: wrap; }\n.throttle-muted { color: var(--throttle-color-muted-foreground); }\n.throttle-banner {\n display: flex; align-items: center; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n background: color-mix(in srgb, var(--throttle-color-warning) 12%, transparent);\n color: var(--throttle-color-warning);\n border-radius: var(--throttle-radius-sm);\n padding: var(--throttle-space-3);\n margin-bottom: var(--throttle-space-4);\n}\n.throttle-panel { display: flex; flex-direction: column; gap: var(--throttle-space-4); }\n/* 100dvh, not 100vh: on mobile browsers 100vh includes the space behind the\n dynamic address/toolbar, so the page would be taller than the visible\n viewport and the card would sit off-centre until the toolbar collapsed. */\n.throttle-page {\n min-height: 100dvh;\n width: 100%;\n background: var(--throttle-color-surface);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--throttle-space-5);\n padding: var(--throttle-space-5);\n}\n.throttle-page__logo { display: flex; justify-content: center; }\n.throttle-page__footer { color: var(--throttle-color-muted-foreground); text-align: center; font-size: var(--throttle-font-size-sm); }\n.throttle-listitem {\n display: flex; align-items: flex-start; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-sm);\n padding: var(--throttle-space-3);\n}\n/* 'rows' variant: hairline rules between items instead of each item carrying\n its own border+radius, so a panel does not read as a card inside a card. */\n.throttle-rows { display: flex; flex-direction: column; }\n.throttle-rowitem {\n display: flex; align-items: flex-start; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n border-top: var(--throttle-border-width) solid var(--throttle-color-border);\n padding: var(--throttle-space-3) 0;\n}\n.throttle-rowitem:first-child { border-top: none; padding-top: 0; }\n.throttle-actions { display: flex; gap: var(--throttle-space-2); flex-wrap: wrap; }\n.throttle-table__money { display: block; text-align: right; font-variant-numeric: tabular-nums; }\n.throttle-lineitem { display: flex; align-items: center; gap: var(--throttle-space-3); padding: var(--throttle-space-2) 0; }\n.throttle-lineitem__image { width: 48px; height: 48px; object-fit: cover; border-radius: var(--throttle-radius-sm); flex: none; }\n.throttle-totals { display: flex; flex-direction: column; gap: var(--throttle-space-1); }\n\n@media (prefers-reduced-motion: reduce) {\n .throttle-button, .throttle-field__input, .throttle-dropdown__item, .throttle-dropdown__trigger, .throttle-tabs__tab, .throttle-table__row, .throttle-modal__close {\n transition: none;\n }\n}\n";
511
+ declare const THROTTLE_STYLES = "\n.throttle-root {\n --throttle-color-primary: #18181b;\n --throttle-color-primary-foreground: #ffffff;\n --throttle-color-background: #ffffff;\n --throttle-color-surface: #f8fafc;\n --throttle-color-foreground: #0e1116;\n --throttle-color-muted: #eceef2;\n --throttle-color-muted-foreground: #5b6472;\n --throttle-color-border: #e2e8f0;\n /* The boundary of an INTERACTIVE control, which WCAG 1.4.11 requires to\n reach 3:1 against its adjacent colour \u2014 an input identified only by a\n 1.23:1 hairline is not identifiable at all. Decorative separators (card\n edges, table rules, dividers) keep --throttle-color-border: they do not\n identify a control, so the requirement does not apply and darkening\n them would only add noise. */\n /* The account dashboard paints nothing by default so it can drop into a\n merchant's page without fighting their background. The accountSurface and\n accountPadding appearance variables opt back into a card.\n No backticks in this comment: the sheet is a TS template literal. */\n --throttle-card-width: 400px;\n --throttle-color-account-surface: transparent;\n --throttle-account-padding: 0;\n --throttle-color-border-control: #8b93a1;\n --throttle-color-danger: #c2321f;\n --throttle-color-danger-surface: #fef2f2;\n --throttle-color-danger-border: #fecaca;\n --throttle-color-success: #127a4a;\n --throttle-color-success-surface: #ecfdf5;\n --throttle-color-success-border: #a7f3d0;\n --throttle-color-warning: #92400e;\n --throttle-color-warning-surface: #fffbeb;\n --throttle-color-warning-border: #fde68a;\n --throttle-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n --throttle-font-size: 16px;\n --throttle-font-size-xs: 12px;\n --throttle-font-size-sm: 14px;\n --throttle-font-size-lg: 20px;\n --throttle-font-size-xl: 24px;\n --throttle-line-height: 1.5;\n --throttle-line-height-tight: 1.25;\n --throttle-radius: 12px;\n --throttle-radius-sm: 8px;\n --throttle-radius-full: 999px;\n --throttle-border-width: 1px;\n --throttle-spacing: 8px;\n --throttle-space-1: 4px;\n --throttle-space-2: var(--throttle-spacing);\n --throttle-space-3: 12px;\n --throttle-space-4: 16px;\n --throttle-space-5: 24px;\n --throttle-space-6: 32px;\n --throttle-control-height: 48px;\n --throttle-control-padding-x: 16px;\n --throttle-shadow-card: 0 1px 3px rgba(15,23,42,.08), 0 1px 2px rgba(15,23,42,.04);\n --throttle-shadow-popover: 0 10px 24px rgba(15,23,42,.12), 0 2px 6px rgba(15,23,42,.06);\n --throttle-transition: 150ms cubic-bezier(.2,0,.2,1);\n --throttle-z-modal: 2147483000;\n --throttle-z-popover: 2147482000;\n font-family: var(--throttle-font-family);\n font-size: var(--throttle-font-size);\n line-height: var(--throttle-line-height);\n color: var(--throttle-color-foreground);\n box-sizing: border-box;\n}\n.throttle-root *, .throttle-root *::before, .throttle-root *::after { box-sizing: inherit; }\n\n.throttle-root[data-throttle-theme=\"dark\"] {\n --throttle-color-primary: #e6edf3;\n --throttle-color-primary-foreground: #0d1117;\n --throttle-color-background: #0d1117;\n --throttle-color-surface: #1c2129;\n --throttle-color-foreground: #e6edf3;\n --throttle-color-muted: #21262d;\n --throttle-color-muted-foreground: #9aa4b2;\n --throttle-color-border: #30363d;\n --throttle-color-border-control: #5c6570;\n --throttle-color-danger: #ff6b58;\n --throttle-color-danger-surface: #2a1513;\n --throttle-color-danger-border: #5c2b25;\n --throttle-color-success: #45c08a;\n --throttle-color-success-surface: #0f2419;\n --throttle-color-success-border: #1f4d36;\n --throttle-color-warning: #e0a53a;\n --throttle-color-warning-surface: #2a2113;\n --throttle-color-warning-border: #5c4a25;\n --throttle-shadow-card: 0 1px 3px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.4);\n --throttle-shadow-popover: 0 10px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.35);\n}\n@media (prefers-color-scheme: dark) {\n .throttle-root[data-throttle-theme=\"auto\"] {\n --throttle-color-primary: #e6edf3;\n --throttle-color-primary-foreground: #0d1117;\n --throttle-color-background: #0d1117;\n --throttle-color-surface: #1c2129;\n --throttle-color-foreground: #e6edf3;\n --throttle-color-muted: #21262d;\n --throttle-color-muted-foreground: #9aa4b2;\n --throttle-color-border: #30363d;\n --throttle-color-border-control: #5c6570;\n --throttle-color-danger: #ff6b58;\n --throttle-color-danger-surface: #2a1513;\n --throttle-color-danger-border: #5c2b25;\n --throttle-color-success: #45c08a;\n --throttle-color-success-surface: #0f2419;\n --throttle-color-success-border: #1f4d36;\n --throttle-color-warning: #e0a53a;\n --throttle-color-warning-surface: #2a2113;\n --throttle-color-warning-border: #5c4a25;\n --throttle-shadow-card: 0 1px 3px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.4);\n --throttle-shadow-popover: 0 10px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.35);\n }\n}\n\n.throttle-card {\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-card);\n padding: var(--throttle-space-5);\n width: 100%;\n max-width: var(--throttle-card-width);\n margin-inline: auto;\n}\n/* Inside a Modal the dialog already provides the surface \u2014 background, radius\n and elevation. A card that draws its own on top is the \"box inside a box\":\n two shadowed rounded rectangles nested, with the card's max-width stranding\n it in the middle of a much wider dialog. */\n.throttle-card--bare { border: none; box-shadow: none; background: none; max-width: none; }\n.throttle-card__header { margin-bottom: var(--throttle-space-4); }\n.throttle-card__header--branded { text-align: center; }\n.throttle-card__logo { display: flex; justify-content: center; margin-bottom: var(--throttle-space-3); }\n.throttle-card__title { font-size: var(--throttle-font-size-xl); line-height: var(--throttle-line-height-tight); font-weight: 600; letter-spacing: -0.02em; margin: 0; }\n.throttle-card__title--branded { font-size: var(--throttle-font-size-xl); }\n.throttle-card__description { color: var(--throttle-color-muted-foreground); margin: var(--throttle-space-1) 0 0; }\n.throttle-card__body { display: flex; flex-direction: column; gap: var(--throttle-space-3); }\n.throttle-card__footer { margin-top: var(--throttle-space-4); text-align: center; }\n.throttle-card__footer--ruled { border-top: var(--throttle-border-width) solid var(--throttle-color-border); padding-top: var(--throttle-space-4); }\n\n.throttle-field { display: flex; flex-direction: column; gap: var(--throttle-space-1); }\n.throttle-field__labelrow { display: flex; align-items: baseline; justify-content: space-between; gap: var(--throttle-space-2); }\n.throttle-field__label { font-weight: 500; }\n.throttle-field__input {\n font: inherit;\n font-size: var(--throttle-font-size);\n color: var(--throttle-color-foreground);\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border-control);\n border-radius: var(--throttle-radius-sm);\n /* padding-block stays 0 so min-height alone owns the height, exactly as\n .throttle-button does. With 12px vertical padding the box computed to\n 50px against the button's 48px \u2014 a 2px mismatch, measured in a browser\n across 19 controls. An input element centres its own text vertically. */\n padding-block: 0;\n padding-inline: var(--throttle-control-padding-x);\n min-height: var(--throttle-control-height);\n width: 100%;\n transition: border-color var(--throttle-transition), box-shadow var(--throttle-transition);\n}\n.throttle-field__input:focus-visible {\n outline: none;\n border-color: var(--throttle-color-primary);\n box-shadow: 0 0 0 2px var(--throttle-color-background), 0 0 0 4px var(--throttle-color-primary);\n}\n.throttle-field__input:disabled { background: var(--throttle-color-muted); color: var(--throttle-color-muted-foreground); cursor: not-allowed; }\n.throttle-field__input::placeholder { color: var(--throttle-color-muted-foreground); opacity: 1; }\n.throttle-field__input--grouped { border: none; border-radius: 0; padding-inline: 0; }\n.throttle-field__hint { color: var(--throttle-color-muted-foreground); font-size: var(--throttle-font-size-xs); }\n/* Always mounted, so it reserves its line whether or not there is an error:\n an error appearing on submit must not push the submit button out from\n under the buyer's pointer. */\n.throttle-field__error { color: var(--throttle-color-danger); font-size: var(--throttle-font-size-xs); line-height: 1rem; }\n/* Reserved a full line under EVERY input even with nothing to say, which\n with the stack gap put 28px of dead space beneath each field, on every\n form and all seven account panels. The element stays mounted when empty\n because role=alert only announces changes to a live region that was\n already there; it just stops occupying a line. */\n.throttle-field__error:empty { display: none; }\n\n.throttle-field-group {\n display: flex;\n flex-direction: column;\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-sm);\n overflow: hidden;\n}\n.throttle-field-group__item { padding: var(--throttle-space-3) var(--throttle-control-padding-x); }\n.throttle-field-group__divider { height: var(--throttle-border-width); background: var(--throttle-color-border); }\n.throttle-field-group__forgot { margin-left: auto; }\n\n.throttle-button {\n font: inherit;\n font-weight: 500;\n border-radius: var(--throttle-radius-sm);\n border: var(--throttle-border-width) solid transparent;\n padding-inline: var(--throttle-control-padding-x);\n padding-block: 0;\n min-height: var(--throttle-control-height);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n /* A label that wraps turns a control into a two-line block of text. */\n white-space: nowrap;\n transition: opacity var(--throttle-transition), background-color var(--throttle-transition), border-color var(--throttle-transition), filter var(--throttle-transition), box-shadow var(--throttle-transition);\n}\n.throttle-button:disabled { opacity: .55; cursor: not-allowed; }\n.throttle-button:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--throttle-color-background), 0 0 0 4px var(--throttle-color-primary); }\n.throttle-button--primary { background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground); width: var(--throttle-button-width, 100%); }\n.throttle-button--primary:hover:not(:disabled) { filter: brightness(0.92); }\n.throttle-button--secondary { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); border-color: var(--throttle-color-border-control); }\n.throttle-button--secondary:hover:not(:disabled) { background: var(--throttle-color-muted); }\n.throttle-button--danger { background: transparent; color: var(--throttle-color-danger); border-color: var(--throttle-color-border); }\n.throttle-button--danger:hover:not(:disabled) { background: color-mix(in srgb, var(--throttle-color-danger) 10%, transparent); }\n/* Link-style actions are the rows panel default, and they carry Delete,\n Remove, Cancel and Sign out. Zero padding with min-height 0 made those\n roughly 20px tall and ~8px apart \u2014 a mis-tap on a phone lands on something\n irreversible. The target is expanded with vertical padding and pulled back\n with an equal negative margin, so the hit box clears 44px while the text\n sits exactly where it did. Collapsing this back to zero padding shrinks the\n target again. */\n.throttle-button--link { background: none; border: none; color: var(--throttle-color-primary); padding-inline: 0; padding-block: var(--throttle-space-3); margin-block: calc(var(--throttle-space-3) * -1); min-height: 0; text-decoration: underline; width: auto; }\n.throttle-button--link:hover:not(:disabled) { opacity: .8; }\n.throttle-button--linkDanger { background: none; border: none; color: var(--throttle-color-danger); padding-inline: 0; padding-block: var(--throttle-space-3); margin-block: calc(var(--throttle-space-3) * -1); min-height: 0; text-decoration: underline; width: auto; }\n.throttle-button--linkDanger:hover:not(:disabled) { opacity: .8; }\n.throttle-button--xs { font-size: var(--throttle-font-size-xs); }\n\n.throttle-alert { border-radius: var(--throttle-radius-sm); padding: var(--throttle-space-3); font-size: var(--throttle-font-size-sm); }\n.throttle-alert--error { background: var(--throttle-color-danger-surface); border: var(--throttle-border-width) solid var(--throttle-color-danger-border); color: var(--throttle-color-danger); }\n.throttle-alert--success { background: var(--throttle-color-success-surface); border: var(--throttle-border-width) solid var(--throttle-color-success-border); color: var(--throttle-color-success); }\n.throttle-alert--info { background: var(--throttle-color-surface); color: var(--throttle-color-muted-foreground); }\n\n.throttle-spinner {\n display: inline-block; width: 1em; height: 1em;\n border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;\n animation: throttle-spin 700ms linear infinite;\n}\n@keyframes throttle-spin { to { transform: rotate(360deg); } }\n.throttle-button--loading { position: relative; }\n.throttle-button__label { display: inline-flex; align-items: center; justify-content: center; gap: var(--throttle-space-2); }\n.throttle-button__label--hidden { visibility: hidden; }\n.throttle-spinner--centred { position: absolute; top: 50%; left: 50%; margin: -0.5em 0 0 -0.5em; }\n\n@media (prefers-reduced-motion: reduce) { .throttle-spinner { animation-duration: 2.4s; } }\n\n.throttle-skeleton {\n background: var(--throttle-color-muted);\n border-radius: var(--throttle-radius-sm);\n animation: throttle-pulse 1.4s ease-in-out infinite; height: 2.5em; }\n@keyframes throttle-pulse { 50% { opacity: .5; } }\n@media (prefers-reduced-motion: reduce) { .throttle-skeleton { animation: none; } }\n\n.throttle-modal__overlay {\n position: fixed; inset: 0; z-index: var(--throttle-z-modal);\n background: rgba(14,17,22,.45);\n display: flex; align-items: center; justify-content: center;\n padding: var(--throttle-space-4);\n overflow-y: auto;\n}\n.throttle-modal__container {\n background: var(--throttle-color-background);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-popover);\n max-width: 720px; width: 100%; max-height: 90vh; overflow-y: auto;\n position: relative;\n}\n/* After the base rule on purpose: both are single-class, so equal specificity\n means source order decides. Declared before it, this silently lost. */\n.throttle-modal__container--compact { max-width: 440px; }\n.throttle-modal__close {\n position: absolute; top: var(--throttle-space-3); right: var(--throttle-space-3);\n background: none; border: none; cursor: pointer; font-size: var(--throttle-font-size-lg);\n color: var(--throttle-color-muted-foreground);\n transition: color var(--throttle-transition);\n}\n.throttle-modal__close:hover { color: var(--throttle-color-foreground); }\n.throttle-modal__header { padding: var(--throttle-space-4) var(--throttle-space-4) 0; }\n.throttle-modal__title { font-size: var(--throttle-font-size-lg); line-height: var(--throttle-line-height-tight); font-weight: 600; margin: 0; }\n.throttle-modal__body { padding: var(--throttle-space-4); }\n\n.throttle-dropdown__trigger { background: none; border: none; cursor: pointer; padding: 0; border-radius: var(--throttle-radius-full); transition: background-color var(--throttle-transition); }\n.throttle-dropdown__trigger:hover { background: var(--throttle-color-surface); }\n.throttle-dropdown__trigger:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: 2px; }\n.throttle-dropdown__menu {\n position: absolute; right: 0; top: calc(100% + var(--throttle-space-2));\n z-index: var(--throttle-z-popover);\n min-width: 260px;\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-popover);\n padding: var(--throttle-space-1);\n}\n.throttle-dropdown__item {\n display: flex; align-items: center; gap: var(--throttle-space-2);\n width: 100%; text-align: left; font: inherit; color: inherit;\n background: none; border: none; cursor: pointer;\n padding: var(--throttle-space-3);\n border-radius: var(--throttle-radius-sm);\n text-decoration: none;\n transition: background-color var(--throttle-transition);\n}\n.throttle-dropdown__item:hover { background: var(--throttle-color-surface); }\n.throttle-dropdown__item:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-dropdown__separator { height: 1px; background: var(--throttle-color-border); margin: var(--throttle-space-1) 0; border: 0; }\n\n.throttle-tabs__list {\n display: flex; gap: var(--throttle-space-1);\n border-bottom: var(--throttle-border-width) solid var(--throttle-color-border);\n overflow-x: auto; scrollbar-width: thin;\n}\n.throttle-tabs__tab {\n font: inherit; background: none; border: none; cursor: pointer; white-space: nowrap;\n padding: var(--throttle-space-3);\n color: var(--throttle-color-muted-foreground);\n border-bottom: 2px solid transparent;\n transition: color var(--throttle-transition), border-color var(--throttle-transition);\n}\n.throttle-tabs__tab:hover { color: var(--throttle-color-foreground); }\n.throttle-tabs__tab--active { color: var(--throttle-color-foreground); border-bottom-color: var(--throttle-color-primary); }\n.throttle-tabs__panel { padding-top: var(--throttle-space-4); }\n\n/* Paints its own ground. A UserButton in a navbar should stay transparent, but\n the dashboard is a large surface of themed text: in dark theme its foreground\n is near-white, so on a light host page it was rendering white-on-white. */\n.throttle-cardframe { width: 100%; min-height: 420px; border: 0; display: block; }\n.throttle-centre { display: flex; align-items: center; justify-content: center; min-height: 160px; }\n.throttle-fieldrow { display: grid; grid-template-columns: 1fr 1fr; gap: var(--throttle-space-4); align-items: start; }\n.throttle-section__title { font-size: var(--throttle-font-size-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--throttle-color-muted-foreground); margin: 0 0 var(--throttle-space-2); font-weight: 600; }\n.throttle-addresses { display: grid; grid-template-columns: 1fr 1fr; gap: var(--throttle-space-5); }\n.throttle-addressblock__line { margin: 0 0 2px; }\n.throttle-timeline { display: flex; flex-direction: column; gap: var(--throttle-space-2); }\n.throttle-timeline__row { display: flex; align-items: center; gap: var(--throttle-space-2); }\n.throttle-timeline__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--throttle-color-border-control); flex: none; }\n.throttle-timeline__label { flex: 1; }\n.throttle-account-root { container-type: inline-size; background: var(--throttle-color-account-surface); color: var(--throttle-color-foreground); padding: var(--throttle-account-padding); }\n.throttle-account { display: flex; gap: var(--throttle-space-5); align-items: flex-start; }\n.throttle-account__content { flex: 1; min-width: 0; }\n.throttle-tabs__rail { flex: none; width: 220px; display: flex; flex-direction: column; gap: 2px; }\n.throttle-tabs__railitem {\n font: inherit;\n font-size: var(--throttle-font-size-sm);\n display: flex;\n align-items: center;\n gap: var(--throttle-space-3);\n width: 100%;\n text-align: left;\n background: none;\n border: none;\n border-radius: var(--throttle-radius-sm);\n padding: 0 var(--throttle-space-3);\n min-height: var(--throttle-control-height);\n color: var(--throttle-color-muted-foreground);\n cursor: pointer;\n transition: background var(--throttle-transition), color var(--throttle-transition);\n}\n.throttle-tabs__railitem:hover { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); }\n.throttle-tabs__railitem:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-tabs__tab:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-tabs__railitem--active { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); font-weight: 500; }\n.throttle-tabs__railicon { flex: none; opacity: .75; }\n\n/* A CONTAINER query, not a viewport one: these components render inside a\n merchant's page, so the viewport says nothing about how much room the\n dashboard actually has \u2014 it could sit in a 400px column on a 1920px screen.\n Below ~560px of container the rail becomes a full-width list above the\n panel: all seven still visible, each still a 44px target. */\n@container (max-width: 560px) {\n /* align-items: flex-start is right in row direction and wrong in column \u2014\n it shrinks the rail to its content width, so width:100% alone cannot make\n it span. Stretch it explicitly when stacked. */\n .throttle-account { flex-direction: column; align-items: stretch; gap: var(--throttle-space-4); }\n .throttle-addresses { grid-template-columns: 1fr; }\n .throttle-fieldrow { grid-template-columns: 1fr; }\n .throttle-tabs__rail { width: 100%; }\n /* One column, and the rail stops sticking \u2014 on a phone a sticky summary\n covers the very line items it is summarising. */\n .throttle-detail { grid-template-columns: 1fr; }\n .throttle-detail__rail { position: static; }\n}\n\n.throttle-table { width: 100%; border-collapse: collapse; text-align: left; }\n.throttle-table__head { color: var(--throttle-color-muted-foreground); font-weight: 500; font-size: var(--throttle-font-size-sm); }\n.throttle-table__row { border-top: var(--throttle-border-width) solid var(--throttle-color-border); cursor: pointer; transition: background-color var(--throttle-transition); }\n.throttle-table__row:hover { background: var(--throttle-color-surface); }\n.throttle-table__row:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-table__cell { padding: var(--throttle-space-3) var(--throttle-space-2); height: 56px; box-sizing: border-box; }\n.throttle-table__scroll { overflow-x: auto; }\n\n.throttle-empty { text-align: center; padding: var(--throttle-space-6) var(--throttle-space-4); }\n.throttle-empty__title { font-weight: 600; margin: 0 0 var(--throttle-space-1); }\n.throttle-empty__description { color: var(--throttle-color-muted-foreground); margin: 0; }\n\n.throttle-avatar {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; border-radius: var(--throttle-radius-full);\n background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground);\n font-size: var(--throttle-font-size-xs); font-weight: 600; text-transform: uppercase;\n}\n\n.throttle-badge {\n display: inline-block; font-size: var(--throttle-font-size-xs); font-weight: 500;\n padding: 2px var(--throttle-space-2); border-radius: var(--throttle-radius-full);\n background: var(--throttle-color-muted); color: var(--throttle-color-muted-foreground);\n}\n.throttle-badge--muted { background: none; border: var(--throttle-border-width) solid var(--throttle-color-border); color: var(--throttle-color-muted-foreground); font-weight: 400; padding: 1px calc(var(--throttle-space-2) - 1px); }\n.throttle-badge--success { background: color-mix(in srgb, var(--throttle-color-success) 15%, transparent); color: var(--throttle-color-success); }\n.throttle-badge--warning { background: color-mix(in srgb, var(--throttle-color-warning) 15%, transparent); color: var(--throttle-color-warning); }\n.throttle-badge--danger { background: color-mix(in srgb, var(--throttle-color-danger) 15%, transparent); color: var(--throttle-color-danger); }\n\n.throttle-stack { display: flex; flex-direction: column; gap: var(--throttle-space-3); }\n.throttle-row { display: flex; align-items: center; justify-content: space-between; gap: var(--throttle-space-2); flex-wrap: wrap; }\n.throttle-muted { color: var(--throttle-color-muted-foreground); }\n.throttle-banner {\n display: flex; align-items: center; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n background: color-mix(in srgb, var(--throttle-color-warning) 12%, transparent);\n color: var(--throttle-color-warning);\n border-radius: var(--throttle-radius-sm);\n padding: var(--throttle-space-3);\n margin-bottom: var(--throttle-space-4);\n}\n.throttle-panel { display: flex; flex-direction: column; gap: var(--throttle-space-4); }\n/* 100dvh, not 100vh: on mobile browsers 100vh includes the space behind the\n dynamic address/toolbar, so the page would be taller than the visible\n viewport and the card would sit off-centre until the toolbar collapsed. */\n.throttle-page {\n min-height: 100dvh;\n width: 100%;\n background: var(--throttle-color-surface);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--throttle-space-5);\n padding: var(--throttle-space-5);\n}\n.throttle-page__logo { display: flex; justify-content: center; }\n.throttle-page__footer { color: var(--throttle-color-muted-foreground); text-align: center; font-size: var(--throttle-font-size-sm); }\n.throttle-listitem {\n display: flex; align-items: flex-start; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-sm);\n padding: var(--throttle-space-3);\n}\n/* 'rows' variant: hairline rules between items instead of each item carrying\n its own border+radius, so a panel does not read as a card inside a card. */\n.throttle-rows { display: flex; flex-direction: column; }\n.throttle-rowitem {\n display: flex; align-items: flex-start; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n border-top: var(--throttle-border-width) solid var(--throttle-color-border);\n padding: var(--throttle-space-3) 0;\n}\n.throttle-rowitem:first-child { border-top: none; padding-top: 0; }\n.throttle-actions {\n display: flex; gap: var(--throttle-space-2); flex-wrap: wrap; align-items: center;\n /* Primary buttons are full-width so a form's submit fills its card. In a row\n of sibling actions that same rule made every button claim 100% and then\n shrink to share the line, squeezing Resume to 59px so its label wrapped to\n two lines inside a 48px box. A custom property INHERITS to the buttons, so\n the row opts them back to content width without a descendant selector \u2014\n those outrank the merchant overrides in appearance.elements. */\n --throttle-button-width: auto;\n}\n.throttle-table__money { display: block; text-align: right; font-variant-numeric: tabular-nums; }\n.throttle-lineitem { display: flex; align-items: flex-start; gap: var(--throttle-space-3); padding: var(--throttle-space-2) 0; }\n/* The UA's 1em paragraph margins pushed a two-line item to 96px, so five\n items filled a screen with mostly whitespace. These carry the spacing\n instead. Separate classes, not a \".throttle-lineitem p\" descendant\n selector -- those outrank the merchant's appearance.elements overrides. */\n.throttle-lineitem__desc { margin: var(--throttle-space-1) 0 0; color: var(--throttle-color-muted-foreground); }\n.throttle-lineitem__meta { margin: var(--throttle-space-1) 0 0; color: var(--throttle-color-muted-foreground); font-size: var(--throttle-font-size-sm); }\n.throttle-lineitem__image { width: 48px; height: 48px; object-fit: cover; border-radius: var(--throttle-radius-sm); flex: none; }\n.throttle-totals { display: flex; flex-direction: column; gap: var(--throttle-space-1); }\n\n/* Order and invoice detail: the record on the left, what it costs and what\n you can do about it on the right. The rail sticks so the total and the\n actions stay reachable on an order with thirty lines, which is exactly when\n a buyer most wants them. Collapses below, where a sticky rail would eat a\n phone screen. */\n.throttle-detail { display: grid; grid-template-columns: minmax(0, 1fr) 17rem; gap: var(--throttle-space-6); align-items: start; }\n.throttle-detail__main { display: flex; flex-direction: column; gap: var(--throttle-space-5); min-width: 0; }\n.throttle-detail__rail {\n display: flex; flex-direction: column; gap: var(--throttle-space-4);\n position: sticky; top: var(--throttle-space-4);\n padding: var(--throttle-space-4);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-md);\n background: var(--throttle-color-surface);\n}\n/* The one number the buyer came for. */\n.throttle-detail__headline { font-size: var(--throttle-font-size-xl); font-weight: 600; line-height: 1.2; }\n.throttle-detail__section { display: flex; flex-direction: column; gap: var(--throttle-space-2); }\n.throttle-detail__label { font-size: var(--throttle-font-size-sm); font-weight: 500; color: var(--throttle-color-muted-foreground); letter-spacing: .04em; text-transform: uppercase; }\n/* A rail action column: full width, stacked, so the primary reads as primary. */\n.throttle-detail__actions { display: flex; flex-direction: column; gap: var(--throttle-space-2); --throttle-button-width: 100%; }\n.throttle-detail__link { display: inline-flex; align-items: center; gap: var(--throttle-space-1); }\n\n@media (prefers-reduced-motion: reduce) {\n .throttle-button, .throttle-field__input, .throttle-dropdown__item, .throttle-dropdown__trigger, .throttle-tabs__tab, .throttle-table__row, .throttle-modal__close {\n transition: none;\n }\n}\n";
490
512
 
491
513
  /**
492
514
  * The only place minor units become major units. Every amount on the wire is
@@ -737,15 +759,22 @@ declare function OrderDetail(props: {
737
759
  orderId: string;
738
760
  onBack?(): void;
739
761
  onViewSubscription?(id: string): void;
762
+ onViewInvoice?(id: string): void;
740
763
  /**
741
- * Status-dependent actions. Each renders ONLY when its handler is supplied,
742
- * because the buyer plane has no commerce writes: a built-in Cancel or Track
743
- * button would be a control that always fails. The merchant owns the
744
- * behaviour, the component owns when it is offered.
764
+ * Status-dependent actions the MERCHANT owns. Each renders only when its
765
+ * handler is supplied, because the buyer plane cannot perform them: a
766
+ * built-in Pay or Track button would be a control that always fails.
745
767
  */
746
768
  onPayNow?(order: OrderActionTarget): void;
747
769
  onReorder?(order: OrderActionTarget): void;
748
770
  onTrackShipment?(order: OrderActionTarget): void;
771
+ /**
772
+ * Cancel and return, by contrast, ARE buyer-plane capabilities, so they are
773
+ * wired in here and need no handler. Opt out with `false` for a storefront
774
+ * that handles them elsewhere.
775
+ */
776
+ allowCancel?: boolean;
777
+ allowReturn?: boolean;
749
778
  appearance?: ThrottleAppearance;
750
779
  localization?: ThrottleLocalization;
751
780
  }): react_jsx_runtime.JSX.Element;
@@ -754,11 +783,38 @@ declare function InvoicesPanel(props: {
754
783
  appearance?: ThrottleAppearance;
755
784
  localization?: ThrottleLocalization;
756
785
  variant?: AccountPanelVariant;
786
+ /** Navigation out of an invoice, forwarded to `InvoiceDetail`. */
787
+ onViewOrder?(orderId: string): void;
788
+ onViewSubscription?(subscriptionId: string): void;
789
+ onPay?(invoice: {
790
+ id: string;
791
+ number: string;
792
+ total: number;
793
+ currency: string;
794
+ }): void;
795
+ /** Opens straight to this invoice. Set by the dashboard on cross-panel navigation. */
796
+ initialOpenId?: string | null;
757
797
  }): react_jsx_runtime.JSX.Element;
758
798
 
759
799
  declare function InvoiceDetail(props: {
760
800
  invoiceId: string;
761
801
  onBack?(): void;
802
+ /**
803
+ * Navigation out of the invoice. An invoice is a record OF something — an
804
+ * order or a subscription — and without these it was a dead end: the buyer
805
+ * could read what they were charged but not reach the thing that charged
806
+ * them. Each link renders only when the handler is supplied AND the server
807
+ * resolved the id.
808
+ */
809
+ onViewOrder?(orderId: string): void;
810
+ onViewSubscription?(subscriptionId: string): void;
811
+ /** Settle an open invoice. Merchant-owned, like the order's Pay now. */
812
+ onPay?(invoice: {
813
+ id: string;
814
+ number: string;
815
+ total: number;
816
+ currency: string;
817
+ }): void;
762
818
  appearance?: ThrottleAppearance;
763
819
  localization?: ThrottleLocalization;
764
820
  }): react_jsx_runtime.JSX.Element;
@@ -44,7 +44,7 @@ type ThrottleVariables = Partial<Record<keyof typeof VARIABLE_PROPERTY, string>>
44
44
  * rendered element without adding its key here ships something a merchant
45
45
  * cannot restyle, which the drift test in Task 15 catches.
46
46
  */
47
- declare const THROTTLE_ELEMENT_KEYS: readonly ["card", "card.header", "card.title", "card.description", "card.body", "card.footer", "card.logo", "field", "field.label", "field.input", "field.hint", "field.error", "field.group", "button", "alert", "spinner", "skeleton", "avatar", "badge", "emptyState", "emptyState.title", "emptyState.description", "modal.overlay", "modal.container", "modal.closeButton", "dropdown.trigger", "dropdown.menu", "dropdown.item", "dropdown.separator", "tabs.list", "tabs.tab", "table", "table.head", "table.row", "table.cell", "signIn.root", "signIn.title", "signIn.logo", "signIn.emailField", "signIn.passwordField", "signIn.submitButton", "signIn.forgotLink", "signIn.switchLink", "signUp.root", "signUp.title", "signUp.logo", "signUp.emailField", "signUp.passwordField", "signUp.submitButton", "signUp.switchLink", "forgotPassword.root", "forgotPassword.title", "forgotPassword.logo", "forgotPassword.emailField", "forgotPassword.submitButton", "forgotPassword.backLink", "resetPassword.root", "resetPassword.title", "resetPassword.logo", "resetPassword.passwordField", "resetPassword.submitButton", "verifyEmail.root", "verifyEmail.title", "verifyEmail.logo", "verifyEmail.resendButton", "authFlow.root", "authModal.overlay", "authModal.container", "signInButton.root", "signUpButton.root", "signOutButton.root", "stepUp.root", "stepUp.title", "stepUp.passwordField", "stepUp.submitButton", "stepUp.cancelButton", "signInPage.root", "signInPage.logo", "signInPage.footer", "signUpPage.root", "signUpPage.logo", "signUpPage.footer", "userButton.root", "userButton.trigger", "userButton.menu", "userButton.identity", "userButton.email", "userButton.badge", "userButton.item", "userButton.manageButton", "userButton.signOutButton", "userButton.signOutAllButton", "accountDashboard.root", "accountDashboard.tabs", "accountDashboard.sidebar", "accountDashboard.panel", "accountModal.overlay", "accountModal.container", "accountModal.header", "accountModal.title", "accountModal.body", "verifyBanner.root", "verifyBanner.message", "verifyBanner.resendButton", "verifyBanner.dismissButton", "profilePanel.root", "profilePanel.form", "profilePanel.submitButton", "addressesPanel.root", "addressesPanel.list", "addressesPanel.item", "addressesPanel.addButton", "addressesPanel.form", "addressesPanel.defaultButton", "addressesPanel.editButton", "addressesPanel.deleteButton", "addressesPanel.table", "addressesPanel.row", "paymentMethodsPanel.root", "paymentMethodsPanel.list", "paymentMethodsPanel.item", "paymentMethodsPanel.defaultButton", "paymentMethodsPanel.deleteButton", "paymentMethodsPanel.addButton", "paymentMethodsPanel.addDialog", "orderDetail.addresses", "orderDetail.shippingAddress", "orderDetail.billingAddress", "orderDetail.timeline", "orderDetail.payButton", "orderDetail.trackButton", "orderDetail.reorderButton", "fieldRow", "confirm.header", "confirm.title", "confirm.body", "confirm.confirmButton", "confirm.cancelButton", "paymentMethodsPanel.table", "paymentMethodsPanel.row", "ordersPanel.root", "ordersPanel.table", "ordersPanel.row", "ordersPanel.list", "ordersPanel.item", "ordersPanel.viewButton", "orderDetail.root", "orderDetail.backButton", "orderDetail.lineItems", "orderDetail.lineItem", "orderDetail.totals", "invoicesPanel.root", "invoicesPanel.table", "invoicesPanel.row", "invoicesPanel.list", "invoicesPanel.item", "invoicesPanel.viewButton", "invoiceDetail.root", "invoiceDetail.backButton", "invoiceDetail.downloadButton", "invoiceDetail.totals", "subscriptionsPanel.root", "subscriptionsPanel.list", "subscriptionsPanel.item", "subscriptionsPanel.cancelButton", "subscriptionsPanel.cancelNowButton", "subscriptionsPanel.pauseButton", "subscriptionsPanel.resumeButton", "subscriptionsPanel.table", "subscriptionsPanel.row", "securityPanel.root", "securityPanel.passwordForm", "securityPanel.passwordButton", "securityPanel.sessionList", "securityPanel.sessionItem", "securityPanel.revokeButton", "securityPanel.revokeAllButton", "securityPanel.table", "securityPanel.row"];
47
+ declare const THROTTLE_ELEMENT_KEYS: readonly ["card", "card.header", "card.title", "card.description", "card.body", "card.footer", "card.logo", "field", "field.label", "field.input", "field.hint", "field.error", "field.group", "button", "alert", "spinner", "skeleton", "avatar", "badge", "emptyState", "emptyState.title", "emptyState.description", "modal.overlay", "modal.container", "modal.closeButton", "dropdown.trigger", "dropdown.menu", "dropdown.item", "dropdown.separator", "tabs.list", "tabs.tab", "table", "table.head", "table.row", "table.cell", "signIn.root", "signIn.title", "signIn.logo", "signIn.emailField", "signIn.passwordField", "signIn.submitButton", "signIn.forgotLink", "signIn.switchLink", "signUp.root", "signUp.title", "signUp.logo", "signUp.emailField", "signUp.passwordField", "signUp.submitButton", "signUp.switchLink", "forgotPassword.root", "forgotPassword.title", "forgotPassword.logo", "forgotPassword.emailField", "forgotPassword.submitButton", "forgotPassword.backLink", "resetPassword.root", "resetPassword.title", "resetPassword.logo", "resetPassword.passwordField", "resetPassword.submitButton", "verifyEmail.root", "verifyEmail.title", "verifyEmail.logo", "verifyEmail.resendButton", "authFlow.root", "authModal.overlay", "authModal.container", "signInButton.root", "signUpButton.root", "signOutButton.root", "stepUp.root", "stepUp.title", "stepUp.passwordField", "stepUp.submitButton", "stepUp.cancelButton", "signInPage.root", "signInPage.logo", "signInPage.footer", "signUpPage.root", "signUpPage.logo", "signUpPage.footer", "userButton.root", "userButton.trigger", "userButton.menu", "userButton.identity", "userButton.email", "userButton.badge", "userButton.item", "userButton.manageButton", "userButton.signOutButton", "userButton.signOutAllButton", "accountDashboard.root", "accountDashboard.tabs", "accountDashboard.sidebar", "accountDashboard.panel", "accountModal.overlay", "accountModal.container", "accountModal.header", "accountModal.title", "accountModal.body", "verifyBanner.root", "verifyBanner.message", "verifyBanner.resendButton", "verifyBanner.dismissButton", "profilePanel.root", "profilePanel.form", "profilePanel.submitButton", "addressesPanel.root", "addressesPanel.list", "addressesPanel.item", "addressesPanel.addButton", "addressesPanel.form", "addressesPanel.defaultButton", "addressesPanel.editButton", "addressesPanel.deleteButton", "addressesPanel.table", "addressesPanel.row", "paymentMethodsPanel.root", "paymentMethodsPanel.list", "paymentMethodsPanel.item", "paymentMethodsPanel.defaultButton", "paymentMethodsPanel.deleteButton", "paymentMethodsPanel.addButton", "paymentMethodsPanel.addDialog", "orderDetail.addresses", "orderDetail.shippingAddress", "orderDetail.billingAddress", "orderDetail.timeline", "orderDetail.payButton", "orderDetail.trackButton", "orderDetail.reorderButton", "orderDetail.layout", "orderDetail.main", "orderDetail.rail", "orderDetail.cancelButton", "orderDetail.returnButton", "orderDetail.invoiceButton", "orderDetail.actions", "invoiceDetail.layout", "invoiceDetail.main", "invoiceDetail.rail", "invoiceDetail.lineItems", "invoiceDetail.lineItem", "invoiceDetail.orderLink", "invoiceDetail.subscriptionLink", "invoiceDetail.payButton", "invoiceDetail.actions", "fieldRow", "confirm.header", "confirm.title", "confirm.body", "confirm.confirmButton", "confirm.cancelButton", "paymentMethodsPanel.table", "paymentMethodsPanel.row", "ordersPanel.root", "ordersPanel.table", "ordersPanel.row", "ordersPanel.list", "ordersPanel.item", "ordersPanel.viewButton", "orderDetail.root", "orderDetail.backButton", "orderDetail.lineItems", "orderDetail.lineItem", "orderDetail.totals", "invoicesPanel.root", "invoicesPanel.table", "invoicesPanel.row", "invoicesPanel.list", "invoicesPanel.item", "invoicesPanel.viewButton", "invoiceDetail.root", "invoiceDetail.backButton", "invoiceDetail.downloadButton", "invoiceDetail.totals", "subscriptionsPanel.root", "subscriptionsPanel.list", "subscriptionsPanel.item", "subscriptionsPanel.cancelButton", "subscriptionsPanel.cancelNowButton", "subscriptionsPanel.pauseButton", "subscriptionsPanel.resumeButton", "subscriptionsPanel.table", "subscriptionsPanel.row", "securityPanel.root", "securityPanel.passwordForm", "securityPanel.passwordButton", "securityPanel.sessionList", "securityPanel.sessionItem", "securityPanel.revokeButton", "securityPanel.revokeAllButton", "securityPanel.table", "securityPanel.row"];
48
48
  type ThrottleElementKey = (typeof THROTTLE_ELEMENT_KEYS)[number];
49
49
  interface ThrottleSlots {
50
50
  Spinner?: ComponentType<{
@@ -222,6 +222,17 @@ declare const enUS: {
222
222
  payNow: string;
223
223
  track: string;
224
224
  reorder: string;
225
+ cancelOrder: string;
226
+ cancelOrderConfirm: string;
227
+ cancelOrderBody: string;
228
+ cancelOrderAction: string;
229
+ requestReturn: string;
230
+ requestReturnConfirm: string;
231
+ requestReturnBody: string;
232
+ requestReturnAction: string;
233
+ returnRequested: string;
234
+ downloadInvoice: string;
235
+ summary: string;
225
236
  empty: string;
226
237
  emptyDescription: string;
227
238
  gatedDescription: string;
@@ -285,6 +296,12 @@ declare const enUS: {
285
296
  refunded: string;
286
297
  period: string;
287
298
  downloadButton: string;
299
+ items: string;
300
+ summary: string;
301
+ viewOrder: string;
302
+ viewSubscription: string;
303
+ payButton: string;
304
+ billedTo: string;
288
305
  /** Display copy for `invoice.status` — the wire values are paid|open|void. */
289
306
  statusLabels: {
290
307
  paid: string;
@@ -393,6 +410,11 @@ declare function OrdersPanel(props: OrderActionHandlers & {
393
410
  localization?: ThrottleLocalization;
394
411
  variant?: AccountPanelVariant;
395
412
  onViewSubscription?(id: string): void;
413
+ /** Forwarded to `OrderDetail`, where both default to on. */
414
+ allowCancel?: boolean;
415
+ allowReturn?: boolean;
416
+ /** Opens straight to this order. Set by the dashboard on cross-panel navigation. */
417
+ initialOpenId?: string | null;
396
418
  }): react_jsx_runtime.JSX.Element;
397
419
 
398
420
  type AccountTab = 'profile' | 'addresses' | 'paymentMethods' | 'orders' | 'invoices' | 'subscriptions' | 'security';
@@ -486,7 +508,7 @@ declare const THROTTLE_STYLE_ID = "throttle-auth-styles";
486
508
  * specificity plus source order is what lets them win. A descendant selector
487
509
  * here would silently outrank them.
488
510
  */
489
- declare const THROTTLE_STYLES = "\n.throttle-root {\n --throttle-color-primary: #18181b;\n --throttle-color-primary-foreground: #ffffff;\n --throttle-color-background: #ffffff;\n --throttle-color-surface: #f8fafc;\n --throttle-color-foreground: #0e1116;\n --throttle-color-muted: #eceef2;\n --throttle-color-muted-foreground: #5b6472;\n --throttle-color-border: #e2e8f0;\n /* The boundary of an INTERACTIVE control, which WCAG 1.4.11 requires to\n reach 3:1 against its adjacent colour \u2014 an input identified only by a\n 1.23:1 hairline is not identifiable at all. Decorative separators (card\n edges, table rules, dividers) keep --throttle-color-border: they do not\n identify a control, so the requirement does not apply and darkening\n them would only add noise. */\n /* The account dashboard paints nothing by default so it can drop into a\n merchant's page without fighting their background. The accountSurface and\n accountPadding appearance variables opt back into a card.\n No backticks in this comment: the sheet is a TS template literal. */\n --throttle-card-width: 400px;\n --throttle-color-account-surface: transparent;\n --throttle-account-padding: 0;\n --throttle-color-border-control: #8b93a1;\n --throttle-color-danger: #c2321f;\n --throttle-color-danger-surface: #fef2f2;\n --throttle-color-danger-border: #fecaca;\n --throttle-color-success: #127a4a;\n --throttle-color-success-surface: #ecfdf5;\n --throttle-color-success-border: #a7f3d0;\n --throttle-color-warning: #92400e;\n --throttle-color-warning-surface: #fffbeb;\n --throttle-color-warning-border: #fde68a;\n --throttle-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n --throttle-font-size: 16px;\n --throttle-font-size-xs: 12px;\n --throttle-font-size-sm: 14px;\n --throttle-font-size-lg: 20px;\n --throttle-font-size-xl: 24px;\n --throttle-line-height: 1.5;\n --throttle-line-height-tight: 1.25;\n --throttle-radius: 12px;\n --throttle-radius-sm: 8px;\n --throttle-radius-full: 999px;\n --throttle-border-width: 1px;\n --throttle-spacing: 8px;\n --throttle-space-1: 4px;\n --throttle-space-2: var(--throttle-spacing);\n --throttle-space-3: 12px;\n --throttle-space-4: 16px;\n --throttle-space-5: 24px;\n --throttle-space-6: 32px;\n --throttle-control-height: 48px;\n --throttle-control-padding-x: 16px;\n --throttle-shadow-card: 0 1px 3px rgba(15,23,42,.08), 0 1px 2px rgba(15,23,42,.04);\n --throttle-shadow-popover: 0 10px 24px rgba(15,23,42,.12), 0 2px 6px rgba(15,23,42,.06);\n --throttle-transition: 150ms cubic-bezier(.2,0,.2,1);\n --throttle-z-modal: 2147483000;\n --throttle-z-popover: 2147482000;\n font-family: var(--throttle-font-family);\n font-size: var(--throttle-font-size);\n line-height: var(--throttle-line-height);\n color: var(--throttle-color-foreground);\n box-sizing: border-box;\n}\n.throttle-root *, .throttle-root *::before, .throttle-root *::after { box-sizing: inherit; }\n\n.throttle-root[data-throttle-theme=\"dark\"] {\n --throttle-color-primary: #e6edf3;\n --throttle-color-primary-foreground: #0d1117;\n --throttle-color-background: #0d1117;\n --throttle-color-surface: #1c2129;\n --throttle-color-foreground: #e6edf3;\n --throttle-color-muted: #21262d;\n --throttle-color-muted-foreground: #9aa4b2;\n --throttle-color-border: #30363d;\n --throttle-color-border-control: #5c6570;\n --throttle-color-danger: #ff6b58;\n --throttle-color-danger-surface: #2a1513;\n --throttle-color-danger-border: #5c2b25;\n --throttle-color-success: #45c08a;\n --throttle-color-success-surface: #0f2419;\n --throttle-color-success-border: #1f4d36;\n --throttle-color-warning: #e0a53a;\n --throttle-color-warning-surface: #2a2113;\n --throttle-color-warning-border: #5c4a25;\n --throttle-shadow-card: 0 1px 3px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.4);\n --throttle-shadow-popover: 0 10px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.35);\n}\n@media (prefers-color-scheme: dark) {\n .throttle-root[data-throttle-theme=\"auto\"] {\n --throttle-color-primary: #e6edf3;\n --throttle-color-primary-foreground: #0d1117;\n --throttle-color-background: #0d1117;\n --throttle-color-surface: #1c2129;\n --throttle-color-foreground: #e6edf3;\n --throttle-color-muted: #21262d;\n --throttle-color-muted-foreground: #9aa4b2;\n --throttle-color-border: #30363d;\n --throttle-color-border-control: #5c6570;\n --throttle-color-danger: #ff6b58;\n --throttle-color-danger-surface: #2a1513;\n --throttle-color-danger-border: #5c2b25;\n --throttle-color-success: #45c08a;\n --throttle-color-success-surface: #0f2419;\n --throttle-color-success-border: #1f4d36;\n --throttle-color-warning: #e0a53a;\n --throttle-color-warning-surface: #2a2113;\n --throttle-color-warning-border: #5c4a25;\n --throttle-shadow-card: 0 1px 3px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.4);\n --throttle-shadow-popover: 0 10px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.35);\n }\n}\n\n.throttle-card {\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-card);\n padding: var(--throttle-space-5);\n width: 100%;\n max-width: var(--throttle-card-width);\n margin-inline: auto;\n}\n/* Inside a Modal the dialog already provides the surface \u2014 background, radius\n and elevation. A card that draws its own on top is the \"box inside a box\":\n two shadowed rounded rectangles nested, with the card's max-width stranding\n it in the middle of a much wider dialog. */\n.throttle-card--bare { border: none; box-shadow: none; background: none; max-width: none; }\n.throttle-card__header { margin-bottom: var(--throttle-space-4); }\n.throttle-card__header--branded { text-align: center; }\n.throttle-card__logo { display: flex; justify-content: center; margin-bottom: var(--throttle-space-3); }\n.throttle-card__title { font-size: var(--throttle-font-size-xl); line-height: var(--throttle-line-height-tight); font-weight: 600; letter-spacing: -0.02em; margin: 0; }\n.throttle-card__title--branded { font-size: var(--throttle-font-size-xl); }\n.throttle-card__description { color: var(--throttle-color-muted-foreground); margin: var(--throttle-space-1) 0 0; }\n.throttle-card__body { display: flex; flex-direction: column; gap: var(--throttle-space-3); }\n.throttle-card__footer { margin-top: var(--throttle-space-4); text-align: center; }\n.throttle-card__footer--ruled { border-top: var(--throttle-border-width) solid var(--throttle-color-border); padding-top: var(--throttle-space-4); }\n\n.throttle-field { display: flex; flex-direction: column; gap: var(--throttle-space-1); }\n.throttle-field__labelrow { display: flex; align-items: baseline; justify-content: space-between; gap: var(--throttle-space-2); }\n.throttle-field__label { font-weight: 500; }\n.throttle-field__input {\n font: inherit;\n font-size: var(--throttle-font-size);\n color: var(--throttle-color-foreground);\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border-control);\n border-radius: var(--throttle-radius-sm);\n /* padding-block stays 0 so min-height alone owns the height, exactly as\n .throttle-button does. With 12px vertical padding the box computed to\n 50px against the button's 48px \u2014 a 2px mismatch, measured in a browser\n across 19 controls. An input element centres its own text vertically. */\n padding-block: 0;\n padding-inline: var(--throttle-control-padding-x);\n min-height: var(--throttle-control-height);\n width: 100%;\n transition: border-color var(--throttle-transition), box-shadow var(--throttle-transition);\n}\n.throttle-field__input:focus-visible {\n outline: none;\n border-color: var(--throttle-color-primary);\n box-shadow: 0 0 0 2px var(--throttle-color-background), 0 0 0 4px var(--throttle-color-primary);\n}\n.throttle-field__input:disabled { background: var(--throttle-color-muted); color: var(--throttle-color-muted-foreground); cursor: not-allowed; }\n.throttle-field__input::placeholder { color: var(--throttle-color-muted-foreground); opacity: 1; }\n.throttle-field__input--grouped { border: none; border-radius: 0; padding-inline: 0; }\n.throttle-field__hint { color: var(--throttle-color-muted-foreground); font-size: var(--throttle-font-size-xs); }\n/* Always mounted, so it reserves its line whether or not there is an error:\n an error appearing on submit must not push the submit button out from\n under the buyer's pointer. */\n.throttle-field__error { color: var(--throttle-color-danger); font-size: var(--throttle-font-size-xs); line-height: 1rem; }\n/* Reserved a full line under EVERY input even with nothing to say, which\n with the stack gap put 28px of dead space beneath each field, on every\n form and all seven account panels. The element stays mounted when empty\n because role=alert only announces changes to a live region that was\n already there; it just stops occupying a line. */\n.throttle-field__error:empty { display: none; }\n\n.throttle-field-group {\n display: flex;\n flex-direction: column;\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-sm);\n overflow: hidden;\n}\n.throttle-field-group__item { padding: var(--throttle-space-3) var(--throttle-control-padding-x); }\n.throttle-field-group__divider { height: var(--throttle-border-width); background: var(--throttle-color-border); }\n.throttle-field-group__forgot { margin-left: auto; }\n\n.throttle-button {\n font: inherit;\n font-weight: 500;\n border-radius: var(--throttle-radius-sm);\n border: var(--throttle-border-width) solid transparent;\n padding-inline: var(--throttle-control-padding-x);\n padding-block: 0;\n min-height: var(--throttle-control-height);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: opacity var(--throttle-transition), background-color var(--throttle-transition), border-color var(--throttle-transition), filter var(--throttle-transition), box-shadow var(--throttle-transition);\n}\n.throttle-button:disabled { opacity: .55; cursor: not-allowed; }\n.throttle-button:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--throttle-color-background), 0 0 0 4px var(--throttle-color-primary); }\n.throttle-button--primary { background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground); width: 100%; }\n.throttle-button--primary:hover:not(:disabled) { filter: brightness(0.92); }\n.throttle-button--secondary { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); border-color: var(--throttle-color-border-control); }\n.throttle-button--secondary:hover:not(:disabled) { background: var(--throttle-color-muted); }\n.throttle-button--danger { background: transparent; color: var(--throttle-color-danger); border-color: var(--throttle-color-border); }\n.throttle-button--danger:hover:not(:disabled) { background: color-mix(in srgb, var(--throttle-color-danger) 10%, transparent); }\n/* Link-style actions are the rows panel default, and they carry Delete,\n Remove, Cancel and Sign out. Zero padding with min-height 0 made those\n roughly 20px tall and ~8px apart \u2014 a mis-tap on a phone lands on something\n irreversible. The target is expanded with vertical padding and pulled back\n with an equal negative margin, so the hit box clears 44px while the text\n sits exactly where it did. Collapsing this back to zero padding shrinks the\n target again. */\n.throttle-button--link { background: none; border: none; color: var(--throttle-color-primary); padding-inline: 0; padding-block: var(--throttle-space-3); margin-block: calc(var(--throttle-space-3) * -1); min-height: 0; text-decoration: underline; width: auto; }\n.throttle-button--link:hover:not(:disabled) { opacity: .8; }\n.throttle-button--linkDanger { background: none; border: none; color: var(--throttle-color-danger); padding-inline: 0; padding-block: var(--throttle-space-3); margin-block: calc(var(--throttle-space-3) * -1); min-height: 0; text-decoration: underline; width: auto; }\n.throttle-button--linkDanger:hover:not(:disabled) { opacity: .8; }\n.throttle-button--xs { font-size: var(--throttle-font-size-xs); }\n\n.throttle-alert { border-radius: var(--throttle-radius-sm); padding: var(--throttle-space-3); font-size: var(--throttle-font-size-sm); }\n.throttle-alert--error { background: var(--throttle-color-danger-surface); border: var(--throttle-border-width) solid var(--throttle-color-danger-border); color: var(--throttle-color-danger); }\n.throttle-alert--success { background: var(--throttle-color-success-surface); border: var(--throttle-border-width) solid var(--throttle-color-success-border); color: var(--throttle-color-success); }\n.throttle-alert--info { background: var(--throttle-color-surface); color: var(--throttle-color-muted-foreground); }\n\n.throttle-spinner {\n display: inline-block; width: 1em; height: 1em;\n border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;\n animation: throttle-spin 700ms linear infinite;\n}\n@keyframes throttle-spin { to { transform: rotate(360deg); } }\n.throttle-button--loading { position: relative; }\n.throttle-button__label { display: inline-flex; align-items: center; justify-content: center; gap: var(--throttle-space-2); }\n.throttle-button__label--hidden { visibility: hidden; }\n.throttle-spinner--centred { position: absolute; top: 50%; left: 50%; margin: -0.5em 0 0 -0.5em; }\n\n@media (prefers-reduced-motion: reduce) { .throttle-spinner { animation-duration: 2.4s; } }\n\n.throttle-skeleton {\n background: var(--throttle-color-muted);\n border-radius: var(--throttle-radius-sm);\n animation: throttle-pulse 1.4s ease-in-out infinite; height: 2.5em; }\n@keyframes throttle-pulse { 50% { opacity: .5; } }\n@media (prefers-reduced-motion: reduce) { .throttle-skeleton { animation: none; } }\n\n.throttle-modal__overlay {\n position: fixed; inset: 0; z-index: var(--throttle-z-modal);\n background: rgba(14,17,22,.45);\n display: flex; align-items: center; justify-content: center;\n padding: var(--throttle-space-4);\n overflow-y: auto;\n}\n.throttle-modal__container {\n background: var(--throttle-color-background);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-popover);\n max-width: 720px; width: 100%; max-height: 90vh; overflow-y: auto;\n position: relative;\n}\n/* After the base rule on purpose: both are single-class, so equal specificity\n means source order decides. Declared before it, this silently lost. */\n.throttle-modal__container--compact { max-width: 440px; }\n.throttle-modal__close {\n position: absolute; top: var(--throttle-space-3); right: var(--throttle-space-3);\n background: none; border: none; cursor: pointer; font-size: var(--throttle-font-size-lg);\n color: var(--throttle-color-muted-foreground);\n transition: color var(--throttle-transition);\n}\n.throttle-modal__close:hover { color: var(--throttle-color-foreground); }\n.throttle-modal__header { padding: var(--throttle-space-4) var(--throttle-space-4) 0; }\n.throttle-modal__title { font-size: var(--throttle-font-size-lg); line-height: var(--throttle-line-height-tight); font-weight: 600; margin: 0; }\n.throttle-modal__body { padding: var(--throttle-space-4); }\n\n.throttle-dropdown__trigger { background: none; border: none; cursor: pointer; padding: 0; border-radius: var(--throttle-radius-full); transition: background-color var(--throttle-transition); }\n.throttle-dropdown__trigger:hover { background: var(--throttle-color-surface); }\n.throttle-dropdown__trigger:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: 2px; }\n.throttle-dropdown__menu {\n position: absolute; right: 0; top: calc(100% + var(--throttle-space-2));\n z-index: var(--throttle-z-popover);\n min-width: 260px;\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-popover);\n padding: var(--throttle-space-1);\n}\n.throttle-dropdown__item {\n display: flex; align-items: center; gap: var(--throttle-space-2);\n width: 100%; text-align: left; font: inherit; color: inherit;\n background: none; border: none; cursor: pointer;\n padding: var(--throttle-space-3);\n border-radius: var(--throttle-radius-sm);\n text-decoration: none;\n transition: background-color var(--throttle-transition);\n}\n.throttle-dropdown__item:hover { background: var(--throttle-color-surface); }\n.throttle-dropdown__item:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-dropdown__separator { height: 1px; background: var(--throttle-color-border); margin: var(--throttle-space-1) 0; border: 0; }\n\n.throttle-tabs__list {\n display: flex; gap: var(--throttle-space-1);\n border-bottom: var(--throttle-border-width) solid var(--throttle-color-border);\n overflow-x: auto; scrollbar-width: thin;\n}\n.throttle-tabs__tab {\n font: inherit; background: none; border: none; cursor: pointer; white-space: nowrap;\n padding: var(--throttle-space-3);\n color: var(--throttle-color-muted-foreground);\n border-bottom: 2px solid transparent;\n transition: color var(--throttle-transition), border-color var(--throttle-transition);\n}\n.throttle-tabs__tab:hover { color: var(--throttle-color-foreground); }\n.throttle-tabs__tab--active { color: var(--throttle-color-foreground); border-bottom-color: var(--throttle-color-primary); }\n.throttle-tabs__panel { padding-top: var(--throttle-space-4); }\n\n/* Paints its own ground. A UserButton in a navbar should stay transparent, but\n the dashboard is a large surface of themed text: in dark theme its foreground\n is near-white, so on a light host page it was rendering white-on-white. */\n.throttle-cardframe { width: 100%; min-height: 420px; border: 0; display: block; }\n.throttle-centre { display: flex; align-items: center; justify-content: center; min-height: 160px; }\n.throttle-fieldrow { display: grid; grid-template-columns: 1fr 1fr; gap: var(--throttle-space-4); align-items: start; }\n.throttle-section__title { font-size: var(--throttle-font-size-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--throttle-color-muted-foreground); margin: 0 0 var(--throttle-space-2); font-weight: 600; }\n.throttle-addresses { display: grid; grid-template-columns: 1fr 1fr; gap: var(--throttle-space-5); }\n.throttle-addressblock__line { margin: 0 0 2px; }\n.throttle-timeline { display: flex; flex-direction: column; gap: var(--throttle-space-2); }\n.throttle-timeline__row { display: flex; align-items: center; gap: var(--throttle-space-2); }\n.throttle-timeline__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--throttle-color-border-control); flex: none; }\n.throttle-timeline__label { flex: 1; }\n.throttle-account-root { container-type: inline-size; background: var(--throttle-color-account-surface); color: var(--throttle-color-foreground); padding: var(--throttle-account-padding); }\n.throttle-account { display: flex; gap: var(--throttle-space-5); align-items: flex-start; }\n.throttle-account__content { flex: 1; min-width: 0; }\n.throttle-tabs__rail { flex: none; width: 220px; display: flex; flex-direction: column; gap: 2px; }\n.throttle-tabs__railitem {\n font: inherit;\n font-size: var(--throttle-font-size-sm);\n display: flex;\n align-items: center;\n gap: var(--throttle-space-3);\n width: 100%;\n text-align: left;\n background: none;\n border: none;\n border-radius: var(--throttle-radius-sm);\n padding: 0 var(--throttle-space-3);\n min-height: var(--throttle-control-height);\n color: var(--throttle-color-muted-foreground);\n cursor: pointer;\n transition: background var(--throttle-transition), color var(--throttle-transition);\n}\n.throttle-tabs__railitem:hover { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); }\n.throttle-tabs__railitem:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-tabs__tab:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-tabs__railitem--active { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); font-weight: 500; }\n.throttle-tabs__railicon { flex: none; opacity: .75; }\n\n/* A CONTAINER query, not a viewport one: these components render inside a\n merchant's page, so the viewport says nothing about how much room the\n dashboard actually has \u2014 it could sit in a 400px column on a 1920px screen.\n Below ~560px of container the rail becomes a full-width list above the\n panel: all seven still visible, each still a 44px target. */\n@container (max-width: 560px) {\n /* align-items: flex-start is right in row direction and wrong in column \u2014\n it shrinks the rail to its content width, so width:100% alone cannot make\n it span. Stretch it explicitly when stacked. */\n .throttle-account { flex-direction: column; align-items: stretch; gap: var(--throttle-space-4); }\n .throttle-addresses { grid-template-columns: 1fr; }\n .throttle-fieldrow { grid-template-columns: 1fr; }\n .throttle-tabs__rail { width: 100%; }\n}\n\n.throttle-table { width: 100%; border-collapse: collapse; text-align: left; }\n.throttle-table__head { color: var(--throttle-color-muted-foreground); font-weight: 500; font-size: var(--throttle-font-size-sm); }\n.throttle-table__row { border-top: var(--throttle-border-width) solid var(--throttle-color-border); cursor: pointer; transition: background-color var(--throttle-transition); }\n.throttle-table__row:hover { background: var(--throttle-color-surface); }\n.throttle-table__row:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-table__cell { padding: var(--throttle-space-3) var(--throttle-space-2); height: 56px; box-sizing: border-box; }\n.throttle-table__scroll { overflow-x: auto; }\n\n.throttle-empty { text-align: center; padding: var(--throttle-space-6) var(--throttle-space-4); }\n.throttle-empty__title { font-weight: 600; margin: 0 0 var(--throttle-space-1); }\n.throttle-empty__description { color: var(--throttle-color-muted-foreground); margin: 0; }\n\n.throttle-avatar {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; border-radius: var(--throttle-radius-full);\n background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground);\n font-size: var(--throttle-font-size-xs); font-weight: 600; text-transform: uppercase;\n}\n\n.throttle-badge {\n display: inline-block; font-size: var(--throttle-font-size-xs); font-weight: 500;\n padding: 2px var(--throttle-space-2); border-radius: var(--throttle-radius-full);\n background: var(--throttle-color-muted); color: var(--throttle-color-muted-foreground);\n}\n.throttle-badge--muted { background: none; border: var(--throttle-border-width) solid var(--throttle-color-border); color: var(--throttle-color-muted-foreground); font-weight: 400; padding: 1px calc(var(--throttle-space-2) - 1px); }\n.throttle-badge--success { background: color-mix(in srgb, var(--throttle-color-success) 15%, transparent); color: var(--throttle-color-success); }\n.throttle-badge--warning { background: color-mix(in srgb, var(--throttle-color-warning) 15%, transparent); color: var(--throttle-color-warning); }\n.throttle-badge--danger { background: color-mix(in srgb, var(--throttle-color-danger) 15%, transparent); color: var(--throttle-color-danger); }\n\n.throttle-stack { display: flex; flex-direction: column; gap: var(--throttle-space-3); }\n.throttle-row { display: flex; align-items: center; justify-content: space-between; gap: var(--throttle-space-2); flex-wrap: wrap; }\n.throttle-muted { color: var(--throttle-color-muted-foreground); }\n.throttle-banner {\n display: flex; align-items: center; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n background: color-mix(in srgb, var(--throttle-color-warning) 12%, transparent);\n color: var(--throttle-color-warning);\n border-radius: var(--throttle-radius-sm);\n padding: var(--throttle-space-3);\n margin-bottom: var(--throttle-space-4);\n}\n.throttle-panel { display: flex; flex-direction: column; gap: var(--throttle-space-4); }\n/* 100dvh, not 100vh: on mobile browsers 100vh includes the space behind the\n dynamic address/toolbar, so the page would be taller than the visible\n viewport and the card would sit off-centre until the toolbar collapsed. */\n.throttle-page {\n min-height: 100dvh;\n width: 100%;\n background: var(--throttle-color-surface);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--throttle-space-5);\n padding: var(--throttle-space-5);\n}\n.throttle-page__logo { display: flex; justify-content: center; }\n.throttle-page__footer { color: var(--throttle-color-muted-foreground); text-align: center; font-size: var(--throttle-font-size-sm); }\n.throttle-listitem {\n display: flex; align-items: flex-start; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-sm);\n padding: var(--throttle-space-3);\n}\n/* 'rows' variant: hairline rules between items instead of each item carrying\n its own border+radius, so a panel does not read as a card inside a card. */\n.throttle-rows { display: flex; flex-direction: column; }\n.throttle-rowitem {\n display: flex; align-items: flex-start; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n border-top: var(--throttle-border-width) solid var(--throttle-color-border);\n padding: var(--throttle-space-3) 0;\n}\n.throttle-rowitem:first-child { border-top: none; padding-top: 0; }\n.throttle-actions { display: flex; gap: var(--throttle-space-2); flex-wrap: wrap; }\n.throttle-table__money { display: block; text-align: right; font-variant-numeric: tabular-nums; }\n.throttle-lineitem { display: flex; align-items: center; gap: var(--throttle-space-3); padding: var(--throttle-space-2) 0; }\n.throttle-lineitem__image { width: 48px; height: 48px; object-fit: cover; border-radius: var(--throttle-radius-sm); flex: none; }\n.throttle-totals { display: flex; flex-direction: column; gap: var(--throttle-space-1); }\n\n@media (prefers-reduced-motion: reduce) {\n .throttle-button, .throttle-field__input, .throttle-dropdown__item, .throttle-dropdown__trigger, .throttle-tabs__tab, .throttle-table__row, .throttle-modal__close {\n transition: none;\n }\n}\n";
511
+ declare const THROTTLE_STYLES = "\n.throttle-root {\n --throttle-color-primary: #18181b;\n --throttle-color-primary-foreground: #ffffff;\n --throttle-color-background: #ffffff;\n --throttle-color-surface: #f8fafc;\n --throttle-color-foreground: #0e1116;\n --throttle-color-muted: #eceef2;\n --throttle-color-muted-foreground: #5b6472;\n --throttle-color-border: #e2e8f0;\n /* The boundary of an INTERACTIVE control, which WCAG 1.4.11 requires to\n reach 3:1 against its adjacent colour \u2014 an input identified only by a\n 1.23:1 hairline is not identifiable at all. Decorative separators (card\n edges, table rules, dividers) keep --throttle-color-border: they do not\n identify a control, so the requirement does not apply and darkening\n them would only add noise. */\n /* The account dashboard paints nothing by default so it can drop into a\n merchant's page without fighting their background. The accountSurface and\n accountPadding appearance variables opt back into a card.\n No backticks in this comment: the sheet is a TS template literal. */\n --throttle-card-width: 400px;\n --throttle-color-account-surface: transparent;\n --throttle-account-padding: 0;\n --throttle-color-border-control: #8b93a1;\n --throttle-color-danger: #c2321f;\n --throttle-color-danger-surface: #fef2f2;\n --throttle-color-danger-border: #fecaca;\n --throttle-color-success: #127a4a;\n --throttle-color-success-surface: #ecfdf5;\n --throttle-color-success-border: #a7f3d0;\n --throttle-color-warning: #92400e;\n --throttle-color-warning-surface: #fffbeb;\n --throttle-color-warning-border: #fde68a;\n --throttle-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n --throttle-font-size: 16px;\n --throttle-font-size-xs: 12px;\n --throttle-font-size-sm: 14px;\n --throttle-font-size-lg: 20px;\n --throttle-font-size-xl: 24px;\n --throttle-line-height: 1.5;\n --throttle-line-height-tight: 1.25;\n --throttle-radius: 12px;\n --throttle-radius-sm: 8px;\n --throttle-radius-full: 999px;\n --throttle-border-width: 1px;\n --throttle-spacing: 8px;\n --throttle-space-1: 4px;\n --throttle-space-2: var(--throttle-spacing);\n --throttle-space-3: 12px;\n --throttle-space-4: 16px;\n --throttle-space-5: 24px;\n --throttle-space-6: 32px;\n --throttle-control-height: 48px;\n --throttle-control-padding-x: 16px;\n --throttle-shadow-card: 0 1px 3px rgba(15,23,42,.08), 0 1px 2px rgba(15,23,42,.04);\n --throttle-shadow-popover: 0 10px 24px rgba(15,23,42,.12), 0 2px 6px rgba(15,23,42,.06);\n --throttle-transition: 150ms cubic-bezier(.2,0,.2,1);\n --throttle-z-modal: 2147483000;\n --throttle-z-popover: 2147482000;\n font-family: var(--throttle-font-family);\n font-size: var(--throttle-font-size);\n line-height: var(--throttle-line-height);\n color: var(--throttle-color-foreground);\n box-sizing: border-box;\n}\n.throttle-root *, .throttle-root *::before, .throttle-root *::after { box-sizing: inherit; }\n\n.throttle-root[data-throttle-theme=\"dark\"] {\n --throttle-color-primary: #e6edf3;\n --throttle-color-primary-foreground: #0d1117;\n --throttle-color-background: #0d1117;\n --throttle-color-surface: #1c2129;\n --throttle-color-foreground: #e6edf3;\n --throttle-color-muted: #21262d;\n --throttle-color-muted-foreground: #9aa4b2;\n --throttle-color-border: #30363d;\n --throttle-color-border-control: #5c6570;\n --throttle-color-danger: #ff6b58;\n --throttle-color-danger-surface: #2a1513;\n --throttle-color-danger-border: #5c2b25;\n --throttle-color-success: #45c08a;\n --throttle-color-success-surface: #0f2419;\n --throttle-color-success-border: #1f4d36;\n --throttle-color-warning: #e0a53a;\n --throttle-color-warning-surface: #2a2113;\n --throttle-color-warning-border: #5c4a25;\n --throttle-shadow-card: 0 1px 3px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.4);\n --throttle-shadow-popover: 0 10px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.35);\n}\n@media (prefers-color-scheme: dark) {\n .throttle-root[data-throttle-theme=\"auto\"] {\n --throttle-color-primary: #e6edf3;\n --throttle-color-primary-foreground: #0d1117;\n --throttle-color-background: #0d1117;\n --throttle-color-surface: #1c2129;\n --throttle-color-foreground: #e6edf3;\n --throttle-color-muted: #21262d;\n --throttle-color-muted-foreground: #9aa4b2;\n --throttle-color-border: #30363d;\n --throttle-color-border-control: #5c6570;\n --throttle-color-danger: #ff6b58;\n --throttle-color-danger-surface: #2a1513;\n --throttle-color-danger-border: #5c2b25;\n --throttle-color-success: #45c08a;\n --throttle-color-success-surface: #0f2419;\n --throttle-color-success-border: #1f4d36;\n --throttle-color-warning: #e0a53a;\n --throttle-color-warning-surface: #2a2113;\n --throttle-color-warning-border: #5c4a25;\n --throttle-shadow-card: 0 1px 3px rgba(0,0,0,.6), 0 1px 2px rgba(0,0,0,.4);\n --throttle-shadow-popover: 0 10px 24px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.35);\n }\n}\n\n.throttle-card {\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-card);\n padding: var(--throttle-space-5);\n width: 100%;\n max-width: var(--throttle-card-width);\n margin-inline: auto;\n}\n/* Inside a Modal the dialog already provides the surface \u2014 background, radius\n and elevation. A card that draws its own on top is the \"box inside a box\":\n two shadowed rounded rectangles nested, with the card's max-width stranding\n it in the middle of a much wider dialog. */\n.throttle-card--bare { border: none; box-shadow: none; background: none; max-width: none; }\n.throttle-card__header { margin-bottom: var(--throttle-space-4); }\n.throttle-card__header--branded { text-align: center; }\n.throttle-card__logo { display: flex; justify-content: center; margin-bottom: var(--throttle-space-3); }\n.throttle-card__title { font-size: var(--throttle-font-size-xl); line-height: var(--throttle-line-height-tight); font-weight: 600; letter-spacing: -0.02em; margin: 0; }\n.throttle-card__title--branded { font-size: var(--throttle-font-size-xl); }\n.throttle-card__description { color: var(--throttle-color-muted-foreground); margin: var(--throttle-space-1) 0 0; }\n.throttle-card__body { display: flex; flex-direction: column; gap: var(--throttle-space-3); }\n.throttle-card__footer { margin-top: var(--throttle-space-4); text-align: center; }\n.throttle-card__footer--ruled { border-top: var(--throttle-border-width) solid var(--throttle-color-border); padding-top: var(--throttle-space-4); }\n\n.throttle-field { display: flex; flex-direction: column; gap: var(--throttle-space-1); }\n.throttle-field__labelrow { display: flex; align-items: baseline; justify-content: space-between; gap: var(--throttle-space-2); }\n.throttle-field__label { font-weight: 500; }\n.throttle-field__input {\n font: inherit;\n font-size: var(--throttle-font-size);\n color: var(--throttle-color-foreground);\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border-control);\n border-radius: var(--throttle-radius-sm);\n /* padding-block stays 0 so min-height alone owns the height, exactly as\n .throttle-button does. With 12px vertical padding the box computed to\n 50px against the button's 48px \u2014 a 2px mismatch, measured in a browser\n across 19 controls. An input element centres its own text vertically. */\n padding-block: 0;\n padding-inline: var(--throttle-control-padding-x);\n min-height: var(--throttle-control-height);\n width: 100%;\n transition: border-color var(--throttle-transition), box-shadow var(--throttle-transition);\n}\n.throttle-field__input:focus-visible {\n outline: none;\n border-color: var(--throttle-color-primary);\n box-shadow: 0 0 0 2px var(--throttle-color-background), 0 0 0 4px var(--throttle-color-primary);\n}\n.throttle-field__input:disabled { background: var(--throttle-color-muted); color: var(--throttle-color-muted-foreground); cursor: not-allowed; }\n.throttle-field__input::placeholder { color: var(--throttle-color-muted-foreground); opacity: 1; }\n.throttle-field__input--grouped { border: none; border-radius: 0; padding-inline: 0; }\n.throttle-field__hint { color: var(--throttle-color-muted-foreground); font-size: var(--throttle-font-size-xs); }\n/* Always mounted, so it reserves its line whether or not there is an error:\n an error appearing on submit must not push the submit button out from\n under the buyer's pointer. */\n.throttle-field__error { color: var(--throttle-color-danger); font-size: var(--throttle-font-size-xs); line-height: 1rem; }\n/* Reserved a full line under EVERY input even with nothing to say, which\n with the stack gap put 28px of dead space beneath each field, on every\n form and all seven account panels. The element stays mounted when empty\n because role=alert only announces changes to a live region that was\n already there; it just stops occupying a line. */\n.throttle-field__error:empty { display: none; }\n\n.throttle-field-group {\n display: flex;\n flex-direction: column;\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-sm);\n overflow: hidden;\n}\n.throttle-field-group__item { padding: var(--throttle-space-3) var(--throttle-control-padding-x); }\n.throttle-field-group__divider { height: var(--throttle-border-width); background: var(--throttle-color-border); }\n.throttle-field-group__forgot { margin-left: auto; }\n\n.throttle-button {\n font: inherit;\n font-weight: 500;\n border-radius: var(--throttle-radius-sm);\n border: var(--throttle-border-width) solid transparent;\n padding-inline: var(--throttle-control-padding-x);\n padding-block: 0;\n min-height: var(--throttle-control-height);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n /* A label that wraps turns a control into a two-line block of text. */\n white-space: nowrap;\n transition: opacity var(--throttle-transition), background-color var(--throttle-transition), border-color var(--throttle-transition), filter var(--throttle-transition), box-shadow var(--throttle-transition);\n}\n.throttle-button:disabled { opacity: .55; cursor: not-allowed; }\n.throttle-button:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--throttle-color-background), 0 0 0 4px var(--throttle-color-primary); }\n.throttle-button--primary { background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground); width: var(--throttle-button-width, 100%); }\n.throttle-button--primary:hover:not(:disabled) { filter: brightness(0.92); }\n.throttle-button--secondary { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); border-color: var(--throttle-color-border-control); }\n.throttle-button--secondary:hover:not(:disabled) { background: var(--throttle-color-muted); }\n.throttle-button--danger { background: transparent; color: var(--throttle-color-danger); border-color: var(--throttle-color-border); }\n.throttle-button--danger:hover:not(:disabled) { background: color-mix(in srgb, var(--throttle-color-danger) 10%, transparent); }\n/* Link-style actions are the rows panel default, and they carry Delete,\n Remove, Cancel and Sign out. Zero padding with min-height 0 made those\n roughly 20px tall and ~8px apart \u2014 a mis-tap on a phone lands on something\n irreversible. The target is expanded with vertical padding and pulled back\n with an equal negative margin, so the hit box clears 44px while the text\n sits exactly where it did. Collapsing this back to zero padding shrinks the\n target again. */\n.throttle-button--link { background: none; border: none; color: var(--throttle-color-primary); padding-inline: 0; padding-block: var(--throttle-space-3); margin-block: calc(var(--throttle-space-3) * -1); min-height: 0; text-decoration: underline; width: auto; }\n.throttle-button--link:hover:not(:disabled) { opacity: .8; }\n.throttle-button--linkDanger { background: none; border: none; color: var(--throttle-color-danger); padding-inline: 0; padding-block: var(--throttle-space-3); margin-block: calc(var(--throttle-space-3) * -1); min-height: 0; text-decoration: underline; width: auto; }\n.throttle-button--linkDanger:hover:not(:disabled) { opacity: .8; }\n.throttle-button--xs { font-size: var(--throttle-font-size-xs); }\n\n.throttle-alert { border-radius: var(--throttle-radius-sm); padding: var(--throttle-space-3); font-size: var(--throttle-font-size-sm); }\n.throttle-alert--error { background: var(--throttle-color-danger-surface); border: var(--throttle-border-width) solid var(--throttle-color-danger-border); color: var(--throttle-color-danger); }\n.throttle-alert--success { background: var(--throttle-color-success-surface); border: var(--throttle-border-width) solid var(--throttle-color-success-border); color: var(--throttle-color-success); }\n.throttle-alert--info { background: var(--throttle-color-surface); color: var(--throttle-color-muted-foreground); }\n\n.throttle-spinner {\n display: inline-block; width: 1em; height: 1em;\n border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;\n animation: throttle-spin 700ms linear infinite;\n}\n@keyframes throttle-spin { to { transform: rotate(360deg); } }\n.throttle-button--loading { position: relative; }\n.throttle-button__label { display: inline-flex; align-items: center; justify-content: center; gap: var(--throttle-space-2); }\n.throttle-button__label--hidden { visibility: hidden; }\n.throttle-spinner--centred { position: absolute; top: 50%; left: 50%; margin: -0.5em 0 0 -0.5em; }\n\n@media (prefers-reduced-motion: reduce) { .throttle-spinner { animation-duration: 2.4s; } }\n\n.throttle-skeleton {\n background: var(--throttle-color-muted);\n border-radius: var(--throttle-radius-sm);\n animation: throttle-pulse 1.4s ease-in-out infinite; height: 2.5em; }\n@keyframes throttle-pulse { 50% { opacity: .5; } }\n@media (prefers-reduced-motion: reduce) { .throttle-skeleton { animation: none; } }\n\n.throttle-modal__overlay {\n position: fixed; inset: 0; z-index: var(--throttle-z-modal);\n background: rgba(14,17,22,.45);\n display: flex; align-items: center; justify-content: center;\n padding: var(--throttle-space-4);\n overflow-y: auto;\n}\n.throttle-modal__container {\n background: var(--throttle-color-background);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-popover);\n max-width: 720px; width: 100%; max-height: 90vh; overflow-y: auto;\n position: relative;\n}\n/* After the base rule on purpose: both are single-class, so equal specificity\n means source order decides. Declared before it, this silently lost. */\n.throttle-modal__container--compact { max-width: 440px; }\n.throttle-modal__close {\n position: absolute; top: var(--throttle-space-3); right: var(--throttle-space-3);\n background: none; border: none; cursor: pointer; font-size: var(--throttle-font-size-lg);\n color: var(--throttle-color-muted-foreground);\n transition: color var(--throttle-transition);\n}\n.throttle-modal__close:hover { color: var(--throttle-color-foreground); }\n.throttle-modal__header { padding: var(--throttle-space-4) var(--throttle-space-4) 0; }\n.throttle-modal__title { font-size: var(--throttle-font-size-lg); line-height: var(--throttle-line-height-tight); font-weight: 600; margin: 0; }\n.throttle-modal__body { padding: var(--throttle-space-4); }\n\n.throttle-dropdown__trigger { background: none; border: none; cursor: pointer; padding: 0; border-radius: var(--throttle-radius-full); transition: background-color var(--throttle-transition); }\n.throttle-dropdown__trigger:hover { background: var(--throttle-color-surface); }\n.throttle-dropdown__trigger:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: 2px; }\n.throttle-dropdown__menu {\n position: absolute; right: 0; top: calc(100% + var(--throttle-space-2));\n z-index: var(--throttle-z-popover);\n min-width: 260px;\n background: var(--throttle-color-background);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius);\n box-shadow: var(--throttle-shadow-popover);\n padding: var(--throttle-space-1);\n}\n.throttle-dropdown__item {\n display: flex; align-items: center; gap: var(--throttle-space-2);\n width: 100%; text-align: left; font: inherit; color: inherit;\n background: none; border: none; cursor: pointer;\n padding: var(--throttle-space-3);\n border-radius: var(--throttle-radius-sm);\n text-decoration: none;\n transition: background-color var(--throttle-transition);\n}\n.throttle-dropdown__item:hover { background: var(--throttle-color-surface); }\n.throttle-dropdown__item:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-dropdown__separator { height: 1px; background: var(--throttle-color-border); margin: var(--throttle-space-1) 0; border: 0; }\n\n.throttle-tabs__list {\n display: flex; gap: var(--throttle-space-1);\n border-bottom: var(--throttle-border-width) solid var(--throttle-color-border);\n overflow-x: auto; scrollbar-width: thin;\n}\n.throttle-tabs__tab {\n font: inherit; background: none; border: none; cursor: pointer; white-space: nowrap;\n padding: var(--throttle-space-3);\n color: var(--throttle-color-muted-foreground);\n border-bottom: 2px solid transparent;\n transition: color var(--throttle-transition), border-color var(--throttle-transition);\n}\n.throttle-tabs__tab:hover { color: var(--throttle-color-foreground); }\n.throttle-tabs__tab--active { color: var(--throttle-color-foreground); border-bottom-color: var(--throttle-color-primary); }\n.throttle-tabs__panel { padding-top: var(--throttle-space-4); }\n\n/* Paints its own ground. A UserButton in a navbar should stay transparent, but\n the dashboard is a large surface of themed text: in dark theme its foreground\n is near-white, so on a light host page it was rendering white-on-white. */\n.throttle-cardframe { width: 100%; min-height: 420px; border: 0; display: block; }\n.throttle-centre { display: flex; align-items: center; justify-content: center; min-height: 160px; }\n.throttle-fieldrow { display: grid; grid-template-columns: 1fr 1fr; gap: var(--throttle-space-4); align-items: start; }\n.throttle-section__title { font-size: var(--throttle-font-size-xs); text-transform: uppercase; letter-spacing: .06em; color: var(--throttle-color-muted-foreground); margin: 0 0 var(--throttle-space-2); font-weight: 600; }\n.throttle-addresses { display: grid; grid-template-columns: 1fr 1fr; gap: var(--throttle-space-5); }\n.throttle-addressblock__line { margin: 0 0 2px; }\n.throttle-timeline { display: flex; flex-direction: column; gap: var(--throttle-space-2); }\n.throttle-timeline__row { display: flex; align-items: center; gap: var(--throttle-space-2); }\n.throttle-timeline__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--throttle-color-border-control); flex: none; }\n.throttle-timeline__label { flex: 1; }\n.throttle-account-root { container-type: inline-size; background: var(--throttle-color-account-surface); color: var(--throttle-color-foreground); padding: var(--throttle-account-padding); }\n.throttle-account { display: flex; gap: var(--throttle-space-5); align-items: flex-start; }\n.throttle-account__content { flex: 1; min-width: 0; }\n.throttle-tabs__rail { flex: none; width: 220px; display: flex; flex-direction: column; gap: 2px; }\n.throttle-tabs__railitem {\n font: inherit;\n font-size: var(--throttle-font-size-sm);\n display: flex;\n align-items: center;\n gap: var(--throttle-space-3);\n width: 100%;\n text-align: left;\n background: none;\n border: none;\n border-radius: var(--throttle-radius-sm);\n padding: 0 var(--throttle-space-3);\n min-height: var(--throttle-control-height);\n color: var(--throttle-color-muted-foreground);\n cursor: pointer;\n transition: background var(--throttle-transition), color var(--throttle-transition);\n}\n.throttle-tabs__railitem:hover { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); }\n.throttle-tabs__railitem:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-tabs__tab:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-tabs__railitem--active { background: var(--throttle-color-surface); color: var(--throttle-color-foreground); font-weight: 500; }\n.throttle-tabs__railicon { flex: none; opacity: .75; }\n\n/* A CONTAINER query, not a viewport one: these components render inside a\n merchant's page, so the viewport says nothing about how much room the\n dashboard actually has \u2014 it could sit in a 400px column on a 1920px screen.\n Below ~560px of container the rail becomes a full-width list above the\n panel: all seven still visible, each still a 44px target. */\n@container (max-width: 560px) {\n /* align-items: flex-start is right in row direction and wrong in column \u2014\n it shrinks the rail to its content width, so width:100% alone cannot make\n it span. Stretch it explicitly when stacked. */\n .throttle-account { flex-direction: column; align-items: stretch; gap: var(--throttle-space-4); }\n .throttle-addresses { grid-template-columns: 1fr; }\n .throttle-fieldrow { grid-template-columns: 1fr; }\n .throttle-tabs__rail { width: 100%; }\n /* One column, and the rail stops sticking \u2014 on a phone a sticky summary\n covers the very line items it is summarising. */\n .throttle-detail { grid-template-columns: 1fr; }\n .throttle-detail__rail { position: static; }\n}\n\n.throttle-table { width: 100%; border-collapse: collapse; text-align: left; }\n.throttle-table__head { color: var(--throttle-color-muted-foreground); font-weight: 500; font-size: var(--throttle-font-size-sm); }\n.throttle-table__row { border-top: var(--throttle-border-width) solid var(--throttle-color-border); cursor: pointer; transition: background-color var(--throttle-transition); }\n.throttle-table__row:hover { background: var(--throttle-color-surface); }\n.throttle-table__row:focus-visible { outline: 2px solid var(--throttle-color-primary); outline-offset: -2px; }\n.throttle-table__cell { padding: var(--throttle-space-3) var(--throttle-space-2); height: 56px; box-sizing: border-box; }\n.throttle-table__scroll { overflow-x: auto; }\n\n.throttle-empty { text-align: center; padding: var(--throttle-space-6) var(--throttle-space-4); }\n.throttle-empty__title { font-weight: 600; margin: 0 0 var(--throttle-space-1); }\n.throttle-empty__description { color: var(--throttle-color-muted-foreground); margin: 0; }\n\n.throttle-avatar {\n display: inline-flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; border-radius: var(--throttle-radius-full);\n background: var(--throttle-color-primary); color: var(--throttle-color-primary-foreground);\n font-size: var(--throttle-font-size-xs); font-weight: 600; text-transform: uppercase;\n}\n\n.throttle-badge {\n display: inline-block; font-size: var(--throttle-font-size-xs); font-weight: 500;\n padding: 2px var(--throttle-space-2); border-radius: var(--throttle-radius-full);\n background: var(--throttle-color-muted); color: var(--throttle-color-muted-foreground);\n}\n.throttle-badge--muted { background: none; border: var(--throttle-border-width) solid var(--throttle-color-border); color: var(--throttle-color-muted-foreground); font-weight: 400; padding: 1px calc(var(--throttle-space-2) - 1px); }\n.throttle-badge--success { background: color-mix(in srgb, var(--throttle-color-success) 15%, transparent); color: var(--throttle-color-success); }\n.throttle-badge--warning { background: color-mix(in srgb, var(--throttle-color-warning) 15%, transparent); color: var(--throttle-color-warning); }\n.throttle-badge--danger { background: color-mix(in srgb, var(--throttle-color-danger) 15%, transparent); color: var(--throttle-color-danger); }\n\n.throttle-stack { display: flex; flex-direction: column; gap: var(--throttle-space-3); }\n.throttle-row { display: flex; align-items: center; justify-content: space-between; gap: var(--throttle-space-2); flex-wrap: wrap; }\n.throttle-muted { color: var(--throttle-color-muted-foreground); }\n.throttle-banner {\n display: flex; align-items: center; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n background: color-mix(in srgb, var(--throttle-color-warning) 12%, transparent);\n color: var(--throttle-color-warning);\n border-radius: var(--throttle-radius-sm);\n padding: var(--throttle-space-3);\n margin-bottom: var(--throttle-space-4);\n}\n.throttle-panel { display: flex; flex-direction: column; gap: var(--throttle-space-4); }\n/* 100dvh, not 100vh: on mobile browsers 100vh includes the space behind the\n dynamic address/toolbar, so the page would be taller than the visible\n viewport and the card would sit off-centre until the toolbar collapsed. */\n.throttle-page {\n min-height: 100dvh;\n width: 100%;\n background: var(--throttle-color-surface);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--throttle-space-5);\n padding: var(--throttle-space-5);\n}\n.throttle-page__logo { display: flex; justify-content: center; }\n.throttle-page__footer { color: var(--throttle-color-muted-foreground); text-align: center; font-size: var(--throttle-font-size-sm); }\n.throttle-listitem {\n display: flex; align-items: flex-start; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-sm);\n padding: var(--throttle-space-3);\n}\n/* 'rows' variant: hairline rules between items instead of each item carrying\n its own border+radius, so a panel does not read as a card inside a card. */\n.throttle-rows { display: flex; flex-direction: column; }\n.throttle-rowitem {\n display: flex; align-items: flex-start; justify-content: space-between; gap: var(--throttle-space-2);\n flex-wrap: wrap;\n border-top: var(--throttle-border-width) solid var(--throttle-color-border);\n padding: var(--throttle-space-3) 0;\n}\n.throttle-rowitem:first-child { border-top: none; padding-top: 0; }\n.throttle-actions {\n display: flex; gap: var(--throttle-space-2); flex-wrap: wrap; align-items: center;\n /* Primary buttons are full-width so a form's submit fills its card. In a row\n of sibling actions that same rule made every button claim 100% and then\n shrink to share the line, squeezing Resume to 59px so its label wrapped to\n two lines inside a 48px box. A custom property INHERITS to the buttons, so\n the row opts them back to content width without a descendant selector \u2014\n those outrank the merchant overrides in appearance.elements. */\n --throttle-button-width: auto;\n}\n.throttle-table__money { display: block; text-align: right; font-variant-numeric: tabular-nums; }\n.throttle-lineitem { display: flex; align-items: flex-start; gap: var(--throttle-space-3); padding: var(--throttle-space-2) 0; }\n/* The UA's 1em paragraph margins pushed a two-line item to 96px, so five\n items filled a screen with mostly whitespace. These carry the spacing\n instead. Separate classes, not a \".throttle-lineitem p\" descendant\n selector -- those outrank the merchant's appearance.elements overrides. */\n.throttle-lineitem__desc { margin: var(--throttle-space-1) 0 0; color: var(--throttle-color-muted-foreground); }\n.throttle-lineitem__meta { margin: var(--throttle-space-1) 0 0; color: var(--throttle-color-muted-foreground); font-size: var(--throttle-font-size-sm); }\n.throttle-lineitem__image { width: 48px; height: 48px; object-fit: cover; border-radius: var(--throttle-radius-sm); flex: none; }\n.throttle-totals { display: flex; flex-direction: column; gap: var(--throttle-space-1); }\n\n/* Order and invoice detail: the record on the left, what it costs and what\n you can do about it on the right. The rail sticks so the total and the\n actions stay reachable on an order with thirty lines, which is exactly when\n a buyer most wants them. Collapses below, where a sticky rail would eat a\n phone screen. */\n.throttle-detail { display: grid; grid-template-columns: minmax(0, 1fr) 17rem; gap: var(--throttle-space-6); align-items: start; }\n.throttle-detail__main { display: flex; flex-direction: column; gap: var(--throttle-space-5); min-width: 0; }\n.throttle-detail__rail {\n display: flex; flex-direction: column; gap: var(--throttle-space-4);\n position: sticky; top: var(--throttle-space-4);\n padding: var(--throttle-space-4);\n border: var(--throttle-border-width) solid var(--throttle-color-border);\n border-radius: var(--throttle-radius-md);\n background: var(--throttle-color-surface);\n}\n/* The one number the buyer came for. */\n.throttle-detail__headline { font-size: var(--throttle-font-size-xl); font-weight: 600; line-height: 1.2; }\n.throttle-detail__section { display: flex; flex-direction: column; gap: var(--throttle-space-2); }\n.throttle-detail__label { font-size: var(--throttle-font-size-sm); font-weight: 500; color: var(--throttle-color-muted-foreground); letter-spacing: .04em; text-transform: uppercase; }\n/* A rail action column: full width, stacked, so the primary reads as primary. */\n.throttle-detail__actions { display: flex; flex-direction: column; gap: var(--throttle-space-2); --throttle-button-width: 100%; }\n.throttle-detail__link { display: inline-flex; align-items: center; gap: var(--throttle-space-1); }\n\n@media (prefers-reduced-motion: reduce) {\n .throttle-button, .throttle-field__input, .throttle-dropdown__item, .throttle-dropdown__trigger, .throttle-tabs__tab, .throttle-table__row, .throttle-modal__close {\n transition: none;\n }\n}\n";
490
512
 
491
513
  /**
492
514
  * The only place minor units become major units. Every amount on the wire is
@@ -737,15 +759,22 @@ declare function OrderDetail(props: {
737
759
  orderId: string;
738
760
  onBack?(): void;
739
761
  onViewSubscription?(id: string): void;
762
+ onViewInvoice?(id: string): void;
740
763
  /**
741
- * Status-dependent actions. Each renders ONLY when its handler is supplied,
742
- * because the buyer plane has no commerce writes: a built-in Cancel or Track
743
- * button would be a control that always fails. The merchant owns the
744
- * behaviour, the component owns when it is offered.
764
+ * Status-dependent actions the MERCHANT owns. Each renders only when its
765
+ * handler is supplied, because the buyer plane cannot perform them: a
766
+ * built-in Pay or Track button would be a control that always fails.
745
767
  */
746
768
  onPayNow?(order: OrderActionTarget): void;
747
769
  onReorder?(order: OrderActionTarget): void;
748
770
  onTrackShipment?(order: OrderActionTarget): void;
771
+ /**
772
+ * Cancel and return, by contrast, ARE buyer-plane capabilities, so they are
773
+ * wired in here and need no handler. Opt out with `false` for a storefront
774
+ * that handles them elsewhere.
775
+ */
776
+ allowCancel?: boolean;
777
+ allowReturn?: boolean;
749
778
  appearance?: ThrottleAppearance;
750
779
  localization?: ThrottleLocalization;
751
780
  }): react_jsx_runtime.JSX.Element;
@@ -754,11 +783,38 @@ declare function InvoicesPanel(props: {
754
783
  appearance?: ThrottleAppearance;
755
784
  localization?: ThrottleLocalization;
756
785
  variant?: AccountPanelVariant;
786
+ /** Navigation out of an invoice, forwarded to `InvoiceDetail`. */
787
+ onViewOrder?(orderId: string): void;
788
+ onViewSubscription?(subscriptionId: string): void;
789
+ onPay?(invoice: {
790
+ id: string;
791
+ number: string;
792
+ total: number;
793
+ currency: string;
794
+ }): void;
795
+ /** Opens straight to this invoice. Set by the dashboard on cross-panel navigation. */
796
+ initialOpenId?: string | null;
757
797
  }): react_jsx_runtime.JSX.Element;
758
798
 
759
799
  declare function InvoiceDetail(props: {
760
800
  invoiceId: string;
761
801
  onBack?(): void;
802
+ /**
803
+ * Navigation out of the invoice. An invoice is a record OF something — an
804
+ * order or a subscription — and without these it was a dead end: the buyer
805
+ * could read what they were charged but not reach the thing that charged
806
+ * them. Each link renders only when the handler is supplied AND the server
807
+ * resolved the id.
808
+ */
809
+ onViewOrder?(orderId: string): void;
810
+ onViewSubscription?(subscriptionId: string): void;
811
+ /** Settle an open invoice. Merchant-owned, like the order's Pay now. */
812
+ onPay?(invoice: {
813
+ id: string;
814
+ number: string;
815
+ total: number;
816
+ currency: string;
817
+ }): void;
762
818
  appearance?: ThrottleAppearance;
763
819
  localization?: ThrottleLocalization;
764
820
  }): react_jsx_runtime.JSX.Element;