@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.
Files changed (168) hide show
  1. package/dist/BiometricConsentScreen.d.ts +95 -0
  2. package/dist/BiometricConsentScreen.js +91 -0
  3. package/dist/BiometricConsentStrings.d.ts +84 -0
  4. package/dist/BiometricConsentStrings.js +31 -0
  5. package/dist/CaptureScreen.d.ts +13 -0
  6. package/dist/CaptureScreen.js +2 -2
  7. package/dist/DemoScreensLayout.css +16 -0
  8. package/dist/DemoScreensRedirectScreen.d.ts +6 -1
  9. package/dist/DemoScreensRedirectScreen.js +3 -2
  10. package/dist/DemoScreensStrings.d.ts +5 -0
  11. package/dist/DigitalIdUploadErrorScreen.d.ts +31 -0
  12. package/dist/DigitalIdUploadErrorScreen.js +26 -0
  13. package/dist/DigitalIdUploadFileTooLargeScreen.d.ts +27 -0
  14. package/dist/DigitalIdUploadFileTooLargeScreen.js +21 -0
  15. package/dist/DigitalIdUploadReviewScreen.d.ts +57 -0
  16. package/dist/DigitalIdUploadReviewScreen.js +44 -0
  17. package/dist/DigitalIdUploadStrings.d.ts +64 -0
  18. package/dist/DigitalIdUploadStrings.js +19 -0
  19. package/dist/DigitalIdUploadTutorialScreen.d.ts +28 -0
  20. package/dist/DigitalIdUploadTutorialScreen.js +23 -0
  21. package/dist/DocumentCaptureIllustration.d.ts +1 -1
  22. package/dist/EkybCountryScreen.d.ts +6 -6
  23. package/dist/EkybCountryScreen.js +20 -7
  24. package/dist/EkybStrings.d.ts +6 -1
  25. package/dist/ErrorScreensScreen.d.ts +5 -2
  26. package/dist/ErrorScreensScreen.js +15 -4
  27. package/dist/ErrorScreensStrings.d.ts +17 -2
  28. package/dist/ErrorScreensStrings.js +18 -10
  29. package/dist/FaceCaptureCapturingScreen.d.ts +63 -0
  30. package/dist/FaceCaptureCapturingScreen.js +62 -2
  31. package/dist/FaceCaptureLayout.css +69 -4
  32. package/dist/FaceCaptureStrings.d.ts +23 -0
  33. package/dist/FormScreen.css +14 -0
  34. package/dist/FormScreen.d.ts +28 -0
  35. package/dist/FormScreen.js +3 -2
  36. package/dist/IdCaptureLayout.css +165 -2
  37. package/dist/IdCaptureStageScreen.d.ts +47 -0
  38. package/dist/IdCaptureStageScreen.js +39 -3
  39. package/dist/IdCaptureStrings.d.ts +19 -0
  40. package/dist/ListScreen.d.ts +19 -0
  41. package/dist/ListScreen.js +7 -2
  42. package/dist/LoaderScreen.d.ts +7 -5
  43. package/dist/LoaderScreen.js +7 -5
  44. package/dist/LoadersStrings.d.ts +18 -5
  45. package/dist/OcrReviewErrorScreen.d.ts +30 -0
  46. package/dist/OcrReviewErrorScreen.js +24 -0
  47. package/dist/OcrReviewLayout.css +24 -0
  48. package/dist/OcrReviewLoadingScreen.d.ts +25 -0
  49. package/dist/OcrReviewLoadingScreen.js +19 -0
  50. package/dist/OcrReviewScreen.d.ts +76 -0
  51. package/dist/OcrReviewScreen.js +65 -0
  52. package/dist/OcrReviewStrings.d.ts +47 -0
  53. package/dist/OcrReviewStrings.js +17 -0
  54. package/dist/OcrReviewSuccessScreen.d.ts +30 -0
  55. package/dist/OcrReviewSuccessScreen.js +24 -0
  56. package/dist/PermissionsAllowScreen.d.ts +8 -11
  57. package/dist/PermissionsAllowScreen.js +8 -11
  58. package/dist/PermissionsAskScreen.d.ts +41 -0
  59. package/dist/PermissionsAskScreen.js +43 -0
  60. package/dist/PermissionsBrowserStepsScreen.d.ts +9 -2
  61. package/dist/PermissionsBrowserStepsScreen.js +12 -3
  62. package/dist/PermissionsLayout.css +47 -0
  63. package/dist/PermissionsStrings.d.ts +20 -9
  64. package/dist/PermissionsStrings.js +10 -4
  65. package/dist/PhoneInputOtpScreen.d.ts +8 -0
  66. package/dist/PhoneInputOtpScreen.js +26 -19
  67. package/dist/PhoneInputStrings.d.ts +11 -3
  68. package/dist/PhoneInputVerifyScreen.js +21 -5
  69. package/dist/QualifiedSignatureDocumentScreen.d.ts +8 -5
  70. package/dist/QualifiedSignatureDocumentScreen.js +9 -6
  71. package/dist/QualifiedSignatureResultScreen.d.ts +16 -13
  72. package/dist/QualifiedSignatureResultScreen.js +17 -18
  73. package/dist/QualifiedSignatureStrings.d.ts +11 -4
  74. package/dist/ResultScreen.d.ts +8 -0
  75. package/dist/ResultScreen.js +14 -3
  76. package/dist/ReusabilityCredentialSelectionScreen.d.ts +95 -0
  77. package/dist/ReusabilityCredentialSelectionScreen.js +94 -0
  78. package/dist/ReusabilityLayout.css +241 -0
  79. package/dist/ReusabilityPrivacyPolicyScreen.d.ts +55 -0
  80. package/dist/ReusabilityPrivacyPolicyScreen.js +44 -0
  81. package/dist/ReusabilityStrings.d.ts +85 -0
  82. package/dist/ReusabilityStrings.js +37 -0
  83. package/dist/ReviewScreen.d.ts +38 -12
  84. package/dist/ReviewScreen.js +41 -8
  85. package/dist/ScreenLayout.css +382 -6
  86. package/dist/VideoSelfieErrorScreen.js +1 -1
  87. package/dist/VideoSelfieIdCaptureScreen.js +1 -1
  88. package/dist/VideoSelfieLayout.css +304 -2
  89. package/dist/VideoSelfieSelfieCaptureScreen.js +1 -1
  90. package/dist/VideoSelfieSpeakScreen.js +1 -1
  91. package/dist/VideoSelfieStrings.d.ts +4 -1
  92. package/dist/VideoSelfieTurnHeadScreen.js +14 -11
  93. package/dist/VideoSelfieTutorialScreen.d.ts +9 -0
  94. package/dist/VideoSelfieTutorialScreen.js +10 -1
  95. package/dist/VideoSelfieWaveScreen.js +1 -1
  96. package/dist/ViewfinderScreen.css +36 -0
  97. package/dist/flows.d.ts +8 -0
  98. package/dist/flows.js +17 -0
  99. package/dist/index.d.ts +16 -0
  100. package/dist/index.js +12 -0
  101. package/dist/styles.css +3 -0
  102. package/package.json +68 -3
  103. package/samples/video-selfie-camera-wide.jpg +0 -0
  104. package/samples/video-selfie-room-wide.jpg +0 -0
  105. package/src/BiometricConsentScreen.tsx +192 -0
  106. package/src/BiometricConsentStrings.ts +119 -0
  107. package/src/CaptureScreen.tsx +17 -0
  108. package/src/DemoScreensLayout.css +16 -0
  109. package/src/DemoScreensRedirectScreen.tsx +14 -6
  110. package/src/DemoScreensStrings.ts +5 -0
  111. package/src/DigitalIdUploadErrorScreen.tsx +83 -0
  112. package/src/DigitalIdUploadFileTooLargeScreen.tsx +67 -0
  113. package/src/DigitalIdUploadReviewScreen.tsx +119 -0
  114. package/src/DigitalIdUploadStrings.ts +88 -0
  115. package/src/DigitalIdUploadTutorialScreen.tsx +59 -0
  116. package/src/DocumentCaptureIllustration.tsx +1 -1
  117. package/src/EkybCountryScreen.tsx +23 -6
  118. package/src/EkybStrings.ts +6 -1
  119. package/src/ErrorScreensScreen.tsx +15 -4
  120. package/src/ErrorScreensStrings.ts +37 -12
  121. package/src/FaceCaptureCapturingScreen.tsx +102 -13
  122. package/src/FaceCaptureLayout.css +69 -4
  123. package/src/FaceCaptureStrings.ts +24 -0
  124. package/src/FormScreen.css +14 -0
  125. package/src/FormScreen.tsx +34 -0
  126. package/src/IdCaptureLayout.css +165 -2
  127. package/src/IdCaptureStageScreen.tsx +75 -0
  128. package/src/IdCaptureStrings.ts +19 -0
  129. package/src/ListScreen.tsx +48 -9
  130. package/src/LoaderScreen.tsx +7 -5
  131. package/src/LoadersStrings.ts +18 -5
  132. package/src/OcrReviewErrorScreen.tsx +53 -0
  133. package/src/OcrReviewLayout.css +24 -0
  134. package/src/OcrReviewLoadingScreen.tsx +48 -0
  135. package/src/OcrReviewScreen.tsx +190 -0
  136. package/src/OcrReviewStrings.ts +69 -0
  137. package/src/OcrReviewSuccessScreen.tsx +52 -0
  138. package/src/PermissionsAllowScreen.tsx +9 -10
  139. package/src/PermissionsAskScreen.tsx +105 -0
  140. package/src/PermissionsBrowserStepsScreen.tsx +11 -3
  141. package/src/PermissionsLayout.css +47 -0
  142. package/src/PermissionsStrings.ts +42 -12
  143. package/src/PhoneInputOtpScreen.tsx +23 -3
  144. package/src/PhoneInputStrings.ts +11 -3
  145. package/src/PhoneInputVerifyScreen.tsx +24 -4
  146. package/src/QualifiedSignatureDocumentScreen.tsx +9 -7
  147. package/src/QualifiedSignatureResultScreen.tsx +28 -26
  148. package/src/QualifiedSignatureStrings.ts +11 -4
  149. package/src/ResultScreen.tsx +33 -2
  150. package/src/ReusabilityCredentialSelectionScreen.tsx +246 -0
  151. package/src/ReusabilityLayout.css +241 -0
  152. package/src/ReusabilityPrivacyPolicyScreen.tsx +109 -0
  153. package/src/ReusabilityStrings.ts +127 -0
  154. package/src/ReviewScreen.tsx +96 -27
  155. package/src/ScreenLayout.css +382 -6
  156. package/src/VideoSelfieErrorScreen.tsx +1 -1
  157. package/src/VideoSelfieIdCaptureScreen.tsx +9 -1
  158. package/src/VideoSelfieLayout.css +304 -2
  159. package/src/VideoSelfieSelfieCaptureScreen.tsx +9 -1
  160. package/src/VideoSelfieSpeakScreen.tsx +9 -1
  161. package/src/VideoSelfieStrings.ts +4 -2
  162. package/src/VideoSelfieTurnHeadScreen.tsx +25 -14
  163. package/src/VideoSelfieTutorialScreen.tsx +11 -0
  164. package/src/VideoSelfieWaveScreen.tsx +9 -1
  165. package/src/ViewfinderScreen.css +36 -0
  166. package/src/flows.ts +25 -0
  167. package/src/index.ts +74 -3
  168. package/src/styles.css +3 -0
