@visns-studio/visns-components 6.6.3 → 6.15.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/README.md +1658 -18
- package/package.json +10 -4
- package/src/components/DataGrid.jsx +619 -158
- package/src/components/Fetch.jsx +80 -3
- package/src/components/Form.jsx +9 -0
- package/src/components/Navigation.jsx +109 -50
- package/src/components/Notification.jsx +279 -9
- package/src/components/TableFilter.jsx +14 -1
- package/src/components/auth/AuthBrandPanel.jsx +43 -0
- package/src/components/auth/AuthLoading.jsx +78 -0
- package/src/components/auth/AuthShell.jsx +59 -0
- package/src/components/auth/ClientAuth.jsx +161 -0
- package/src/components/auth/ClientAuthFrame.jsx +59 -0
- package/src/components/auth/ClientLogin.jsx +266 -55
- package/src/components/auth/ClientOTPVerify.jsx +587 -115
- package/src/components/auth/ImpersonateGate.jsx +254 -0
- package/src/components/auth/Login.jsx +134 -41
- package/src/components/auth/LogoutScreen.jsx +112 -0
- package/src/components/auth/Reset.jsx +134 -77
- package/src/components/auth/TwoFactorAuth.jsx +475 -297
- package/src/components/auth/Verify.jsx +237 -126
- package/src/components/auth/authEndpoints.js +105 -0
- package/src/components/auth/authFont.js +23 -0
- package/src/components/auth/authHelpers.js +465 -0
- package/src/components/auth/clientAuthProtocols.js +240 -0
- package/src/components/auth/useOptionalRouter.js +49 -0
- package/src/components/callQueue/CallQueuePop.jsx +1502 -0
- package/src/components/callQueue/CallQueueSettings.jsx +508 -0
- package/src/components/callQueue/callQueueHelpers.js +280 -0
- package/src/components/callQueue/callQueueSettingsHelpers.js +75 -0
- package/src/components/columns/AutoGrowCell.jsx +141 -0
- package/src/components/columns/ColumnRenderers.jsx +53 -7
- package/src/components/generic/GenericAuth.jsx +163 -96
- package/src/components/generic/GenericDetail.jsx +215 -90
- package/src/components/generic/GenericIndex.jsx +20 -47
- package/src/components/generic/GenericMain.jsx +5 -0
- package/src/components/generic/GroupedReportRenderer.jsx +1 -5
- package/src/components/generic/StandardModal.jsx +17 -5
- package/src/components/generic/reportSemanticSteps/SemanticEntityStep.jsx +1 -6
- package/src/components/generic/reportSemanticSteps/SemanticFieldsStep.jsx +4 -11
- package/src/components/generic/reportSemanticSteps/SemanticFiltersStep.jsx +9 -27
- package/src/components/generic/reportSemanticSteps/SemanticGroupingStep.jsx +5 -13
- package/src/components/generic/reportSemanticSteps/SemanticParameterPrompt.jsx +5 -13
- package/src/components/generic/reportSemanticSteps/SemanticPreviewStep.jsx +14 -31
- package/src/components/generic/reportSemanticSteps/SemanticRelationsStep.jsx +3 -9
- package/src/components/generic/reportSemanticSteps/SemanticValueInput.jsx +2 -15
- package/src/components/navActive.js +60 -0
- package/src/components/notify/desktopNotifications.js +256 -0
- package/src/components/sketch/SketchField.jsx +12 -2
- package/src/components/sms/SmsComposeModal.jsx +495 -0
- package/src/components/sms/SmsInbox.jsx +596 -0
- package/src/components/sms/SmsInboxBadge.jsx +468 -0
- package/src/components/sms/SmsLineSettings.jsx +854 -0
- package/src/components/sms/SmsThreadPanel.jsx +1184 -0
- package/src/components/sms/smsEndpoints.js +56 -0
- package/src/components/sms/smsHelpers.js +1075 -0
- package/src/components/sms/smsLiveState.js +132 -0
- package/src/components/sms/useSmsLive.js +307 -0
- package/src/components/styles/CallQueuePop.module.scss +646 -0
- package/src/components/styles/CallQueueSettings.module.scss +460 -0
- package/src/components/styles/ClientAuth.module.scss +229 -0
- package/src/components/styles/DataGrid.module.scss +10 -0
- package/src/components/styles/GenericDetail.module.scss +153 -26
- package/src/components/styles/GenericIndex.module.scss +13 -0
- package/src/components/styles/GenericMain.module.scss +19 -2
- package/src/components/styles/ImpersonateGate.module.scss +85 -0
- package/src/components/styles/Login.module.scss +13 -122
- package/src/components/styles/LogoutScreen.module.scss +89 -0
- package/src/components/styles/Navigation.module.scss +509 -223
- package/src/components/styles/Notification.module.scss +103 -0
- package/src/components/styles/Reset.module.scss +52 -186
- package/src/components/styles/Sms.module.scss +2382 -0
- package/src/components/styles/TableFilter.module.scss +118 -98
- package/src/components/styles/TwoFactorAuth.module.scss +115 -176
- package/src/components/styles/Vault.module.scss +1983 -0
- package/src/components/styles/Verify.module.scss +57 -180
- package/src/components/styles/_authBrandPanel.scss +163 -0
- package/src/components/styles/_authShell.scss +369 -0
- package/src/components/styles/global-datagrid.css +29 -0
- package/src/components/utils/buildEnv.js +67 -0
- package/src/components/utils/displayValue.js +94 -0
- package/src/components/utils/useDensity.js +345 -9
- package/src/components/vault/OtpChip.jsx +208 -0
- package/src/components/vault/PasswordGenerator.jsx +145 -0
- package/src/components/vault/QrScanner.jsx +326 -0
- package/src/components/vault/VaultAccessLog.jsx +225 -0
- package/src/components/vault/VaultConfirmPanel.jsx +113 -0
- package/src/components/vault/VaultEntryForm.jsx +740 -0
- package/src/components/vault/VaultManager.jsx +1000 -0
- package/src/components/vault/VaultQuickSearch.jsx +681 -0
- package/src/components/vault/qrDecode.js +257 -0
- package/src/components/vault/useDebouncedValue.js +22 -0
- package/src/components/vault/useVaultReveal.js +160 -0
- package/src/components/vault/vaultClipboard.js +33 -0
- package/src/components/vault/vaultEndpoints.js +40 -0
- package/src/components/vault/vaultFit.js +116 -0
- package/src/components/vault/vaultHelpers.js +547 -0
- package/src/components/vault/vaultNavigation.jsx +58 -0
- package/src/components/vault/vaultOtp.js +105 -0
- package/src/index.js +233 -1
|
@@ -12,6 +12,120 @@
|
|
|
12
12
|
* dropped, which is exactly how a rail like this loses its padding.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The one-row tab strip.
|
|
18
|
+
*
|
|
19
|
+
* A rail's items laid out in a row, each an unadorned label, with a 3px accent
|
|
20
|
+
* edge under the selected one instead of the vertical rail's brand fill. It is
|
|
21
|
+
* the treatment narrow viewports get for any rail without expandable parents
|
|
22
|
+
* (`.flatFilter`, inside the phone media query at the bottom of this file),
|
|
23
|
+
* and the treatment a page opts into at every width with
|
|
24
|
+
* `<TableFilter variant="underline">` — a vertical rail spends a fifth of the
|
|
25
|
+
* page on navigation, which pays for itself at seven tabs and does not at two.
|
|
26
|
+
*
|
|
27
|
+
* The selectors inside are deliberately longer than the ones they override:
|
|
28
|
+
* `.subactive` and `.activetab button` carry `!important`, so only a more
|
|
29
|
+
* specific `!important` can take the brand fill back off.
|
|
30
|
+
*/
|
|
31
|
+
@mixin tab-strip {
|
|
32
|
+
.tableFilter,
|
|
33
|
+
.tableFilter.mobileOpen {
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-wrap: nowrap;
|
|
36
|
+
align-items: stretch;
|
|
37
|
+
gap: var(--spacing-xs, 0.25rem);
|
|
38
|
+
max-height: none;
|
|
39
|
+
overflow-x: auto;
|
|
40
|
+
overflow-y: hidden;
|
|
41
|
+
/* Momentum panning on iOS. */
|
|
42
|
+
-webkit-overflow-scrolling: touch;
|
|
43
|
+
/* The scrollbar is noise on a two-tab strip; the overflowing tab is
|
|
44
|
+
the affordance. */
|
|
45
|
+
scrollbar-width: none;
|
|
46
|
+
-ms-overflow-style: none;
|
|
47
|
+
/* The dropdown drew itself a card. A strip sits on the panel it is
|
|
48
|
+
already inside. */
|
|
49
|
+
padding: 0;
|
|
50
|
+
border: none;
|
|
51
|
+
border-radius: 0;
|
|
52
|
+
margin-bottom: 0;
|
|
53
|
+
/* No baseline rule under the row: every surface this rail sits on
|
|
54
|
+
(`.grid__subnav` in Profile, GenericIndex and GenericDetail) already
|
|
55
|
+
draws its own border a few pixels below, and a second hairline
|
|
56
|
+
alongside it read as a mistake. The 3px edge under the selected tab
|
|
57
|
+
is the whole marker. */
|
|
58
|
+
box-shadow: none;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.tableFilter::-webkit-scrollbar {
|
|
62
|
+
display: none;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.tableFilter > li {
|
|
66
|
+
flex: 0 0 auto;
|
|
67
|
+
margin: 0;
|
|
68
|
+
border-bottom: none;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Inactive tabs are muted labels, not tinted blocks. `white-space: nowrap`
|
|
72
|
+
is what keeps the row one row: without it a two-word tab wraps and the
|
|
73
|
+
strip grows a second line instead of overflowing. */
|
|
74
|
+
.tableFilter > li > .link,
|
|
75
|
+
.tableFilter > li > .parentLink,
|
|
76
|
+
.tableFilter > li > button {
|
|
77
|
+
display: block;
|
|
78
|
+
white-space: nowrap;
|
|
79
|
+
padding: 0.75rem var(--spacing-md, 1rem);
|
|
80
|
+
border: none;
|
|
81
|
+
border-bottom: 3px solid transparent;
|
|
82
|
+
border-radius: 0;
|
|
83
|
+
background: none !important;
|
|
84
|
+
color: var(--paragraph-color, #6b7280) !important;
|
|
85
|
+
font-size: var(--font-size-sm, 0.8125rem);
|
|
86
|
+
font-weight: var(--font-weight-medium, 500);
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* The selected tab. `--primary-color` first because it is what the rail
|
|
91
|
+
already fills the active item with everywhere else; `--accent-color`
|
|
92
|
+
covers apps that only declare that one, and the literal keeps the edge
|
|
93
|
+
visible in an app that declares neither. */
|
|
94
|
+
.tableFilter > li > .subactive,
|
|
95
|
+
.tableFilter > li.activetab > button {
|
|
96
|
+
background: none !important;
|
|
97
|
+
color: var(--heading-color, #111) !important;
|
|
98
|
+
font-weight: var(--font-weight-semibold, 600);
|
|
99
|
+
border-bottom-color: var(
|
|
100
|
+
--primary-color,
|
|
101
|
+
var(--accent-color, #0076c0)
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Touch devices keep :hover stuck on the last tap, which on the old rule
|
|
106
|
+
tinted whichever tab was tapped last and made it compete with the
|
|
107
|
+
selected one. */
|
|
108
|
+
.tableFilter > li > .link:hover,
|
|
109
|
+
.tableFilter > li > .parentLink:hover,
|
|
110
|
+
.tableFilter > li > button:hover {
|
|
111
|
+
background: none !important;
|
|
112
|
+
color: var(--heading-color, #111) !important;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* The opt-in variant. Same strip, at every width; TableFilter sets this class
|
|
117
|
+
alongside `.flatFilter` when a page asks for `variant="underline"`. The
|
|
118
|
+
container's own bottom margin goes: the strip is separated from the panel
|
|
119
|
+
below it by that panel's own spacing, and 20px of air under a tab row reads
|
|
120
|
+
as a gap in the page. */
|
|
121
|
+
.tableFilterContainer.underlineFilter {
|
|
122
|
+
/* Both classes: `.tableFilterContainer` below sets a 20px bottom margin,
|
|
123
|
+
and a single-class selector here would lose to it on source order. */
|
|
124
|
+
margin-bottom: 0;
|
|
125
|
+
|
|
126
|
+
@include tab-strip;
|
|
127
|
+
}
|
|
128
|
+
|
|
15
129
|
.tableFilterContainer {
|
|
16
130
|
width: 100%;
|
|
17
131
|
position: relative;
|
|
@@ -299,103 +413,9 @@
|
|
|
299
413
|
border-left: none;
|
|
300
414
|
}
|
|
301
415
|
|
|
302
|
-
/*
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
expandable children, and exists only inside this media query — above
|
|
307
|
-
759px the class matches nothing and the rail is byte-for-byte the
|
|
308
|
-
vertical list it has always been.
|
|
309
|
-
|
|
310
|
-
The strip pans horizontally with a thumb and marks the selection with a
|
|
311
|
-
3px accent edge rather than the full brand fill: on a phone the fill was
|
|
312
|
-
a solid band the width of the screen, which read as a header rather than
|
|
313
|
-
as one tab out of several.
|
|
314
|
-
|
|
315
|
-
These selectors are deliberately longer than the ones they override —
|
|
316
|
-
`.subactive` and `.activetab button` carry `!important`, so only a more
|
|
317
|
-
specific `!important` can take the fill back off. --------------------- */
|
|
318
|
-
|
|
319
|
-
.flatFilter .tableFilter,
|
|
320
|
-
.flatFilter .tableFilter.mobileOpen {
|
|
321
|
-
display: flex;
|
|
322
|
-
flex-wrap: nowrap;
|
|
323
|
-
align-items: stretch;
|
|
324
|
-
gap: var(--spacing-xs, 0.25rem);
|
|
325
|
-
max-height: none;
|
|
326
|
-
overflow-x: auto;
|
|
327
|
-
overflow-y: hidden;
|
|
328
|
-
/* Momentum panning on iOS. */
|
|
329
|
-
-webkit-overflow-scrolling: touch;
|
|
330
|
-
/* The scrollbar is noise on a two-tab strip; the overflowing tab is
|
|
331
|
-
the affordance. */
|
|
332
|
-
scrollbar-width: none;
|
|
333
|
-
-ms-overflow-style: none;
|
|
334
|
-
/* The dropdown drew itself a card. A strip sits on the panel it is
|
|
335
|
-
already inside. */
|
|
336
|
-
padding: 0;
|
|
337
|
-
border: none;
|
|
338
|
-
border-radius: 0;
|
|
339
|
-
margin-bottom: 0;
|
|
340
|
-
/* No baseline rule under the row: every surface this rail sits on
|
|
341
|
-
(`.grid__subnav` in Profile, GenericIndex and GenericDetail) already
|
|
342
|
-
draws its own border a few pixels below, and a second hairline
|
|
343
|
-
alongside it read as a mistake. The 3px edge under the selected tab
|
|
344
|
-
is the whole marker. */
|
|
345
|
-
box-shadow: none;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
.flatFilter .tableFilter::-webkit-scrollbar {
|
|
349
|
-
display: none;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
.flatFilter .tableFilter > li {
|
|
353
|
-
flex: 0 0 auto;
|
|
354
|
-
margin: 0;
|
|
355
|
-
border-bottom: none;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/* Inactive tabs are muted labels, not tinted blocks. `white-space: nowrap`
|
|
359
|
-
is what keeps the row one row: without it a two-word tab wraps and the
|
|
360
|
-
strip grows a second line instead of overflowing. */
|
|
361
|
-
.flatFilter .tableFilter > li > .link,
|
|
362
|
-
.flatFilter .tableFilter > li > .parentLink,
|
|
363
|
-
.flatFilter .tableFilter > li > button {
|
|
364
|
-
display: block;
|
|
365
|
-
white-space: nowrap;
|
|
366
|
-
padding: 0.75rem var(--spacing-md, 1rem);
|
|
367
|
-
border: none;
|
|
368
|
-
border-bottom: 3px solid transparent;
|
|
369
|
-
border-radius: 0;
|
|
370
|
-
background: none !important;
|
|
371
|
-
color: var(--paragraph-color, #6b7280) !important;
|
|
372
|
-
font-size: var(--font-size-sm, 0.8125rem);
|
|
373
|
-
font-weight: var(--font-weight-medium, 500);
|
|
374
|
-
cursor: pointer;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/* The selected tab. `--primary-color` first because it is what the rail
|
|
378
|
-
already fills the active item with everywhere else; `--accent-color`
|
|
379
|
-
covers apps that only declare that one, and the literal keeps the edge
|
|
380
|
-
visible in an app that declares neither. */
|
|
381
|
-
.flatFilter .tableFilter > li > .subactive,
|
|
382
|
-
.flatFilter .tableFilter > li.activetab > button {
|
|
383
|
-
background: none !important;
|
|
384
|
-
color: var(--heading-color, #111) !important;
|
|
385
|
-
font-weight: var(--font-weight-semibold, 600);
|
|
386
|
-
border-bottom-color: var(
|
|
387
|
-
--primary-color,
|
|
388
|
-
var(--accent-color, #0076c0)
|
|
389
|
-
);
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
/* Touch devices keep :hover stuck on the last tap, which on the old rule
|
|
393
|
-
tinted whichever tab was tapped last and made it compete with the
|
|
394
|
-
selected one. */
|
|
395
|
-
.flatFilter .tableFilter > li > .link:hover,
|
|
396
|
-
.flatFilter .tableFilter > li > .parentLink:hover,
|
|
397
|
-
.flatFilter .tableFilter > li > button:hover {
|
|
398
|
-
background: none !important;
|
|
399
|
-
color: var(--heading-color, #111) !important;
|
|
416
|
+
/* The one-row tab strip. Shared with the opt-in `.underlineFilter`
|
|
417
|
+
variant — see the mixin at the top of this file. */
|
|
418
|
+
.flatFilter {
|
|
419
|
+
@include tab-strip;
|
|
400
420
|
}
|
|
401
421
|
}
|
|
@@ -1,208 +1,147 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Two-factor verification.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the pre-6.1 centred card (`.lcontainer` / `.lwrap` / `.login`, with
|
|
5
|
+
* its own greys and its own button) with the two-pane sign-in language. Signing
|
|
6
|
+
* in with 2FA on is one journey, and it used to change design halfway through
|
|
7
|
+
* it: the login screen, then a differently-styled card, then the app.
|
|
8
|
+
*
|
|
9
|
+
* Everything shared with the other auth screens comes from _authShell.scss.
|
|
10
|
+
* Only what is particular to entering a code lives here.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
@use './authShell' as *;
|
|
14
|
+
|
|
15
|
+
@include auth-shell;
|
|
16
|
+
|
|
17
|
+
/* The code field is read digit by digit, so it is set wide, centred and
|
|
18
|
+
monospaced — nothing like the identifier fields on the login screen. */
|
|
19
|
+
.code {
|
|
20
|
+
input {
|
|
21
|
+
font-family: 'SFMono-Regular', 'Menlo', 'Consolas', monospace;
|
|
22
|
+
font-size: 1.3rem;
|
|
23
|
+
font-weight: 600;
|
|
24
|
+
letter-spacing: 0.55rem;
|
|
25
|
+
/* The tracking is applied to the right of each glyph, so without this
|
|
26
|
+
the run of digits sits visibly left of centre. */
|
|
27
|
+
text-indent: 0.55rem;
|
|
28
|
+
text-align: center;
|
|
29
|
+
padding-top: 1.35rem;
|
|
11
30
|
}
|
|
12
31
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
transform-origin: top left;
|
|
19
|
-
cursor: text;
|
|
20
|
-
padding: 0 1rem;
|
|
21
|
-
font-size: 0.9rem;
|
|
22
|
-
color: #6b7280;
|
|
32
|
+
label {
|
|
33
|
+
/* Centred with the value it labels, rather than hanging off the left
|
|
34
|
+
edge of a field whose contents are centred. */
|
|
35
|
+
left: 50%;
|
|
36
|
+
transform: translateX(-50%);
|
|
23
37
|
}
|
|
24
38
|
|
|
25
|
-
input
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
text-align: center;
|
|
39
|
+
input:focus + label,
|
|
40
|
+
input:not(:placeholder-shown) + label {
|
|
41
|
+
transform: translateX(-50%) translateY(-0.85rem);
|
|
29
42
|
}
|
|
30
43
|
}
|
|
31
44
|
|
|
32
|
-
.
|
|
33
|
-
.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
/* Where the code went, in code mode: the masked number the SMS was sent to.
|
|
46
|
+
Sits directly under the subtitle so it reads as part of the instruction. */
|
|
47
|
+
.destination {
|
|
48
|
+
display: inline-flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
gap: 0.4rem;
|
|
51
|
+
margin: -1.4rem 0 1.6rem;
|
|
52
|
+
padding: 0.35rem 0.7rem;
|
|
53
|
+
border: 1px solid var(--line);
|
|
54
|
+
border-radius: 999px;
|
|
55
|
+
background: var(--warm);
|
|
56
|
+
font-size: 0.82rem;
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
color: var(--ink);
|
|
59
|
+
|
|
60
|
+
svg {
|
|
61
|
+
flex: none;
|
|
62
|
+
color: var(--navy);
|
|
63
|
+
}
|
|
49
64
|
}
|
|
50
65
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
display:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
/* Resend sits on the same line as the expiry note: one is the reason for the
|
|
67
|
+
other. */
|
|
68
|
+
.resendRow {
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: baseline;
|
|
71
|
+
justify-content: space-between;
|
|
72
|
+
gap: 1rem;
|
|
73
|
+
margin-top: 1.1rem;
|
|
74
|
+
font-size: 0.82rem;
|
|
75
|
+
color: var(--muted);
|
|
58
76
|
}
|
|
59
77
|
|
|
60
|
-
.
|
|
61
|
-
width: 28rem;
|
|
62
|
-
padding: 2rem;
|
|
78
|
+
.expiry {
|
|
63
79
|
margin: 0;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
background-color: white;
|
|
68
|
-
border-radius: 0.75rem;
|
|
69
|
-
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
|
|
70
|
-
0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
71
|
-
|
|
72
|
-
> .formItem {
|
|
73
|
-
padding: 0;
|
|
74
|
-
|
|
75
|
-
small {
|
|
76
|
-
position: absolute;
|
|
77
|
-
width: 18px;
|
|
78
|
-
height: 18px;
|
|
79
|
-
right: 14px;
|
|
80
|
-
top: 14px;
|
|
81
|
-
opacity: 0.4;
|
|
82
|
-
color: #6b7280;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
h2 {
|
|
87
|
-
text-align: center;
|
|
88
|
-
margin-bottom: 0.5rem;
|
|
89
|
-
color: #111827;
|
|
90
|
-
font-weight: 600;
|
|
91
|
-
font-size: 1.5rem;
|
|
92
|
-
}
|
|
80
|
+
font-size: 0.82rem;
|
|
81
|
+
line-height: 1.5;
|
|
82
|
+
color: var(--muted);
|
|
93
83
|
}
|
|
94
84
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
85
|
+
/* The link is disabled while the request is in flight and, if the consumer set
|
|
86
|
+
a cooldown, for that many seconds after — .link already carries the disabled
|
|
87
|
+
treatment, this only holds the countdown's width steady. */
|
|
88
|
+
.resend {
|
|
89
|
+
flex: none;
|
|
90
|
+
font-variant-numeric: tabular-nums;
|
|
101
91
|
}
|
|
102
92
|
|
|
103
|
-
.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
font-size: 0.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
color: var(--primary-color, #4f46e5);
|
|
112
|
-
text-decoration: none;
|
|
113
|
-
font-weight: 500;
|
|
114
|
-
|
|
115
|
-
&:hover {
|
|
116
|
-
text-decoration: underline;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
93
|
+
/* "Having trouble?" and the way back to the login screen. Quiet, and last. */
|
|
94
|
+
.help {
|
|
95
|
+
margin: 1.6rem 0 0;
|
|
96
|
+
padding-top: 1.1rem;
|
|
97
|
+
border-top: 1px solid var(--line);
|
|
98
|
+
font-size: 0.82rem;
|
|
99
|
+
line-height: 1.5;
|
|
100
|
+
color: var(--muted);
|
|
119
101
|
}
|
|
120
102
|
|
|
121
|
-
.
|
|
122
|
-
|
|
123
|
-
display: flex;
|
|
103
|
+
.back {
|
|
104
|
+
display: inline-flex;
|
|
124
105
|
align-items: center;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
.btn {
|
|
135
|
-
width: max-content;
|
|
136
|
-
display: inline-block;
|
|
137
|
-
position: relative;
|
|
138
|
-
padding: 0.75rem 1rem;
|
|
106
|
+
gap: 0.35rem;
|
|
107
|
+
margin-top: 0.6rem;
|
|
108
|
+
padding: 0;
|
|
109
|
+
border: none;
|
|
110
|
+
background: none;
|
|
111
|
+
font-family: inherit;
|
|
112
|
+
font-size: 0.85rem;
|
|
113
|
+
font-weight: 600;
|
|
114
|
+
color: var(--navy);
|
|
139
115
|
cursor: pointer;
|
|
140
|
-
font-size: 0.875rem;
|
|
141
|
-
font-weight: 500;
|
|
142
|
-
color: white;
|
|
143
|
-
text-decoration: none;
|
|
144
|
-
overflow: hidden;
|
|
145
|
-
background: var(--primary-color, #4f46e5);
|
|
146
|
-
border: 1px solid var(--primary-color, #4f46e5);
|
|
147
|
-
border-radius: 0.5rem;
|
|
148
|
-
outline: none;
|
|
149
|
-
transition: all 0.2s ease;
|
|
150
|
-
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
151
116
|
|
|
152
117
|
&:hover {
|
|
153
|
-
|
|
154
|
-
border-color: var(--secondary-color, #3cbf7d);
|
|
118
|
+
text-decoration: underline;
|
|
155
119
|
}
|
|
156
120
|
|
|
157
|
-
|
|
158
|
-
|
|
121
|
+
svg {
|
|
122
|
+
flex: none;
|
|
159
123
|
}
|
|
160
124
|
}
|
|
161
125
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
padding: 0;
|
|
168
|
-
background: white;
|
|
169
|
-
font-weight: 500;
|
|
170
|
-
transition: all 0.3s ease;
|
|
171
|
-
color: var(--primary-color, #4f46e5) !important;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
.rememberMeIndicator {
|
|
126
|
+
/* Carried over in spirit from the old screen's remember-me confirmation, which
|
|
127
|
+
was the one thing about it worth keeping: after typing a password and then a
|
|
128
|
+
code, it is genuinely useful to be told the box you ticked two screens ago is
|
|
129
|
+
still ticked. */
|
|
130
|
+
.remembered {
|
|
175
131
|
display: flex;
|
|
176
132
|
align-items: center;
|
|
177
|
-
|
|
178
|
-
margin: 0.
|
|
179
|
-
padding: 0.
|
|
180
|
-
|
|
181
|
-
border-radius:
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
&:hover {
|
|
188
|
-
background-color: rgba(var(--primary-rgb), 0.12);
|
|
189
|
-
transform: translateY(-1px);
|
|
190
|
-
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.08);
|
|
191
|
-
}
|
|
133
|
+
gap: 0.45rem;
|
|
134
|
+
margin: 0.9rem 0 0;
|
|
135
|
+
padding: 0.55rem 0.75rem;
|
|
136
|
+
border-left: 3px solid var(--navy);
|
|
137
|
+
border-radius: 0.4rem;
|
|
138
|
+
background: var(--warm);
|
|
139
|
+
font-size: 0.82rem;
|
|
140
|
+
font-weight: 500;
|
|
141
|
+
color: var(--ink);
|
|
192
142
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
color: var(--
|
|
196
|
-
font-weight: 500;
|
|
197
|
-
display: flex;
|
|
198
|
-
align-items: center;
|
|
199
|
-
|
|
200
|
-
&::before {
|
|
201
|
-
content: '✓';
|
|
202
|
-
display: inline-block;
|
|
203
|
-
margin-right: 0.5rem;
|
|
204
|
-
font-weight: bold;
|
|
205
|
-
font-size: 0.9rem;
|
|
206
|
-
}
|
|
143
|
+
svg {
|
|
144
|
+
flex: none;
|
|
145
|
+
color: var(--navy);
|
|
207
146
|
}
|
|
208
147
|
}
|