@neofaceid/web-sdk 1.32.0 → 1.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -91,6 +91,14 @@ export declare interface AuthorizeOptions {
91
91
  onSuccess?: (result: LivenessChallengeResult) => void;
92
92
  onError?: (error: NeoFaceError) => void;
93
93
  onCancel?: () => void;
94
+ /**
95
+ * NEO-420 · US14.9 — "screen flash" assistivo: quando o frame está muito
96
+ * escuro, inverte o fundo para branco alto brilho para usar a tela como
97
+ * fonte de luz. Só ajuda quando faz diferença: se não subir o brilho,
98
+ * reverte. Nunca usado como sinal de liveness (essa decisão é do servidor).
99
+ * Default: `true`.
100
+ */
101
+ autoLighting?: boolean;
94
102
  }
95
103
 
96
104
  export declare class BiometricCaptureModal {
@@ -1626,7 +1634,7 @@ export declare const validateToken: (applicationToken: string) => Promise<boolea
1626
1634
  * MINOR: Incrementado quando adicionamos funcionalidades mantendo compatibilidade
1627
1635
  * PATCH: Incrementado quando corrigimos bugs mantendo compatibilidade
1628
1636
  */
1629
- export declare const VERSION = "1.32.0";
1637
+ export declare const VERSION = "1.34.0";
1630
1638
 
1631
1639
  /**
1632
1640
  * Executa `fn(sessionId)`. Se o servidor devolver 410 (sessão consumida/expirada),
@@ -10866,7 +10866,7 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
10866
10866
  initializeBiometricDetection,
10867
10867
  isAdvancedDetectionAvailable
10868
10868
  }, Symbol.toStringTag, { value: "Module" }));
10869
- const VERSION = "1.32.0";
10869
+ const VERSION = "1.34.0";
10870
10870
  const RELEASE_DATE = "2026-09-02";
10871
10871
  let cachedSession = null;
10872
10872
  function getCachedCaptureSession() {
@@ -12459,6 +12459,201 @@ function AuthorizePermissionDenied({
12459
12459
  ] })
12460
12460
  ] });
12461
12461
  }
12462
+ function measureFrameBrightness(video, options = {}) {
12463
+ if (!video || video.videoWidth === 0 || video.videoHeight === 0) return 0;
12464
+ const sample = options.sample ?? 64;
12465
+ const vw = video.videoWidth;
12466
+ const vh = video.videoHeight;
12467
+ const roi = options.roi ?? centerRoi(vw, vh, 0.4);
12468
+ const canvas = options.scratch ?? document.createElement("canvas");
12469
+ canvas.width = sample;
12470
+ canvas.height = sample;
12471
+ const ctx = canvas.getContext("2d", { willReadFrequently: true });
12472
+ if (!ctx) return 0;
12473
+ try {
12474
+ ctx.drawImage(
12475
+ video,
12476
+ roi.x,
12477
+ roi.y,
12478
+ roi.width,
12479
+ roi.height,
12480
+ 0,
12481
+ 0,
12482
+ sample,
12483
+ sample
12484
+ );
12485
+ const data = ctx.getImageData(0, 0, sample, sample).data;
12486
+ return computeLumaMean(data);
12487
+ } catch {
12488
+ return 0;
12489
+ }
12490
+ }
12491
+ function centerRoi(vw, vh, fraction) {
12492
+ const w = Math.round(vw * fraction);
12493
+ const h = Math.round(vh * fraction);
12494
+ return {
12495
+ x: Math.round((vw - w) / 2),
12496
+ y: Math.round((vh - h) / 2),
12497
+ width: w,
12498
+ height: h
12499
+ };
12500
+ }
12501
+ function computeLumaMean(rgba) {
12502
+ const len = rgba.length;
12503
+ if (len === 0) return 0;
12504
+ let sum = 0;
12505
+ let n = 0;
12506
+ for (let i = 0; i < len; i += 4) {
12507
+ const r = rgba[i];
12508
+ const g = rgba[i + 1];
12509
+ const b = rgba[i + 2];
12510
+ sum += 0.2126 * r + 0.7152 * g + 0.0722 * b;
12511
+ n += 1;
12512
+ }
12513
+ if (n === 0) return 0;
12514
+ return sum / (n * 255);
12515
+ }
12516
+ const DARK_THRESHOLD = 0.235;
12517
+ const IMPROVEMENT_TARGET = 0.12;
12518
+ const SAMPLE_INTERVAL_MS = 600;
12519
+ const EVALUATION_DELAY_MS = 600;
12520
+ const MIN_TOGGLE_MS = 3e3;
12521
+ function useScreenFlash(videoRef, options = {}) {
12522
+ const enabled = options.enabled ?? true;
12523
+ const darkThreshold = options.darkThreshold ?? DARK_THRESHOLD;
12524
+ const improvementTarget = options.improvementTarget ?? IMPROVEMENT_TARGET;
12525
+ const sampleIntervalMs = options.sampleIntervalMs ?? SAMPLE_INTERVAL_MS;
12526
+ const minToggleMs = options.minToggleMs ?? MIN_TOGGLE_MS;
12527
+ const [flashOn, setFlashOn] = useState(false);
12528
+ const [lastBrightness, setLastBrightness] = useState(0);
12529
+ const darkStreakRef = useRef(0);
12530
+ const lastToggleAtRef = useRef(0);
12531
+ const preFlashBrightnessRef = useRef(null);
12532
+ const flashOnRef = useRef(false);
12533
+ const scratchRef = useRef(null);
12534
+ useEffect(() => {
12535
+ flashOnRef.current = flashOn;
12536
+ }, [flashOn]);
12537
+ useEffect(() => {
12538
+ if (!enabled) {
12539
+ setFlashOn(false);
12540
+ return () => {
12541
+ };
12542
+ }
12543
+ if (typeof document !== "undefined" && !scratchRef.current) {
12544
+ scratchRef.current = document.createElement("canvas");
12545
+ }
12546
+ let timer = null;
12547
+ let evalTimer = null;
12548
+ let disposed = false;
12549
+ const tick = () => {
12550
+ if (disposed) return;
12551
+ const b = measureFrameBrightness(videoRef.current, {
12552
+ scratch: scratchRef.current ?? void 0
12553
+ });
12554
+ setLastBrightness(b);
12555
+ const now = Date.now();
12556
+ if (!flashOnRef.current) {
12557
+ if (b > 0 && b < darkThreshold) {
12558
+ darkStreakRef.current += 1;
12559
+ } else {
12560
+ darkStreakRef.current = 0;
12561
+ }
12562
+ if (darkStreakRef.current >= 2 && now - lastToggleAtRef.current >= minToggleMs) {
12563
+ preFlashBrightnessRef.current = b;
12564
+ lastToggleAtRef.current = now;
12565
+ flashOnRef.current = true;
12566
+ setFlashOn(true);
12567
+ darkStreakRef.current = 0;
12568
+ evalTimer = setTimeout(() => {
12569
+ if (disposed) return;
12570
+ const after = measureFrameBrightness(videoRef.current, {
12571
+ scratch: scratchRef.current ?? void 0
12572
+ });
12573
+ const gained = after - (preFlashBrightnessRef.current ?? 0);
12574
+ if (gained < improvementTarget) {
12575
+ lastToggleAtRef.current = Date.now();
12576
+ flashOnRef.current = false;
12577
+ setFlashOn(false);
12578
+ }
12579
+ preFlashBrightnessRef.current = null;
12580
+ }, EVALUATION_DELAY_MS);
12581
+ }
12582
+ }
12583
+ };
12584
+ timer = setInterval(tick, sampleIntervalMs);
12585
+ tick();
12586
+ return () => {
12587
+ disposed = true;
12588
+ if (timer) clearInterval(timer);
12589
+ if (evalTimer) clearTimeout(evalTimer);
12590
+ };
12591
+ }, [enabled, darkThreshold, improvementTarget, sampleIntervalMs, minToggleMs, videoRef]);
12592
+ return { flashOn, lastBrightness };
12593
+ }
12594
+ function ScreenFlashOverlay({
12595
+ active,
12596
+ zIndex = 10001,
12597
+ onDismiss
12598
+ }) {
12599
+ if (!active) return null;
12600
+ const overlayStyle = {
12601
+ position: "fixed",
12602
+ inset: 0,
12603
+ background: "#FFFFFF",
12604
+ zIndex,
12605
+ pointerEvents: "none",
12606
+ animation: "nfid-flash-in 200ms ease-out"
12607
+ };
12608
+ const hintStyle = {
12609
+ position: "fixed",
12610
+ top: 12,
12611
+ left: "50%",
12612
+ transform: "translateX(-50%)",
12613
+ zIndex: zIndex + 1,
12614
+ background: "rgba(10,19,32,.72)",
12615
+ color: "#FFFFFF",
12616
+ fontSize: 12,
12617
+ fontWeight: 600,
12618
+ letterSpacing: 0.2,
12619
+ padding: "6px 12px",
12620
+ borderRadius: 999,
12621
+ pointerEvents: onDismiss ? "auto" : "none",
12622
+ display: "flex",
12623
+ alignItems: "center",
12624
+ gap: 8
12625
+ };
12626
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
12627
+ /* @__PURE__ */ jsx("style", { children: `
12628
+ @keyframes nfid-flash-in { from { opacity: 0 } to { opacity: 1 } }
12629
+ @media (prefers-reduced-motion: reduce) {
12630
+ .nfid-screen-flash { animation: none !important; }
12631
+ }
12632
+ ` }),
12633
+ /* @__PURE__ */ jsx("div", { className: "nfid-screen-flash", style: overlayStyle, "aria-hidden": "true" }),
12634
+ /* @__PURE__ */ jsxs("div", { className: "nfid-screen-flash-hint", style: hintStyle, role: "status", children: [
12635
+ "Aumentando a luz da tela",
12636
+ onDismiss && /* @__PURE__ */ jsx(
12637
+ "button",
12638
+ {
12639
+ type: "button",
12640
+ onClick: onDismiss,
12641
+ "aria-label": "Desligar iluminação assistiva",
12642
+ style: {
12643
+ background: "transparent",
12644
+ border: "none",
12645
+ color: "#FFFFFF",
12646
+ cursor: "pointer",
12647
+ fontSize: 14,
12648
+ lineHeight: 1,
12649
+ padding: "0 4px"
12650
+ },
12651
+ children: "×"
12652
+ }
12653
+ )
12654
+ ] })
12655
+ ] });
12656
+ }
12462
12657
  const STYLE_ID = "neofaceid-authorize-styles";
