@funnelsgrove/payments 0.7.13 → 0.7.15

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.
@@ -18,12 +18,35 @@ export type SolidgateCheckoutDialogContent = {
18
18
  customerEmailUnavailable: string;
19
19
  customerEmailContinue: string;
20
20
  };
21
+ export type SolidgateCheckoutDialogPresentation = {
22
+ buttonColor: string;
23
+ cardSubmitLabel: string;
24
+ countdownLabel: string;
25
+ discountAmountLabel: string;
26
+ discountLabel: string;
27
+ discountPercent: number;
28
+ originalPriceLabel: string;
29
+ originalPriceValue: string;
30
+ promoActive: boolean;
31
+ promoCode: string;
32
+ promoCodeLabel: string;
33
+ remainingSeconds: number;
34
+ satisfactionLabel: string;
35
+ satisfactionPercent: string;
36
+ savedLabel: string;
37
+ secureLabel: string;
38
+ themeColor: string;
39
+ title: string;
40
+ totalLabel: string;
41
+ totalValue: string;
42
+ };
21
43
  export type SolidgateCheckoutDialogProps = {
22
44
  open: boolean;
23
45
  request: Omit<PrepareSolidgateCheckoutInput, 'signal'>;
24
46
  customerEmail?: string | null;
25
47
  checkoutAnalytics?: SolidgateCheckoutAnalyticsContext | null;
26
48
  content?: Partial<SolidgateCheckoutDialogContent>;
49
+ presentation?: SolidgateCheckoutDialogPresentation;
27
50
  onClose: () => void;
28
51
  onCustomerEmailCommit?: (email: string) => Promise<string>;
29
52
  onSuccess?: (checkout: SolidgateCheckoutPreparation) => void | Promise<void>;
@@ -41,4 +64,4 @@ export type SolidgateCheckoutAnalyticsContext = {
41
64
  stepType: Extract<FunnelStepType, 'checkout' | 'paywall_offer' | 'upsell_offer'>;
42
65
  stepContractVersion: number;
43
66
  };
44
- export declare function SolidgateCheckoutDialog({ open, request, customerEmail, checkoutAnalytics, content, onClose, onCustomerEmailCommit, onSuccess, onRetry, onError, onStateChange, }: SolidgateCheckoutDialogProps): import("react/jsx-runtime").JSX.Element | null;
67
+ export declare function SolidgateCheckoutDialog({ open, request, customerEmail, checkoutAnalytics, content, presentation, onClose, onCustomerEmailCommit, onSuccess, onRetry, onError, onStateChange, }: SolidgateCheckoutDialogProps): import("react/jsx-runtime").JSX.Element | null;
@@ -34,6 +34,14 @@ const initialView = {
34
34
  checkout: null,
35
35
  canResumeVerification: false,
36
36
  };
37
+ const formatCountdown = (remainingSeconds) => {
38
+ const normalizedSeconds = Number.isFinite(remainingSeconds)
39
+ ? Math.max(0, Math.floor(remainingSeconds))
40
+ : 0;
41
+ const minutes = Math.floor(normalizedSeconds / 60);
42
+ const seconds = normalizedSeconds % 60;
43
+ return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
44
+ };
37
45
  const trackSolidgateCheckoutEvent = async (eventName, attemptId, context) => {
38
46
  var _a;
39
47
  if (!context) {
@@ -76,7 +84,7 @@ const safeDestroyPaymentForm = (instance) => {
76
84
  // Cleanup must stay safe when the remote SDK is partially initialized.
77
85
  }
78
86
  };
79
- function SolidgatePaymentForm({ checkout, hidden, loadingLabel, onError, onMounted, onSubmit, onVerify, }) {
87
+ function SolidgatePaymentForm({ buttonColor, cardSubmitLabel, checkout, hidden, loadingLabel, onError, onMounted, onSubmit, onVerify, }) {
80
88
  const instanceRef = useRef(null);
81
89
  const applePayContainerRef = useRef(null);
82
90
  const googlePayContainerRef = useRef(null);
@@ -84,7 +92,38 @@ function SolidgatePaymentForm({ checkout, hidden, loadingLabel, onError, onMount
84
92
  safeDestroyPaymentForm(instanceRef.current);
85
93
  instanceRef.current = null;
86
94
  }, [checkout.attemptId]);
87
- return (_jsxs("div", { className: 'solidgate-checkout-payment', "data-solidgate-attempt-id": checkout.attemptId, hidden: hidden, "aria-hidden": hidden || undefined, children: [_jsxs("div", { className: 'solidgate-checkout-wallets', children: [_jsx("div", { ref: applePayContainerRef, "data-solidgate-wallet": 'apple-pay' }), _jsx("div", { ref: googlePayContainerRef, "data-solidgate-wallet": 'google-pay' })] }), _jsx(Suspense, { fallback: (_jsx("p", { role: 'status', className: 'solidgate-checkout-status-text', children: loadingLabel })), children: _jsx(SolidgatePayment, { merchantData: checkout.initialization.merchantData, width: '100%', formParams: { isSolidLogoVisible: true }, applePayContainerRef: applePayContainerRef, googlePayContainerRef: googlePayContainerRef, onReadyPaymentInstance: (instance) => {
95
+ const walletButtonType = checkout.display.billingInterval ? 'subscribe' : 'buy';
96
+ return (_jsxs("div", { className: 'solidgate-checkout-payment', "data-solidgate-attempt-id": checkout.attemptId, hidden: hidden, "aria-hidden": hidden || undefined, children: [_jsxs("div", { className: 'solidgate-checkout-wallets', children: [_jsx("div", { ref: applePayContainerRef, "data-solidgate-wallet": 'apple-pay' }), _jsx("div", { ref: googlePayContainerRef, "data-solidgate-wallet": 'google-pay' })] }), _jsx(Suspense, { fallback: (_jsx("p", { role: 'status', className: 'solidgate-checkout-status-text', children: loadingLabel })), children: _jsx(SolidgatePayment, { merchantData: checkout.initialization.merchantData, width: '100%', formParams: {
97
+ autoFocus: false,
98
+ isSolidLogoVisible: true,
99
+ submitButtonText: cardSubmitLabel,
100
+ }, styles: {
101
+ form_body: {
102
+ 'font-family': 'Inter, Arial, sans-serif',
103
+ },
104
+ input_group: {
105
+ input: {
106
+ 'border-color': '#d8d9dd',
107
+ 'border-radius': '10px',
108
+ },
109
+ },
110
+ submit_button: {
111
+ 'background-color': buttonColor,
112
+ 'border-radius': '10px',
113
+ 'font-size': '16px',
114
+ 'font-weight': '800',
115
+ height: '52px',
116
+ },
117
+ }, applePayButtonParams: {
118
+ color: 'black',
119
+ enabled: true,
120
+ integrationType: 'js',
121
+ type: walletButtonType,
122
+ }, googlePayButtonParams: {
123
+ color: 'black',
124
+ enabled: true,
125
+ type: walletButtonType,
126
+ }, applePayContainerRef: applePayContainerRef, googlePayContainerRef: googlePayContainerRef, onReadyPaymentInstance: (instance) => {
88
127
  if (instanceRef.current && instanceRef.current !== instance) {
89
128
  try {
90
129
  instanceRef.current.unsubscribeAll();
@@ -96,7 +135,7 @@ function SolidgatePaymentForm({ checkout, hidden, loadingLabel, onError, onMount
96
135
  instanceRef.current = instance;
97
136
  }, onMounted: onMounted, onSubmit: onSubmit, onVerify: onVerify, onSuccess: onVerify, onFail: onVerify, onError: onError }, checkout.attemptId) })] }));
98
137
  }
99
- export function SolidgateCheckoutDialog({ open, request, customerEmail, checkoutAnalytics, content, onClose, onCustomerEmailCommit, onSuccess, onRetry, onError, onStateChange, }) {
138
+ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkoutAnalytics, content, presentation, onClose, onCustomerEmailCommit, onSuccess, onRetry, onError, onStateChange, }) {
100
139
  const copy = useMemo(() => (Object.assign(Object.assign({}, defaultContent), content)), [content]);
101
140
  const [view, setView] = useState(initialView);
102
141
  const normalizedCustomerEmail = normalizeValidEmail(customerEmail);
@@ -104,6 +143,7 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
104
143
  const [committedEmail, setCommittedEmail] = useState(normalizedCustomerEmail);
105
144
  const [emailError, setEmailError] = useState(null);
106
145
  const [emailSubmitting, setEmailSubmitting] = useState(false);
146
+ const [mountedPaymentAttemptId, setMountedPaymentAttemptId] = useState(null);
107
147
  const prepareAbortRef = useRef(null);
108
148
  const statusAbortRef = useRef(null);
109
149
  const successAttemptRef = useRef(null);
@@ -192,6 +232,7 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
192
232
  prepareAbortRef.current = controller;
193
233
  successAttemptRef.current = null;
194
234
  paymentInfoAttemptRef.current = null;
235
+ setMountedPaymentAttemptId(null);
195
236
  queueMicrotask(() => {
196
237
  if (!controller.signal.aborted) {
197
238
  setState(initialView);
@@ -213,6 +254,9 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
213
254
  });
214
255
  return () => controller.abort();
215
256
  }, [committedEmail, normalizedRequest, open, requiresEmailCommit, setState]);
257
+ const paymentFormMounted = Boolean(view.checkout && mountedPaymentAttemptId === view.checkout.attemptId);
258
+ const showPreparingLoader = view.state === 'loading'
259
+ || (view.state === 'ready' && !paymentFormMounted);
216
260
  useEffect(() => {
217
261
  var _a;
218
262
  if (!open) {
@@ -227,12 +271,14 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
227
271
  }
228
272
  };
229
273
  window.addEventListener('keydown', handleKeyDown);
230
- (_a = closeButtonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
274
+ if (!showPreparingLoader) {
275
+ (_a = closeButtonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
276
+ }
231
277
  return () => {
232
278
  window.removeEventListener('keydown', handleKeyDown);
233
279
  previouslyFocused === null || previouslyFocused === void 0 ? void 0 : previouslyFocused.focus();
234
280
  };
235
- }, [open]);
281
+ }, [open, showPreparingLoader]);
236
282
  useEffect(() => () => {
237
283
  var _a, _b;
238
284
  (_a = prepareAbortRef.current) === null || _a === void 0 ? void 0 : _a.abort();
@@ -330,25 +376,36 @@ export function SolidgateCheckoutDialog({ open, request, customerEmail, checkout
330
376
  : view.state === 'recoverable_error'
331
377
  ? copy.error
332
378
  : null;
333
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: 'solidgate-checkout-overlay', children: _jsxs("div", { role: 'dialog', "aria-modal": 'true', "aria-labelledby": 'solidgate-checkout-title', "data-checkout-state": view.state, className: 'solidgate-checkout-dialog', children: [_jsxs("div", { className: 'solidgate-checkout-header', children: [_jsx("h2", { id: 'solidgate-checkout-title', className: 'solidgate-checkout-title', children: copy.title }), _jsx("button", { ref: closeButtonRef, type: 'button', onClick: onClose, "aria-label": copy.closeAriaLabel, className: 'solidgate-checkout-close', children: "\u00D7" })] }), view.state === 'collecting_email' ? (_jsxs("form", { className: 'solidgate-checkout-email-form', onSubmit: (event) => void commitCustomerEmail(event), children: [_jsxs("label", { className: 'solidgate-checkout-email-label', children: [copy.customerEmailLabel, _jsx("input", { type: 'email', autoComplete: 'email', inputMode: 'email', maxLength: 320, required: true, value: emailInput, onChange: (event) => {
334
- setEmailInput(event.target.value);
335
- setEmailError(null);
336
- }, placeholder: copy.customerEmailPlaceholder, "aria-invalid": Boolean(emailError), className: 'solidgate-checkout-email-input' })] }), emailError ? (_jsx("p", { role: 'alert', className: 'solidgate-checkout-alert', children: emailError })) : null, _jsx("button", { type: 'submit', disabled: emailSubmitting, className: 'solidgate-checkout-action', children: copy.customerEmailContinue })] })) : null, view.checkout ? (_jsx(SolidgatePaymentForm, { checkout: view.checkout, hidden: !showForm, loadingLabel: copy.loading, onMounted: () => {
337
- if (view.state === 'loading') {
338
- setState(Object.assign(Object.assign({}, view), { state: 'ready' }));
339
- }
340
- }, onSubmit: () => {
341
- var _a, _b, _c;
342
- if (paymentInfoAttemptRef.current !== ((_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId)) {
343
- paymentInfoAttemptRef.current = ((_b = view.checkout) === null || _b === void 0 ? void 0 : _b.attemptId) || null;
344
- void trackSolidgateCheckoutEvent('add_payment_info', ((_c = view.checkout) === null || _c === void 0 ? void 0 : _c.attemptId) || '', checkoutAnalyticsRef.current);
345
- }
346
- setState(Object.assign(Object.assign({}, view), { state: 'submitting' }));
347
- }, onVerify: () => void verifyCanonicalStatus(), onError: () => {
348
- var _a;
349
- setState(Object.assign(Object.assign({}, view), { state: 'recoverable_error', canResumeVerification: false }));
350
- (_a = onErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onErrorRef, copyRef.current.error);
351
- } }, view.checkout.attemptId)) : null, statusMessage && view.state !== 'ready' ? (_jsx("div", { className: 'solidgate-checkout-status', children: _jsx("p", { role: 'status', "aria-live": 'polite', children: statusMessage }) })) : null, view.state === 'verifying' && view.canResumeVerification ? (_jsx("button", { type: 'button', onClick: () => void verifyCanonicalStatus(), className: 'solidgate-checkout-action solidgate-checkout-action--spaced', children: copy.resumeVerification })) : null, (view.state === 'recoverable_error' || view.state === 'expired') && onRetry ? (_jsx("button", { type: 'button', onClick: onRetry, className: 'solidgate-checkout-action solidgate-checkout-action--spaced', children: copy.retry })) : null] }) }), _jsx("style", { children: solidgateCheckoutDialogStyles })] }));
379
+ const showPromo = Boolean((presentation === null || presentation === void 0 ? void 0 : presentation.promoActive) &&
380
+ presentation.discountPercent > 0 &&
381
+ presentation.promoCode.trim());
382
+ const presentationStyle = presentation
383
+ ? {
384
+ '--solidgate-checkout-theme-color': presentation.themeColor,
385
+ }
386
+ : undefined;
387
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: `solidgate-checkout-overlay${presentation ? ' is-branded' : ''}`, style: presentationStyle, children: [showPreparingLoader ? (_jsxs("div", { className: 'solidgate-checkout-loader', role: 'status', "aria-live": 'polite', children: [_jsx("span", { className: 'solidgate-checkout-spinner', "aria-hidden": 'true' }), _jsx("span", { className: 'solidgate-checkout-visually-hidden', children: copy.loading })] })) : null, view.state !== 'loading' || view.checkout ? (_jsxs("div", { role: 'dialog', "aria-modal": 'true', "aria-hidden": showPreparingLoader || undefined, "aria-labelledby": 'solidgate-checkout-title', "data-checkout-state": view.state, className: [
388
+ 'solidgate-checkout-dialog',
389
+ showPreparingLoader ? 'is-preparing' : '',
390
+ presentation ? 'is-branded' : '',
391
+ ].filter(Boolean).join(' '), children: [_jsxs("div", { className: 'solidgate-checkout-header', children: [_jsx("button", { ref: closeButtonRef, type: 'button', onClick: onClose, "aria-label": copy.closeAriaLabel, className: 'solidgate-checkout-close', children: _jsx("span", { "aria-hidden": 'true' }) }), _jsx("h2", { id: 'solidgate-checkout-title', className: 'solidgate-checkout-title', children: (presentation === null || presentation === void 0 ? void 0 : presentation.title) || copy.title })] }), presentation ? (_jsxs("section", { className: 'solidgate-checkout-summary', children: [showPromo ? (_jsxs("p", { className: 'solidgate-checkout-countdown', children: [presentation.discountPercent, "% ", presentation.countdownLabel, ' ', formatCountdown(presentation.remainingSeconds), " min"] })) : null, _jsxs("p", { className: 'solidgate-checkout-satisfaction', children: [_jsx("strong", { children: presentation.satisfactionPercent }), ' ', presentation.satisfactionLabel] }), showPromo ? (_jsxs("div", { className: 'solidgate-checkout-price-stack', children: [_jsxs("div", { className: 'solidgate-checkout-price-row is-muted', children: [_jsx("span", { children: presentation.originalPriceLabel }), _jsx("span", { className: 'solidgate-checkout-strike', children: presentation.originalPriceValue })] }), _jsxs("div", { className: 'solidgate-checkout-price-row is-discount', children: [_jsx("strong", { children: presentation.discountLabel }), _jsx("strong", { children: presentation.discountAmountLabel })] }), _jsxs("div", { className: 'solidgate-checkout-promo', children: [_jsx("span", { children: presentation.promoCodeLabel }), _jsx("strong", { children: presentation.promoCode.trim() })] })] })) : null, _jsxs("div", { className: `solidgate-checkout-total${showPromo ? '' : ' is-plain'}`, children: [_jsx("span", { children: presentation.totalLabel }), _jsx("strong", { children: presentation.totalValue })] }), showPromo ? (_jsxs("p", { className: 'solidgate-checkout-saved', children: [_jsx("span", { "aria-hidden": 'true', children: "\uD83D\uDD25" }), presentation.savedLabel] })) : null] })) : null, view.state === 'collecting_email' ? (_jsxs("form", { className: 'solidgate-checkout-email-form', onSubmit: (event) => void commitCustomerEmail(event), children: [_jsxs("label", { className: 'solidgate-checkout-email-label', children: [copy.customerEmailLabel, _jsx("input", { type: 'email', autoComplete: 'email', inputMode: 'email', maxLength: 320, required: true, value: emailInput, onChange: (event) => {
392
+ setEmailInput(event.target.value);
393
+ setEmailError(null);
394
+ }, placeholder: copy.customerEmailPlaceholder, "aria-invalid": Boolean(emailError), className: 'solidgate-checkout-email-input' })] }), emailError ? (_jsx("p", { role: 'alert', className: 'solidgate-checkout-alert', children: emailError })) : null, _jsx("button", { type: 'submit', disabled: emailSubmitting, className: 'solidgate-checkout-action', children: copy.customerEmailContinue })] })) : null, view.checkout ? (_jsx(SolidgatePaymentForm, { buttonColor: (presentation === null || presentation === void 0 ? void 0 : presentation.buttonColor) || '#3f51b5', cardSubmitLabel: (presentation === null || presentation === void 0 ? void 0 : presentation.cardSubmitLabel) || 'Pay securely', checkout: view.checkout, hidden: !showForm, loadingLabel: copy.loading, onMounted: () => {
395
+ var _a;
396
+ setMountedPaymentAttemptId(((_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId) || null);
397
+ }, onSubmit: () => {
398
+ var _a, _b, _c;
399
+ if (paymentInfoAttemptRef.current !== ((_a = view.checkout) === null || _a === void 0 ? void 0 : _a.attemptId)) {
400
+ paymentInfoAttemptRef.current = ((_b = view.checkout) === null || _b === void 0 ? void 0 : _b.attemptId) || null;
401
+ void trackSolidgateCheckoutEvent('add_payment_info', ((_c = view.checkout) === null || _c === void 0 ? void 0 : _c.attemptId) || '', checkoutAnalyticsRef.current);
402
+ }
403
+ setState(Object.assign(Object.assign({}, view), { state: 'submitting' }));
404
+ }, onVerify: () => void verifyCanonicalStatus(), onError: () => {
405
+ var _a;
406
+ setState(Object.assign(Object.assign({}, view), { state: 'recoverable_error', canResumeVerification: false }));
407
+ (_a = onErrorRef.current) === null || _a === void 0 ? void 0 : _a.call(onErrorRef, copyRef.current.error);
408
+ } }, view.checkout.attemptId)) : null, presentation && view.checkout && showForm ? (_jsx("p", { className: 'solidgate-checkout-secure', children: presentation.secureLabel })) : null, statusMessage && view.state !== 'ready' ? (_jsx("div", { className: 'solidgate-checkout-status', children: _jsx("p", { role: 'status', "aria-live": 'polite', children: statusMessage }) })) : null, view.state === 'verifying' && view.canResumeVerification ? (_jsx("button", { type: 'button', onClick: () => void verifyCanonicalStatus(), className: 'solidgate-checkout-action solidgate-checkout-action--spaced', children: copy.resumeVerification })) : null, (view.state === 'recoverable_error' || view.state === 'expired') && onRetry ? (_jsx("button", { type: 'button', onClick: onRetry, className: 'solidgate-checkout-action solidgate-checkout-action--spaced', children: copy.retry })) : null] })) : null] }), _jsx("style", { children: solidgateCheckoutDialogStyles })] }));
352
409
  }
353
410
  const solidgateCheckoutDialogStyles = `
354
411
  .solidgate-checkout-overlay {
@@ -365,6 +422,14 @@ const solidgateCheckoutDialogStyles = `
365
422
  backdrop-filter: blur(4px);
366
423
  }
367
424
 
425
+ .solidgate-checkout-overlay.is-branded {
426
+ z-index: 110;
427
+ align-items: stretch;
428
+ padding: 0;
429
+ background: #fff;
430
+ backdrop-filter: none;
431
+ }
432
+
368
433
  .solidgate-checkout-dialog {
369
434
  box-sizing: border-box;
370
435
  width: min(100%, 512px);
@@ -378,14 +443,77 @@ const solidgateCheckoutDialogStyles = `
378
443
  box-shadow: 0 24px 80px rgb(17 24 39 / 22%);
379
444
  }
380
445
 
446
+ .solidgate-checkout-dialog.is-branded {
447
+ width: min(100%, 430px);
448
+ height: 100svh;
449
+ max-height: 100svh;
450
+ border: 0;
451
+ border-radius: 0;
452
+ background: #fff;
453
+ padding: 0 17px 28px;
454
+ color: #303136;
455
+ box-shadow: none;
456
+ font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
457
+ }
458
+
459
+ .solidgate-checkout-dialog.is-preparing {
460
+ position: absolute;
461
+ visibility: hidden;
462
+ pointer-events: none;
463
+ }
464
+
465
+ .solidgate-checkout-loader {
466
+ display: grid;
467
+ place-items: center;
468
+ }
469
+
470
+ .solidgate-checkout-spinner {
471
+ box-sizing: border-box;
472
+ width: 44px;
473
+ height: 44px;
474
+ border: 4px solid var(--color-border, #d1d5db);
475
+ border-top-color: var(--color-primary, #22c55e);
476
+ border-radius: 50%;
477
+ animation: solidgate-checkout-spin 720ms linear infinite;
478
+ }
479
+
480
+ .solidgate-checkout-visually-hidden {
481
+ position: absolute;
482
+ width: 1px;
483
+ height: 1px;
484
+ overflow: hidden;
485
+ clip: rect(0 0 0 0);
486
+ clip-path: inset(50%);
487
+ white-space: nowrap;
488
+ }
489
+
490
+ @keyframes solidgate-checkout-spin {
491
+ to {
492
+ transform: rotate(360deg);
493
+ }
494
+ }
495
+
496
+ @media (prefers-reduced-motion: reduce) {
497
+ .solidgate-checkout-spinner {
498
+ animation-duration: 1.6s;
499
+ }
500
+ }
501
+
381
502
  .solidgate-checkout-header {
503
+ position: relative;
382
504
  display: flex;
383
505
  align-items: center;
384
- justify-content: space-between;
506
+ justify-content: center;
385
507
  gap: 16px;
386
508
  margin-bottom: 16px;
387
509
  }
388
510
 
511
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-header {
512
+ min-height: 70px;
513
+ margin: 0 -17px;
514
+ padding: 0 56px;
515
+ }
516
+
389
517
  .solidgate-checkout-title {
390
518
  margin: 0;
391
519
  color: var(--color-text, #111827);
@@ -394,7 +522,18 @@ const solidgateCheckoutDialogStyles = `
394
522
  line-height: 1.3;
395
523
  }
396
524
 
525
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-title {
526
+ color: #020203;
527
+ font-size: 24px;
528
+ font-weight: 900;
529
+ line-height: 1.15;
530
+ text-align: center;
531
+ }
532
+
397
533
  .solidgate-checkout-close {
534
+ position: absolute;
535
+ left: 0;
536
+ top: 50%;
398
537
  width: 36px;
399
538
  height: 36px;
400
539
  flex: none;
@@ -403,14 +542,158 @@ const solidgateCheckoutDialogStyles = `
403
542
  background: var(--color-bg, #f9fafb);
404
543
  color: var(--color-text, #111827);
405
544
  font-size: 22px;
406
- line-height: 1;
545
+ transform: translateY(-50%);
407
546
  cursor: pointer;
408
547
  }
409
548
 
549
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-close {
550
+ left: 16px;
551
+ width: 40px;
552
+ height: 40px;
553
+ border: 0;
554
+ border-radius: 999px;
555
+ background: #f2f2f3;
556
+ color: #aaa;
557
+ }
558
+
559
+ .solidgate-checkout-close span,
560
+ .solidgate-checkout-close span::after {
561
+ position: absolute;
562
+ left: 50%;
563
+ top: 50%;
564
+ width: 22px;
565
+ height: 3px;
566
+ border-radius: 999px;
567
+ background: currentColor;
568
+ content: '';
569
+ }
570
+
571
+ .solidgate-checkout-close span {
572
+ transform: translate(-50%, -50%) rotate(45deg);
573
+ }
574
+
575
+ .solidgate-checkout-close span::after {
576
+ transform: translate(-50%, -50%) rotate(90deg);
577
+ }
578
+
410
579
  .solidgate-checkout-close:hover {
411
580
  background: var(--color-accent-soft, #eef2ff);
412
581
  }
413
582
 
583
+ .solidgate-checkout-summary {
584
+ color: #303136;
585
+ }
586
+
587
+ .solidgate-checkout-countdown {
588
+ min-height: 37px;
589
+ display: flex;
590
+ align-items: center;
591
+ justify-content: center;
592
+ margin: 0;
593
+ border-radius: 12px;
594
+ background: color-mix(in srgb, var(--solidgate-checkout-theme-color) 10%, #fff);
595
+ color: var(--solidgate-checkout-theme-color);
596
+ font-size: 16px;
597
+ font-weight: 900;
598
+ text-align: center;
599
+ }
600
+
601
+ .solidgate-checkout-satisfaction {
602
+ margin: 17px 0 21px;
603
+ color: #2f3034;
604
+ font-size: 19px;
605
+ font-weight: 800;
606
+ line-height: 1.15;
607
+ text-align: center;
608
+ }
609
+
610
+ .solidgate-checkout-satisfaction strong {
611
+ color: var(--solidgate-checkout-theme-color);
612
+ }
613
+
614
+ .solidgate-checkout-price-stack {
615
+ display: flex;
616
+ flex-direction: column;
617
+ gap: 8px;
618
+ }
619
+
620
+ .solidgate-checkout-price-row,
621
+ .solidgate-checkout-promo,
622
+ .solidgate-checkout-total {
623
+ display: flex;
624
+ align-items: center;
625
+ justify-content: space-between;
626
+ gap: 12px;
627
+ }
628
+
629
+ .solidgate-checkout-price-row {
630
+ font-size: 17px;
631
+ }
632
+
633
+ .solidgate-checkout-price-row.is-muted {
634
+ color: #9d9d9f;
635
+ font-weight: 500;
636
+ }
637
+
638
+ .solidgate-checkout-strike {
639
+ text-decoration: line-through 2px;
640
+ }
641
+
642
+ .solidgate-checkout-price-row.is-discount {
643
+ color: #040508;
644
+ font-weight: 900;
645
+ }
646
+
647
+ .solidgate-checkout-price-row.is-discount strong:last-child {
648
+ color: #ff2544;
649
+ }
650
+
651
+ .solidgate-checkout-promo {
652
+ min-height: 42px;
653
+ border-radius: 13px;
654
+ background: #f0f0f0;
655
+ padding: 0 14px;
656
+ color: #8d8d90;
657
+ font-size: 16px;
658
+ }
659
+
660
+ .solidgate-checkout-promo strong {
661
+ color: #050609;
662
+ font-weight: 900;
663
+ }
664
+
665
+ .solidgate-checkout-total {
666
+ min-height: 76px;
667
+ margin-top: 20px;
668
+ border-top: 1px solid #dedede;
669
+ font-size: 23px;
670
+ font-weight: 800;
671
+ }
672
+
673
+ .solidgate-checkout-total.is-plain {
674
+ margin-top: 0;
675
+ }
676
+
677
+ .solidgate-checkout-total strong {
678
+ font-size: 25px;
679
+ font-weight: 900;
680
+ }
681
+
682
+ .solidgate-checkout-saved {
683
+ width: fit-content;
684
+ min-height: 36px;
685
+ display: flex;
686
+ align-items: center;
687
+ gap: 7px;
688
+ margin: 0 auto 12px;
689
+ border-radius: 999px;
690
+ background: #fff3cf;
691
+ padding: 0 13px;
692
+ color: #2e3034;
693
+ font-size: 14px;
694
+ font-weight: 800;
695
+ }
696
+
414
697
  .solidgate-checkout-email-form,
415
698
  .solidgate-checkout-email-label,
416
699
  .solidgate-checkout-wallets {
@@ -487,6 +770,25 @@ const solidgateCheckoutDialogStyles = `
487
770
  margin-bottom: 12px;
488
771
  }
489
772
 
773
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-wallets {
774
+ margin-top: 4px;
775
+ }
776
+
777
+ .solidgate-checkout-dialog.is-branded .solidgate-checkout-wallets > div:not(:empty) {
778
+ min-height: 48px;
779
+ }
780
+
781
+ .solidgate-checkout-secure {
782
+ width: fit-content;
783
+ margin: 14px auto 0;
784
+ border-radius: 999px;
785
+ background: #edfff4;
786
+ padding: 8px 14px;
787
+ color: #2b2d31;
788
+ font-size: 13px;
789
+ font-weight: 700;
790
+ }
791
+
490
792
  .solidgate-checkout-payment[hidden] {
491
793
  display: none;
492
794
  }
@@ -984,12 +984,13 @@ const sharedStripeCheckoutV2Styles = `
984
984
  .shared-checkout-special-offer-gift--image {
985
985
  position: relative;
986
986
  width: min(100%, 250px);
987
+ aspect-ratio: 1;
987
988
  }
988
989
 
989
990
  .shared-checkout-special-offer-gift-image {
990
991
  display: block;
991
992
  width: 100%;
992
- aspect-ratio: 1;
993
+ height: 100%;
993
994
  background-position: center;
994
995
  background-repeat: no-repeat;
995
996
  background-size: contain;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnelsgrove/payments",
3
- "version": "0.7.13",
3
+ "version": "0.7.15",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/The-Solid-Grove/funnelsgrove.git",