@smileid/web-components 11.4.5 → 11.6.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/esm/DocumentCaptureScreens-DjSTdVP-.js +5398 -0
- package/dist/esm/DocumentCaptureScreens-DjSTdVP-.js.map +1 -0
- package/dist/esm/{Navigation-Bb7MPLE8.js → Navigation-6DH3vF4-.js} +28 -22
- package/dist/esm/Navigation-6DH3vF4-.js.map +1 -0
- package/dist/esm/{PoweredBySmileId-CxbaihMu.js → PoweredBySmileId-DoKwoPUd.js} +424 -6
- package/dist/esm/PoweredBySmileId-DoKwoPUd.js.map +1 -0
- package/dist/esm/SelfieCaptureScreens-CtX-4Tco.js +11470 -0
- package/dist/esm/SelfieCaptureScreens-CtX-4Tco.js.map +1 -0
- package/dist/esm/combobox.js +1 -1
- package/dist/esm/document.js +1 -1
- package/dist/esm/end-user-consent.js +713 -2
- package/dist/esm/end-user-consent.js.map +1 -1
- package/dist/esm/index-BqyuTk9f.js +1366 -0
- package/dist/esm/{index-C4RTMbgw.js.map → index-BqyuTk9f.js.map} +1 -1
- package/dist/esm/localisation.js +1 -1
- package/dist/esm/main.js +14 -14
- package/dist/esm/navigation.js +1 -1
- package/dist/esm/package-CjZI-cNQ.js +2540 -0
- package/dist/esm/package-CjZI-cNQ.js.map +1 -0
- package/dist/esm/selfie.js +1 -1
- package/dist/esm/smart-camera-web.js +81 -37
- package/dist/esm/smart-camera-web.js.map +1 -1
- package/dist/esm/totp-consent.js +731 -2
- package/dist/esm/totp-consent.js.map +1 -1
- package/dist/esm/validate.js +31 -0
- package/dist/esm/validate.js.map +1 -0
- package/dist/smart-camera-web.js +1513 -383
- package/dist/smart-camera-web.js.map +1 -1
- package/dist/types/main.d.ts +18 -1
- package/dist/types/validate.d.ts +21 -0
- package/lib/components/document/src/DocumentCaptureScreens.js +97 -18
- package/lib/components/document/src/assets/lottie.d.ts +12 -0
- package/lib/components/document/src/assets/svg-inline.d.ts +8 -0
- package/lib/components/document/src/document-auto-capture/DocumentAutoCapture.stories.js +75 -0
- package/lib/components/document/src/document-auto-capture/DocumentAutoCapture.tsx +1458 -0
- package/lib/components/document/src/document-auto-capture/README.md +73 -0
- package/lib/components/document/src/document-auto-capture/assets/Greenbook_Shimmer.svg +42 -0
- package/lib/components/document/src/document-auto-capture/assets/ID_Back_Shimmer.svg +8 -0
- package/lib/components/document/src/document-auto-capture/assets/ID_Front_Shimmer.svg +20 -0
- package/lib/components/document/src/document-auto-capture/assets/Passport-Shimmer.svg +143 -0
- package/lib/components/document/src/document-auto-capture/assets/shimmers.ts +21 -0
- package/lib/components/document/src/document-auto-capture/assets/svg-raw.d.ts +4 -0
- package/lib/components/document/src/document-auto-capture/components/CaptureButton.tsx +122 -0
- package/lib/components/document/src/document-auto-capture/components/Overlay.tsx +167 -0
- package/lib/components/document/src/document-auto-capture/components/TuningPanel.tsx +856 -0
- package/lib/components/document/src/document-auto-capture/constants/captureLayout.ts +58 -0
- package/lib/components/document/src/document-auto-capture/detection/cvErrorRecovery.ts +40 -0
- package/lib/components/document/src/document-auto-capture/detection/documentAspect.ts +20 -0
- package/lib/components/document/src/document-auto-capture/detection/qualityScoring.ts +35 -0
- package/lib/components/document/src/document-auto-capture/detection/seamRejection.ts +209 -0
- package/lib/components/document/src/document-auto-capture/detection/synthesisTiming.ts +10 -0
- package/lib/components/document/src/document-auto-capture/hooks/useCamera.ts +117 -0
- package/lib/components/document/src/document-auto-capture/hooks/useCardDetection.ts +3059 -0
- package/lib/components/document/src/document-auto-capture/index.ts +4 -0
- package/lib/components/document/src/document-auto-capture/theme.ts +40 -0
- package/lib/components/document/src/document-auto-capture/utils/debug.ts +25 -0
- package/lib/components/document/src/document-auto-capture/utils/opencvLoader.ts +86 -0
- package/lib/components/document/src/document-capture-instructions/DocumentCaptureInstructions.tsx +327 -244
- package/lib/components/document/src/document-capture-review/DocumentCaptureReview.js +153 -189
- package/lib/components/document/src/document-capture-submission/DocumentCaptureSubmission.tsx +432 -0
- package/lib/components/document/src/document-capture-submission/index.js +3 -0
- package/lib/components/navigation/src/Navigation.js +27 -8
- package/lib/components/selfie/README.md +13 -0
- package/lib/components/selfie/src/SelfieCaptureScreens.js +56 -8
- package/lib/components/selfie/src/enhanced-smartselfie-capture/EnhancedSmartSelfieCapture.tsx +684 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/EnhancedSmartSelfieConsent.tsx +71 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/EnhancedSmartSelfieSubmission.tsx +181 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/OvalProgress.tsx +87 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/Icon.svg +8 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/accessories.svg +77 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/active_liveness_animation.lottie +0 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/device.svg +12 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/device_orientation.lottie +0 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/good.svg +52 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/id-card.svg +9 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/illustrations.tsx +852 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/instructions-img.svg +3 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/multiple-faces.svg +69 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/person.svg +6 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/phone.svg +8 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/poor-lighting.svg +53 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/assets/too_dark_animation.lottie +0 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/ActiveLivenessOverlay.tsx +226 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/AlertDisplay.tsx +38 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/BackNavigation.tsx +45 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/CameraPreview.tsx +96 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/CaptureControls.tsx +97 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/CaptureGuidelines.tsx +374 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/ConsentView.tsx +460 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/SubmissionView.tsx +426 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/components/index.ts +3 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/constants.ts +23 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/hooks/index.ts +2 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/hooks/useCamera.ts +238 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/hooks/useFaceCapture.ts +1075 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/index.ts +1 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/alertMessages.ts +20 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/canvas.ts +108 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/faceDetection.ts +545 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/imageCapture.ts +66 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/imageQuality.ts +151 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/index.ts +5 -0
- package/lib/components/selfie/src/enhanced-smartselfie-capture/utils/mediapipeManager.ts +215 -0
- package/lib/components/selfie/src/selfie-capture-wrapper/SelfieCaptureWrapper.tsx +24 -1
- package/lib/components/selfie/src/smartselfie-capture/SmartSelfieCapture.tsx +2 -2
- package/lib/components/selfie/src/smartselfie-capture/hooks/useFaceCapture.ts +15 -7
- package/lib/components/selfie/src/smartselfie-capture/utils/canvas.ts +4 -6
- package/lib/components/signature-pad/package.json +1 -1
- package/lib/components/smart-camera-web/src/README.md +11 -0
- package/lib/components/smart-camera-web/src/SmartCameraWeb.js +89 -8
- package/lib/components/totp-consent/src/TotpConsent.js +1 -1
- package/lib/domain/localisation/index.js +2 -2
- package/package.json +9 -5
- package/dist/esm/DocumentCaptureScreens-D2G0NOQr.js +0 -4147
- package/dist/esm/DocumentCaptureScreens-D2G0NOQr.js.map +0 -1
- package/dist/esm/EndUserConsent-uHfA3txP.js +0 -717
- package/dist/esm/EndUserConsent-uHfA3txP.js.map +0 -1
- package/dist/esm/Navigation-Bb7MPLE8.js.map +0 -1
- package/dist/esm/PoweredBySmileId-CxbaihMu.js.map +0 -1
- package/dist/esm/SelfieCaptureScreens-Dr7VzON7.js +0 -7651
- package/dist/esm/SelfieCaptureScreens-Dr7VzON7.js.map +0 -1
- package/dist/esm/TotpConsent-Depzg0ti.js +0 -734
- package/dist/esm/TotpConsent-Depzg0ti.js.map +0 -1
- package/dist/esm/index-C4RTMbgw.js +0 -1360
- package/dist/esm/package-D6YrpMcO.js +0 -565
- package/dist/esm/package-D6YrpMcO.js.map +0 -1
- package/dist/esm/styles-BTEClL7R.js +0 -419
- package/dist/esm/styles-BTEClL7R.js.map +0 -1
- /package/lib/components/document/src/assets/lottie/{taking photo of green book passport.lottie → greenbook.lottie} +0 -0
- /package/lib/components/document/src/assets/lottie/{taking photo of ID FLIP 2D.lottie → id-card-flip.lottie} +0 -0
- /package/lib/components/document/src/assets/lottie/{taking photo of ID.lottie → id-card.lottie} +0 -0
- /package/lib/components/document/src/assets/lottie/{taking photo of passport 2.lottie → passport.lottie} +0 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
import type { FunctionComponent } from 'preact';
|
|
2
|
+
import { useState } from 'preact/hooks';
|
|
3
|
+
import { t } from '../../../../../domain/localisation';
|
|
4
|
+
import {
|
|
5
|
+
SmileIdLogo,
|
|
6
|
+
CheckIcon,
|
|
7
|
+
ChevronDownIcon,
|
|
8
|
+
} from '../assets/illustrations';
|
|
9
|
+
|
|
10
|
+
// Icon URLs — Vite resolves these to URL strings via the `*.svg` ambient
|
|
11
|
+
// module declaration in lib/types.d.ts.
|
|
12
|
+
// eslint-disable-next-line import/no-unresolved
|
|
13
|
+
import phoneIcon from '../assets/phone.svg';
|
|
14
|
+
// eslint-disable-next-line import/no-unresolved
|
|
15
|
+
import personIcon from '../assets/person.svg';
|
|
16
|
+
// eslint-disable-next-line import/no-unresolved
|
|
17
|
+
import idCardIcon from '../assets/id-card.svg';
|
|
18
|
+
// eslint-disable-next-line import/no-unresolved
|
|
19
|
+
import deviceIcon from '../assets/device.svg';
|
|
20
|
+
|
|
21
|
+
interface ConsentViewProps {
|
|
22
|
+
themeColor: string;
|
|
23
|
+
hideAttribution: boolean;
|
|
24
|
+
partnerName?: string;
|
|
25
|
+
partnerLogo?: string;
|
|
26
|
+
policyUrl?: string;
|
|
27
|
+
onGranted: () => void;
|
|
28
|
+
onDenied: () => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const ITEMS: { icon: string; key: string }[] = [
|
|
32
|
+
{ icon: phoneIcon, key: 'selfie.ess.consent.items.contact' },
|
|
33
|
+
{ icon: personIcon, key: 'selfie.ess.consent.items.personal' },
|
|
34
|
+
{ icon: idCardIcon, key: 'selfie.ess.consent.items.biometric' },
|
|
35
|
+
{ icon: deviceIcon, key: 'selfie.ess.consent.items.device' },
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Returns the input only if it is a syntactically valid absolute URL whose
|
|
40
|
+
* protocol is `http:` or `https:`. Anything else (including `javascript:`,
|
|
41
|
+
* `data:`, malformed strings, or non-strings) is rejected. This prevents a
|
|
42
|
+
* malicious partner config from injecting an XSS vector through props that
|
|
43
|
+
* are rendered as `href`/`src`.
|
|
44
|
+
*/
|
|
45
|
+
const safeHttpUrl = (value?: string): string | undefined => {
|
|
46
|
+
if (typeof value !== 'string' || value.length === 0) return undefined;
|
|
47
|
+
try {
|
|
48
|
+
const parsed = new URL(value);
|
|
49
|
+
if (parsed.protocol === 'https:' || parsed.protocol === 'http:') {
|
|
50
|
+
return parsed.toString();
|
|
51
|
+
}
|
|
52
|
+
} catch {
|
|
53
|
+
/* fall through */
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Strict-mode consent screen rendered as the first step of the Enhanced
|
|
60
|
+
* SmartSelfie flow. Purpose-built for ESS and intentionally separate from the
|
|
61
|
+
* legacy `<end-user-consent>` element used by KYC products — modifying that
|
|
62
|
+
* element would change behaviour for every other product.
|
|
63
|
+
*/
|
|
64
|
+
export const ConsentView: FunctionComponent<ConsentViewProps> = ({
|
|
65
|
+
themeColor,
|
|
66
|
+
hideAttribution,
|
|
67
|
+
partnerName,
|
|
68
|
+
partnerLogo,
|
|
69
|
+
policyUrl,
|
|
70
|
+
onGranted,
|
|
71
|
+
onDenied,
|
|
72
|
+
}) => {
|
|
73
|
+
const [accepted, setAccepted] = useState(false);
|
|
74
|
+
const [learnMoreOpen, setLearnMoreOpen] = useState(false);
|
|
75
|
+
const partner = partnerName;
|
|
76
|
+
const safePolicyUrl = safeHttpUrl(policyUrl);
|
|
77
|
+
const safePartnerLogo = safeHttpUrl(partnerLogo);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<div className="ess-consent">
|
|
81
|
+
<div className="logos">
|
|
82
|
+
{safePartnerLogo && (
|
|
83
|
+
<img className="partner-logo" src={safePartnerLogo} alt={partner} />
|
|
84
|
+
)}
|
|
85
|
+
<div className="smile-logo" aria-hidden="true">
|
|
86
|
+
<SmileIdLogo />
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<h1 className="title">
|
|
91
|
+
{partner} {t('selfie.ess.consent.titleSuffix')}{' '}
|
|
92
|
+
<span style={{ whiteSpace: 'nowrap' }}>Smile ID.</span>
|
|
93
|
+
</h1>
|
|
94
|
+
|
|
95
|
+
<p className="body">
|
|
96
|
+
{t('selfie.ess.consent.bodyPrefix')}
|
|
97
|
+
<strong>Smile ID</strong>
|
|
98
|
+
{t('selfie.ess.consent.bodyMiddle')}
|
|
99
|
+
<strong>{partner}</strong>
|
|
100
|
+
{t('selfie.ess.consent.bodySuffix')}
|
|
101
|
+
</p>
|
|
102
|
+
|
|
103
|
+
<ul className="items">
|
|
104
|
+
{ITEMS.map((it) => (
|
|
105
|
+
<li key={it.key}>
|
|
106
|
+
<img src={it.icon} alt="" aria-hidden="true" />
|
|
107
|
+
<span>{t(it.key)}</span>
|
|
108
|
+
</li>
|
|
109
|
+
))}
|
|
110
|
+
</ul>
|
|
111
|
+
|
|
112
|
+
<label className="checkbox">
|
|
113
|
+
<input
|
|
114
|
+
type="checkbox"
|
|
115
|
+
checked={accepted}
|
|
116
|
+
onChange={(e) => setAccepted((e.target as HTMLInputElement).checked)}
|
|
117
|
+
/>
|
|
118
|
+
<span className="box" aria-hidden="true">
|
|
119
|
+
<CheckIcon />
|
|
120
|
+
</span>
|
|
121
|
+
<span className="copy">{t('selfie.ess.consent.consentCheckbox')}</span>
|
|
122
|
+
</label>
|
|
123
|
+
|
|
124
|
+
<button
|
|
125
|
+
type="button"
|
|
126
|
+
className="learn-more"
|
|
127
|
+
onClick={() => setLearnMoreOpen((v) => !v)}
|
|
128
|
+
aria-expanded={learnMoreOpen}
|
|
129
|
+
>
|
|
130
|
+
<span className="chevron" data-open={learnMoreOpen} aria-hidden="true">
|
|
131
|
+
<ChevronDownIcon />
|
|
132
|
+
</span>
|
|
133
|
+
<span>{t('selfie.ess.consent.learnMore')}</span>
|
|
134
|
+
</button>
|
|
135
|
+
|
|
136
|
+
{learnMoreOpen && (
|
|
137
|
+
<p className="learn-more-copy">
|
|
138
|
+
{t('selfie.ess.consent.learnMoreBodyPrefix')}
|
|
139
|
+
<strong>Smile ID</strong>
|
|
140
|
+
{t('selfie.ess.consent.learnMoreBodyAnd')}
|
|
141
|
+
<strong>{partner}</strong>
|
|
142
|
+
{t('selfie.ess.consent.learnMoreBodySuffix')}
|
|
143
|
+
<br />
|
|
144
|
+
{t('selfie.ess.consent.learnMoreShare')}
|
|
145
|
+
<br />
|
|
146
|
+
{t('selfie.ess.consent.learnMoreRightsPrefix')}{' '}
|
|
147
|
+
<a
|
|
148
|
+
href="https://dsar.usesmileid.com"
|
|
149
|
+
target="_blank"
|
|
150
|
+
rel="noopener noreferrer"
|
|
151
|
+
style={{ color: themeColor }}
|
|
152
|
+
>
|
|
153
|
+
{t('selfie.ess.consent.dsarLink')}
|
|
154
|
+
</a>{' '}
|
|
155
|
+
{t('selfie.ess.consent.learnMoreRightsMiddle')}{' '}
|
|
156
|
+
<a
|
|
157
|
+
href="https://usesmileid.com/legal/privacy-policy/"
|
|
158
|
+
target="_blank"
|
|
159
|
+
rel="noopener noreferrer"
|
|
160
|
+
style={{ color: themeColor }}
|
|
161
|
+
>
|
|
162
|
+
Smile ID
|
|
163
|
+
</a>
|
|
164
|
+
{safePolicyUrl ? (
|
|
165
|
+
<>
|
|
166
|
+
{' '}
|
|
167
|
+
{t('selfie.ess.consent.partnerPrivacyTailLinked')}{' '}
|
|
168
|
+
<a
|
|
169
|
+
href={safePolicyUrl}
|
|
170
|
+
target="_blank"
|
|
171
|
+
rel="noopener noreferrer"
|
|
172
|
+
style={{ color: themeColor }}
|
|
173
|
+
>
|
|
174
|
+
{partner}
|
|
175
|
+
</a>{' '}
|
|
176
|
+
{t('selfie.ess.consent.partnerPrivacyTailEnd')}
|
|
177
|
+
</>
|
|
178
|
+
) : (
|
|
179
|
+
<>
|
|
180
|
+
{' '}
|
|
181
|
+
{t('selfie.ess.consent.partnerPrivacyTailLinked')}{' '}
|
|
182
|
+
<strong>{partner}</strong>{' '}
|
|
183
|
+
{t('selfie.ess.consent.partnerPrivacyTailEnd')}
|
|
184
|
+
</>
|
|
185
|
+
)}
|
|
186
|
+
</p>
|
|
187
|
+
)}
|
|
188
|
+
|
|
189
|
+
<div className="actions">
|
|
190
|
+
<button
|
|
191
|
+
type="button"
|
|
192
|
+
className="allow"
|
|
193
|
+
style={{ background: themeColor, borderColor: themeColor }}
|
|
194
|
+
disabled={!accepted}
|
|
195
|
+
onClick={onGranted}
|
|
196
|
+
>
|
|
197
|
+
{t('selfie.ess.consent.allow')}
|
|
198
|
+
</button>
|
|
199
|
+
<button
|
|
200
|
+
type="button"
|
|
201
|
+
className="deny"
|
|
202
|
+
style={{ color: themeColor, borderColor: themeColor }}
|
|
203
|
+
onClick={onDenied}
|
|
204
|
+
>
|
|
205
|
+
{t('selfie.ess.consent.deny')}
|
|
206
|
+
</button>
|
|
207
|
+
</div>
|
|
208
|
+
|
|
209
|
+
{!hideAttribution && (
|
|
210
|
+
// @ts-expect-error preact-custom-element types
|
|
211
|
+
<powered-by-smile-id />
|
|
212
|
+
)}
|
|
213
|
+
|
|
214
|
+
<style>{`
|
|
215
|
+
:host { display: block; height: 100%; }
|
|
216
|
+
.ess-consent {
|
|
217
|
+
display: flex;
|
|
218
|
+
flex-direction: column;
|
|
219
|
+
min-height: 100%;
|
|
220
|
+
padding: clamp(0.75rem, 2.5dvh, 1.5rem) clamp(1rem, 4vw, 1.25rem) clamp(0.5rem, 1.5dvh, 0.5rem);
|
|
221
|
+
font-family: "DM Sans", system-ui, sans-serif;
|
|
222
|
+
background: #F5F7FA;
|
|
223
|
+
color: #1A1A1A;
|
|
224
|
+
box-sizing: border-box;
|
|
225
|
+
}
|
|
226
|
+
.ess-consent > powered-by-smile-id {
|
|
227
|
+
display: block;
|
|
228
|
+
width: 100%;
|
|
229
|
+
padding-top: clamp(0.5rem, 1.5dvh, 1rem);
|
|
230
|
+
background: #F5F7FA;
|
|
231
|
+
flex-shrink: 0;
|
|
232
|
+
}
|
|
233
|
+
.logos {
|
|
234
|
+
display: flex;
|
|
235
|
+
align-items: center;
|
|
236
|
+
justify-content: center;
|
|
237
|
+
margin-top: clamp(0.5rem, 1.5dvh, 1.25rem);
|
|
238
|
+
margin-bottom: clamp(0.75rem, 2.25dvh, 1.75rem);
|
|
239
|
+
flex-shrink: 0;
|
|
240
|
+
}
|
|
241
|
+
.partner-logo {
|
|
242
|
+
width: 40px;
|
|
243
|
+
height: 40px;
|
|
244
|
+
border-radius: 50%;
|
|
245
|
+
object-fit: cover;
|
|
246
|
+
background: #F9F0E7CC;
|
|
247
|
+
border: 2px solid #F9F0E7CC;
|
|
248
|
+
box-shadow: 0 2px 6px rgba(0,0,0,0.08);
|
|
249
|
+
position: relative;
|
|
250
|
+
z-index: 2;
|
|
251
|
+
}
|
|
252
|
+
.smile-logo {
|
|
253
|
+
width: 40px;
|
|
254
|
+
height: 40px;
|
|
255
|
+
border-radius: 50%;
|
|
256
|
+
background: #F9F0E7CC;
|
|
257
|
+
border: 2px solid #F9F0E7CC;
|
|
258
|
+
box-shadow: 0 2px 6px rgba(0,0,0,0.08);
|
|
259
|
+
display: inline-flex;
|
|
260
|
+
align-items: center;
|
|
261
|
+
justify-content: center;
|
|
262
|
+
margin-left: -5px;
|
|
263
|
+
z-index: 1;
|
|
264
|
+
}
|
|
265
|
+
.smile-logo svg { display: block; }
|
|
266
|
+
.title {
|
|
267
|
+
font-family: "DM Sans", system-ui, sans-serif;
|
|
268
|
+
font-size: clamp(15px, 2.2dvh, 18px);
|
|
269
|
+
font-weight: 600;
|
|
270
|
+
line-height: 1.25;
|
|
271
|
+
text-align: center;
|
|
272
|
+
color: #21232C;
|
|
273
|
+
margin: 0 0 clamp(0.5rem, 1.2dvh, 1rem);
|
|
274
|
+
flex-shrink: 0;
|
|
275
|
+
}
|
|
276
|
+
.body {
|
|
277
|
+
color: #5E646E;
|
|
278
|
+
text-align: justify;
|
|
279
|
+
font-family: "DM Sans", system-ui, sans-serif;
|
|
280
|
+
font-size: clamp(11px, 1.5dvh, 12px);
|
|
281
|
+
font-style: normal;
|
|
282
|
+
font-weight: 400;
|
|
283
|
+
line-height: 1.35;
|
|
284
|
+
margin: 0 0 clamp(0.5rem, 1.2dvh, 1rem);
|
|
285
|
+
flex-shrink: 0;
|
|
286
|
+
}
|
|
287
|
+
.body strong {
|
|
288
|
+
color: #5E646E;
|
|
289
|
+
font-family: "DM Sans", system-ui, sans-serif;
|
|
290
|
+
font-size: 12px;
|
|
291
|
+
font-style: normal;
|
|
292
|
+
font-weight: 700;
|
|
293
|
+
line-height: normal;
|
|
294
|
+
}
|
|
295
|
+
.items {
|
|
296
|
+
list-style: none;
|
|
297
|
+
padding: 0;
|
|
298
|
+
margin: 0 0 clamp(0.5rem, 1.2dvh, 1rem);
|
|
299
|
+
display: flex;
|
|
300
|
+
flex-direction: column;
|
|
301
|
+
gap: clamp(6px, 1.4dvh, 16px);
|
|
302
|
+
flex-shrink: 0;
|
|
303
|
+
}
|
|
304
|
+
.items li {
|
|
305
|
+
display: flex;
|
|
306
|
+
align-items: center;
|
|
307
|
+
gap: 0.85rem;
|
|
308
|
+
color: #21232C;
|
|
309
|
+
font-family: "DM Sans", system-ui, sans-serif;
|
|
310
|
+
font-size: clamp(11px, 1.5dvh, 12px);
|
|
311
|
+
font-style: normal;
|
|
312
|
+
font-weight: 400;
|
|
313
|
+
line-height: 1.35;
|
|
314
|
+
}
|
|
315
|
+
.items img {
|
|
316
|
+
width: clamp(22px, 3.4dvh, 28px);
|
|
317
|
+
height: clamp(22px, 3.4dvh, 28px);
|
|
318
|
+
flex-shrink: 0;
|
|
319
|
+
object-fit: contain;
|
|
320
|
+
object-position: left center;
|
|
321
|
+
}
|
|
322
|
+
.checkbox {
|
|
323
|
+
display: flex;
|
|
324
|
+
align-items: flex-start;
|
|
325
|
+
/* gap = items gap (0.85rem) + half the width difference between an
|
|
326
|
+
items icon (28px) and the 20px checkbox so the trailing text
|
|
327
|
+
column lines up with the text above. */
|
|
328
|
+
gap: calc(0.85rem + 4px);
|
|
329
|
+
margin-bottom: clamp(0.4rem, 1dvh, 0.75rem);
|
|
330
|
+
cursor: pointer;
|
|
331
|
+
flex-shrink: 0;
|
|
332
|
+
}
|
|
333
|
+
.checkbox input { position: absolute; opacity: 0; pointer-events: none; }
|
|
334
|
+
.checkbox .box {
|
|
335
|
+
width: 20px;
|
|
336
|
+
height: 20px;
|
|
337
|
+
/* Center the 20px box within the 28px icon lane used by .items img
|
|
338
|
+
so the icon column visually aligns with those above. */
|
|
339
|
+
margin-left: 4px;
|
|
340
|
+
border-radius: 4px;
|
|
341
|
+
background: transparent;
|
|
342
|
+
border: 1.5px solid #2D2B2A;
|
|
343
|
+
color: #F9F0E7;
|
|
344
|
+
flex-shrink: 0;
|
|
345
|
+
display: inline-flex;
|
|
346
|
+
align-items: center;
|
|
347
|
+
justify-content: center;
|
|
348
|
+
box-sizing: border-box;
|
|
349
|
+
transition: background 120ms ease, border-color 120ms ease;
|
|
350
|
+
}
|
|
351
|
+
.checkbox .box svg { display: block; opacity: 0; transition: opacity 120ms ease; }
|
|
352
|
+
.checkbox input:checked + .box {
|
|
353
|
+
background: #2D2B2A;
|
|
354
|
+
border-color: #2D2B2A;
|
|
355
|
+
}
|
|
356
|
+
.checkbox input:checked + .box svg { opacity: 1; }
|
|
357
|
+
.checkbox .copy {
|
|
358
|
+
color: #5E646E;
|
|
359
|
+
text-align: justify;
|
|
360
|
+
font-family: "DM Sans", system-ui, sans-serif;
|
|
361
|
+
font-size: clamp(11px, 1.5dvh, 12px);
|
|
362
|
+
font-style: normal;
|
|
363
|
+
font-weight: 400;
|
|
364
|
+
line-height: 1.35;
|
|
365
|
+
}
|
|
366
|
+
.learn-more {
|
|
367
|
+
display: inline-flex;
|
|
368
|
+
align-items: center;
|
|
369
|
+
/* Match the checkbox/items icon column so trailing text aligns. */
|
|
370
|
+
gap: calc(0.85rem + 4px);
|
|
371
|
+
background: transparent;
|
|
372
|
+
border: none;
|
|
373
|
+
padding: 0;
|
|
374
|
+
color: #21232C;
|
|
375
|
+
font-family: "DM Sans", system-ui, sans-serif;
|
|
376
|
+
font-size: clamp(11px, 1.5dvh, 12px);
|
|
377
|
+
font-style: normal;
|
|
378
|
+
font-weight: 700;
|
|
379
|
+
line-height: normal;
|
|
380
|
+
cursor: pointer;
|
|
381
|
+
margin-bottom: clamp(0.3rem, 0.8dvh, 0.5rem);
|
|
382
|
+
flex-shrink: 0;
|
|
383
|
+
}
|
|
384
|
+
.learn-more .chevron {
|
|
385
|
+
width: 20px;
|
|
386
|
+
height: 20px;
|
|
387
|
+
/* Center the 20px chevron within the 28px icon lane to align with
|
|
388
|
+
the icons above. */
|
|
389
|
+
margin-left: 4px;
|
|
390
|
+
border-radius: 50%;
|
|
391
|
+
background: #2D2B2A;
|
|
392
|
+
color: #F9F0E7;
|
|
393
|
+
display: inline-flex;
|
|
394
|
+
align-items: center;
|
|
395
|
+
justify-content: center;
|
|
396
|
+
transition: transform 150ms ease;
|
|
397
|
+
flex-shrink: 0;
|
|
398
|
+
}
|
|
399
|
+
.learn-more .chevron[data-open="true"] { transform: rotate(180deg); }
|
|
400
|
+
.learn-more-copy {
|
|
401
|
+
color: #5E646E;
|
|
402
|
+
text-align: justify;
|
|
403
|
+
font-family: "DM Sans", system-ui, sans-serif;
|
|
404
|
+
font-size: clamp(11px, 1.5dvh, 12px);
|
|
405
|
+
font-style: normal;
|
|
406
|
+
font-weight: 400;
|
|
407
|
+
line-height: 1.35;
|
|
408
|
+
margin: 0 0 0.5rem;
|
|
409
|
+
flex-shrink: 1;
|
|
410
|
+
overflow: hidden;
|
|
411
|
+
}
|
|
412
|
+
.learn-more-copy strong {
|
|
413
|
+
color: #5E646E;
|
|
414
|
+
font-family: "DM Sans", system-ui, sans-serif;
|
|
415
|
+
font-size: 12px;
|
|
416
|
+
font-style: normal;
|
|
417
|
+
font-weight: 700;
|
|
418
|
+
line-height: normal;
|
|
419
|
+
}
|
|
420
|
+
.actions {
|
|
421
|
+
display: flex;
|
|
422
|
+
flex-direction: column;
|
|
423
|
+
gap: clamp(0.4rem, 1dvh, 0.75rem);
|
|
424
|
+
align-items: stretch;
|
|
425
|
+
padding-top: clamp(0.5rem, 1.5dvh, 1.5rem);
|
|
426
|
+
flex-shrink: 0;
|
|
427
|
+
}
|
|
428
|
+
.allow {
|
|
429
|
+
width: 100%;
|
|
430
|
+
height: clamp(40px, 6dvh, 48px);
|
|
431
|
+
padding: 0 1rem;
|
|
432
|
+
border-radius: 24px;
|
|
433
|
+
border: 1px solid;
|
|
434
|
+
color: white;
|
|
435
|
+
font-size: clamp(0.95rem, 1.8dvh, 1.05rem);
|
|
436
|
+
font-weight: 600;
|
|
437
|
+
font-family: inherit;
|
|
438
|
+
cursor: pointer;
|
|
439
|
+
box-shadow: 0 1px 2px 0 rgba(16, 24, 40, 0.05);
|
|
440
|
+
}
|
|
441
|
+
.allow:disabled { opacity: 0.45; cursor: not-allowed; }
|
|
442
|
+
.deny {
|
|
443
|
+
width: 100%;
|
|
444
|
+
height: clamp(40px, 6dvh, 48px);
|
|
445
|
+
padding: 0 1rem;
|
|
446
|
+
background: transparent;
|
|
447
|
+
border: 1px solid;
|
|
448
|
+
border-radius: 24px;
|
|
449
|
+
font-size: clamp(0.95rem, 1.8dvh, 1.05rem);
|
|
450
|
+
font-weight: 600;
|
|
451
|
+
font-family: inherit;
|
|
452
|
+
cursor: pointer;
|
|
453
|
+
box-shadow: 0 1px 2px 0 rgba(16, 24, 40, 0.05);
|
|
454
|
+
}
|
|
455
|
+
`}</style>
|
|
456
|
+
</div>
|
|
457
|
+
);
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
export default ConsentView;
|