12463
12658
  const GESTURE_TO_GLYPH = {
12464
12659
  center: "center",
@@ -12502,6 +12697,7 @@ function AuthorizeModalComponent({
12502
12697
  onSuccess,
12503
12698
  onError,
12504
12699
  onCancel,
12700
+ autoLighting = true,
12505
12701
  onClose
12506
12702
  }) {
12507
12703
  const videoRef = useRef(null);
@@ -12513,6 +12709,10 @@ function AuthorizeModalComponent({
12513
12709
  const [failureAt, setFailureAt] = useState(void 0);
12514
12710
  const [runCounter, setRunCounter] = useState(0);
12515
12711
  const cancelRef = useRef(false);
12712
+ const [flashDismissed, setFlashDismissed] = useState(false);
12713
+ const { flashOn } = useScreenFlash(videoRef, {
12714
+ enabled: autoLighting && !flashDismissed && phase === "challenging"
12715
+ });
12516
12716
  const locale = getLocale();
12517
12717
  const headerAppName = appName ?? getAppName() ?? "sua aplicação";
12518
12718
  const headerAmount = typeof amount === "number" && Number.isFinite(amount) ? formatCurrency(amount, locale) : null;
@@ -12664,42 +12864,51 @@ function AuthorizeModalComponent({
12664
12864
  }
12665
12865
  ) });
12666
12866
  }
12667
- return /* @__PURE__ */ jsx(Sheet, { open: true, onDismiss: void 0, dismissOnOverlay: false, ariaLabel: "Autorização por biometria", children: /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
12867
+ return /* @__PURE__ */ jsxs(Sheet, { open: true, onDismiss: void 0, dismissOnOverlay: false, ariaLabel: "Autorização por biometria", children: [
12668
12868
  /* @__PURE__ */ jsx(
12669
- "button",
12869
+ ScreenFlashOverlay,
12670
12870
  {
12671
- type: "button",
12672
- className: "nfid-authorize-close",
12673
- onClick: handleClose,
12674
- "aria-label": "Cancelar autorização",
12675
- children: /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12" }) })
12871
+ active: flashOn,
12872
+ onDismiss: () => setFlashDismissed(true)
12676
12873
  }
12677
12874
  ),
12678
- /* @__PURE__ */ jsxs("div", { className: "nfid-authorize-header", children: [
12679
- /* @__PURE__ */ jsx("span", { className: "nfid-authorize-appname", children: headerAppName }),
12680
- headerAmount && /* @__PURE__ */ jsxs("span", { className: "nfid-authorize-amount", children: [
12681
- "Autorizando ",
12682
- headerAmount
12683
- ] }),
12684
- /* @__PURE__ */ jsx("span", { className: "nfid-authorize-brand", children: "NeoFaceID" })
12685
- ] }),
12686
- /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx(ChallengeRing, { progress, size: 220, children: /* @__PURE__ */ jsx("video", { ref: videoRef, className: "nfid-authorize-video", autoPlay: true, muted: true, playsInline: true }) }) }),
12687
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 12, marginTop: 16 }, children: [
12688
- /* @__PURE__ */ jsx(ChallengeGlyph, { gesture: gestureKey, size: 40 }),
12875
+ /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
12689
12876
  /* @__PURE__ */ jsx(
12690
- "p",
12877
+ "button",
12691
12878
  {
12692
- className: "nfid-authorize-instruction",
12693
- "aria-live": "assertive",
12694
- style: { margin: 0 },
12695
- children: instruction
12879
+ type: "button",
12880
+ className: "nfid-authorize-close",
12881
+ onClick: handleClose,
12882
+ "aria-label": "Cancelar autorização",
12883
+ children: /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12" }) })
12696
12884
  }
12697
- )
12698
- ] }),
12699
- phase === "preparing" && /* @__PURE__ */ jsx("p", { className: "nfid-authorize-support", children: "Ligando sua câmera…" }),
12700
- /* @__PURE__ */ jsx("div", { className: "nfid-authorize-actions", children: /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleClose, children: "Não consigo fazer esse movimento" }) }),
12701
- /* @__PURE__ */ jsx("div", { className: "nfid-authorize-footer", children: /* @__PURE__ */ jsx("span", { className: "nfid-authorize-seal", children: "Protegido por NeoFaceID" }) })
12702
- ] }) });
12885
+ ),
12886
+ /* @__PURE__ */ jsxs("div", { className: "nfid-authorize-header", children: [
12887
+ /* @__PURE__ */ jsx("span", { className: "nfid-authorize-appname", children: headerAppName }),
12888
+ headerAmount && /* @__PURE__ */ jsxs("span", { className: "nfid-authorize-amount", children: [
12889
+ "Autorizando ",
12890
+ headerAmount
12891
+ ] }),
12892
+ /* @__PURE__ */ jsx("span", { className: "nfid-authorize-brand", children: "NeoFaceID" })
12893
+ ] }),
12894
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx(ChallengeRing, { progress, size: 220, children: /* @__PURE__ */ jsx("video", { ref: videoRef, className: "nfid-authorize-video", autoPlay: true, muted: true, playsInline: true }) }) }),
12895
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 12, marginTop: 16 }, children: [
12896
+ /* @__PURE__ */ jsx(ChallengeGlyph, { gesture: gestureKey, size: 40 }),
12897
+ /* @__PURE__ */ jsx(
12898
+ "p",
12899
+ {
12900
+ className: "nfid-authorize-instruction",
12901
+ "aria-live": "assertive",
12902
+ style: { margin: 0 },
12903
+ children: instruction
12904
+ }
12905
+ )
12906
+ ] }),
12907
+ phase === "preparing" && /* @__PURE__ */ jsx("p", { className: "nfid-authorize-support", children: "Ligando sua câmera…" }),
12908
+ /* @__PURE__ */ jsx("div", { className: "nfid-authorize-actions", children: /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleClose, children: "Não consigo fazer esse movimento" }) }),
12909
+ /* @__PURE__ */ jsx("div", { className: "nfid-authorize-footer", children: /* @__PURE__ */ jsx("span", { className: "nfid-authorize-seal", children: "Protegido por NeoFaceID" }) })
12910
+ ] })
12911
+ ] });
12703
12912
  }
