@visns-studio/visns-components 6.17.1 → 6.20.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/package.json +10 -7
- package/src/components/AssociationManager.jsx +344 -177
- package/src/components/AsyncSelect.jsx +2 -2
- package/src/components/Autocomplete.jsx +57 -12
- package/src/components/Breadcrumb.jsx +23 -4
- package/src/components/ClientAssociationManager.jsx +321 -145
- package/src/components/DataGrid.jsx +625 -20
- package/src/components/DropZone.jsx +4 -1
- package/src/components/Form.jsx +233 -6
- package/src/components/MultiSelect.jsx +2 -2
- package/src/components/Navigation.jsx +45 -25
- package/src/components/TableFilter.jsx +172 -12
- package/src/components/UniversalSearch.jsx +390 -0
- package/src/components/auth/Login.jsx +164 -8
- package/src/components/auth/Profile.jsx +209 -22
- package/src/components/auth/authEndpoints.js +4 -0
- package/src/components/auth/webauthn.js +194 -0
- package/src/components/columns/ColumnRenderers.jsx +6 -1
- package/src/components/controls/DataGridSearch.jsx +11 -5
- package/src/components/generic/GenericAuth.jsx +6 -0
- package/src/components/generic/GenericDashboard.jsx +93 -36
- package/src/components/generic/GenericDetail.jsx +146 -61
- package/src/components/generic/GenericIndex.jsx +134 -38
- package/src/components/generic/GenericSettings.jsx +220 -0
- package/src/components/generic/StandardModal.jsx +165 -8
- package/src/components/generic/dashboardChartDefaults.js +230 -0
- package/src/components/generic/shared/indexLayout.js +38 -0
- package/src/components/navActive.js +25 -0
- package/src/components/settings/IntegrationsManager.jsx +474 -0
- package/src/components/sms/SmsLineSettings.jsx +16 -12
- package/src/components/styles/AssociationManager.module.scss +4 -363
- package/src/components/styles/AuditLog.module.scss +6 -6
- package/src/components/styles/AuditLogs.module.scss +3 -3
- package/src/components/styles/Autocomplete.module.scss +7 -7
- package/src/components/styles/BusinessCardOcr.module.scss +6 -1
- package/src/components/styles/CallQueueSettings.module.scss +4 -1
- package/src/components/styles/CameraPlacement.module.scss +19 -19
- package/src/components/styles/CategorizedDropZone.module.scss +6 -1
- package/src/components/styles/ClientAssociationManager.module.scss +5 -289
- package/src/components/styles/ClientAuth.module.scss +1 -1
- package/src/components/styles/DataGrid.module.scss +455 -8
- package/src/components/styles/Field.module.scss +32 -24
- package/src/components/styles/Form.module.scss +123 -3
- package/src/components/styles/GenericDashboard.module.scss +612 -825
- package/src/components/styles/GenericDetail.module.scss +406 -61
- package/src/components/styles/GenericDynamic.module.scss +25 -25
- package/src/components/styles/GenericEditableTable.module.scss +33 -33
- package/src/components/styles/GenericFormBuilder.module.scss +119 -119
- package/src/components/styles/GenericIndex.module.scss +483 -38
- package/src/components/styles/GenericMain.module.scss +6 -3
- package/src/components/styles/GenericQuote.module.scss +399 -81
- package/src/components/styles/GenericReport.module.scss +8 -8
- package/src/components/styles/GenericSettings.module.scss +209 -0
- package/src/components/styles/GenericSort.module.scss +9 -9
- package/src/components/styles/Integrations.module.scss +321 -0
- package/src/components/styles/List.module.scss +4 -4
- package/src/components/styles/Login.module.scss +57 -0
- package/src/components/styles/MultiSelect.module.scss +4 -4
- package/src/components/styles/Navigation.module.scss +12 -12
- package/src/components/styles/Notification.module.scss +12 -8
- package/src/components/styles/NotificationList.module.scss +5 -5
- package/src/components/styles/Profile.module.scss +5 -5
- package/src/components/styles/QrCode.module.scss +4 -4
- package/src/components/styles/QuickAction.module.scss +20 -20
- package/src/components/styles/SortableQuoteItems.module.scss +4 -4
- package/src/components/styles/TableFilter.module.scss +128 -17
- package/src/components/styles/TicketConversation.module.scss +497 -0
- package/src/components/styles/UniversalSearch.module.scss +229 -0
- package/src/components/styles/Vault.module.scss +413 -0
- package/src/components/styles/_associationManager.scss +467 -0
- package/src/components/styles/_authBrandPanel.scss +15 -9
- package/src/components/styles/_controls.scss +43 -39
- package/src/components/styles/global-datagrid.css +196 -0
- package/src/components/styles/global.css +168 -17
- package/src/components/tickets/TicketConversation.jsx +455 -0
- package/src/components/utils/rowActionSettings.js +117 -0
- package/src/components/vault/VaultClientPicker.jsx +183 -0
- package/src/components/vault/VaultEntryForm.jsx +23 -0
- package/src/components/vault/VaultManager.jsx +382 -34
- package/src/components/vault/VaultShareModal.jsx +454 -0
- package/src/components/vault/vaultEndpoints.js +16 -2
- package/src/components/vault/vaultShares.js +247 -0
- package/src/index.js +35 -0
- package/src/utils/fetchUtil.js +38 -14
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Association manager — shared presentation
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// `AssociationManager` and the older `ClientAssociationManager` render the same
|
|
5
|
+
// thing (GenericDetail routes BOTH `component: "AssociationManager"` and
|
|
6
|
+
// `component: "ClientAssociationManager"` to the former), so the look lives in
|
|
7
|
+
// one mixin and each CSS module includes it. Class names are hashed per file,
|
|
8
|
+
// so the two stay independent modules while sharing a single definition.
|
|
9
|
+
//
|
|
10
|
+
// The panel renders inside a host page's card — the "Customer Assignments" tab
|
|
11
|
+
// on a contact, the "Assignments" tab on a customer — so it paints NO surface
|
|
12
|
+
// of its own at the top level. It also draws no title: the tab above it already
|
|
13
|
+
// names the thing, and repeating it inside the panel was the loudest part of
|
|
14
|
+
// the old design. `config.showTitle` opts a standalone mount back in.
|
|
15
|
+
//
|
|
16
|
+
// Everything is a CSS custom property with a fallback, in the library's usual
|
|
17
|
+
// pattern: the package carries no palette.
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
@use 'controls' as *;
|
|
21
|
+
|
|
22
|
+
@mixin association-manager {
|
|
23
|
+
.container {
|
|
24
|
+
// Local aliases so a row, a chip and a field all mix against the same
|
|
25
|
+
// ink rather than each restating an rgba() of their own.
|
|
26
|
+
--am-ink: var(--paragraph-color, #2b2b2b);
|
|
27
|
+
--am-accent: var(--primary-color, #1b3933);
|
|
28
|
+
--am-surface: var(--paper, #fff);
|
|
29
|
+
--am-line: var(--border-color, #{rgba(43, 43, 43, 0.14)});
|
|
30
|
+
--am-muted: color-mix(in srgb, var(--am-ink) 72%, transparent);
|
|
31
|
+
--am-quiet: color-mix(in srgb, var(--am-ink) 3%, transparent);
|
|
32
|
+
--am-radius: var(--card-radius, 10px);
|
|
33
|
+
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
gap: var(--spacing-lg, 1.5rem);
|
|
37
|
+
color: var(--am-ink);
|
|
38
|
+
font-size: 0.85rem;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ----------------------------------------------------------------------
|
|
42
|
+
// optional heading (standalone mounts only — see the note above)
|
|
43
|
+
// ----------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
.heading {
|
|
46
|
+
margin: 0;
|
|
47
|
+
color: var(--am-accent);
|
|
48
|
+
font-size: 1rem;
|
|
49
|
+
font-weight: 600;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.headingNote {
|
|
53
|
+
margin: 0.15rem 0 0;
|
|
54
|
+
color: var(--am-muted);
|
|
55
|
+
font-size: 0.8rem;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.loading,
|
|
59
|
+
.empty {
|
|
60
|
+
margin: 0;
|
|
61
|
+
color: var(--am-muted);
|
|
62
|
+
font-size: 0.8rem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.loading {
|
|
66
|
+
padding: 1rem 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// An empty list is a dashed outline rather than a filled slab: nothing to
|
|
70
|
+
// read here, so nothing should draw the eye.
|
|
71
|
+
.empty {
|
|
72
|
+
padding: 1.1rem 1rem;
|
|
73
|
+
text-align: center;
|
|
74
|
+
border: 1px dashed var(--am-line);
|
|
75
|
+
border-radius: var(--am-radius);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ----------------------------------------------------------------------
|
|
79
|
+
// the multiple-primary notice
|
|
80
|
+
// ----------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
// Stated once, quietly, in the amber family — not a filled banner with a
|
|
83
|
+
// 4px bar down its side.
|
|
84
|
+
.notice {
|
|
85
|
+
display: flex;
|
|
86
|
+
gap: 0.55rem;
|
|
87
|
+
align-items: flex-start;
|
|
88
|
+
padding: 0.65rem 0.8rem;
|
|
89
|
+
color: #7a5c00;
|
|
90
|
+
font-size: 0.8rem;
|
|
91
|
+
background: color-mix(in srgb, #b98900 8%, transparent);
|
|
92
|
+
border: 1px solid color-mix(in srgb, #b98900 32%, transparent);
|
|
93
|
+
border-radius: var(--am-radius);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.noticeIcon {
|
|
97
|
+
flex: none;
|
|
98
|
+
margin-top: 0.1rem;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.noticeBody {
|
|
102
|
+
flex: 1 1 auto;
|
|
103
|
+
min-width: 0;
|
|
104
|
+
|
|
105
|
+
strong {
|
|
106
|
+
display: block;
|
|
107
|
+
font-weight: 600;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
p {
|
|
111
|
+
margin: 0.15rem 0 0;
|
|
112
|
+
line-height: 1.4;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.noticeAction {
|
|
117
|
+
@include button-base;
|
|
118
|
+
@include button-small;
|
|
119
|
+
|
|
120
|
+
margin-top: 0.55rem;
|
|
121
|
+
color: inherit;
|
|
122
|
+
background: none;
|
|
123
|
+
border-color: currentcolor;
|
|
124
|
+
|
|
125
|
+
&:hover:not(:disabled) {
|
|
126
|
+
background: color-mix(in srgb, #b98900 14%, transparent);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ----------------------------------------------------------------------
|
|
131
|
+
// the list
|
|
132
|
+
// ----------------------------------------------------------------------
|
|
133
|
+
|
|
134
|
+
.section {
|
|
135
|
+
display: flex;
|
|
136
|
+
flex-direction: column;
|
|
137
|
+
gap: 0.5rem;
|
|
138
|
+
min-width: 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.sectionHead {
|
|
142
|
+
display: flex;
|
|
143
|
+
gap: var(--spacing-sm, 0.5rem);
|
|
144
|
+
align-items: center;
|
|
145
|
+
justify-content: space-between;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.sectionTitle {
|
|
149
|
+
margin: 0;
|
|
150
|
+
color: var(--am-muted);
|
|
151
|
+
font-size: 0.72rem;
|
|
152
|
+
font-weight: 600;
|
|
153
|
+
letter-spacing: 0.04em;
|
|
154
|
+
text-transform: uppercase;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.list {
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: column;
|
|
160
|
+
overflow: hidden;
|
|
161
|
+
background: var(--am-surface);
|
|
162
|
+
border: 1px solid var(--am-line);
|
|
163
|
+
border-radius: var(--am-radius);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.row {
|
|
167
|
+
display: flex;
|
|
168
|
+
gap: var(--spacing-md, 1rem);
|
|
169
|
+
align-items: center;
|
|
170
|
+
padding: 0.6rem 0.85rem;
|
|
171
|
+
border-bottom: 1px solid var(--am-line);
|
|
172
|
+
transition: background var(--speed, 160ms)
|
|
173
|
+
var(--ease, cubic-bezier(0.4, 0, 0.2, 1));
|
|
174
|
+
|
|
175
|
+
&:last-child {
|
|
176
|
+
border-bottom: 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
&:hover {
|
|
180
|
+
background: var(--hover-color, rgb(0 0 0 / 3%));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* The primary row is marked by a rule down its edge, not by tinting the
|
|
185
|
+
whole slab — one row in a list of five should read as *marked*, not as a
|
|
186
|
+
different kind of object. */
|
|
187
|
+
.rowPrimary {
|
|
188
|
+
box-shadow: inset 2px 0 0 0 var(--am-accent);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.main {
|
|
192
|
+
display: flex;
|
|
193
|
+
flex: 1 1 auto;
|
|
194
|
+
flex-direction: column;
|
|
195
|
+
gap: 0.15rem;
|
|
196
|
+
min-width: 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.entityName {
|
|
200
|
+
display: flex;
|
|
201
|
+
gap: 0.4rem;
|
|
202
|
+
align-items: center;
|
|
203
|
+
font-weight: 600;
|
|
204
|
+
line-height: 1.3;
|
|
205
|
+
overflow-wrap: anywhere;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.chip {
|
|
209
|
+
display: inline-flex;
|
|
210
|
+
flex: none;
|
|
211
|
+
gap: 0.2rem;
|
|
212
|
+
align-items: center;
|
|
213
|
+
padding: 1px 7px;
|
|
214
|
+
color: var(--am-muted);
|
|
215
|
+
font-size: 0.7rem;
|
|
216
|
+
font-weight: 600;
|
|
217
|
+
white-space: nowrap;
|
|
218
|
+
background: var(--am-quiet);
|
|
219
|
+
border: 1px solid var(--am-line);
|
|
220
|
+
border-radius: 999px;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* Outlined, in the brand ink — the old badge was a solid dark slab with
|
|
224
|
+
uppercase white type, which read as a warning. */
|
|
225
|
+
.chipPrimary {
|
|
226
|
+
color: var(--am-accent);
|
|
227
|
+
background: color-mix(in srgb, var(--am-accent) 8%, transparent);
|
|
228
|
+
border-color: color-mix(in srgb, var(--am-accent) 35%, transparent);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* Relationship, role, notes and the date all read as one quiet line of
|
|
232
|
+
metadata under the name, separated by middots, the way the rest of the
|
|
233
|
+
app writes a subtitle. */
|
|
234
|
+
.meta {
|
|
235
|
+
display: flex;
|
|
236
|
+
flex-wrap: wrap;
|
|
237
|
+
gap: 0.3rem;
|
|
238
|
+
align-items: center;
|
|
239
|
+
color: var(--am-muted);
|
|
240
|
+
font-size: 0.75rem;
|
|
241
|
+
line-height: 1.4;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.sep {
|
|
245
|
+
opacity: 0.5;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.relationshipType {
|
|
249
|
+
text-transform: capitalize;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.notes {
|
|
253
|
+
overflow-wrap: anywhere;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.date {
|
|
257
|
+
display: inline-flex;
|
|
258
|
+
gap: 0.25rem;
|
|
259
|
+
align-items: center;
|
|
260
|
+
white-space: nowrap;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ----------------------------------------------------------------------
|
|
264
|
+
// row actions
|
|
265
|
+
// ----------------------------------------------------------------------
|
|
266
|
+
|
|
267
|
+
/* Revealed on hover, but never *only* on hover: `:focus-within` keeps them
|
|
268
|
+
reachable from the keyboard, and a coarse pointer (the iPad this is used
|
|
269
|
+
on) has no hover state at all, so there they are simply always shown. */
|
|
270
|
+
.actions {
|
|
271
|
+
display: flex;
|
|
272
|
+
flex: none;
|
|
273
|
+
gap: 0.15rem;
|
|
274
|
+
align-items: center;
|
|
275
|
+
opacity: 0;
|
|
276
|
+
transition: opacity var(--speed, 160ms)
|
|
277
|
+
var(--ease, cubic-bezier(0.4, 0, 0.2, 1));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.row:hover .actions,
|
|
281
|
+
.row:focus-within .actions {
|
|
282
|
+
opacity: 1;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@media (hover: none), (pointer: coarse) {
|
|
286
|
+
.actions {
|
|
287
|
+
opacity: 1;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.iconButton {
|
|
292
|
+
display: inline-flex;
|
|
293
|
+
align-items: center;
|
|
294
|
+
justify-content: center;
|
|
295
|
+
width: 28px;
|
|
296
|
+
height: 28px;
|
|
297
|
+
padding: 0;
|
|
298
|
+
color: var(--am-muted);
|
|
299
|
+
background: none;
|
|
300
|
+
border: 0;
|
|
301
|
+
border-radius: 6px;
|
|
302
|
+
cursor: pointer;
|
|
303
|
+
transition:
|
|
304
|
+
color var(--speed, 160ms) var(--ease, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
305
|
+
background var(--speed, 160ms) var(--ease, cubic-bezier(0.4, 0, 0.2, 1));
|
|
306
|
+
|
|
307
|
+
&:hover:not(:disabled) {
|
|
308
|
+
color: var(--am-ink);
|
|
309
|
+
background: var(--am-quiet);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
&:focus-visible {
|
|
313
|
+
opacity: 1;
|
|
314
|
+
outline: 2px solid var(--highlight-color, #3cbf7d);
|
|
315
|
+
outline-offset: 1px;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* Currently primary: the star is already lit, and the button takes it back
|
|
320
|
+
off. Coloured so the state is legible before the hover. */
|
|
321
|
+
.iconButtonOn {
|
|
322
|
+
color: var(--am-accent);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Destructive, stated in colour on hover only — a solid red button on every
|
|
326
|
+
row made removal the most prominent thing on the panel. */
|
|
327
|
+
.iconButtonDanger {
|
|
328
|
+
&:hover:not(:disabled) {
|
|
329
|
+
color: var(--danger-color, #be3e3e);
|
|
330
|
+
background: var(--danger-light, rgb(190 62 62 / 12%));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// ----------------------------------------------------------------------
|
|
335
|
+
// the add form
|
|
336
|
+
// ----------------------------------------------------------------------
|
|
337
|
+
|
|
338
|
+
.addToggle {
|
|
339
|
+
@include button-secondary;
|
|
340
|
+
@include button-small;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/* Two columns from 820px — the width at which a `Customer` and a `Site`
|
|
344
|
+
select can sit side by side without either becoming a slot machine. */
|
|
345
|
+
.form {
|
|
346
|
+
display: grid;
|
|
347
|
+
grid-template-columns: minmax(0, 1fr);
|
|
348
|
+
gap: var(--spacing-md, 1rem);
|
|
349
|
+
padding: var(--spacing-md, 1rem);
|
|
350
|
+
background: var(--am-quiet);
|
|
351
|
+
border: 1px solid var(--am-line);
|
|
352
|
+
border-radius: var(--am-radius);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
@media (min-width: 820px) {
|
|
356
|
+
.form {
|
|
357
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.field {
|
|
362
|
+
display: flex;
|
|
363
|
+
flex-direction: column;
|
|
364
|
+
gap: 0.3rem;
|
|
365
|
+
min-width: 0;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/* A textarea, a checkbox and the button row each own the full width: they
|
|
369
|
+
do not pair with anything. */
|
|
370
|
+
.fieldWide,
|
|
371
|
+
.formActions {
|
|
372
|
+
grid-column: 1 / -1;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.label {
|
|
376
|
+
color: var(--am-muted);
|
|
377
|
+
font-size: 0.72rem;
|
|
378
|
+
font-weight: 600;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.required {
|
|
382
|
+
color: var(--danger-color, #be3e3e);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.selectField,
|
|
386
|
+
.textField,
|
|
387
|
+
.textareaField {
|
|
388
|
+
@include input-base;
|
|
389
|
+
|
|
390
|
+
font-size: 0.85rem;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.textareaField {
|
|
394
|
+
min-height: 4.5rem;
|
|
395
|
+
padding-top: 0.55rem;
|
|
396
|
+
padding-bottom: 0.55rem;
|
|
397
|
+
line-height: 1.4;
|
|
398
|
+
resize: vertical;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/* The checkbox is pinned on every axis. The host CRM styles bare `input`
|
|
402
|
+
with a text-field height and a pill radius, and a flex parent will happily
|
|
403
|
+
stretch a box that has not been told its maximum — which rendered the
|
|
404
|
+
"Primary Assignment" tick as a wide oval. */
|
|
405
|
+
.checkboxLabel {
|
|
406
|
+
display: inline-flex;
|
|
407
|
+
gap: 0.5rem;
|
|
408
|
+
align-items: center;
|
|
409
|
+
margin-top: 0.2rem;
|
|
410
|
+
color: var(--am-ink);
|
|
411
|
+
font-size: 0.8rem;
|
|
412
|
+
cursor: pointer;
|
|
413
|
+
|
|
414
|
+
input[type='checkbox'] {
|
|
415
|
+
flex: 0 0 16px;
|
|
416
|
+
box-sizing: border-box;
|
|
417
|
+
width: 16px;
|
|
418
|
+
min-width: 16px;
|
|
419
|
+
max-width: 16px;
|
|
420
|
+
height: 16px;
|
|
421
|
+
min-height: 16px;
|
|
422
|
+
max-height: 16px;
|
|
423
|
+
padding: 0;
|
|
424
|
+
margin: 0;
|
|
425
|
+
border-radius: 3px;
|
|
426
|
+
cursor: pointer;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.formActions {
|
|
431
|
+
display: flex;
|
|
432
|
+
gap: 0.5rem;
|
|
433
|
+
align-items: center;
|
|
434
|
+
justify-content: flex-end;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.primaryButton {
|
|
438
|
+
@include button-primary;
|
|
439
|
+
@include button-small;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.secondaryButton {
|
|
443
|
+
@include button-secondary;
|
|
444
|
+
@include button-small;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
@media (max-width: 640px) {
|
|
448
|
+
.row {
|
|
449
|
+
flex-wrap: wrap;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.actions {
|
|
453
|
+
margin-left: auto;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/* Reversed so the primary action is under the thumb on the right, and
|
|
457
|
+
both stretched so neither is a small target on a phone. */
|
|
458
|
+
.formActions {
|
|
459
|
+
flex-direction: row-reverse;
|
|
460
|
+
|
|
461
|
+
> * {
|
|
462
|
+
flex: 1 1 0;
|
|
463
|
+
width: auto;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
@mixin auth-brand-panel($collapse: hide) {
|
|
28
28
|
.brand {
|
|
29
29
|
position: relative;
|
|
30
|
-
background-color: var(--navy-deep);
|
|
30
|
+
background-color: var(--navy-deep, #16202e);
|
|
31
31
|
background-size: cover;
|
|
32
32
|
background-position: center 62%;
|
|
33
33
|
overflow: hidden;
|
|
@@ -46,19 +46,25 @@
|
|
|
46
46
|
content: '';
|
|
47
47
|
position: absolute;
|
|
48
48
|
inset: 0;
|
|
49
|
+
// The nine stops here were hardcoded `rgba(16, 25, 42, …)` — the
|
|
50
|
+
// navy of the CRM this component was first written for. Over a
|
|
51
|
+
// green-branded consumer's artwork the bottom half of the panel
|
|
52
|
+
// turned blue, so the sign-in screen advertised somebody else's
|
|
53
|
+
// brand. `--brand-ground` is the consumer's own ground; the navy
|
|
54
|
+
// survives only as its fallback.
|
|
49
55
|
background:
|
|
50
56
|
linear-gradient(
|
|
51
57
|
to top,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
color-mix(in srgb, var(--brand-ground, #10192a) 94%, transparent) 0%,
|
|
59
|
+
color-mix(in srgb, var(--brand-ground, #10192a) 88%, transparent) 18%,
|
|
60
|
+
color-mix(in srgb, var(--brand-ground, #10192a) 62%, transparent) 42%,
|
|
61
|
+
color-mix(in srgb, var(--brand-ground, #10192a) 22%, transparent) 70%,
|
|
62
|
+
color-mix(in srgb, var(--brand-ground, #10192a) 6%, transparent) 100%
|
|
57
63
|
),
|
|
58
64
|
linear-gradient(
|
|
59
65
|
to right,
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
color-mix(in srgb, var(--brand-ground, #10192a) 50%, transparent) 0%,
|
|
67
|
+
color-mix(in srgb, var(--brand-ground, #10192a) 0%, transparent) 55%
|
|
62
68
|
);
|
|
63
69
|
}
|
|
64
70
|
|
|
@@ -111,7 +117,7 @@
|
|
|
111
117
|
top: 50%;
|
|
112
118
|
width: 1.5rem;
|
|
113
119
|
height: 2px;
|
|
114
|
-
background: var(--flag);
|
|
120
|
+
background: var(--flag, #8a8f98);
|
|
115
121
|
}
|
|
116
122
|
}
|
|
117
123
|
|
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
gap: 0.4rem;
|
|
19
19
|
width: max-content;
|
|
20
20
|
min-height: var(--control-height, 2.5rem);
|
|
21
|
-
padding: 0 var(--spacing-md);
|
|
21
|
+
padding: 0 var(--spacing-md, 1rem);
|
|
22
22
|
border: 1px solid transparent;
|
|
23
|
-
border-radius: var(--radius-sm);
|
|
24
|
-
font-family: var(--font-family);
|
|
23
|
+
border-radius: var(--radius-sm, 8px);
|
|
24
|
+
font-family: var(--font-family, inherit);
|
|
25
25
|
// Was 1rem against 15px body text, so buttons shouted slightly.
|
|
26
|
-
font-size: var(--font-size-sm);
|
|
27
|
-
font-weight: var(--font-weight-semibold);
|
|
26
|
+
font-size: var(--font-size-sm, 0.8125rem);
|
|
27
|
+
font-weight: var(--font-weight-semibold, 600);
|
|
28
28
|
line-height: 1;
|
|
29
29
|
text-decoration: none;
|
|
30
30
|
white-space: nowrap;
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
// Was `all 0.2s`, which animates layout properties too and makes hover
|
|
33
33
|
// feel laggy. Only what actually changes.
|
|
34
34
|
transition:
|
|
35
|
-
background-color var(--speed) var(--ease),
|
|
36
|
-
border-color var(--speed) var(--ease),
|
|
37
|
-
color var(--speed) var(--ease);
|
|
35
|
+
background-color var(--speed, 160ms) var(--ease, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
36
|
+
border-color var(--speed, 160ms) var(--ease, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
37
|
+
color var(--speed, 160ms) var(--ease, cubic-bezier(0.4, 0, 0.2, 1));
|
|
38
38
|
|
|
39
39
|
&:disabled,
|
|
40
40
|
&[aria-disabled='true'] {
|
|
@@ -42,21 +42,25 @@
|
|
|
42
42
|
cursor: not-allowed;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
// Focus
|
|
46
|
-
//
|
|
47
|
-
//
|
|
45
|
+
// Focus was documented as "handled globally by the app's _focus.scss" —
|
|
46
|
+
// a file that does not exist in this package, so every shared control
|
|
47
|
+
// shipped with browser-default focus only. It is handled here now.
|
|
48
|
+
&:focus-visible {
|
|
49
|
+
outline: 2px solid var(--highlight-color, #3cbf7d);
|
|
50
|
+
outline-offset: 2px;
|
|
51
|
+
}
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
@mixin button-primary {
|
|
51
55
|
@include button-base;
|
|
52
56
|
|
|
53
|
-
background: var(--primary-color);
|
|
54
|
-
border-color: var(--primary-color);
|
|
57
|
+
background: var(--primary-color, #1b3933);
|
|
58
|
+
border-color: var(--primary-color, #1b3933);
|
|
55
59
|
color: #fff;
|
|
56
60
|
|
|
57
61
|
&:hover:not(:disabled) {
|
|
58
|
-
background: var(--primary-color-darker);
|
|
59
|
-
border-color: var(--primary-color-darker);
|
|
62
|
+
background: var(--primary-color-darker, #12241f);
|
|
63
|
+
border-color: var(--primary-color-darker, #12241f);
|
|
60
64
|
// Was a light-blue fill with navy text, which dropped below a legible
|
|
61
65
|
// contrast on hover — the one state where feedback matters most.
|
|
62
66
|
color: #fff;
|
|
@@ -66,13 +70,13 @@
|
|
|
66
70
|
@mixin button-secondary {
|
|
67
71
|
@include button-base;
|
|
68
72
|
|
|
69
|
-
background: var(--paper);
|
|
70
|
-
border-color: var(--border-color);
|
|
71
|
-
color: var(--text-color);
|
|
73
|
+
background: var(--paper, #fff);
|
|
74
|
+
border-color: var(--border-color, #e1e1e1);
|
|
75
|
+
color: var(--text-color, #2b2b2b);
|
|
72
76
|
|
|
73
77
|
&:hover:not(:disabled) {
|
|
74
|
-
border-color: var(--border-color-dark);
|
|
75
|
-
background: var(--hover-color);
|
|
78
|
+
border-color: var(--border-color-dark, #c9c9c9);
|
|
79
|
+
background: var(--hover-color, rgba(27, 57, 51, 0.06));
|
|
76
80
|
}
|
|
77
81
|
}
|
|
78
82
|
|
|
@@ -81,10 +85,10 @@
|
|
|
81
85
|
|
|
82
86
|
background: none;
|
|
83
87
|
border-color: transparent;
|
|
84
|
-
color: var(--primary-color);
|
|
88
|
+
color: var(--primary-color, #1b3933);
|
|
85
89
|
|
|
86
90
|
&:hover:not(:disabled) {
|
|
87
|
-
background: var(--primary-color-light);
|
|
91
|
+
background: var(--primary-color-light, rgba(27, 57, 51, 0.16));
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
|
|
@@ -93,18 +97,18 @@
|
|
|
93
97
|
|
|
94
98
|
background: none;
|
|
95
99
|
border-color: transparent;
|
|
96
|
-
color: var(--danger-color);
|
|
100
|
+
color: var(--danger-color, #be3e3e);
|
|
97
101
|
|
|
98
102
|
&:hover:not(:disabled) {
|
|
99
|
-
background: var(--danger-light);
|
|
100
|
-
border-color: var(--danger-color);
|
|
103
|
+
background: var(--danger-light, rgba(190, 62, 62, 0.12));
|
|
104
|
+
border-color: var(--danger-color, #be3e3e);
|
|
101
105
|
}
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
@mixin button-small {
|
|
105
109
|
min-height: var(--control-height-sm, 2rem);
|
|
106
|
-
padding: 0 var(--spacing-sm);
|
|
107
|
-
font-size: var(--font-size-xs);
|
|
110
|
+
padding: 0 var(--spacing-sm, 0.5rem);
|
|
111
|
+
font-size: var(--font-size-xs, 0.75rem);
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
/* --- Inputs -------------------------------------------------------------- */
|
|
@@ -113,27 +117,27 @@
|
|
|
113
117
|
width: 100%;
|
|
114
118
|
min-height: var(--control-height, 2.5rem);
|
|
115
119
|
padding: 0 var(--input-padding-x, 0.65rem);
|
|
116
|
-
border: 1px solid var(--border-color);
|
|
117
|
-
border-radius: var(--radius-sm);
|
|
118
|
-
background: var(--paper);
|
|
119
|
-
font-family: var(--font-family);
|
|
120
|
-
font-size: var(--font-size-md);
|
|
121
|
-
color: var(--text-color);
|
|
120
|
+
border: 1px solid var(--border-color, #e1e1e1);
|
|
121
|
+
border-radius: var(--radius-sm, 8px);
|
|
122
|
+
background: var(--paper, #fff);
|
|
123
|
+
font-family: var(--font-family, inherit);
|
|
124
|
+
font-size: var(--font-size-md, 0.9375rem);
|
|
125
|
+
color: var(--text-color, #2b2b2b);
|
|
122
126
|
transition:
|
|
123
|
-
border-color var(--speed) var(--ease),
|
|
124
|
-
box-shadow var(--speed) var(--ease);
|
|
127
|
+
border-color var(--speed, 160ms) var(--ease, cubic-bezier(0.4, 0, 0.2, 1)),
|
|
128
|
+
box-shadow var(--speed, 160ms) var(--ease, cubic-bezier(0.4, 0, 0.2, 1));
|
|
125
129
|
|
|
126
130
|
&::placeholder {
|
|
127
|
-
color: var(--muted-color);
|
|
131
|
+
color: var(--muted-color, rgba(43, 60, 43, 0.72));
|
|
128
132
|
}
|
|
129
133
|
|
|
130
134
|
&:hover:not(:disabled) {
|
|
131
|
-
border-color: var(--border-color-dark);
|
|
135
|
+
border-color: var(--border-color-dark, #c9c9c9);
|
|
132
136
|
}
|
|
133
137
|
|
|
134
138
|
&:disabled {
|
|
135
|
-
background: var(--bg-color-secondary);
|
|
136
|
-
color: var(--disabled-color);
|
|
139
|
+
background: var(--bg-color-secondary, #eeece7);
|
|
140
|
+
color: var(--disabled-color, rgba(43, 60, 43, 0.38));
|
|
137
141
|
cursor: not-allowed;
|
|
138
142
|
}
|
|
139
143
|
}
|