@@ -64,6 +64,14 @@ export interface PrizmaResultScreenProps extends Omit<PrizmaScreenShellProps, 'd
64
64
  * job (Face Match's verdict Snackbar). DEVIATIONS #VS-17.
65
65
  */
66
66
  linkLabel?: string;
67
+ /**
68
+ * Where the tertiary link sits in the stack. `below` (default) is archetype
69
+ * A's position; `above` puts it over the primary CTA, which is what the
70
+ * permission frames draw ("Quit process" over "Allow permission",
71
+ * DEVIATIONS #GEN-3, #VS-17). The slot those rows escalated: the archetype
72
+ * still owns both positions, a screen only picks one of them.
73
+ */
74
+ linkPosition?: 'below' | 'above';
67
75
  /** "verified by" attribution copy for the footer tag. */
68
76
  verifiedLabel: string;
69
77
  navLabel?: string;
@@ -26,12 +26,23 @@ import './ScreenLayout.css';
26
26
  * `ProcessingScreen` stays the pure spinner/no-CTA case; reach for this one as
27
27
  * soon as a result screen needs a button.
28
28
  */
29
- export const PrizmaResultScreen = forwardRef(({ progress, status = 'none', title, subtitle, glyph, children, bandContent, disclaimer, ctaOrientation = 'stacked', ctaLabel, secondaryCtaLabel, linkLabel, verifiedLabel, navLabel, screenId, showHeader = true, showFooter = true, overrides, onAction, ...shell }, ref) => (_jsxs(PrizmaScreenShell, { ref: ref, ...shell, children: [_jsx(PrizmaScreenNav, { reserved: !showHeader, logo: overrides?.logo, navLabel: navLabel }), progress ? (_jsx("div", { className: "prizma-screen-layout__progress", children: progress })) : null, _jsxs("div", { className: "prizma-screen-layout__content prizma-screen-layout__content--centered", children: [glyph, _jsx(PrizmaTitle, { variant: overrides?.align === 'left' ? 'left' : 'centered', title: title, showSubtitle: Boolean(subtitle), subtitle: subtitle, icon: status === 'loading'
29
+ export const PrizmaResultScreen = forwardRef(({ progress, status = 'none', title, subtitle, glyph, children, bandContent, disclaimer, ctaOrientation = 'stacked', ctaLabel, secondaryCtaLabel, linkLabel, linkPosition = 'below', verifiedLabel, navLabel, screenId, showHeader = true, showFooter = true, overrides, onAction, ...shell }, ref) => (_jsxs(PrizmaScreenShell, { ref: ref, ...shell, children: [_jsx(PrizmaScreenNav, { reserved: !showHeader, logo: overrides?.logo, navLabel: navLabel }), progress ? (_jsx("div", { className: "prizma-screen-layout__progress", children: progress })) : null, _jsxs("div", { className: "prizma-screen-layout__content prizma-screen-layout__content--centered", children: [glyph, _jsx(PrizmaTitle, { variant: overrides?.align === 'left' ? 'left' : 'centered', title: title, showSubtitle: Boolean(subtitle), subtitle: subtitle, icon: status === 'loading'
30
30
  ? { type: 'spinner' }
31
31
  : status === 'none'
32
32
  ? { type: 'none' }
33
- : { type: 'status', status } }), children] }), ctaLabel || secondaryCtaLabel || linkLabel || disclaimer || bandContent ? (_jsxs("div", { className: "prizma-screen-layout__band prizma-screen-layout__band--result", children: [bandContent ? (_jsx("div", { className: "prizma-screen-layout__band__content", children: bandContent })) : null, disclaimer ? _jsx(PrizmaDisclaimer, { text: disclaimer }) : null, _jsxs("div", { className: ctaOrientation === 'row'
33
+ : { type: 'status', status } }), children] }), ctaLabel || secondaryCtaLabel || linkLabel || disclaimer || bandContent ? (_jsxs("div", { className: [
34
+ 'prizma-screen-layout__band',
35
+ 'prizma-screen-layout__band--result',
36
+ // No footer tag to reserve `--pcs-footer-space` for — same gap the
37
+ // Review archetype's `--bare` fallback exists for (ScreenLayout.css).
38
+ // Every existing F consumer always shows the tag, so this has never
39
+ // fired before; without it the CTA sits ~40px further from the
40
+ // bottom than Figma's flat Spacing/24 draws.
41
+ !showFooter ? 'prizma-screen-layout__band--bare' : '',
42
+ ]
43
+ .filter(Boolean)
44
+ .join(' '), children: [bandContent ? (_jsx("div", { className: "prizma-screen-layout__band__content", children: bandContent })) : null, disclaimer ? _jsx(PrizmaDisclaimer, { text: disclaimer }) : null, _jsxs("div", { className: ctaOrientation === 'row'
34
45
  ? 'prizma-screen-layout__band__ctas prizma-screen-layout__band__ctas--row'
35
- : 'prizma-screen-layout__band__ctas', children: [ctaLabel ? (_jsx(PrizmaButton, { variant: "primary", size: "L", onClick: () => onAction?.({ type: 'cta', screenId }), children: ctaLabel })) : null, secondaryCtaLabel ? (_jsx(PrizmaButton, { variant: "secondary", size: "L", onClick: () => onAction?.({ type: 'secondary', screenId }), children: secondaryCtaLabel })) : null, linkLabel ? (_jsx(PrizmaButton, { variant: "tertiary-link", size: "L", onClick: () => onAction?.({ type: 'tertiary', screenId }), children: linkLabel })) : null] })] })) : null, showFooter ? (_jsx("div", { className: "prizma-screen-layout__footer", children: _jsx(PrizmaTag, { label: verifiedLabel }) })) : null] })));
46
+ : 'prizma-screen-layout__band__ctas', children: [linkLabel && linkPosition === 'above' ? (_jsx(PrizmaButton, { variant: "tertiary-link", size: "L", onClick: () => onAction?.({ type: 'tertiary', screenId }), children: linkLabel })) : null, ctaLabel ? (_jsx(PrizmaButton, { variant: "primary", size: "L", onClick: () => onAction?.({ type: 'cta', screenId }), children: ctaLabel })) : null, secondaryCtaLabel ? (_jsx(PrizmaButton, { variant: "secondary", size: "L", onClick: () => onAction?.({ type: 'secondary', screenId }), children: secondaryCtaLabel })) : null, linkLabel && linkPosition === 'below' ? (_jsx(PrizmaButton, { variant: "tertiary-link", size: "L", onClick: () => onAction?.({ type: 'tertiary', screenId }), children: linkLabel })) : null] })] })) : null, showFooter ? (_jsx("div", { className: "prizma-screen-layout__footer", children: _jsx(PrizmaTag, { label: verifiedLabel }) })) : null] })));
36
47
  PrizmaResultScreen.displayName = 'PrizmaResultScreen';
37
48
  export default PrizmaResultScreen;
@@ -0,0 +1,95 @@
1
+ import React from 'react';
2
+ import { type PrizmaListScreenProps } from './ListScreen';
3
+ import type { PrizmaScreenActionHandler, PrizmaScreenOverrides } from './types';
4
+ import type { ReusableCredential, ReusabilityStrings } from './ReusabilityStrings';
5
+ import './ScreenLayout.css';
6
+ import './ReusabilityLayout.css';
7
+ /** The sentinel the SDK submits for the capture row (`SCAN_NEW_DOCUMENT`,
8
+ * `identityReuseStateMachine.ts`): `{ accepted: false }`, then ID Capture. */
9
+ export declare const REUSABILITY_SCAN_NEW: "scanNew";
10
+ export type ReusabilitySelection = string | typeof REUSABILITY_SCAN_NEW;
11
+ export interface ReusabilityCredentialSelectionScreenProps extends Omit<PrizmaListScreenProps, 'status' | 'title' | 'subtitle' | 'glyph' | 'children' | 'listAlign' | 'scrollList' | 'disclaimer' | 'ctaLabel' | 'secondaryCtaLabel' | 'linkLabel' | 'secondaryLinkLabel' | 'overlay' | 'verifiedLabel' | 'navLabel'> {
12
+ /** Module copy — this screen reads the `selection` and `sharedDetails` slices. */
13
+ strings: ReusabilityStrings;
14
+ /**
15
+ * The documents the network found for this person, best match FIRST — the
16
+ * backend orders them and the first row wears the "Recommended" pill (SDK
17
+ * `recommended={index === 0}`). One or more; the frame draws two
18
+ * (`Multiple documents`) and one (`Single document`).
19
+ */
20
+ credentials: ReusableCredential[];
21
+ /**
22
+ * "What data will be shared?" was pressed: Core's bottom sheet listing the
23
+ * recipient's data request is presented over the dimmed selection
24
+ * (`shared info`, 7877:68927). Its one button emits `cta` and closes it.
25
+ */
26
+ sharedDetails?: boolean;
27
+ /**
28
+ * Fired with the chosen credential's id, or `REUSABILITY_SCAN_NEW` for the
29
+ * capture row; `onAction` still reports the tap as `cta`. Named like ID
30
+ * Capture's `onDocumentSelect` — `onSelect` is a native <div> event the shell
31
+ * already passes through.
32
+ */
33
+ onCredentialSelect?: (selection: ReusabilitySelection) => void;
34
+ screenId?: string;
35
+ overrides?: PrizmaScreenOverrides;
36
+ onAction?: PrizmaScreenActionHandler;
37
+ }
38
+ /**
39
+ * Reusability (Incode Bridge) — choose the document to reuse, built on the
40
+ * List archetype (GUIDELINES.md §6-G, `PrizmaListScreen`).
41
+ *
42
+ * ONE screen for three of the section's four frames: `Multiple documents`
43
+ * (7877:68816) and `Single document` (7877:68875) are the same skeleton — nav →
44
+ * Title (H2 + H5) → the credential list → "Scan a new document" → two tertiary
45
+ * links → tag — differing only in how many rows the network returned; and
46
+ * `Shared data` (7877:68927) is that screen with Core's bottom sheet presented
47
+ * over it (`sharedDetails`).
48
+ *
49
+ * WHY ARCHETYPE G. The rows ARE the actions — tapping a document advances the
50
+ * session with no confirm step (consent review 2026-09-16: "remove the confirm
51
+ * button: selecting a document advances the user immediately"; the Web SDK's
52
+ * ENG-57939 built exactly that) — so there is no primary CTA, and G is the one
53
+ * archetype whose band may carry links alone. ID Capture's document chooser is
54
+ * the same shape on the same archetype.
55
+ *
56
+ * Six things are deliberate:
57
+ *
58
+ * 1. The rows are composed here from Core's tokens, not from Core's
59
+ * `PrizmaCardListVerificationOptions`. The frame calls them "Verification
60
+ * options card list", but a reusable credential has a different anatomy —
61
+ * type label + status pill, flag + masked number, verified date — and the
62
+ * capture row is one line with a pill. Core ships neither that row nor a
63
+ * plain status pill; both are proposed (DEVIATIONS #RU-1, #RU-2) and the
64
+ * rules live once in `ReusabilityLayout.css`.
65
+ * 2. Every row is a real `<button>` that emits `cta` and names its credential
66
+ * through `onCredentialSelect` — the one-click rule. No radio, no selected
67
+ * state: the frame draws none and the decision was to drop them. The SDK's
68
+ * shipped `role="radio"` + confirm is the generation BEFORE this frame.
69
+ * 3. The first row wears "Recommended", because the backend sorts best match
70
+ * first; the capture row wears "Slowest". The pills are the frame's own
71
+ * fills on Core tokens; their 12px type is the one value Core's scale
72
+ * cannot express (#RU-2).
73
+ * 4. The flag is Core's raster bank (`PrizmaCountryFlag`, 24×18), never the
74
+ * frame's emoji glyph (owner decision 2026-07-12). A country outside the
75
+ * bank falls back to the emoji the host supplies — Core's own fallback rule
76
+ * (#RU-3).
77
+ * 5. The two links ride the archetype's band: "What data will be shared?" in
78
+ * `linkLabel` (emits `secondary`) and "Incode’s Privacy Policy" in the new
79
+ * `secondaryLinkLabel` slot (emits `tertiary`) — two non-primary actions a
80
+ * host must tell apart (#PI-10), so each has its own action. The band's
81
+ * flat Spacing/16 stands between them where the frame's Button group
82
+ * tightens the pair by 8 (#RU-4).
83
+ * 6. The sheet rides the archetype's new `overlay` slot — the same contract E
84
+ * gained for Biometric Consent (#BC-8): the screen owns the scrim and the
85
+ * anchoring (the foundation's `__sheet-scrim` / `__sheet-panel`), Core owns
86
+ * the panel — `PrizmaBottomSheetContent variant="dialog"` with its H1
87
+ * title, H5 subtitle, the bullet list in `body`, and its own Button Group
88
+ * reduced to "Understood". With the sheet up the rows and links are under
89
+ * the scrim and do not report (#RU-5).
90
+ *
91
+ * The nav keeps the logo and draws no close: the frame's top-right ✕ is the
92
+ * SDK page chrome, not a Prizma screen control (GUIDELINES §3; #RU-6).
93
+ */
94
+ export declare const ReusabilityCredentialSelectionScreen: React.ForwardRefExoticComponent<ReusabilityCredentialSelectionScreenProps & React.RefAttributes<HTMLDivElement>>;
95
+ export default ReusabilityCredentialSelectionScreen;
@@ -0,0 +1,94 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { PrizmaBottomSheetContent } from '@incodetech/prizma-core-web/bottom-sheet';
5
+ import { PrizmaCountryFlag } from '@incodetech/prizma-core-web/combined';
6
+ import { PrizmaListScreen } from './ListScreen';
7
+ import './ScreenLayout.css';
8
+ import './ReusabilityLayout.css';
9
+ /** The sentinel the SDK submits for the capture row (`SCAN_NEW_DOCUMENT`,
10
+ * `identityReuseStateMachine.ts`): `{ accepted: false }`, then ID Capture. */
11
+ export const REUSABILITY_SCAN_NEW = 'scanNew';
12
+ /**
13
+ * Reusability (Incode Bridge) — choose the document to reuse, built on the
14
+ * List archetype (GUIDELINES.md §6-G, `PrizmaListScreen`).
15
+ *
16
+ * ONE screen for three of the section's four frames: `Multiple documents`
17
+ * (7877:68816) and `Single document` (7877:68875) are the same skeleton — nav →
18
+ * Title (H2 + H5) → the credential list → "Scan a new document" → two tertiary
19
+ * links → tag — differing only in how many rows the network returned; and
20
+ * `Shared data` (7877:68927) is that screen with Core's bottom sheet presented
21
+ * over it (`sharedDetails`).
22
+ *
23
+ * WHY ARCHETYPE G. The rows ARE the actions — tapping a document advances the
24
+ * session with no confirm step (consent review 2026-09-16: "remove the confirm
25
+ * button: selecting a document advances the user immediately"; the Web SDK's
26
+ * ENG-57939 built exactly that) — so there is no primary CTA, and G is the one
27
+ * archetype whose band may carry links alone. ID Capture's document chooser is
28
+ * the same shape on the same archetype.
29
+ *
30
+ * Six things are deliberate:
31
+ *
32
+ * 1. The rows are composed here from Core's tokens, not from Core's
33
+ * `PrizmaCardListVerificationOptions`. The frame calls them "Verification
34
+ * options card list", but a reusable credential has a different anatomy —
35
+ * type label + status pill, flag + masked number, verified date — and the
36
+ * capture row is one line with a pill. Core ships neither that row nor a
37
+ * plain status pill; both are proposed (DEVIATIONS #RU-1, #RU-2) and the
38
+ * rules live once in `ReusabilityLayout.css`.
39
+ * 2. Every row is a real `<button>` that emits `cta` and names its credential
40
+ * through `onCredentialSelect` — the one-click rule. No radio, no selected
41
+ * state: the frame draws none and the decision was to drop them. The SDK's
42
+ * shipped `role="radio"` + confirm is the generation BEFORE this frame.
43
+ * 3. The first row wears "Recommended", because the backend sorts best match
44
+ * first; the capture row wears "Slowest". The pills are the frame's own
45
+ * fills on Core tokens; their 12px type is the one value Core's scale
46
+ * cannot express (#RU-2).
47
+ * 4. The flag is Core's raster bank (`PrizmaCountryFlag`, 24×18), never the
48
+ * frame's emoji glyph (owner decision 2026-07-12). A country outside the
49
+ * bank falls back to the emoji the host supplies — Core's own fallback rule
50
+ * (#RU-3).
51
+ * 5. The two links ride the archetype's band: "What data will be shared?" in
52
+ * `linkLabel` (emits `secondary`) and "Incode’s Privacy Policy" in the new
53
+ * `secondaryLinkLabel` slot (emits `tertiary`) — two non-primary actions a
54
+ * host must tell apart (#PI-10), so each has its own action. The band's
55
+ * flat Spacing/16 stands between them where the frame's Button group
56
+ * tightens the pair by 8 (#RU-4).
57
+ * 6. The sheet rides the archetype's new `overlay` slot — the same contract E
58
+ * gained for Biometric Consent (#BC-8): the screen owns the scrim and the
59
+ * anchoring (the foundation's `__sheet-scrim` / `__sheet-panel`), Core owns
60
+ * the panel — `PrizmaBottomSheetContent variant="dialog"` with its H1
61
+ * title, H5 subtitle, the bullet list in `body`, and its own Button Group
62
+ * reduced to "Understood". With the sheet up the rows and links are under
63
+ * the scrim and do not report (#RU-5).
64
+ *
65
+ * The nav keeps the logo and draws no close: the frame's top-right ✕ is the
66
+ * SDK page chrome, not a Prizma screen control (GUIDELINES §3; #RU-6).
67
+ */
68
+ export const ReusabilityCredentialSelectionScreen = forwardRef(({ strings, credentials, sharedDetails = false, onCredentialSelect, screenId = sharedDetails
69
+ ? 'reusability-shared-details'
70
+ : `reusability-selection-${credentials.length > 1 ? 'multiple' : 'single'}`, overrides, onAction, ...shell }, ref) => {
71
+ const { selection, sharedDetails: shared } = strings;
72
+ const choose = (choice) => {
73
+ if (sharedDetails)
74
+ return;
75
+ onCredentialSelect?.(choice);
76
+ onAction?.({ type: 'cta', screenId });
77
+ };
78
+ const sheet = sharedDetails ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "prizma-screen-layout__sheet-scrim", "aria-hidden": "true" }), _jsx("div", { className: "prizma-screen-layout__sheet-panel", children: _jsx(PrizmaBottomSheetContent, { variant: "dialog", title: shared.title, subtitle: shared.subtitle, body: _jsx("ul", { className: "reusability-shared-list", children: shared.items.map((item) => (_jsx("li", { children: item }, item))) }), buttonGroupProps: {
79
+ primaryLabel: shared.ctaLabel,
80
+ showSecondary: false,
81
+ onPrimaryClick: () => onAction?.({ type: 'cta', screenId }),
82
+ } }) })] })) : undefined;
83
+ return (_jsx(PrizmaListScreen, { ref: ref, title: selection.title, subtitle: selection.subtitle, linkLabel: selection.sharedDataLink, secondaryLinkLabel: selection.privacyPolicyLink, verifiedLabel: strings.verifiedLabel, navLabel: strings.navLabel, screenId: screenId, overrides: overrides,
84
+ /* With the sheet up, the links are under the scrim and must not
85
+ report: the sheet's "Understood" is the only action. */
86
+ onAction: sharedDetails ? undefined : onAction, overlay: sheet, ...shell, children: _jsxs("div", { className: "reusability-credentials", role: "group", "aria-label": selection.listLabel, children: [_jsx("div", { className: "reusability-credentials__group", children: credentials.map((credential, index) => (_jsxs("button", { type: "button", className: "reusability-credential", onClick: () => choose(credential.id), tabIndex: sharedDetails ? -1 : undefined, children: [_jsxs("span", { className: "reusability-credential__head", children: [_jsx("span", { className: "reusability-credential__type", children: selection.documentType[credential.documentType] }), index === 0 ? (_jsx("span", { className: "reusability-pill reusability-pill--recommended", children: selection.recommendedTag })) : null] }), _jsxs("span", { className: "reusability-credential__number", children: [_jsx("span", { className: "reusability-credential__flag", "aria-hidden": "true", children: _jsx(PrizmaCountryFlag, { country: {
87
+ code: credential.countryCode,
88
+ name: credential.countryCode,
89
+ dialCode: '',
90
+ flag: credential.countryFlag ?? '',
91
+ } }) }), _jsx("span", { children: credential.maskedNumber })] }), _jsxs("span", { className: "reusability-credential__verified", children: [_jsx("span", { children: selection.verifiedPrefix }), " ", _jsx("span", { children: credential.verifiedOn })] })] }, credential.id))) }), _jsx("div", { className: "reusability-credentials__group", children: _jsx("button", { type: "button", className: "reusability-credential", onClick: () => choose(REUSABILITY_SCAN_NEW), tabIndex: sharedDetails ? -1 : undefined, children: _jsxs("span", { className: "reusability-credential__head", children: [_jsx("span", { className: "reusability-credential__type", children: selection.scanNewLabel }), _jsx("span", { className: "reusability-pill reusability-pill--neutral", children: selection.slowestTag })] }) }) })] }) }));
92
+ });
93
+ ReusabilityCredentialSelectionScreen.displayName = 'ReusabilityCredentialSelectionScreen';
94
+ export default ReusabilityCredentialSelectionScreen;
@@ -0,0 +1,241 @@
1
+ /* Reusability (Incode Bridge) — module layout additions.
2
+ *
3
+ * Three recipes, every value a Prizma token: the credential rows the selection
4
+ * screen lists, the bullet list inside the shared-details sheet, and the framed
5
+ * reader the privacy policy scrolls in. The content column, the 24px gutters,
6
+ * the title → list offset, the CTA band, the sheet scrim and panel and the
7
+ * anchored footer are all the foundation's (`ScreenLayout.css`); the sheet
8
+ * itself, the buttons, the title and the flag raster are Core's.
9
+ *
10
+ * WHY THE ROWS ARE COMPOSED HERE. The frame names the list "Verification
11
+ * options card list", but it is not Core's `Card / Verification options item`
12
+ * (60px card icon + title + chevron): each row is a document-type label with a
13
+ * status pill, the masked number behind a flag, and the date it was verified —
14
+ * and the last row is a single line with a pill. Core ships no card with that
15
+ * anatomy and no plain status pill (its `PrizmaCardTag` is the ⚡ Instant pill,
16
+ * with the glyph baked in). Both are built below from Core's own tokens — no
17
+ * palette, no radius, no spacing invented — and both are logged as component
18
+ * proposals (DEVIATIONS #RU-1, #RU-2). The moment Core ships them, these rules
19
+ * go and the screen imports the component.
20
+ */
21
+
22
+ /* ── The credential list ─────────────────────────────────────────────────────
23
+ * Two bordered containers, Spacing/16 apart (`options`, 7877:68823): the
24
+ * reusable documents in the first, "Scan a new document" alone in the second.
25
+ * Rows inside a container touch, each drawing a top hairline the way Core's
26
+ * verification-options rows do (`Card.css`); the container clips the corners. */
27
+ .reusability-credentials {
28
+ display: flex;
29
+ flex-direction: column;
30
+ gap: var(--prizma-spacing-16);
31
+ width: 100%;
32
+ }
33
+
34
+ .reusability-credentials__group {
35
+ display: flex;
36
+ flex-direction: column;
37
+ overflow: hidden;
38
+ box-sizing: border-box;
39
+ width: 100%;
40
+ background-color: var(--prizma-surface-neutral-0);
41
+ border: var(--prizma-border-width-regular) solid var(--prizma-border-neutral-100);
42
+ border-radius: var(--prizma-border-radius-medium);
43
+ }
44
+
45
+ /* The row IS the action — a real <button>, one tap advances (consent review
46
+ * 2026-09-16: "remove the confirm button"). Button reset, then the frame's
47
+ * Spacing/16 padding and Spacing/8 between its lines. */
48
+ .reusability-credential {
49
+ display: flex;
50
+ flex-direction: column;
51
+ align-items: stretch;
52
+ gap: var(--prizma-spacing-8);
53
+ box-sizing: border-box;
54
+ width: 100%;
55
+ margin: 0;
56
+ padding: var(--prizma-spacing-16);
57
+ background-color: var(--prizma-surface-neutral-0);
58
+ border: none;
59
+ border-top: var(--prizma-border-width-regular) solid var(--prizma-border-neutral-100);
60
+ color: var(--prizma-text-body-800-primary);
61
+ font-family: var(--prizma-body-family);
62
+ text-align: left;
63
+ cursor: pointer;
64
+ -webkit-font-smoothing: antialiased;
65
+ }
66
+
67
+ .reusability-credentials__group > .reusability-credential:first-child {
68
+ border-top: none;
69
+ }
70
+
71
+ /* Keyboard focus: Core's Button ring, so a row and the links below it light
72
+ * up the same way. Inset, because the group clips its corners. */
73
+ .reusability-credential:focus-visible {
74
+ outline: var(--prizma-button-focus-ring-width) solid var(--prizma-border-status-focus);
75
+ outline-offset: calc(-1 * var(--prizma-button-focus-ring-width));
76
+ }
77
+
78
+ /* Line 1: the document-type label, the pill at the far right. */
79
+ .reusability-credential__head {
80
+ display: flex;
81
+ align-items: center;
82
+ justify-content: space-between;
83
+ gap: var(--prizma-spacing-8);
84
+ width: 100%;
85
+ }
86
+
87
+ .reusability-credential__type {
88
+ margin: 0;
89
+ color: var(--prizma-text-body-800-primary);
90
+ font-family: var(--prizma-body-family);
91
+ font-size: var(--prizma-body-m-regular-font-size);
92
+ font-weight: var(--prizma-body-m-regular-font-weight);
93
+ line-height: var(--prizma-body-m-regular-line-height);
94
+ letter-spacing: var(--prizma-body-m-regular-letter-spacing);
95
+ }
96
+
97
+ /* Line 2: the flag and the masked number, Headline/H5. */
98
+ .reusability-credential__number {
99
+ display: flex;
100
+ align-items: center;
101
+ gap: var(--prizma-spacing-4);
102
+ margin: 0;
103
+ color: var(--prizma-text-body-800-primary);
104
+ font-family: var(--prizma-headline-family);
105
+ font-size: var(--prizma-headline-h5-font-size);
106
+ font-weight: var(--prizma-headline-h5-font-weight);
107
+ line-height: var(--prizma-headline-h5-line-height);
108
+ letter-spacing: var(--prizma-headline-h5-letter-spacing);
109
+ }
110
+
111
+ /* Core's flag raster is 24×18; the frame draws an emoji glyph at the text
112
+ * size. The raster wins (owner decision 2026-07-12: flags are images, never
113
+ * emoji) and keeps its own geometry — DEVIATIONS #RU-3. */
114
+ .reusability-credential__flag {
115
+ display: inline-flex;
116
+ flex: 0 0 auto;
117
+ align-items: center;
118
+ }
119
+
120
+ /* Line 3: "Verified Apr 2023", Body/M in the secondary ink. */
121
+ .reusability-credential__verified {
122
+ margin: 0;
123
+ color: var(--prizma-text-body-500-secondary);
124
+ font-family: var(--prizma-body-family);
125
+ font-size: var(--prizma-body-m-regular-font-size);
126
+ font-weight: var(--prizma-body-m-regular-font-weight);
127
+ line-height: var(--prizma-body-m-regular-line-height);
128
+ letter-spacing: var(--prizma-body-m-regular-letter-spacing);
129
+ }
130
+
131
+ /* ── The status pill ─────────────────────────────────────────────────────────
132
+ * "Recommended" on the best match, "Slowest" on the capture row. Surface/Brand/50
133
+ * for the first, inked with Card/Tag/Text — the mode-aware AA pair Core's own
134
+ * ⚡ pill uses (Brand.600 light · Focus.400 dark; owner call 2026-07-14), because
135
+ * the frame's Text/Accent/Brand on Brand/50 is blue on blue in dark mode;
136
+ * Surface/Neutral/50 with a Border/Neutral/200 hairline for the second — the
137
+ * frame's own fills. Radius x-small (4) and Spacing/2 × Spacing/4 padding, as
138
+ * drawn.
139
+ *
140
+ * TYPE: the frame sets the label in Body/S Regular (12px). Core's generated
141
+ * scale has no 12px text step — Body/M and Label/M are 14 — so the pill takes
142
+ * Label/M Regular, the smallest token the scale has. DEVIATIONS #RU-2. */
143
+ .reusability-pill {
144
+ display: inline-flex;
145
+ align-items: center;
146
+ flex: 0 0 auto;
147
+ padding: var(--prizma-spacing-2) var(--prizma-spacing-4);
148
+ border-radius: var(--prizma-border-radius-x-small);
149
+ font-family: var(--prizma-body-family);
150
+ font-size: var(--prizma-label-m-regular-font-size);
151
+ font-weight: var(--prizma-label-m-regular-font-weight);
152
+ line-height: var(--prizma-label-m-regular-line-height);
153
+ letter-spacing: var(--prizma-label-m-regular-letter-spacing);
154
+ white-space: nowrap;
155
+ }
156
+
157
+ .reusability-pill--recommended {
158
+ background-color: var(--prizma-surface-brand-50);
159
+ color: var(--prizma-card-tag-text);
160
+ }
161
+
162
+ .reusability-pill--neutral {
163
+ background-color: var(--prizma-surface-neutral-50);
164
+ border: var(--prizma-border-width-regular) solid var(--prizma-border-neutral-200);
165
+ color: var(--prizma-text-body-800-primary);
166
+ }
167
+
168
+ /* ── The shared-details list ─────────────────────────────────────────────────
169
+ * Inside Core's dialog sheet (`__body` slot): the recipient's data request as
170
+ * bullets, Headline/H5 in the primary ink, Spacing/8 apart, the browser's own
171
+ * disc marker on a Spacing/24 indent (`Documents list`, 7877:68985). Core's
172
+ * sheet supplies the Spacing/24 above it. */
173
+ .reusability-shared-list {
174
+ display: flex;
175
+ flex-direction: column;
176
+ gap: var(--prizma-spacing-8);
177
+ margin: 0;
178
+ padding: 0 0 0 var(--prizma-spacing-24);
179
+ color: var(--prizma-text-body-800-primary);
180
+ font-family: var(--prizma-headline-family);
181
+ font-size: var(--prizma-headline-h5-font-size);
182
+ font-weight: var(--prizma-headline-h5-font-weight);
183
+ line-height: var(--prizma-headline-h5-line-height);
184
+ letter-spacing: var(--prizma-headline-h5-letter-spacing);
185
+ text-align: left;
186
+ }
187
+
188
+ .reusability-shared-list > li {
189
+ margin: 0;
190
+ padding: 0;
191
+ }
192
+
193
+ /* ── The privacy-policy reader ───────────────────────────────────────────────
194
+ * The framed, scrolling document Qualified Signature's viewers draw
195
+ * (`.qualified-signature-document--framed`, DEVIATIONS #QS-n): a hairline
196
+ * frame on radius-small, Spacing/16 inside, Body/M prose with Spacing/12
197
+ * between paragraphs, the dateline first. The frame's `demo_5` draws the text
198
+ * unframed on a 32px gutter; the framed reader is what every document viewer
199
+ * in this package draws (owner call 2026-09-29, "take reference from other
200
+ * screens"), so it is followed here — DEVIATIONS #RU-7.
201
+ *
202
+ * FOUNDATION REQUEST: this is the SECOND module drawing the framed reader.
203
+ * Promote it to `ScreenLayout.css` as `__document` (the #DC-29 / #BC-8 idiom:
204
+ * the third consumer moves the recipe), and both module copies go. */
205
+ .reusability-document {
206
+ flex: 1 1 auto;
207
+ min-height: 0;
208
+ box-sizing: border-box;
209
+ width: 100%;
210
+ overflow-y: auto;
211
+ overscroll-behavior: contain;
212
+ padding: var(--prizma-spacing-16);
213
+ margin-bottom: var(--prizma-spacing-16);
214
+ background-color: var(--prizma-surface-neutral-0);
215
+ border: var(--prizma-border-width-regular) solid var(--prizma-border-neutral-100);
216
+ border-radius: var(--prizma-border-radius-small);
217
+ text-align: start;
218
+ }
219
+
220
+ .reusability-document > * {
221
+ margin: 0;
222
+ }
223
+
224
+ .reusability-document > * + * {
225
+ margin-top: var(--prizma-spacing-12);
226
+ }
227
+
228
+ .reusability-document__meta,
229
+ .reusability-document__prose {
230
+ color: var(--prizma-text-body-800-primary);
231
+ font-family: var(--prizma-body-family);
232
+ font-size: var(--prizma-body-m-regular-font-size);
233
+ font-weight: var(--prizma-body-m-regular-font-weight);
234
+ line-height: var(--prizma-body-m-regular-line-height);
235
+ letter-spacing: var(--prizma-body-m-regular-letter-spacing);
236
+ text-align: left;
237
+ }
238
+
239
+ .reusability-document__meta {
240
+ color: var(--prizma-text-body-500-secondary);
241
+ }
@@ -0,0 +1,55 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import { type PrizmaListScreenProps } from './ListScreen';
3
+ import type { PrizmaScreenActionHandler, PrizmaScreenOverrides } from './types';
4
+ import type { ReusabilityStrings } from './ReusabilityStrings';
5
+ import './ScreenLayout.css';
6
+ import './ReusabilityLayout.css';
7
+ export interface ReusabilityPrivacyPolicyScreenProps extends Omit<PrizmaListScreenProps, 'status' | 'title' | 'subtitle' | 'glyph' | 'children' | 'listAlign' | 'scrollList' | 'disclaimer' | 'ctaLabel' | 'secondaryCtaLabel' | 'linkLabel' | 'secondaryLinkLabel' | 'overlay' | 'verifiedLabel' | 'navLabel'> {
8
+ /** Module copy — this screen reads the `privacyPolicy` slice. */
9
+ strings: ReusabilityStrings;
10
+ /**
11
+ * The policy itself. HOST-supplied content, never module copy — the same
12
+ * slot contract Qualified Signature's document viewers use for the contract
13
+ * page (GUIDELINES §10): paragraphs in `.reusability-document__prose`, the
14
+ * dateline in `.reusability-document__meta`. The host supplies it in the
15
+ * session's language; it is legal text and is never machine translated.
16
+ */
17
+ body?: ReactNode;
18
+ screenId?: string;
19
+ overrides?: PrizmaScreenOverrides;
20
+ onAction?: PrizmaScreenActionHandler;
21
+ }
22
+ /**
23
+ * Reusability (Incode Bridge) — Incode's privacy policy, read inside the flow.
24
+ * Built on the List archetype (GUIDELINES.md §6-G), the way Qualified
25
+ * Signature's document viewers are: the `__list` middle is "content filling the
26
+ * space between the title block and the CTA band", which is what a document is,
27
+ * and the band carries one full-width button.
28
+ *
29
+ * Figma: `demo_5` (7877:68997), the frame the "Incode’s Privacy Policy" link
30
+ * opens — the Demo App's terms layout re-used: the Incode logo top-LEFT on a
31
+ * 32px gutter, "Last Modified: August 5, 2024", the policy as an unframed wall
32
+ * of Body/M text, and a raised white band with "Done".
33
+ *
34
+ * Three deltas from that frame, all the system's (DEVIATIONS #RU-7):
35
+ * 1. The nav is the archetype's — logo centred, no close — and the document
36
+ * sits on the column's 24px gutter like every screen in this package
37
+ * (GUIDELINES §3, §5). The frame's left logo and 32 gutter are the Demo
38
+ * App's chrome, not a module's.
39
+ * 2. The frame draws no heading. GUIDELINES §4 gives every screen exactly one
40
+ * H2 and G has no title-less path (the same delta QS's `viewdoc` records),
41
+ * so the screen carries the link's own label as its title.
42
+ * 3. The policy scrolls inside the framed reader every document viewer here
43
+ * draws (`.reusability-document`, the QS recipe), not unframed to the
44
+ * frame's edge; the title, the button and the tag hold still while it pans.
45
+ *
46
+ * The policy is the host's (`body`), like QS's contract page: the SDK owns no
47
+ * legal text and translates none — the host supplies the document in the
48
+ * session's language. "Done" is the frame's primary and emits `cta`: it
49
+ * closes the policy and returns to the selection, where nothing has changed. On the Web SDK this
50
+ * link opens the policy in a NEW TAB instead (`identityReuse.opensInNewTab`);
51
+ * this screen is the in-flow reading the frame draws, which is what a native
52
+ * host presents.
53
+ */
54
+ export declare const ReusabilityPrivacyPolicyScreen: React.ForwardRefExoticComponent<ReusabilityPrivacyPolicyScreenProps & React.RefAttributes<HTMLDivElement>>;
55
+ export default ReusabilityPrivacyPolicyScreen;
@@ -0,0 +1,44 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { forwardRef } from 'react';
4
+ import { PrizmaListScreen } from './ListScreen';
5
+ import './ScreenLayout.css';
6
+ import './ReusabilityLayout.css';
7
+ /**
8
+ * Reusability (Incode Bridge) — Incode's privacy policy, read inside the flow.
9
+ * Built on the List archetype (GUIDELINES.md §6-G), the way Qualified
10
+ * Signature's document viewers are: the `__list` middle is "content filling the
11
+ * space between the title block and the CTA band", which is what a document is,
12
+ * and the band carries one full-width button.
13
+ *
14
+ * Figma: `demo_5` (7877:68997), the frame the "Incode’s Privacy Policy" link
15
+ * opens — the Demo App's terms layout re-used: the Incode logo top-LEFT on a
16
+ * 32px gutter, "Last Modified: August 5, 2024", the policy as an unframed wall
17
+ * of Body/M text, and a raised white band with "Done".
18
+ *
19
+ * Three deltas from that frame, all the system's (DEVIATIONS #RU-7):
20
+ * 1. The nav is the archetype's — logo centred, no close — and the document
21
+ * sits on the column's 24px gutter like every screen in this package
22
+ * (GUIDELINES §3, §5). The frame's left logo and 32 gutter are the Demo
23
+ * App's chrome, not a module's.
24
+ * 2. The frame draws no heading. GUIDELINES §4 gives every screen exactly one
25
+ * H2 and G has no title-less path (the same delta QS's `viewdoc` records),
26
+ * so the screen carries the link's own label as its title.
27
+ * 3. The policy scrolls inside the framed reader every document viewer here
28
+ * draws (`.reusability-document`, the QS recipe), not unframed to the
29
+ * frame's edge; the title, the button and the tag hold still while it pans.
30
+ *
31
+ * The policy is the host's (`body`), like QS's contract page: the SDK owns no
32
+ * legal text and translates none — the host supplies the document in the
33
+ * session's language. "Done" is the frame's primary and emits `cta`: it
34
+ * closes the policy and returns to the selection, where nothing has changed. On the Web SDK this
35
+ * link opens the policy in a NEW TAB instead (`identityReuse.opensInNewTab`);
36
+ * this screen is the in-flow reading the frame draws, which is what a native
37
+ * host presents.
38
+ */
39
+ export const ReusabilityPrivacyPolicyScreen = forwardRef(({ strings, body, screenId = 'reusability-privacy-policy', overrides, onAction, ...shell }, ref) => {
40
+ const { privacyPolicy } = strings;
41
+ return (_jsx(PrizmaListScreen, { ref: ref, title: privacyPolicy.title, ctaLabel: privacyPolicy.ctaLabel, verifiedLabel: strings.verifiedLabel, navLabel: strings.navLabel, screenId: screenId, overrides: overrides, onAction: onAction, ...shell, children: _jsx("div", { className: "reusability-document", role: "region", "aria-label": privacyPolicy.title, tabIndex: 0, children: body }) }));
42
+ });
43
+ ReusabilityPrivacyPolicyScreen.displayName = 'ReusabilityPrivacyPolicyScreen';
44
+ export default ReusabilityPrivacyPolicyScreen;