12704
12913
  async function progressiveHold(setter) {
12705
12914
  const total = 1500;
@@ -12935,7 +13144,7 @@ class DocumentCaptureModal {
12935
13144
  </div>
12936
13145
  <div class="neoface-doc-instruction">
12937
13146
  <svg class="neoface-doc-instruction-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>
12938
- <span>Evite reflexos e sombras</span>
13147
+ <span>Sem reflexo do flash sobre o texto</span>
12939
13148
  </div>
12940
13149
  </div>
12941
13150
  </div>
@@ -12991,15 +13200,16 @@ class DocumentCaptureModal {
12991
13200
  <div class="neoface-doc-body">
12992
13201
  <div class="neoface-doc-preview-single">
12993
13202
  <span class="neoface-doc-preview-label">${label}</span>
12994
- <img class="neoface-doc-preview-img neoface-doc-preview-current" />
13203
+ <img class="neoface-doc-preview-img neoface-doc-preview-current" alt="Prévia do documento capturado" />
12995
13204
  </div>
12996
-
13205
+
13206
+ <h3 class="neoface-doc-preview-question" id="neoface-doc-preview-question">Está legível?</h3>
12997
13207
  <div class="neoface-doc-preview-hint">
12998
13208
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>
12999
- <span>Verifique se todos os dados estão legíveis</span>
13209
+ <span>Confira se dá para ler nome, número e data sem esforço.</span>
13000
13210
  </div>
13001
13211
  </div>
13002
-
13212
+
13003
13213
  <div class="neoface-doc-footer">
13004
13214
  <button class="neoface-doc-btn neoface-doc-btn-secondary neoface-doc-retake-btn">
13005
13215
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
@@ -13008,11 +13218,11 @@ class DocumentCaptureModal {
13008
13218
  </svg>
13009
13219
  Refazer
13010
13220
  </button>
13011
- <button class="neoface-doc-btn neoface-doc-btn-success neoface-doc-confirm-btn">
13221
+ <button class="neoface-doc-btn neoface-doc-btn-primary neoface-doc-confirm-btn">
13012
13222
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
13013
13223
  <path d="M20 6L9 17l-5-5"/>
13014
13224
  </svg>
13015
- ${isLastStep ? "Confirmar e Enviar" : "Próximo"}
13225
+ ${isLastStep ? "Sim, enviar" : "Sim, próximo"}
13016
13226
  </button>
13017
13227
  </div>
13018
13228
 
@@ -13429,8 +13639,8 @@ class DocumentCaptureModal {
13429
13639
  }
13430
13640
 
13431
13641
  .neoface-doc-select-option:hover {
13432
- background: rgba(0, 200, 255, 0.1);
13433
- border-color: rgba(0, 200, 255, 0.4);
13642
+ background: rgba(0, 145, 246, 0.1);
13643
+ border-color: rgba(0, 145, 246, 0.4);
13434
13644
  transform: translateX(4px);
13435
13645
  }
13436
13646
 
@@ -13440,7 +13650,7 @@ class DocumentCaptureModal {
13440
13650
  justify-content: center;
13441
13651
  width: 44px;
13442
13652
  height: 44px;
13443
- background: rgba(0, 200, 255, 0.15);
13653
+ background: rgba(0, 145, 246, 0.15);
13444
13654
  border-radius: 12px;
13445
13655
  color: #0091F6;
13446
13656
  }
@@ -13476,8 +13686,8 @@ class DocumentCaptureModal {
13476
13686
  align-items: center;
13477
13687
  justify-content: center;
13478
13688
  padding: 14px 16px;
13479
- background: rgba(0, 200, 255, 0.08);
13480
- border: 1px solid rgba(0, 200, 255, 0.15);
13689
+ background: rgba(0, 145, 246, 0.08);
13690
+ border: 1px solid rgba(0, 145, 246, 0.15);
13481
13691
  border-radius: 10px;
13482
13692
  color: rgba(255, 255, 255, 0.8);
13483
13693
  font-size: 13px;
@@ -13494,13 +13704,13 @@ class DocumentCaptureModal {
13494
13704
  flex-shrink: 0;
13495
13705
  }
13496
13706
 
13497
- /* Camera */
13707
+ /* Camera — ISO/IEC 7810 ID-1 (85.60 × 53.98 mm ≈ 1.586:1) */
13498
13708
  .neoface-doc-camera-container {
13499
13709
  position: relative;
13500
13710
  background: #000;
13501
13711
  border-radius: 16px;
13502
13712
  overflow: hidden;
13503
- aspect-ratio: 4/3;
13713
+ aspect-ratio: 1.586 / 1;
13504
13714
  }
13505
13715
 
13506
13716
  .neoface-doc-video {
@@ -13522,20 +13732,19 @@ class DocumentCaptureModal {
13522
13732
  pointer-events: none;
13523
13733
  }
13524
13734
 
13735
+ /* Moldura Focus Frame — proporção ID-1 (1.586:1), sem borda contínua. */
13525
13736
  .neoface-doc-frame {
13526
- width: 75%;
13527
- height: 65%;
13737
+ width: 82%;
13738
+ aspect-ratio: 1.586 / 1;
13528
13739
  position: relative;
13529
- border: 2px dashed rgba(0, 200, 255, 0.5);
13530
13740
  border-radius: 12px;
13531
- background: rgba(0, 200, 255, 0.03);
13532
13741
  }
13533
-
13742
+
13534
13743
  .neoface-doc-corner {
13535
13744
  position: absolute;
13536
13745
  width: 28px;
13537
13746
  height: 28px;
13538
- border-color: #0091F6;
13747
+ border-color: var(--nfid-action, #0059C4);
13539
13748
  border-style: solid;
13540
13749
  }
13541
13750
 
@@ -13624,23 +13833,31 @@ class DocumentCaptureModal {
13624
13833
  width: 75%;
13625
13834
  height: auto;
13626
13835
  border-radius: 12px;
13627
- border: 2px solid rgba(0, 200, 255, 0.3);
13836
+ border: 2px solid rgba(0, 145, 246, 0.3);
13628
13837
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
13629
13838
  }
13630
13839
 
13840
+ .neoface-doc-preview-question {
13841
+ margin: 12px 0 4px;
13842
+ font-size: 17px;
13843
+ font-weight: 700;
13844
+ color: var(--nfid-text, #0A1320);
13845
+ text-align: center;
13846
+ }
13847
+
13631
13848
  .neoface-doc-preview-hint {
13632
13849
  display: flex;
13633
13850
  align-items: center;
13634
13851
  gap: 10px;
13635
13852
  padding: 12px 16px;
13636
- background: rgba(0, 200, 255, 0.08);
13637
- border: 1px solid rgba(0, 200, 255, 0.15);
13853
+ background: rgba(0, 145, 246, 0.08);
13854
+ border: 1px solid rgba(0, 145, 246, 0.15);
13638
13855
  border-radius: 10px;
13639
13856
  font-size: 13px;
13640
13857
  color: rgba(255, 255, 255, 0.8);
13641
13858
  margin-top: 8px;
13642
13859
  }
13643
-
13860
+
13644
13861
  .neoface-doc-preview-hint svg {
13645
13862
  color: #0091F6;
13646
13863
  flex-shrink: 0;
@@ -13675,7 +13892,7 @@ class DocumentCaptureModal {
13675
13892
 
13676
13893
  .neoface-doc-btn-primary:hover {
13677
13894
  transform: translateY(-2px);
13678
- box-shadow: 0 6px 20px rgba(0, 200, 255, 0.4);
13895
+ box-shadow: 0 6px 20px rgba(0, 145, 246, 0.4);
13679
13896
  }
13680
13897
 
13681
13898
  .neoface-doc-btn-success {