@incodetech/prizma-core-screens 0.2.7 → 0.2.12
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/BiometricConsentScreen.d.ts +95 -0
- package/dist/BiometricConsentScreen.js +91 -0
- package/dist/BiometricConsentStrings.d.ts +84 -0
- package/dist/BiometricConsentStrings.js +31 -0
- package/dist/CaptureScreen.d.ts +13 -0
- package/dist/CaptureScreen.js +2 -2
- package/dist/DemoScreensLayout.css +16 -0
- package/dist/DemoScreensRedirectScreen.d.ts +6 -1
- package/dist/DemoScreensRedirectScreen.js +3 -2
- package/dist/DemoScreensStrings.d.ts +5 -0
- package/dist/DigitalIdUploadErrorScreen.d.ts +31 -0
- package/dist/DigitalIdUploadErrorScreen.js +26 -0
- package/dist/DigitalIdUploadFileTooLargeScreen.d.ts +27 -0
- package/dist/DigitalIdUploadFileTooLargeScreen.js +21 -0
- package/dist/DigitalIdUploadReviewScreen.d.ts +57 -0
- package/dist/DigitalIdUploadReviewScreen.js +44 -0
- package/dist/DigitalIdUploadStrings.d.ts +64 -0
- package/dist/DigitalIdUploadStrings.js +19 -0
- package/dist/DigitalIdUploadTutorialScreen.d.ts +28 -0
- package/dist/DigitalIdUploadTutorialScreen.js +23 -0
- package/dist/DocumentCaptureIllustration.d.ts +1 -1
- package/dist/EkybCountryScreen.d.ts +6 -6
- package/dist/EkybCountryScreen.js +20 -7
- package/dist/EkybStrings.d.ts +6 -1
- package/dist/ErrorScreensScreen.d.ts +5 -2
- package/dist/ErrorScreensScreen.js +15 -4
- package/dist/ErrorScreensStrings.d.ts +17 -2
- package/dist/ErrorScreensStrings.js +18 -10
- package/dist/FaceCaptureCapturingScreen.d.ts +63 -0
- package/dist/FaceCaptureCapturingScreen.js +62 -2
- package/dist/FaceCaptureLayout.css +69 -4
- package/dist/FaceCaptureStrings.d.ts +23 -0
- package/dist/FormScreen.css +14 -0
- package/dist/FormScreen.d.ts +28 -0
- package/dist/FormScreen.js +3 -2
- package/dist/IdCaptureLayout.css +165 -2
- package/dist/IdCaptureStageScreen.d.ts +47 -0
- package/dist/IdCaptureStageScreen.js +39 -3
- package/dist/IdCaptureStrings.d.ts +19 -0
- package/dist/ListScreen.d.ts +19 -0
- package/dist/ListScreen.js +7 -2
- package/dist/LoaderScreen.d.ts +7 -5
- package/dist/LoaderScreen.js +7 -5
- package/dist/LoadersStrings.d.ts +18 -5
- package/dist/OcrReviewErrorScreen.d.ts +30 -0
- package/dist/OcrReviewErrorScreen.js +24 -0
- package/dist/OcrReviewLayout.css +24 -0
- package/dist/OcrReviewLoadingScreen.d.ts +25 -0
- package/dist/OcrReviewLoadingScreen.js +19 -0
- package/dist/OcrReviewScreen.d.ts +76 -0
- package/dist/OcrReviewScreen.js +65 -0
- package/dist/OcrReviewStrings.d.ts +47 -0
- package/dist/OcrReviewStrings.js +17 -0
- package/dist/OcrReviewSuccessScreen.d.ts +30 -0
- package/dist/OcrReviewSuccessScreen.js +24 -0
- package/dist/PermissionsAllowScreen.d.ts +8 -11
- package/dist/PermissionsAllowScreen.js +8 -11
- package/dist/PermissionsAskScreen.d.ts +41 -0
- package/dist/PermissionsAskScreen.js +43 -0
- package/dist/PermissionsBrowserStepsScreen.d.ts +9 -2
- package/dist/PermissionsBrowserStepsScreen.js +12 -3
- package/dist/PermissionsLayout.css +47 -0
- package/dist/PermissionsStrings.d.ts +20 -9
- package/dist/PermissionsStrings.js +10 -4
- package/dist/PhoneInputOtpScreen.d.ts +8 -0
- package/dist/PhoneInputOtpScreen.js +26 -19
- package/dist/PhoneInputStrings.d.ts +11 -3
- package/dist/PhoneInputVerifyScreen.js +21 -5
- package/dist/QualifiedSignatureDocumentScreen.d.ts +8 -5
- package/dist/QualifiedSignatureDocumentScreen.js +9 -6
- package/dist/QualifiedSignatureResultScreen.d.ts +16 -13
- package/dist/QualifiedSignatureResultScreen.js +17 -18
- package/dist/QualifiedSignatureStrings.d.ts +11 -4
- package/dist/ResultScreen.d.ts +8 -0
- package/dist/ResultScreen.js +14 -3
- package/dist/ReusabilityCredentialSelectionScreen.d.ts +95 -0
- package/dist/ReusabilityCredentialSelectionScreen.js +94 -0
- package/dist/ReusabilityLayout.css +241 -0
- package/dist/ReusabilityPrivacyPolicyScreen.d.ts +55 -0
- package/dist/ReusabilityPrivacyPolicyScreen.js +44 -0
- package/dist/ReusabilityStrings.d.ts +85 -0
- package/dist/ReusabilityStrings.js +37 -0
- package/dist/ReviewScreen.d.ts +38 -12
- package/dist/ReviewScreen.js +41 -8
- package/dist/ScreenLayout.css +382 -6
- package/dist/VideoSelfieErrorScreen.js +1 -1
- package/dist/VideoSelfieIdCaptureScreen.js +1 -1
- package/dist/VideoSelfieLayout.css +304 -2
- package/dist/VideoSelfieSelfieCaptureScreen.js +1 -1
- package/dist/VideoSelfieSpeakScreen.js +1 -1
- package/dist/VideoSelfieStrings.d.ts +4 -1
- package/dist/VideoSelfieTurnHeadScreen.js +14 -11
- package/dist/VideoSelfieTutorialScreen.d.ts +9 -0
- package/dist/VideoSelfieTutorialScreen.js +10 -1
- package/dist/VideoSelfieWaveScreen.js +1 -1
- package/dist/ViewfinderScreen.css +36 -0
- package/dist/flows.d.ts +8 -0
- package/dist/flows.js +17 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +12 -0
- package/dist/styles.css +3 -0
- package/package.json +68 -3
- package/samples/video-selfie-camera-wide.jpg +0 -0
- package/samples/video-selfie-room-wide.jpg +0 -0
- package/src/BiometricConsentScreen.tsx +192 -0
- package/src/BiometricConsentStrings.ts +119 -0
- package/src/CaptureScreen.tsx +17 -0
- package/src/DemoScreensLayout.css +16 -0
- package/src/DemoScreensRedirectScreen.tsx +14 -6
- package/src/DemoScreensStrings.ts +5 -0
- package/src/DigitalIdUploadErrorScreen.tsx +83 -0
- package/src/DigitalIdUploadFileTooLargeScreen.tsx +67 -0
- package/src/DigitalIdUploadReviewScreen.tsx +119 -0
- package/src/DigitalIdUploadStrings.ts +88 -0
- package/src/DigitalIdUploadTutorialScreen.tsx +59 -0
- package/src/DocumentCaptureIllustration.tsx +1 -1
- package/src/EkybCountryScreen.tsx +23 -6
- package/src/EkybStrings.ts +6 -1
- package/src/ErrorScreensScreen.tsx +15 -4
- package/src/ErrorScreensStrings.ts +37 -12
- package/src/FaceCaptureCapturingScreen.tsx +102 -13
- package/src/FaceCaptureLayout.css +69 -4
- package/src/FaceCaptureStrings.ts +24 -0
- package/src/FormScreen.css +14 -0
- package/src/FormScreen.tsx +34 -0
- package/src/IdCaptureLayout.css +165 -2
- package/src/IdCaptureStageScreen.tsx +75 -0
- package/src/IdCaptureStrings.ts +19 -0
- package/src/ListScreen.tsx +48 -9
- package/src/LoaderScreen.tsx +7 -5
- package/src/LoadersStrings.ts +18 -5
- package/src/OcrReviewErrorScreen.tsx +53 -0
- package/src/OcrReviewLayout.css +24 -0
- package/src/OcrReviewLoadingScreen.tsx +48 -0
- package/src/OcrReviewScreen.tsx +190 -0
- package/src/OcrReviewStrings.ts +69 -0
- package/src/OcrReviewSuccessScreen.tsx +52 -0
- package/src/PermissionsAllowScreen.tsx +9 -10
- package/src/PermissionsAskScreen.tsx +105 -0
- package/src/PermissionsBrowserStepsScreen.tsx +11 -3
- package/src/PermissionsLayout.css +47 -0
- package/src/PermissionsStrings.ts +42 -12
- package/src/PhoneInputOtpScreen.tsx +23 -3
- package/src/PhoneInputStrings.ts +11 -3
- package/src/PhoneInputVerifyScreen.tsx +24 -4
- package/src/QualifiedSignatureDocumentScreen.tsx +9 -7
- package/src/QualifiedSignatureResultScreen.tsx +28 -26
- package/src/QualifiedSignatureStrings.ts +11 -4
- package/src/ResultScreen.tsx +33 -2
- package/src/ReusabilityCredentialSelectionScreen.tsx +246 -0
- package/src/ReusabilityLayout.css +241 -0
- package/src/ReusabilityPrivacyPolicyScreen.tsx +109 -0
- package/src/ReusabilityStrings.ts +127 -0
- package/src/ReviewScreen.tsx +96 -27
- package/src/ScreenLayout.css +382 -6
- package/src/VideoSelfieErrorScreen.tsx +1 -1
- package/src/VideoSelfieIdCaptureScreen.tsx +9 -1
- package/src/VideoSelfieLayout.css +304 -2
- package/src/VideoSelfieSelfieCaptureScreen.tsx +9 -1
- package/src/VideoSelfieSpeakScreen.tsx +9 -1
- package/src/VideoSelfieStrings.ts +4 -2
- package/src/VideoSelfieTurnHeadScreen.tsx +25 -14
- package/src/VideoSelfieTutorialScreen.tsx +11 -0
- package/src/VideoSelfieWaveScreen.tsx +9 -1
- package/src/ViewfinderScreen.css +36 -0
- package/src/flows.ts +25 -0
- package/src/index.ts +74 -3
- package/src/styles.css +3 -0
|
@@ -13,6 +13,14 @@
|
|
|
13
13
|
* spoken step) carry the band here.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
/* The air above the stepper band, named once because TWO rules depend on it:
|
|
17
|
+
* the band's own offset and the ring's, which counts down from Figma's y=188.
|
|
18
|
+
* Scoped to a shell that actually carries the band, so no other module's
|
|
19
|
+
* screen inherits a property it never reads. */
|
|
20
|
+
.prizma-screen-shell:has(> .video-selfie-stepper) {
|
|
21
|
+
--vs-top-reserve: max(var(--pcs-status-bar, 47px), var(--prizma-spacing-24));
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
/* ── Journey stepper band ────────────────────────────────────────────────────
|
|
17
25
|
* Figma draws the Stepper as the first thing under the OS status bar — no logo
|
|
18
26
|
* row above it (`top content` frame, y=54, the Stepper 342 wide at x=24 on
|
|
@@ -42,7 +50,14 @@
|
|
|
42
50
|
* ScreenLayout.css already reserves for the tag and shutter, which must sit
|
|
43
51
|
* above the scrim for exactly the same reason. DEVIATIONS #VS-2. */
|
|
44
52
|
z-index: 2;
|
|
45
|
-
|
|
53
|
+
/* Clear the OS status bar, and NEVER sit flush against the top edge. A host
|
|
54
|
+
* that draws no phone chrome sets `--pcs-status-bar: 0px` — Core Lab's
|
|
55
|
+
* desktop panel does — and the band then started at pixel zero, hard against
|
|
56
|
+
* the browser bar (Camila, 2026-10-09: "the stepper is way too high and
|
|
57
|
+
* touches the screen border"). The floor is the content column's own
|
|
58
|
+
* Spacing/24 gutter, the same air every other screen has above its first
|
|
59
|
+
* block; on a phone the 47 reserve is larger and nothing moves. */
|
|
60
|
+
margin-top: var(--vs-top-reserve, var(--pcs-status-bar, 47px));
|
|
46
61
|
padding-inline: var(--prizma-spacing-24);
|
|
47
62
|
}
|
|
48
63
|
|
|
@@ -63,6 +78,74 @@
|
|
|
63
78
|
z-index: 1;
|
|
64
79
|
}
|
|
65
80
|
|
|
81
|
+
/* A band carrying the coaching bubble keeps the bubble's own height; the frame
|
|
82
|
+
* below is what gives ground on a short screen.
|
|
83
|
+
*
|
|
84
|
+
* `.video-selfie-band` is `flex: 1; min-height: 0`, so on a 360 × 640 panel the
|
|
85
|
+
* flex column took the whole shortfall out of THIS band: it collapsed to zero
|
|
86
|
+
* and the bubble — which is still painted — overflowed it in both directions,
|
|
87
|
+
* across the stepper above and the document frame below (Camila, 2026-10-07).
|
|
88
|
+
* `IdCaptureLayout.css` already names the rule for this exact column: the frame
|
|
89
|
+
* is the one part that shrinks, the band above it keeps its content height. Same
|
|
90
|
+
* rule, this module's class. */
|
|
91
|
+
.video-selfie-band:has(> .video-selfie-feedback) {
|
|
92
|
+
flex: 0 0 auto;
|
|
93
|
+
min-height: min-content;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* …and the band UNDER the document stage never gives up the footer's own
|
|
97
|
+
* footprint, so the frame stops above the verified tag instead of sliding under
|
|
98
|
+
* it. `ScreenLayout.css` reserves `--pcs-footer-space` on
|
|
99
|
+
* `.prizma-screen-layout__content`; these are camera surfaces with no content
|
|
100
|
+
* column, so the reserve has to be claimed here, and claiming it as the BAND's
|
|
101
|
+
* minimum rather than as padding on the viewfinder is what keeps the reference
|
|
102
|
+
* untouched: at 390 the band is already ~100 tall, so a 72 floor is a no-op and
|
|
103
|
+
* the frame stays exactly where Figma centres it (y 172–627 of a 91–708 content
|
|
104
|
+
* area). On a 640-tall panel the floor binds, and the frame — the one part of
|
|
105
|
+
* this column that may get smaller (owner, 2026-08-18) — gives the height back
|
|
106
|
+
* through Core's own `flex-basis`, its aspect narrowing it to match. */
|
|
107
|
+
.video-selfie-stage + .video-selfie-band {
|
|
108
|
+
min-height: var(--pcs-footer-space);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* ── The camera owns the window; only the HUD is a column ────────────────────
|
|
112
|
+
* The five camera screens carry `data-pcs-overlay="window"` on their shell.
|
|
113
|
+
* That attribute is the screens package's contract with a host that FRAMES a
|
|
114
|
+
* screen — Core Lab's desktop panel, which otherwise lays every screen inside
|
|
115
|
+
* the 800 x 840 white card Elena's eKYB frames draw. A form belongs in that
|
|
116
|
+
* card. A camera does not: boxed into it, the feed and its scrim were a narrow
|
|
117
|
+
* strip with white either side of them on a 1440 panel, the desktop version of
|
|
118
|
+
* the "phone pasted onto the tablet" her 2026-10-02 call already fixed for the
|
|
119
|
+
* tablet (Camila, 2026-10-08). `PermissionsAskScreen` set the same attribute
|
|
120
|
+
* first, for its dialog's dim.
|
|
121
|
+
*
|
|
122
|
+
* NOT fixed here: Face Capture's, ID Capture's and Document Capture's camera
|
|
123
|
+
* stages sit in the same card for the same reason. The rule reads as theirs
|
|
124
|
+
* too, but their screens have not been looked at on the panel — reported. */
|
|
125
|
+
|
|
126
|
+
/* ── The HUD stays in a column when the panel is wider than the reference ─────
|
|
127
|
+
* On a panel wider than 390 the camera feed and its scrim are full-bleed — that
|
|
128
|
+
* is what a camera does on a real device, and what the Lab's laid-out
|
|
129
|
+
* breakpoints draw (`bleed`, convert.ts). The copy over the feed is NOT: left to
|
|
130
|
+
* `width: 100%` the stepper ran the full 720 of a tablet and the coaching bubble
|
|
131
|
+
* with it, which reads as a stretched phone rather than a tablet (Camila,
|
|
132
|
+
* 2026-10-07).
|
|
133
|
+
*
|
|
134
|
+
* `--pcs-column` is the host's own property for this — the same contract as
|
|
135
|
+
* `--pcs-status-bar` — and it is already what `ScreenLayout`'s content and band
|
|
136
|
+
* read on a device panel: 390 on a phone, 468 on a tablet or desktop one. Here
|
|
137
|
+
* the two Spacing/24 gutters come off it, because these bands sit INSIDE
|
|
138
|
+
* `.prizma-viewfinder__content`'s own padding, so the result is exactly the
|
|
139
|
+
* content width the reference has (342 at 390, 420 on a tablet). Unset — a plain
|
|
140
|
+
* 390 screen, any SDK host — the calc resolves to 342 and nothing moves. */
|
|
141
|
+
.video-selfie-stepper > *,
|
|
142
|
+
.video-selfie-feedback,
|
|
143
|
+
.video-selfie-recording,
|
|
144
|
+
.video-selfie-turn {
|
|
145
|
+
max-width: calc(var(--pcs-column, 390px) - 2 * var(--prizma-spacing-24));
|
|
146
|
+
margin-inline: auto;
|
|
147
|
+
}
|
|
148
|
+
|
|
66
149
|
/* ── The face ring sits in the SAME place on every screen ────────────────────
|
|
67
150
|
* Figma puts `ring-uploading` at (27, 188) on every frame that draws it —
|
|
68
151
|
* `8.x`, `9.x`, the four head turns and the wave — and never moves it. Left
|
|
@@ -81,7 +164,95 @@
|
|
|
81
164
|
* DEVIATIONS #VS-24. */
|
|
82
165
|
.video-selfie-band--ring {
|
|
83
166
|
justify-content: flex-start;
|
|
84
|
-
|
|
167
|
+
/* 188 is Figma's, and on a panel SHORTER than the 844 the frames are drawn
|
|
168
|
+
* against it is read proportionally: 154 at 693, 143 at 640. The reference
|
|
169
|
+
* and anything taller keep the literal 188, which is what `min()` guarantees.
|
|
170
|
+
* Fixed, it was 29% of a 640 panel — the ring plus its status block ran up to
|
|
171
|
+
* 67px past the fold (Camila, 2026-10-07), and the air above a ring is the
|
|
172
|
+
* first thing that should give. */
|
|
173
|
+
padding-top: max(
|
|
174
|
+
0px,
|
|
175
|
+
calc(
|
|
176
|
+
min(188px, 100cqh * 188 / 844) - var(--vs-top-reserve, var(--pcs-status-bar, 47px)) -
|
|
177
|
+
37px - var(--prizma-spacing-40)
|
|
178
|
+
)
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* ── On a LANDSCAPE window the ring centres instead ──────────────────────────
|
|
183
|
+
* 188 is a portrait measurement: it is 22% down an 844 phone, and the capture
|
|
184
|
+
* block reads as sitting near the top with the instruction under it. Down a
|
|
185
|
+
* 1440 x 820 browser window the same offset leaves the whole bottom half empty
|
|
186
|
+
* and the composition reads as a phone screen pinned to the top of a desktop
|
|
187
|
+
* page (Camila, 2026-10-09).
|
|
188
|
+
*
|
|
189
|
+
* #VS-24's rule survives intact, and it is the reason this is an OFFSET and not
|
|
190
|
+
* `justify-content: center`. The rule is that the ring does not move BETWEEN
|
|
191
|
+
* screens — a capture window that jumps as the step advances reads as a glitch
|
|
192
|
+
* — and the stack under the ring is a different height on every one of them (an
|
|
193
|
+
* instruction here, a spinner and a label there, an arrow chip on the turns).
|
|
194
|
+
* Centring that stack would move the ring again, which is the exact bug #VS-24
|
|
195
|
+
* was written for. Centring the RING instead depends on two numbers only: the
|
|
196
|
+
* shell's height and Core's own 335 capture box. Every ring screen lands in the
|
|
197
|
+
* same place, and the copy flows below it as before. */
|
|
198
|
+
@container pcs-screen (min-aspect-ratio: 1 / 1) {
|
|
199
|
+
.video-selfie-band--ring {
|
|
200
|
+
padding-top: max(
|
|
201
|
+
0px,
|
|
202
|
+
calc(
|
|
203
|
+
(100cqh - 335px) / 2 - var(--vs-top-reserve, var(--pcs-status-bar, 47px)) - 37px -
|
|
204
|
+
var(--prizma-spacing-40)
|
|
205
|
+
)
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/* ── …and on a short panel the ring itself gives ground ──────────────────────
|
|
211
|
+
* Scaling the offset is not enough at 640: the stack below the ring is a title
|
|
212
|
+
* and a subtitle on the verdict beats ("Selfie not captured, try again") and an
|
|
213
|
+
* arrow plus an instruction on the turns, and all of it is content height the
|
|
214
|
+
* band cannot take back.
|
|
215
|
+
*
|
|
216
|
+
* So the RING shrinks, exactly the way `IdCaptureLayout.css` already lets the
|
|
217
|
+
* document frame shrink and for the same stated reason — the capture window may
|
|
218
|
+
* get smaller, that is not a constraint (owner, 2026-08-18). Core's stage is
|
|
219
|
+
* `width: 100%; aspect-ratio: 1`, so giving it a flex basis of its own width and
|
|
220
|
+
* letting the column take the shortfall out of its HEIGHT makes the aspect
|
|
221
|
+
* narrow it back: still a circle, still centred, just smaller. Everything inside
|
|
222
|
+
* it is already proportional (the ring is an SVG on a 335 viewBox, the
|
|
223
|
+
* silhouette is in %), so nothing else has to be told.
|
|
224
|
+
*
|
|
225
|
+
* 87.7cqw is Core's own capture width (`min(87.7cqw, 335px)` — 335 of the 390
|
|
226
|
+
* reference); it is named here only because a flex basis cannot read it off the
|
|
227
|
+
* element it is sizing. Outside the query not one of these declarations exists,
|
|
228
|
+
* so the reference stage is untouched. */
|
|
229
|
+
@container pcs-screen (max-height: 720px) {
|
|
230
|
+
.prizma-viewfinder__content:has(> .video-selfie-band--ring) {
|
|
231
|
+
min-height: 0;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.video-selfie-band--ring {
|
|
235
|
+
min-height: 0;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.video-selfie-band--ring > .prizma-selfie-capture {
|
|
239
|
+
flex: 0 1 auto;
|
|
240
|
+
min-height: 0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.video-selfie-band--ring .prizma-selfie-capture__stage {
|
|
244
|
+
flex: 0 1 auto;
|
|
245
|
+
min-height: 0;
|
|
246
|
+
width: auto;
|
|
247
|
+
max-width: 100%;
|
|
248
|
+
flex-basis: min(335px, 87.7cqw);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/* The copy under the ring keeps its own height — the ring is what shrinks. */
|
|
252
|
+
.video-selfie-band--ring > .prizma-selfie-capture > :not(.prizma-selfie-capture__stage),
|
|
253
|
+
.video-selfie-band--ring > .video-selfie-turn {
|
|
254
|
+
flex-shrink: 0;
|
|
255
|
+
}
|
|
85
256
|
}
|
|
86
257
|
|
|
87
258
|
/* ── Recording indicator (10.1 / 11.1 / 11.3 / 11.5) ─────────────────────────
|
|
@@ -117,6 +288,20 @@
|
|
|
117
288
|
bottom: 0;
|
|
118
289
|
z-index: 3;
|
|
119
290
|
padding: var(--prizma-spacing-16);
|
|
291
|
+
/* The SCRIM is full-bleed; the card is not. On a panel wider than the
|
|
292
|
+
* reference the panel keeps the host's column (`--pcs-column`, see the HUD
|
|
293
|
+
* block above) and centres, so the card stays a card instead of a 720-wide
|
|
294
|
+
* strip. Its own Spacing/16 inset is untouched, which is what keeps the
|
|
295
|
+
* reference rendering byte-identical: at 390 the column IS the panel. */
|
|
296
|
+
max-width: var(--pcs-column, none);
|
|
297
|
+
margin-inline: auto;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* Core's Modal caps itself too, so on a tablet's 468 column the card has room
|
|
301
|
+
* to spare inside the panel and was landing flush left. Centre it, same as the
|
|
302
|
+
* coaching bubble. */
|
|
303
|
+
.video-selfie-sheet-panel > * {
|
|
304
|
+
margin-inline: auto;
|
|
120
305
|
}
|
|
121
306
|
|
|
122
307
|
/* The confirmation dialog (10.4) is a true centred modal over a dimmed screen,
|
|
@@ -173,6 +358,36 @@
|
|
|
173
358
|
height: var(--prizma-title-icon-size);
|
|
174
359
|
}
|
|
175
360
|
|
|
361
|
+
/* ── The tutorial's seven rows on a short panel ──────────────────────────────
|
|
362
|
+
* The promise list fits the 844 reference to the pixel — measured 497 of the
|
|
363
|
+
* 497 the column leaves — so on a 693 or 640 panel the last two rows painted
|
|
364
|
+
* through the CTA and the verified tag (Camila, 2026-10-07).
|
|
365
|
+
*
|
|
366
|
+
* The concession is the one archetype G already ships and this module already
|
|
367
|
+
* uses on its Android settings walk-through: the ROWS pan, the title, the CTA
|
|
368
|
+
* band and the anchored tag hold still (`__list--scroll`, ScreenLayout.css).
|
|
369
|
+
* It is applied here, under a container query, rather than through the
|
|
370
|
+
* `scrollList` prop, because that variant also adds a Spacing/16 margin below
|
|
371
|
+
* the list — on the reference that is 16 of the 497 the rows need, so the prop
|
|
372
|
+
* would start clipping the very screen it is meant to leave alone.
|
|
373
|
+
*
|
|
374
|
+
* 720 is the same line the live cues use: the reference is 844, and anything
|
|
375
|
+
* at 640 or 693 is a short panel. */
|
|
376
|
+
@container pcs-screen (max-height: 720px) {
|
|
377
|
+
.video-selfie-tutorial .prizma-screen-layout__list {
|
|
378
|
+
overflow-y: auto;
|
|
379
|
+
/* `__list--scroll`'s own Spacing/16, so the row the clip cuts through is not
|
|
380
|
+
flush against the CTA. Inside the query it costs the reference nothing. */
|
|
381
|
+
margin-bottom: var(--prizma-spacing-16);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/* Rows keep their intrinsic height instead of being squeezed — the reason
|
|
385
|
+
`__list--scroll` carries the same declaration. */
|
|
386
|
+
.video-selfie-tutorial .prizma-screen-layout__list > * {
|
|
387
|
+
flex-shrink: 0;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
176
391
|
/* ── The OS settings walk-through (2.5) ──────────────────────────────────────
|
|
177
392
|
* Two labelled sections inside archetype G's list slot: a numbered step list
|
|
178
393
|
* and a plain note. CONTENT typography only — the offset above the block is
|
|
@@ -348,6 +563,82 @@
|
|
|
348
563
|
margin-block: 0 auto;
|
|
349
564
|
}
|
|
350
565
|
|
|
566
|
+
/* Core caps the pill itself at 400 (CaptureFeedback.css, FLAG-DOUBLE-MAXWIDTH),
|
|
567
|
+
* which is narrower than a tablet's 420 column — so inside the wrapper it has
|
|
568
|
+
* 20px to spare and was landing flush left, off the frame's centre line. Same
|
|
569
|
+
* centring `.video-selfie-stage` needs, for the same reason. */
|
|
570
|
+
.video-selfie-feedback > .prizma-capture-feedback {
|
|
571
|
+
margin-inline: auto;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/* ── The live cues go COMPACT on a small phone ───────────────────────────────
|
|
575
|
+
* `PrizmaCaptureFeedback` ships two templates on its own `Show Animation` axis:
|
|
576
|
+
* A, the 135px pill with the illustration beside the copy at Headline/H3, and
|
|
577
|
+
* B, a 72px pill with no illustration at Headline/H5 (CaptureFeedback.css,
|
|
578
|
+
* "Compact modifier"). The module's frames draw A, and A is what every screen
|
|
579
|
+
* with room keeps.
|
|
580
|
+
*
|
|
581
|
+
* It is the wrong template on a small phone. At 320 the pill's 70px
|
|
582
|
+
* illustration column plus its Spacing/16 gap take 86 of the 272 the content
|
|
583
|
+
* has — a third of the width spent on a decoration — so "Center your ID inside
|
|
584
|
+
* the frame" wrapped to three lines and the pill grew to 150; on the 640-tall
|
|
585
|
+
* panel the same pill is a quarter of the whole screen. Either way it ate the
|
|
586
|
+
* air the document frame needs, and the frame came down through it (Camila,
|
|
587
|
+
* 2026-10-07: "in smaller phones, the live cues should change to the compact
|
|
588
|
+
* version"). Template B says the same two lines in 72.
|
|
589
|
+
*
|
|
590
|
+
* A CONTAINER query, and in the SCREENS layer rather than CaptureFeedback.css,
|
|
591
|
+
* for the reason `ScreenLayout.css` gives on the capture notice: Core web
|
|
592
|
+
* components are width-agnostic by design, and the browser viewport is not the
|
|
593
|
+
* phone — in Core Lab a 320 shell sits inside a 1400px window, so `@media`
|
|
594
|
+
* would read the wrong number. `pcs-screen` is the shell's own container
|
|
595
|
+
* (ScreenShell.css).
|
|
596
|
+
*
|
|
597
|
+
* Two triggers, because two different things run out:
|
|
598
|
+
* · 340 wide — the line above the narrowest phone we support and below the
|
|
599
|
+
* next one, the same threshold the capture notice drops its glyph at: 320
|
|
600
|
+
* goes compact, 360 and 390 keep the illustration.
|
|
601
|
+
* · 720 tall — the reference is 844 and the frames are drawn against it. A
|
|
602
|
+
* panel at 640 or 693 has no air to spend on a 135px pill, however wide it
|
|
603
|
+
* is. 720 clears 844, 932 and the tablet's 1024.
|
|
604
|
+
*
|
|
605
|
+
* Nothing is re-skinned: the pill's fill, radius, stroke and shadow are Core's
|
|
606
|
+
* and identical between A and B (capture-feedback.md §4.4). What changes is
|
|
607
|
+
* exactly Template B's four switches. DEVIATIONS #VS-30. */
|
|
608
|
+
/* ⚠ ONE `or` condition, not two comma-separated queries. A container query
|
|
609
|
+
* names its container ONCE and the conditions go in a single boolean group:
|
|
610
|
+
* `pcs-screen (a), pcs-screen (b)` parses in Chrome and is a hard error in
|
|
611
|
+
* lightningcss, so the hub's production build failed on it while the dev server
|
|
612
|
+
* was fine. Any future multi-condition query in this package wants this shape. */
|
|
613
|
+
@container pcs-screen ((max-width: 340px) or (max-height: 720px)) {
|
|
614
|
+
.video-selfie-feedback .prizma-capture-feedback__illustration {
|
|
615
|
+
display: none;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/* Template B: body padding-bottom 12 → 16, itemSpacing 8 → 4. */
|
|
619
|
+
.video-selfie-feedback .prizma-capture-feedback__body {
|
|
620
|
+
padding: var(--prizma-spacing-16) 0;
|
|
621
|
+
gap: var(--prizma-spacing-4);
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/* Title Headline/H3 → Headline/H5. */
|
|
625
|
+
.video-selfie-feedback .prizma-capture-feedback__title {
|
|
626
|
+
font-weight: var(--prizma-headline-h5-font-weight);
|
|
627
|
+
font-size: var(--prizma-headline-h5-font-size);
|
|
628
|
+
line-height: var(--prizma-headline-h5-line-height);
|
|
629
|
+
letter-spacing: var(--prizma-headline-h5-letter-spacing);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/* Subtitle Headline/H5 → Body/M Regular. */
|
|
633
|
+
.video-selfie-feedback .prizma-capture-feedback__subtitle {
|
|
634
|
+
font-family: var(--prizma-body-family);
|
|
635
|
+
font-weight: var(--prizma-body-m-regular-font-weight);
|
|
636
|
+
font-size: var(--prizma-body-m-regular-font-size);
|
|
637
|
+
line-height: var(--prizma-body-m-regular-line-height);
|
|
638
|
+
letter-spacing: var(--prizma-body-m-regular-letter-spacing);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
351
642
|
/* ── The head-turn mark and its instruction ──────────────────────────────────
|
|
352
643
|
* The `🙂↔️ Turn Head` band puts a 48 circled arrow between the ring and the
|
|
353
644
|
* line that says which way to turn (`element container` 342×48, the glyph
|
|
@@ -375,6 +666,17 @@
|
|
|
375
666
|
color: var(--prizma-icon-neutral-50-static);
|
|
376
667
|
}
|
|
377
668
|
|
|
669
|
+
/* The mark NEVER mirrors in a right-to-left locale (owner decision, Sofia
|
|
670
|
+
* 2026-10-07). A head turn is a physical direction, not a reading direction,
|
|
671
|
+
* so "left" stays left in Hebrew too. Core flips the horizontal chevrons in
|
|
672
|
+
* RTL through `[dir="rtl"] .prizma-icon--rtl-mirror` (Navigation.css); this
|
|
673
|
+
* rule, the same selector scoped to the mark, outranks it on this screen only
|
|
674
|
+
* and every other chevron keeps mirroring. The solid circle arrows the mark
|
|
675
|
+
* used to be never flipped, so this restores their behaviour. */
|
|
676
|
+
[dir='rtl'] .video-selfie-turn__mark .prizma-icon--rtl-mirror {
|
|
677
|
+
transform: none;
|
|
678
|
+
}
|
|
679
|
+
|
|
378
680
|
/* Step rows — the <ol> `PrizmaList` would supply, composed here only because
|
|
379
681
|
* the wrapper has no variant reaching Core's plain `number` squircle (#VS-16).
|
|
380
682
|
* The gap is the icon family's own Spacing/12; nothing new is declared. */
|
|
@@ -126,7 +126,15 @@ export const VideoSelfieSelfieCaptureScreen = forwardRef<
|
|
|
126
126
|
state === 'start' ? (feedback ? slice.feedback[feedback] : slice.startLabel) : undefined;
|
|
127
127
|
|
|
128
128
|
return (
|
|
129
|
-
<PrizmaScreenShell
|
|
129
|
+
<PrizmaScreenShell
|
|
130
|
+
ref={ref}
|
|
131
|
+
dark
|
|
132
|
+
/* The camera owns the whole window, never a column of it — see the
|
|
133
|
+
contract note in `VideoSelfieLayout.css`. */
|
|
134
|
+
data-pcs-overlay="window"
|
|
135
|
+
className={className}
|
|
136
|
+
{...shell}
|
|
137
|
+
>
|
|
130
138
|
<div className="prizma-viewfinder__surface">{camera}</div>
|
|
131
139
|
<div className="video-selfie-stepper">
|
|
132
140
|
<PrizmaStepper
|
|
@@ -178,7 +178,15 @@ export const VideoSelfieSpeakScreen = forwardRef<
|
|
|
178
178
|
);
|
|
179
179
|
|
|
180
180
|
return (
|
|
181
|
-
<PrizmaScreenShell
|
|
181
|
+
<PrizmaScreenShell
|
|
182
|
+
ref={ref}
|
|
183
|
+
dark
|
|
184
|
+
/* The camera owns the whole window, never a column of it — see the
|
|
185
|
+
contract note in `VideoSelfieLayout.css`. */
|
|
186
|
+
data-pcs-overlay="window"
|
|
187
|
+
className={className}
|
|
188
|
+
{...shell}
|
|
189
|
+
>
|
|
182
190
|
<div className="prizma-viewfinder__surface">{camera}</div>
|
|
183
191
|
<div className="video-selfie-stepper">
|
|
184
192
|
<PrizmaStepper
|
|
@@ -289,7 +289,9 @@ export interface VideoSelfieStrings {
|
|
|
289
289
|
stepError: { title: string; ctaLabel: string };
|
|
290
290
|
/** `14.3` — the whole module blew up. */
|
|
291
291
|
moduleError: { title: string; ctaLabel: string; quitLabel: string };
|
|
292
|
-
/** `14.4` — connectivity.
|
|
293
|
-
|
|
292
|
+
/** `14.4` — connectivity. The supporting line is the generic family's
|
|
293
|
+
* (`ErrorScreensStrings.noConnection.subtitle`), so this screen reads
|
|
294
|
+
* like every other module's connectivity screen (#F-34, #PI-8). */
|
|
295
|
+
noConnection: { title: string; subtitle?: string; ctaLabel: string; quitLabel: string };
|
|
294
296
|
};
|
|
295
297
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { forwardRef, type ReactNode } from 'react';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
IconChevronDown,
|
|
4
|
+
IconChevronLeft,
|
|
5
|
+
IconChevronRight,
|
|
6
|
+
IconChevronUp,
|
|
7
7
|
} from '@incodetech/prizma-core-icons';
|
|
8
8
|
import { PrizmaSelfieCapture } from '@incodetech/prizma-core-web/selfie-capture';
|
|
9
9
|
import { PrizmaStepper } from '@incodetech/prizma-core-web/stepper';
|
|
@@ -26,17 +26,20 @@ export type VideoSelfieTurnStage = 'ask' | 'done';
|
|
|
26
26
|
* Direction → the mark under the ring, from the canonical bank at 2xl (48) —
|
|
27
27
|
* the size the frames draw it (`element container` 342×48, the glyph centred).
|
|
28
28
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
29
|
+
* Since the Core and Enterprise icon unification (Sofia, 2026-10-06) the
|
|
30
|
+
* mark is the library chevron at 2xl: the four solid circle arrows left the
|
|
31
|
+
* bank (their old names now alias the chevrons). Nothing is drawn here (§10).
|
|
32
|
+
*
|
|
33
|
+
* The mark never mirrors in RTL (Sofia, 2026-10-07): a head turn is a
|
|
34
|
+
* physical direction, so the chevrons keep their LTR orientation in Hebrew.
|
|
35
|
+
* The opt-out is one scoped rule in `VideoSelfieLayout.css`; the chevrons
|
|
36
|
+
* still mirror everywhere else.
|
|
34
37
|
*/
|
|
35
38
|
const TURN_ICON: Record<VideoSelfieTurnDirection, ReactNode> = {
|
|
36
|
-
left: <
|
|
37
|
-
right: <
|
|
38
|
-
up: <
|
|
39
|
-
down: <
|
|
39
|
+
left: <IconChevronLeft size="2xl" />,
|
|
40
|
+
right: <IconChevronRight size="2xl" />,
|
|
41
|
+
up: <IconChevronUp size="2xl" />,
|
|
42
|
+
down: <IconChevronDown size="2xl" />,
|
|
40
43
|
};
|
|
41
44
|
|
|
42
45
|
export interface VideoSelfieTurnHeadScreenProps
|
|
@@ -99,7 +102,15 @@ export const VideoSelfieTurnHeadScreen = forwardRef<
|
|
|
99
102
|
},
|
|
100
103
|
ref,
|
|
101
104
|
) => (
|
|
102
|
-
<PrizmaScreenShell
|
|
105
|
+
<PrizmaScreenShell
|
|
106
|
+
ref={ref}
|
|
107
|
+
dark
|
|
108
|
+
/* The camera owns the whole window, never a column of it — see the
|
|
109
|
+
contract note in `VideoSelfieLayout.css`. */
|
|
110
|
+
data-pcs-overlay="window"
|
|
111
|
+
className={className}
|
|
112
|
+
{...shell}
|
|
113
|
+
>
|
|
103
114
|
<div className="prizma-viewfinder__surface">{camera}</div>
|
|
104
115
|
<div className="video-selfie-stepper">
|
|
105
116
|
<PrizmaStepper
|
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
VideoSelfieTutorialRowKind,
|
|
19
19
|
} from './VideoSelfieStrings';
|
|
20
20
|
import './ScreenLayout.css';
|
|
21
|
+
import './VideoSelfieLayout.css';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Journey beat → canonical bank glyph. ONE map, in one place — the same seven
|
|
@@ -78,6 +79,14 @@ export interface VideoSelfieTutorialScreenProps
|
|
|
78
79
|
* NOT archetype A: A centres one illustration in the flexible middle; here the
|
|
79
80
|
* middle is a seven-row list that must span the column and start at the top —
|
|
80
81
|
* the distinction `ScreenLayout.css` draws between `__flex` and `__list`.
|
|
82
|
+
*
|
|
83
|
+
* The one class it carries, `video-selfie-tutorial`, exists so the module's
|
|
84
|
+
* stylesheet can reach this screen on a SHORT panel: seven rows fit the 844
|
|
85
|
+
* reference to the pixel (measured 497 of 497), and on a 640 or 693 one they
|
|
86
|
+
* paint straight through the CTA. `VideoSelfieLayout.css` lets them pan there,
|
|
87
|
+
* the same concession the Android settings walk-through already makes with
|
|
88
|
+
* `scrollList` — and `scrollList` itself is not used here because its
|
|
89
|
+
* Spacing/16 margin would take the reference below the 497 the rows need.
|
|
81
90
|
*/
|
|
82
91
|
export const VideoSelfieTutorialScreen = forwardRef<
|
|
83
92
|
HTMLDivElement,
|
|
@@ -90,12 +99,14 @@ export const VideoSelfieTutorialScreen = forwardRef<
|
|
|
90
99
|
screenId = `video-selfie-tutorial-${documentType}`,
|
|
91
100
|
overrides,
|
|
92
101
|
onAction,
|
|
102
|
+
className,
|
|
93
103
|
...shell
|
|
94
104
|
},
|
|
95
105
|
ref,
|
|
96
106
|
) => (
|
|
97
107
|
<PrizmaListScreen
|
|
98
108
|
ref={ref}
|
|
109
|
+
className={['video-selfie-tutorial', className].filter(Boolean).join(' ')}
|
|
99
110
|
title={strings.tutorial.title}
|
|
100
111
|
subtitle={strings.tutorial.subtitle}
|
|
101
112
|
ctaLabel={strings.tutorial.ctaLabel}
|
|
@@ -75,7 +75,15 @@ export const VideoSelfieWaveScreen = forwardRef<HTMLDivElement, VideoSelfieWaveS
|
|
|
75
75
|
const seen = stage === 'success';
|
|
76
76
|
|
|
77
77
|
return (
|
|
78
|
-
<PrizmaScreenShell
|
|
78
|
+
<PrizmaScreenShell
|
|
79
|
+
ref={ref}
|
|
80
|
+
dark
|
|
81
|
+
/* The camera owns the whole window, never a column of it — see the
|
|
82
|
+
contract note in `VideoSelfieLayout.css`. */
|
|
83
|
+
data-pcs-overlay="window"
|
|
84
|
+
className={className}
|
|
85
|
+
{...shell}
|
|
86
|
+
>
|
|
79
87
|
<div className="prizma-viewfinder__surface">{camera}</div>
|
|
80
88
|
<div className="video-selfie-stepper">
|
|
81
89
|
<PrizmaStepper
|
package/src/ViewfinderScreen.css
CHANGED
|
@@ -13,6 +13,42 @@
|
|
|
13
13
|
object-fit: cover;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/* ── A feed has an ASPECT, and the plate has to match it ─────────────────────
|
|
17
|
+
* `object-fit: cover` is right for a live feed and wrong for a still: a phone
|
|
18
|
+
* plate is 390 x 844, and covering a 1440 x 820 browser window scales it 3.7x,
|
|
19
|
+
* so the subject fills the window and her face lands nowhere near the capture
|
|
20
|
+
* ring (Camila, 2026-10-09: "the image is now too zoomed in because full screen
|
|
21
|
+
* is not good for this image ratio"). A real desktop webcam does not hand the
|
|
22
|
+
* page a portrait frame; it hands it a landscape one.
|
|
23
|
+
*
|
|
24
|
+
* So the HOST may supply two plates and the viewfinder picks the one whose
|
|
25
|
+
* shape fits the shell it is actually being drawn at:
|
|
26
|
+
*
|
|
27
|
+
* <div className="prizma-viewfinder__surface">
|
|
28
|
+
* <img data-pcs-plate="tall" src={portrait} alt="" />
|
|
29
|
+
* <img data-pcs-plate="wide" src={landscape} alt="" />
|
|
30
|
+
* </div>
|
|
31
|
+
*
|
|
32
|
+
* Supply one and nothing changes — an untagged `<img>` or `<video>` is shown at
|
|
33
|
+
* every shape, which is every existing caller. A CONTAINER query, not a media
|
|
34
|
+
* one, for the reason `ScreenLayout.css` gives on the capture notice: the
|
|
35
|
+
* browser viewport is not the screen, and in Core Lab a 390 shell sits inside a
|
|
36
|
+
* 1400px window. The line is square: anything wider than it is tall takes the
|
|
37
|
+
* landscape plate. */
|
|
38
|
+
.prizma-viewfinder__surface > [data-pcs-plate='wide'] {
|
|
39
|
+
display: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@container pcs-screen (min-aspect-ratio: 1 / 1) {
|
|
43
|
+
.prizma-viewfinder__surface > [data-pcs-plate='tall'] {
|
|
44
|
+
display: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.prizma-viewfinder__surface > [data-pcs-plate='wide'] {
|
|
48
|
+
display: block;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
16
52
|
.prizma-viewfinder__content {
|
|
17
53
|
position: relative;
|
|
18
54
|
z-index: 1;
|
package/src/flows.ts
CHANGED
|
@@ -83,6 +83,10 @@ export interface FaceCaptureFlowVariant {
|
|
|
83
83
|
ctaLoading?: boolean;
|
|
84
84
|
/** FaceCaptureCapturingScreen — which of the 15 `capturing.*` sections. */
|
|
85
85
|
state?: FaceCaptureCapturingState;
|
|
86
|
+
/** FaceCaptureCapturingScreen — raise the "Need more time?" offer over the
|
|
87
|
+
* feed. A modifier of `state`, not one of the fifteen: the fallback timer
|
|
88
|
+
* runs underneath whichever guidance is showing. */
|
|
89
|
+
extendTime?: boolean;
|
|
86
90
|
/** FaceCaptureLoadingScreen — `loading.uploading` vs `loading.processing`. */
|
|
87
91
|
stage?: 'uploading' | 'processing';
|
|
88
92
|
/** FaceCaptureResultErrorScreen — the `*Exhausted` half of the error pairs. */
|
|
@@ -140,6 +144,14 @@ export const faceCaptureFlow: readonly FaceCaptureFlowStep[] = [
|
|
|
140
144
|
/** The off-path screens: manual capture (offered when auto-capture is turned
|
|
141
145
|
* off or gives up), the two error verdicts, and the connectivity error. */
|
|
142
146
|
export const faceCaptureBranches: readonly FaceCaptureFlowStep[] = [
|
|
147
|
+
{
|
|
148
|
+
// A branch, not a step: it only appears when accessibility mode is ON for
|
|
149
|
+
// the flow AND the fallback timer is 20 s from expiring. It returns to the
|
|
150
|
+
// capturing states it came from, so it never "follows" anything.
|
|
151
|
+
screenId: 'face-capture-capturing-extend-time',
|
|
152
|
+
component: FaceCaptureCapturingScreen,
|
|
153
|
+
variant: { state: 'alignFace', extendTime: true },
|
|
154
|
+
},
|
|
143
155
|
{
|
|
144
156
|
screenId: 'face-capture-manual-capture',
|
|
145
157
|
component: FaceCaptureManualCaptureScreen,
|
|
@@ -479,6 +491,10 @@ export interface IdCaptureFlowVariant {
|
|
|
479
491
|
vertical?: boolean;
|
|
480
492
|
/** IdCaptureStageScreen — which stage section. */
|
|
481
493
|
state?: IdCaptureStageState;
|
|
494
|
+
/** IdCaptureStageScreen — raise the "Need more time?" offer over the feed.
|
|
495
|
+
* A modifier of `state`, not one of the eleven: the fallback timer runs
|
|
496
|
+
* underneath whichever stage is showing. */
|
|
497
|
+
extendTime?: boolean;
|
|
482
498
|
/** IdCaptureStageScreen — the `*-manual` sections. */
|
|
483
499
|
manual?: boolean;
|
|
484
500
|
/** IdCaptureResultScreen — which verdict section. */
|
|
@@ -633,6 +649,15 @@ export const idCaptureBranches: readonly IdCaptureFlowStep[] = [
|
|
|
633
649
|
screenId: 'id-capture-age-verification',
|
|
634
650
|
component: IdCaptureAgeVerificationScreen,
|
|
635
651
|
},
|
|
652
|
+
{
|
|
653
|
+
// A branch, not a step: it only appears when accessibility mode is ON for
|
|
654
|
+
// the flow AND the 30 s fallback timer is 20 s from expiring. It returns
|
|
655
|
+
// to the hint stage it came from, so it never "follows" anything — the
|
|
656
|
+
// same shape as Face Capture's `capturing-extend-time`.
|
|
657
|
+
screenId: 'id-capture-front-extend-time',
|
|
658
|
+
component: IdCaptureStageScreen,
|
|
659
|
+
variant: { state: 'hint', extendTime: true },
|
|
660
|
+
},
|
|
636
661
|
{
|
|
637
662
|
screenId: 'id-capture-front-manual',
|
|
638
663
|
component: IdCaptureStageScreen,
|