smartcomply-web-sdk 1.0.62 → 1.0.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/esm/flow/DocumentCapture.d.ts +19 -1
  2. package/dist/esm/flow/DocumentCapture.d.ts.map +1 -1
  3. package/dist/esm/flow/DocumentCapture.js +144 -77
  4. package/dist/esm/flow/DocumentCapture.js.map +1 -1
  5. package/dist/esm/flow/SmartComplyFlow.d.ts.map +1 -1
  6. package/dist/esm/flow/SmartComplyFlow.js +76 -103
  7. package/dist/esm/flow/SmartComplyFlow.js.map +1 -1
  8. package/dist/esm/flow/icons.d.ts +14 -0
  9. package/dist/esm/flow/icons.d.ts.map +1 -0
  10. package/dist/esm/flow/icons.js +34 -0
  11. package/dist/esm/flow/icons.js.map +1 -0
  12. package/dist/esm/flow/spinner.d.ts +15 -0
  13. package/dist/esm/flow/spinner.d.ts.map +1 -0
  14. package/dist/esm/flow/spinner.js +55 -0
  15. package/dist/esm/flow/spinner.js.map +1 -0
  16. package/dist/esm/flow/theme.d.ts +19 -0
  17. package/dist/esm/flow/theme.d.ts.map +1 -1
  18. package/dist/esm/flow/theme.js +19 -0
  19. package/dist/esm/flow/theme.js.map +1 -1
  20. package/dist/esm/modules/liveness/LivenessUI.d.ts +10 -0
  21. package/dist/esm/modules/liveness/LivenessUI.d.ts.map +1 -1
  22. package/dist/esm/modules/liveness/LivenessUI.js +17 -16
  23. package/dist/esm/modules/liveness/LivenessUI.js.map +1 -1
  24. package/dist/esm/modules/liveness/liveness.d.ts +2 -0
  25. package/dist/esm/modules/liveness/liveness.d.ts.map +1 -1
  26. package/dist/esm/modules/liveness/liveness.js +1 -1
  27. package/dist/esm/modules/liveness/liveness.js.map +1 -1
  28. package/dist/flow/DocumentCapture.d.ts +19 -1
  29. package/dist/flow/DocumentCapture.d.ts.map +1 -1
  30. package/dist/flow/DocumentCapture.js +144 -77
  31. package/dist/flow/DocumentCapture.js.map +1 -1
  32. package/dist/flow/SmartComplyFlow.d.ts.map +1 -1
  33. package/dist/flow/SmartComplyFlow.js +75 -102
  34. package/dist/flow/SmartComplyFlow.js.map +1 -1
  35. package/dist/flow/icons.d.ts +14 -0
  36. package/dist/flow/icons.d.ts.map +1 -0
  37. package/dist/flow/icons.js +37 -0
  38. package/dist/flow/icons.js.map +1 -0
  39. package/dist/flow/spinner.d.ts +15 -0
  40. package/dist/flow/spinner.d.ts.map +1 -0
  41. package/dist/flow/spinner.js +59 -0
  42. package/dist/flow/spinner.js.map +1 -0
  43. package/dist/flow/theme.d.ts +19 -0
  44. package/dist/flow/theme.d.ts.map +1 -1
  45. package/dist/flow/theme.js +20 -1
  46. package/dist/flow/theme.js.map +1 -1
  47. package/dist/modules/liveness/LivenessUI.d.ts +10 -0
  48. package/dist/modules/liveness/LivenessUI.d.ts.map +1 -1
  49. package/dist/modules/liveness/LivenessUI.js +17 -16
  50. package/dist/modules/liveness/LivenessUI.js.map +1 -1
  51. package/dist/modules/liveness/liveness.d.ts +2 -0
  52. package/dist/modules/liveness/liveness.d.ts.map +1 -1
  53. package/dist/modules/liveness/liveness.js +1 -1
  54. package/dist/modules/liveness/liveness.js.map +1 -1
  55. package/dist/smartcomply.browser.js +316 -202
  56. package/dist/smartcomply.browser.js.map +4 -4
  57. package/package.json +1 -1
@@ -6,6 +6,8 @@ const theme_1 = require("./theme");
6
6
  const DocumentCapture_1 = require("./DocumentCapture");
7
7
  const device_1 = require("../utils/device");
8
8
  const documentRules_1 = require("../utils/documentRules");
9
+ const icons_1 = require("./icons");
10
+ const spinner_1 = require("./spinner");
9
11
  const STEP_ORDER = [
10
12
  "loading",
11
13
  "welcome",
@@ -229,18 +231,6 @@ function _formatDocType(code) {
229
231
  }
230
232
  // SmartComplyFlow
231
233
  // ─────────────────────────────────────────────────────────────────────
232
- // Add CSS animation keyframes for spin animations
233
- const style = document.createElement('style');
234
- style.textContent = `
235
- @keyframes sc-spin {
236
- 0% { transform: rotate(0deg); }
237
- 100% { transform: rotate(360deg); }
238
- }
239
- `;
240
- if (!document.head.querySelector('style[data-sc-animations]')) {
241
- style.setAttribute('data-sc-animations', 'true');
242
- document.head.appendChild(style);
243
- }
244
234
  class SmartComplyFlow {
245
235
  constructor(options) {
246
236
  this.theme = (0, theme_1.getTheme)("default");
@@ -612,27 +602,9 @@ class SmartComplyFlow {
612
602
  // ── Loading ─────────────────────────────────────────────────────
613
603
  renderLoading(container) {
614
604
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:300px;gap:16px;";
615
- const spinnerWrap = document.createElement("div");
616
- spinnerWrap.style.cssText = "position:relative;width:60px;height:60px;flex-shrink:0;";
617
- const ring = document.createElement("div");
618
- ring.style.cssText = `
619
- position:absolute;inset:0;border-radius:50%;
620
- border:3px solid ${this.theme.border};
621
- border-top-color:${this.theme.primary};
622
- animation:sc-spin 0.9s linear infinite;
623
- `;
624
- const centre = document.createElement("div");
625
- centre.style.cssText = `
626
- position:absolute;inset:0;
627
- display:flex;align-items:center;justify-content:center;
628
- font-size:22px;
629
- `;
630
- centre.textContent = "\uD83D\uDEE1\uFE0F";
631
- spinnerWrap.appendChild(ring);
632
- spinnerWrap.appendChild(centre);
633
- container.appendChild(spinnerWrap);
605
+ container.appendChild((0, spinner_1.renderSpinner)(this.theme, { size: 60, icon: (0, icons_1.icon)("shield", 22) }));
634
606
  const label = document.createElement("div");
635
- label.style.cssText = `color:${this.theme.text};font-size:15px;font-weight:600;`;
607
+ label.style.cssText = `color:${this.theme.text};font-size:${theme_1.TYPE.base}px;font-weight:600;`;
636
608
  label.textContent = "Setting up secure session";
637
609
  container.appendChild(label);
638
610
  const sub = document.createElement("div");
@@ -651,11 +623,11 @@ class SmartComplyFlow {
651
623
  iconWrap.style.cssText = `
652
624
  width:50px;height:50px;border-radius:14px;
653
625
  display:flex;align-items:center;justify-content:center;
654
- font-size:22px;
626
+ color:${this.theme.primary};
655
627
  background:linear-gradient(135deg,${this.theme.primary}22,${this.theme.primaryGlow});
656
628
  border:1.5px solid ${this.theme.primary}33;
657
629
  `;
658
- iconWrap.textContent = isDocFlow ? "🪪" : "🛡️";
630
+ iconWrap.innerHTML = (0, icons_1.icon)(isDocFlow ? "id-card" : "shield", 24);
659
631
  topRow.appendChild(iconWrap);
660
632
  const badge = document.createElement("div");
661
633
  badge.style.cssText = `
@@ -674,7 +646,7 @@ class SmartComplyFlow {
674
646
  titleWrap.style.cssText = "display:flex;flex-direction:column;gap:5px;";
675
647
  const title = document.createElement("h2");
676
648
  title.style.cssText = `
677
- color:${this.theme.text};font-size:20px;font-weight:700;
649
+ color:${this.theme.text};font-size:${theme_1.TYPE.heading}px;font-weight:700;
678
650
  margin:0;line-height:1.2;
679
651
  `;
680
652
  // W2: Use client brand name in title
@@ -708,7 +680,7 @@ class SmartComplyFlow {
708
680
  const stepsWrap = document.createElement("div");
709
681
  stepsWrap.style.cssText = `
710
682
  width:100%;display:flex;flex-direction:column;gap:0;
711
- border-radius:12px;overflow:hidden;
683
+ border-radius:${theme_1.RADIUS.md}px;overflow:hidden;
712
684
  border:1.5px solid ${this.theme.border};
713
685
  `;
714
686
  steps.forEach((step, i) => {
@@ -721,7 +693,7 @@ class SmartComplyFlow {
721
693
  `;
722
694
  const iconEl = document.createElement("div");
723
695
  iconEl.style.cssText = `
724
- width:28px;height:28px;border-radius:8px;flex-shrink:0;
696
+ width:28px;height:28px;border-radius:${theme_1.RADIUS.sm}px;flex-shrink:0;
725
697
  display:flex;align-items:center;justify-content:center;
726
698
  font-size:13px;
727
699
  background:${this.theme.primary}12;
@@ -949,7 +921,7 @@ class SmartComplyFlow {
949
921
  // Dropdown field
950
922
  const select = document.createElement("select");
951
923
  select.style.cssText = `
952
- width:100%;padding:13px 16px;border-radius:12px;
924
+ width:100%;padding:13px 16px;border-radius:${theme_1.RADIUS.md}px;
953
925
  font-size:15px;
954
926
  background:${this.theme.inputBg};
955
927
  color:${this.theme.text};
@@ -984,7 +956,7 @@ class SmartComplyFlow {
984
956
  fileInput.type = "file";
985
957
  fileInput.accept = "image/*";
986
958
  fileInput.style.cssText = `
987
- width:100%;padding:12px 16px;border-radius:12px;
959
+ width:100%;padding:12px 16px;border-radius:${theme_1.RADIUS.md}px;
988
960
  font-size:14px;font-weight:500;
989
961
  background:${this.theme.inputBg};
990
962
  color:${this.theme.text};
@@ -1028,7 +1000,7 @@ class SmartComplyFlow {
1028
1000
  if (rule?.numeric)
1029
1001
  input.inputMode = "numeric";
1030
1002
  input.style.cssText = `
1031
- width:100%;padding:14px 16px;border-radius:12px;
1003
+ width:100%;padding:14px 16px;border-radius:${theme_1.RADIUS.md}px;
1032
1004
  font-size:16px;font-weight:500;
1033
1005
  background:${this.theme.inputBg};
1034
1006
  color:${this.theme.text};
@@ -1090,7 +1062,7 @@ class SmartComplyFlow {
1090
1062
  errorEl.id = "sc-id-error";
1091
1063
  errorEl.style.cssText = `
1092
1064
  color:${this.theme.error};font-size:13px;display:none;
1093
- padding:8px 12px;border-radius:8px;background:${this.theme.errorBg};
1065
+ padding:8px 12px;border-radius:${theme_1.RADIUS.sm}px;background:${this.theme.errorBg};
1094
1066
  `;
1095
1067
  container.appendChild(errorEl);
1096
1068
  // Submit
@@ -1111,7 +1083,7 @@ class SmartComplyFlow {
1111
1083
  };
1112
1084
  submitBtn.addEventListener("click", async () => {
1113
1085
  submitBtn.disabled = true;
1114
- submitBtn.innerHTML = `<span style="display:inline-flex;align-items:center;justify-content:center;gap:8px;"><span style="width:13px;height:13px;border-radius:50%;border:2px solid rgba(255,255,255,0.3);border-top-color:#fff;animation:sc-spin 0.6s linear infinite;display:inline-block;flex-shrink:0;"></span>Verifying...</span>`;
1086
+ submitBtn.innerHTML = `<span style="display:inline-flex;align-items:center;justify-content:center;gap:8px;">${(0, spinner_1.renderInlineSpinner)("#fff", 13)}Verifying...</span>`;
1115
1087
  errorEl.style.display = "none";
1116
1088
  try {
1117
1089
  this.verificationResult = await this.sdk.onboarding.verify({
@@ -1238,11 +1210,11 @@ class SmartComplyFlow {
1238
1210
  // W13: Pre-warm camera silently while user reads this screen
1239
1211
  this._prewarmCamera();
1240
1212
  const iconWrap = document.createElement("div");
1241
- iconWrap.style.cssText = `width:64px;height:64px;border-radius:50%;background:${this.theme.primary}15;border:2px solid ${this.theme.primary}30;display:flex;align-items:center;justify-content:center;font-size:28px;`;
1242
- iconWrap.textContent = "🛡️";
1213
+ iconWrap.style.cssText = `width:64px;height:64px;border-radius:50%;background:${this.theme.primary}15;border:2px solid ${this.theme.primary}30;display:flex;align-items:center;justify-content:center;color:${this.theme.primary};`;
1214
+ iconWrap.innerHTML = (0, icons_1.icon)("shield", 28);
1243
1215
  container.appendChild(iconWrap);
1244
1216
  const title = document.createElement("h2");
1245
- title.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
1217
+ title.style.cssText = `color:${this.theme.text};font-size:${theme_1.TYPE.heading}px;font-weight:700;margin:0;`;
1246
1218
  title.textContent = this._ivsName ? `Is this you?` : "Identity Confirmed";
1247
1219
  container.appendChild(title);
1248
1220
  if (this._ivsName) {
@@ -1306,12 +1278,25 @@ class SmartComplyFlow {
1306
1278
  }
1307
1279
  // W13: Pre-warm camera while user reads
1308
1280
  this._prewarmCamera();
1281
+ // Step badge — pairs with DocumentCapture.showPreview's "Step 1 of 2"
1282
+ // badge shown right after capture, so this doesn't read as unexplained
1283
+ // repetition: that screen checked photo clarity, this one checks the
1284
+ // OCR-extracted data.
1285
+ const stepBadge = document.createElement("div");
1286
+ stepBadge.style.cssText = `
1287
+ display:inline-flex;align-items:center;gap:5px;
1288
+ padding:3px 11px;border-radius:${theme_1.RADIUS.pill}px;
1289
+ font-size:10.5px;font-weight:600;letter-spacing:0.2px;
1290
+ color:${this.theme.primary};background:${this.theme.primary}15;border:1px solid ${this.theme.primary}30;
1291
+ `;
1292
+ stepBadge.textContent = "STEP 2 OF 2 · CHECK WHAT WE READ";
1293
+ container.appendChild(stepBadge);
1309
1294
  const iconWrap = document.createElement("div");
1310
- iconWrap.style.cssText = `width:64px;height:64px;border-radius:50%;background:${this.theme.primary}15;border:2px solid ${this.theme.primary}30;display:flex;align-items:center;justify-content:center;font-size:28px;`;
1311
- iconWrap.textContent = "📄";
1295
+ iconWrap.style.cssText = `width:64px;height:64px;border-radius:50%;background:${this.theme.primary}15;border:2px solid ${this.theme.primary}30;display:flex;align-items:center;justify-content:center;color:${this.theme.primary};`;
1296
+ iconWrap.innerHTML = (0, icons_1.icon)("document", 28);
1312
1297
  container.appendChild(iconWrap);
1313
1298
  const title = document.createElement("h2");
1314
- title.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
1299
+ title.style.cssText = `color:${this.theme.text};font-size:${theme_1.TYPE.heading}px;font-weight:700;margin:0;`;
1315
1300
  title.textContent = "Are these your details?";
1316
1301
  container.appendChild(title);
1317
1302
  const sub = document.createElement("p");
@@ -1403,19 +1388,10 @@ class SmartComplyFlow {
1403
1388
  // ── W6+W7+W8: OCR Gate (document verification) ───────────────────
1404
1389
  renderOcrGate(container) {
1405
1390
  container.style.cssText += "display:flex;flex-direction:column;align-items:center;gap:14px;padding:20px 0;text-align:center;";
1406
- const spinnerWrap = document.createElement("div");
1407
- spinnerWrap.style.cssText = "position:relative;width:52px;height:52px;flex-shrink:0;";
1408
- const ring = document.createElement("div");
1409
- ring.style.cssText = `position:absolute;inset:0;border-radius:50%;border:3px solid ${this.theme.border};border-top-color:${this.theme.primary};animation:sc-spin 0.9s linear infinite;`;
1410
- const centre = document.createElement("div");
1411
- centre.style.cssText = "position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:20px;";
1412
- centre.textContent = "📄";
1413
- spinnerWrap.appendChild(ring);
1414
- spinnerWrap.appendChild(centre);
1415
- container.appendChild(spinnerWrap);
1391
+ container.appendChild((0, spinner_1.renderSpinner)(this.theme, { size: 52, icon: (0, icons_1.icon)("document", 20) }));
1416
1392
  const statusEl = document.createElement("div");
1417
1393
  statusEl.setAttribute("aria-live", "polite");
1418
- statusEl.style.cssText = `color:${this.theme.text};font-size:15px;font-weight:600;`;
1394
+ statusEl.style.cssText = `color:${this.theme.text};font-size:${theme_1.TYPE.base}px;font-weight:600;`;
1419
1395
  statusEl.textContent = "Reading your document…";
1420
1396
  container.appendChild(statusEl);
1421
1397
  const subEl = document.createElement("div");
@@ -1516,7 +1492,7 @@ class SmartComplyFlow {
1516
1492
  icon.textContent = "📅";
1517
1493
  container.appendChild(icon);
1518
1494
  const t = document.createElement("h2");
1519
- t.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
1495
+ t.style.cssText = `color:${this.theme.text};font-size:${theme_1.TYPE.heading}px;font-weight:700;margin:0;`;
1520
1496
  t.textContent = "Document Expired";
1521
1497
  container.appendChild(t);
1522
1498
  const d = document.createElement("p");
@@ -1542,7 +1518,7 @@ class SmartComplyFlow {
1542
1518
  icon.textContent = "🔍";
1543
1519
  container.appendChild(icon);
1544
1520
  const t = document.createElement("h2");
1545
- t.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
1521
+ t.style.cssText = `color:${this.theme.text};font-size:${theme_1.TYPE.heading}px;font-weight:700;margin:0;`;
1546
1522
  t.textContent = "Document Photo Unclear";
1547
1523
  container.appendChild(t);
1548
1524
  const msg = reason === "image_too_blurry" ? "Your document photo is too blurry. Please retake it in good lighting with a steady hand."
@@ -1579,11 +1555,11 @@ class SmartComplyFlow {
1579
1555
  verificationResult: this.verificationResult || undefined,
1580
1556
  });
1581
1557
  const iconWrap = document.createElement("div");
1582
- iconWrap.style.cssText = `width:80px;height:80px;border-radius:50%;background:${this.theme.successBg};border:3px solid ${this.theme.success};display:flex;align-items:center;justify-content:center;font-size:36px;font-weight:700;color:${this.theme.success};animation:sc-pop 0.4s ease;`;
1583
- iconWrap.textContent = "✓";
1558
+ iconWrap.style.cssText = `width:80px;height:80px;border-radius:50%;background:${this.theme.successBg};border:3px solid ${this.theme.success};display:flex;align-items:center;justify-content:center;color:${this.theme.success};animation:sc-pop 0.4s ease;`;
1559
+ iconWrap.innerHTML = (0, icons_1.icon)("check", 36);
1584
1560
  container.appendChild(iconWrap);
1585
1561
  const title = document.createElement("h2");
1586
- title.style.cssText = `color:${this.theme.text};font-size:22px;font-weight:700;margin:0;`;
1562
+ title.style.cssText = `color:${this.theme.text};font-size:${theme_1.TYPE.headingLg}px;font-weight:700;margin:0;`;
1587
1563
  title.textContent = "You're all done!";
1588
1564
  container.appendChild(title);
1589
1565
  const desc = document.createElement("p");
@@ -1610,7 +1586,7 @@ class SmartComplyFlow {
1610
1586
  icon.textContent = "⚠️";
1611
1587
  container.appendChild(icon);
1612
1588
  const t = document.createElement("h2");
1613
- t.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
1589
+ t.style.cssText = `color:${this.theme.text};font-size:${theme_1.TYPE.heading}px;font-weight:700;margin:0;`;
1614
1590
  t.textContent = "Unable to Complete Verification";
1615
1591
  container.appendChild(t);
1616
1592
  const d = document.createElement("p");
@@ -1665,15 +1641,12 @@ class SmartComplyFlow {
1665
1641
  }
1666
1642
  this.documentBlob = blob;
1667
1643
  // Show scanning state
1668
- captureContainer.innerHTML = `
1669
- <div style="display:flex;flex-direction:column;align-items:center;gap:14px;padding:28px 20px;">
1670
- <div style="position:relative;width:52px;height:52px;">
1671
- <div style="position:absolute;inset:0;border-radius:50%;border:3px solid ${this.theme.border};border-top-color:${this.theme.primary};animation:sc-spin 0.8s linear infinite;"></div>
1672
- <div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:20px;">🔍</div>
1673
- </div>
1644
+ captureContainer.innerHTML = "";
1645
+ captureContainer.style.cssText += "display:flex;flex-direction:column;align-items:center;gap:14px;padding:28px 20px;";
1646
+ captureContainer.appendChild((0, spinner_1.renderSpinner)(this.theme, { size: 52, icon: (0, icons_1.icon)("search", 20) }));
1647
+ captureContainer.insertAdjacentHTML("beforeend", `
1674
1648
  <div style="color:${this.theme.text};font-size:14px;font-weight:600;">Scanning document...</div>
1675
- <div style="color:${this.theme.textSecondary};font-size:12px;text-align:center;max-width:200px;line-height:1.5;">Running OCR and verifying your identity</div>
1676
- </div>`;
1649
+ <div style="color:${this.theme.textSecondary};font-size:12px;text-align:center;max-width:200px;line-height:1.5;">Running OCR and verifying your identity</div>`);
1677
1650
  // Create liveness entry with document.
1678
1651
  // Use the first collected field value as identifier when available
1679
1652
  // (document flow has no data-verification step, so collectedFields is
@@ -1737,15 +1710,12 @@ class SmartComplyFlow {
1737
1710
  console.log(`Retrying document processing (attempt ${retryCount}/${maxRetries})`);
1738
1711
  // Show retry message
1739
1712
  if (captureContainer) {
1740
- captureContainer.innerHTML = `
1741
- <div style="display:flex;flex-direction:column;align-items:center;gap:16px;padding:28px 20px;text-align:center;">
1742
- <div style="position:relative;width:52px;height:52px;">
1743
- <div style="position:absolute;inset:0;border-radius:50%;border:3px solid ${this.theme.border};border-top-color:${this.theme.primary};animation:sc-spin 0.8s linear infinite;"></div>
1744
- <div style="position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:20px;">🔄</div>
1745
- </div>
1713
+ captureContainer.innerHTML = "";
1714
+ captureContainer.style.cssText += "display:flex;flex-direction:column;align-items:center;gap:16px;padding:28px 20px;text-align:center;";
1715
+ captureContainer.appendChild((0, spinner_1.renderSpinner)(this.theme, { size: 52, icon: (0, icons_1.icon)("refresh", 20) }));
1716
+ captureContainer.insertAdjacentHTML("beforeend", `
1746
1717
  <div style="color:${this.theme.text};font-size:14px;font-weight:600;">Retrying...</div>
1747
- <div style="color:${this.theme.textSecondary};font-size:12px;max-width:240px;line-height:1.5;">Attempt ${retryCount} of ${maxRetries}</div>
1748
- </div>`;
1718
+ <div style="color:${this.theme.textSecondary};font-size:12px;max-width:240px;line-height:1.5;">Attempt ${retryCount} of ${maxRetries}</div>`);
1749
1719
  }
1750
1720
  // Wait before retry
1751
1721
  await new Promise(resolve => setTimeout(resolve, 2000));
@@ -1807,7 +1777,7 @@ class SmartComplyFlow {
1807
1777
  const retryBtn = document.createElement("button");
1808
1778
  retryBtn.textContent = "Try Again";
1809
1779
  retryBtn.setAttribute("aria-label", "Retake document photo");
1810
- retryBtn.style.cssText = `margin-top:8px;padding:12px 24px;border-radius:8px;background:${this.theme.primary};color:#fff;border:none;font-size:14px;font-weight:600;cursor:pointer;`;
1780
+ retryBtn.style.cssText = `margin-top:8px;padding:12px 24px;border-radius:${theme_1.RADIUS.sm}px;background:${this.theme.primary};color:#fff;border:none;font-size:14px;font-weight:600;cursor:pointer;`;
1811
1781
  retryBtn.addEventListener("click", () => this.showStep("document_capture"));
1812
1782
  wrap.appendChild(retryBtn);
1813
1783
  }
@@ -1868,6 +1838,12 @@ class SmartComplyFlow {
1868
1838
  : "liveness_only",
1869
1839
  // B4: pass pre-warmed stream so camera.open() is skipped
1870
1840
  prewarmedStream: this._prewarmedStream || undefined,
1841
+ colors: {
1842
+ primary: this.theme.primary,
1843
+ success: this.theme.success,
1844
+ error: this.theme.error,
1845
+ warning: this.theme.warning,
1846
+ },
1871
1847
  }, ["BLINK"], this.livenessEntryId || undefined)
1872
1848
  .then((result) => {
1873
1849
  // W11: After submit, end user is done — show "You're all done" screen.
@@ -1909,14 +1885,14 @@ class SmartComplyFlow {
1909
1885
  // /v1/sdk/liveness/submit/) are an operator-facing problem, not something
1910
1886
  // the end user can act on — never show "wallet"/"balance" language to them.
1911
1887
  const isBillingErr = /wallet|balance|insufficient.*fund|payment.*required/i.test(message);
1912
- const errorIcon = isCameraErr ? "📷"
1913
- : isNetworkErr ? "📡"
1914
- : isAuthErr ? "⏱"
1915
- : isDocQuality ? "🔍"
1916
- : isExpiredDoc ? "📅"
1917
- : isFaceMatch ? "🤳"
1918
- : isBillingErr ? "⚠️"
1919
- : "✕";
1888
+ const errorIconName = isCameraErr ? "camera"
1889
+ : isNetworkErr ? "network"
1890
+ : isAuthErr ? "clock"
1891
+ : isDocQuality ? "search"
1892
+ : isExpiredDoc ? "calendar"
1893
+ : isFaceMatch ? "face"
1894
+ : isBillingErr ? "warning"
1895
+ : "close";
1920
1896
  const errorTitle = isCameraErr ? "Camera Access Required"
1921
1897
  : isNetworkErr ? "Connection Problem"
1922
1898
  : isAuthErr ? "Session Expired"
@@ -1945,14 +1921,14 @@ class SmartComplyFlow {
1945
1921
  iconWrap.style.cssText = `
1946
1922
  width:72px;height:72px;border-radius:50%;
1947
1923
  display:flex;align-items:center;justify-content:center;
1948
- font-size:28px;
1924
+ color:${this.theme.error};
1949
1925
  background:${this.theme.errorBg};
1950
1926
  border:3px solid ${this.theme.error};
1951
1927
  `;
1952
- iconWrap.textContent = errorIcon;
1928
+ iconWrap.innerHTML = (0, icons_1.icon)(errorIconName, 28);
1953
1929
  wrapper.appendChild(iconWrap);
1954
1930
  const title = document.createElement("h2");
1955
- title.style.cssText = `color:${this.theme.text};font-size:18px;font-weight:700;margin:0;`;
1931
+ title.style.cssText = `color:${this.theme.text};font-size:${theme_1.TYPE.heading}px;font-weight:700;margin:0;`;
1956
1932
  title.textContent = errorTitle;
1957
1933
  wrapper.appendChild(title);
1958
1934
  const desc = document.createElement("p");
@@ -1991,7 +1967,7 @@ class SmartComplyFlow {
1991
1967
  this.headerBackBtn.innerHTML = "&#8592;";
1992
1968
  this.headerBackBtn.setAttribute("aria-label", "Go back to previous step");
1993
1969
  this.headerBackBtn.style.cssText = `
1994
- width:30px;height:30px;border-radius:8px;flex-shrink:0;
1970
+ width:30px;height:30px;border-radius:${theme_1.RADIUS.sm}px;flex-shrink:0;
1995
1971
  display:none;align-items:center;justify-content:center;
1996
1972
  border:1.5px solid ${this.theme.border};cursor:pointer;
1997
1973
  font-size:16px;line-height:1;
@@ -2049,7 +2025,7 @@ class SmartComplyFlow {
2049
2025
  closeBtn.innerHTML = "✕";
2050
2026
  closeBtn.setAttribute("aria-label", "Close identity verification");
2051
2027
  closeBtn.style.cssText = `
2052
- width:32px;height:32px;border-radius:8px;flex-shrink:0;
2028
+ width:32px;height:32px;border-radius:${theme_1.RADIUS.sm}px;flex-shrink:0;
2053
2029
  display:flex;align-items:center;justify-content:center;
2054
2030
  border:none;cursor:pointer;font-size:16px;
2055
2031
  background:${this.theme.shimmer};color:${this.theme.textMuted};
@@ -2086,7 +2062,7 @@ class SmartComplyFlow {
2086
2062
  createStepTitle(text) {
2087
2063
  const el = document.createElement("h3");
2088
2064
  el.style.cssText = `
2089
- color:${this.theme.text};font-size:18px;font-weight:700;
2065
+ color:${this.theme.text};font-size:${theme_1.TYPE.heading}px;font-weight:700;
2090
2066
  margin:0;
2091
2067
  `;
2092
2068
  el.textContent = text;
@@ -2096,7 +2072,7 @@ class SmartComplyFlow {
2096
2072
  const card = document.createElement("button");
2097
2073
  card.setAttribute("aria-label", subtitle ? `${title}: ${subtitle}` : title);
2098
2074
  card.style.cssText = `
2099
- width:100%;padding:13px 16px;border-radius:12px;
2075
+ width:100%;padding:13px 16px;border-radius:${theme_1.RADIUS.md}px;
2100
2076
  background:${this.theme.cardBg};
2101
2077
  border:2px solid ${this.theme.border};
2102
2078
  cursor:pointer;text-align:left;
@@ -2136,7 +2112,7 @@ class SmartComplyFlow {
2136
2112
  const btn = document.createElement("button");
2137
2113
  btn.textContent = text;
2138
2114
  btn.style.cssText = `
2139
- width:100%;padding:14px;border-radius:12px;
2115
+ width:100%;padding:14px;border-radius:${theme_1.RADIUS.md}px;
2140
2116
  font-size:15px;font-weight:600;
2141
2117
  background:${this.theme.primary};color:#fff;
2142
2118
  border:none;cursor:pointer;
@@ -2157,7 +2133,7 @@ class SmartComplyFlow {
2157
2133
  const btn = document.createElement("button");
2158
2134
  btn.textContent = text;
2159
2135
  btn.style.cssText = `
2160
- width:100%;padding:12px;border-radius:12px;
2136
+ width:100%;padding:12px;border-radius:${theme_1.RADIUS.md}px;
2161
2137
  font-size:14px;font-weight:500;
2162
2138
  background:transparent;color:${this.theme.textSecondary};
2163
2139
  border:none;cursor:pointer;
@@ -2295,9 +2271,6 @@ class SmartComplyFlow {
2295
2271
  const style = document.createElement("style");
2296
2272
  style.id = "sc-flow-styles";
2297
2273
  style.textContent = `
2298
- @keyframes sc-spin {
2299
- to { transform: rotate(360deg); }
2300
- }
2301
2274
  @keyframes sc-pop {
2302
2275
  0% { transform: scale(0.8); opacity: 0; }
2303
2276
  50% { transform: scale(1.05); }