@visns-studio/visns-components 6.0.4 → 6.0.5
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 +1 -1
- package/src/components/DataGrid.jsx +30 -12
- package/src/components/auth/Login.jsx +203 -175
- package/src/components/columns/ColumnRenderers.jsx +34 -0
- package/src/components/generic/GenericFormBuilder.jsx +550 -25
- package/src/components/generic/GenericIndex.jsx +15 -5
- package/src/components/styles/DataGrid.module.scss +38 -22
- package/src/components/styles/Form.module.scss +32 -33
- package/src/components/styles/GenericDetail.module.scss +28 -30
- package/src/components/styles/GenericDynamic.module.scss +7 -21
- package/src/components/styles/GenericEditableTable.module.scss +5 -22
- package/src/components/styles/GenericFormBuilder.module.scss +545 -30
- package/src/components/styles/GenericIndex.module.scss +17 -32
- package/src/components/styles/GenericMain.module.scss +18 -6
- package/src/components/styles/GenericQuote.module.scss +7 -22
- package/src/components/styles/GenericReport.module.scss +5 -37
- package/src/components/styles/Login.module.scss +415 -239
- package/src/components/styles/Navigation.module.scss +124 -35
- package/src/components/styles/Profile.module.scss +5 -26
- package/src/components/styles/QuickAction.module.scss +34 -29
- package/src/components/styles/_controls.scss +139 -0
- package/src/components/styles/global.css +54 -15
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
padding: 0;
|
|
12
12
|
margin: 0;
|
|
13
13
|
line-height: 1.45;
|
|
14
|
-
|
|
14
|
+
/* The mark and the navigation were butted together, reading as one
|
|
15
|
+
run of items. A hairline gives the logo its own territory. */
|
|
16
|
+
margin-right: var(--spacing-md);
|
|
17
|
+
padding-right: var(--spacing-md);
|
|
18
|
+
border-right: 1px solid rgba(255, 255, 255, 0.18);
|
|
15
19
|
|
|
16
20
|
.logoButton {
|
|
17
21
|
background: none;
|
|
@@ -101,19 +105,24 @@
|
|
|
101
105
|
a,
|
|
102
106
|
span,
|
|
103
107
|
button {
|
|
104
|
-
font-size:
|
|
108
|
+
font-size: var(--font-size-sm);
|
|
109
|
+
font-weight: var(--font-weight-medium);
|
|
105
110
|
display: flex;
|
|
106
111
|
flex-wrap: nowrap;
|
|
107
112
|
align-items: center;
|
|
108
|
-
gap: 0.
|
|
113
|
+
gap: 0.35rem;
|
|
109
114
|
box-sizing: border-box;
|
|
110
|
-
|
|
115
|
+
/* Was 0.35em/0.5em — a tap target under the 44px guideline and
|
|
116
|
+
visually cramped against the taller header. */
|
|
117
|
+
padding: 0.55rem 0.7rem;
|
|
111
118
|
margin: 0;
|
|
112
119
|
line-height: 1;
|
|
113
120
|
text-decoration: none;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
transition:
|
|
121
|
+
border-radius: var(--radius-sm);
|
|
122
|
+
/* `all` also animated layout properties. Only what changes. */
|
|
123
|
+
transition:
|
|
124
|
+
background-color var(--speed) var(--ease),
|
|
125
|
+
color var(--speed) var(--ease);
|
|
117
126
|
background: none;
|
|
118
127
|
border: none;
|
|
119
128
|
cursor: pointer;
|
|
@@ -124,7 +133,16 @@
|
|
|
124
133
|
a,
|
|
125
134
|
span,
|
|
126
135
|
button {
|
|
127
|
-
color:
|
|
136
|
+
color: rgba(255, 255, 255, 0.82);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* Nothing responded to the pointer unless it was already the
|
|
140
|
+
active page, so the bar felt inert. */
|
|
141
|
+
&:not(.active):hover a,
|
|
142
|
+
&:not(.active):hover span,
|
|
143
|
+
&:not(.active):hover button {
|
|
144
|
+
background: rgba(255, 255, 255, 0.12);
|
|
145
|
+
color: #fff;
|
|
128
146
|
}
|
|
129
147
|
|
|
130
148
|
svg {
|
|
@@ -133,19 +151,21 @@
|
|
|
133
151
|
visibility: hidden;
|
|
134
152
|
}
|
|
135
153
|
|
|
136
|
-
|
|
154
|
+
/* Only the current page wears the brand red. Hover shared it
|
|
155
|
+
before, so pointing at any item made it look selected and the
|
|
156
|
+
real active item was impossible to pick out while moving the
|
|
157
|
+
mouse across the bar. Hover is handled above, as a quiet lift. */
|
|
137
158
|
&.active a,
|
|
138
|
-
&:hover span,
|
|
139
159
|
&.active span,
|
|
140
|
-
&:hover button,
|
|
141
160
|
&.active button {
|
|
142
|
-
background:
|
|
143
|
-
color:
|
|
161
|
+
background: var(--secondary-color);
|
|
162
|
+
color: #fff;
|
|
163
|
+
font-weight: var(--font-weight-semibold);
|
|
144
164
|
}
|
|
145
165
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
color:
|
|
166
|
+
&.active svg,
|
|
167
|
+
&:hover svg {
|
|
168
|
+
color: #fff;
|
|
149
169
|
}
|
|
150
170
|
|
|
151
171
|
> ul {
|
|
@@ -330,11 +350,34 @@
|
|
|
330
350
|
justify-self: end;
|
|
331
351
|
position: relative;
|
|
332
352
|
z-index: 1000; // Higher z-index to stay above sticky header
|
|
353
|
+
/* Account actions are a different kind of thing from page navigation, so
|
|
354
|
+
a hairline separates them rather than leaving one undifferentiated row
|
|
355
|
+
of targets. */
|
|
356
|
+
padding-left: var(--spacing-md);
|
|
357
|
+
margin-left: var(--spacing-sm);
|
|
333
358
|
|
|
334
359
|
> ul {
|
|
335
360
|
list-style: none;
|
|
336
361
|
display: flex;
|
|
337
|
-
|
|
362
|
+
/* A faint inset holds the icons together as one group rather than
|
|
363
|
+
leaving them as loose targets floating in the bar.
|
|
364
|
+
Deliberately count-agnostic: projects mount a different number of
|
|
365
|
+
actions here, so this is padding and a pill radius rather than
|
|
366
|
+
anything sized to a fixed set. If a project mounts more than fits,
|
|
367
|
+
the group scrolls instead of pushing the navigation. */
|
|
368
|
+
background: rgba(255, 255, 255, 0.1);
|
|
369
|
+
border-radius: var(--radius-pill);
|
|
370
|
+
/* An even ring around the chips; any more and the group reads as a
|
|
371
|
+
separate control rather than a container for them. */
|
|
372
|
+
padding: 4px;
|
|
373
|
+
max-width: 100%;
|
|
374
|
+
overflow-x: auto;
|
|
375
|
+
scrollbar-width: none;
|
|
376
|
+
|
|
377
|
+
&::-webkit-scrollbar {
|
|
378
|
+
display: none;
|
|
379
|
+
}
|
|
380
|
+
|
|
338
381
|
margin: 0;
|
|
339
382
|
flex-wrap: nowrap;
|
|
340
383
|
flex-direction: row;
|
|
@@ -356,39 +399,85 @@
|
|
|
356
399
|
z-index: 1002;
|
|
357
400
|
}
|
|
358
401
|
|
|
359
|
-
a
|
|
402
|
+
a,
|
|
403
|
+
button {
|
|
360
404
|
color: var(--tertiary-color);
|
|
361
405
|
box-sizing: border-box;
|
|
362
|
-
padding: 0.35rem;
|
|
363
406
|
text-decoration: none;
|
|
364
407
|
background: none;
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
408
|
+
font: inherit;
|
|
409
|
+
padding: 0;
|
|
410
|
+
/* Was a 1px border in the header's own colour — invisible, but it
|
|
411
|
+
still consumed the ring of space that would have made these
|
|
412
|
+
read as buttons. */
|
|
413
|
+
border: none;
|
|
414
|
+
/* Circular, so each chip nests inside the pill-shaped group at any
|
|
415
|
+
position — a rounded square cut across the container's curve at
|
|
416
|
+
the two ends. Also stays correct however many actions a project
|
|
417
|
+
mounts, since no chip is styled by its position. */
|
|
418
|
+
border-radius: var(--radius-pill);
|
|
419
|
+
/* `all` animated layout too; and the hover scale made the icons
|
|
420
|
+
wobble against a static header. Colour alone is enough feedback
|
|
421
|
+
on a 36px target. */
|
|
422
|
+
transition: background-color var(--speed) var(--ease);
|
|
368
423
|
display: flex;
|
|
369
424
|
align-items: center;
|
|
370
425
|
justify-content: center;
|
|
371
|
-
|
|
372
|
-
|
|
426
|
+
/* 32px was below the 44px guideline and awkward to hit. */
|
|
427
|
+
width: 36px;
|
|
428
|
+
height: 36px;
|
|
373
429
|
position: relative;
|
|
374
430
|
z-index: 1003;
|
|
375
|
-
transform: translateZ(0) translateX(0) translateY(0); // Force compositor layer
|
|
376
|
-
will-change: transform, background-color; // Optimize for animations
|
|
377
|
-
/* Remove contain: layout to prevent rendering optimization conflicts */
|
|
378
|
-
outline: none;
|
|
379
431
|
appearance: none;
|
|
380
|
-
backface-visibility: hidden; // Prevent rendering glitches
|
|
381
|
-
-webkit-backface-visibility: hidden;
|
|
382
|
-
/* Force onto own layer to prevent culling */
|
|
383
|
-
isolation: isolate;
|
|
384
432
|
|
|
433
|
+
/* Brand red on hover, matching the rest of the bar. A neutral
|
|
434
|
+
white lift read as a system default rather than a Prime
|
|
435
|
+
control, and left this cluster looking unrelated to everything
|
|
436
|
+
around it. */
|
|
385
437
|
&:hover,
|
|
386
438
|
&.active {
|
|
387
|
-
background: var(--
|
|
388
|
-
transform: translateZ(0) scale(1.05); // Slight scale on hover
|
|
439
|
+
background: var(--secondary-color);
|
|
389
440
|
|
|
390
441
|
svg {
|
|
391
|
-
color:
|
|
442
|
+
color: #fff !important;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
svg {
|
|
447
|
+
/* Components mounted here (notifications, switch account)
|
|
448
|
+
colour their own icons, which is why they hovered
|
|
449
|
+
differently from the plain links beside them. */
|
|
450
|
+
color: var(--tertiary-color);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/* Components mounted into this cluster ship their own trigger styles —
|
|
455
|
+
the notification bell is 40px with its own hover fill and a scale
|
|
456
|
+
transform, against 36px flat siblings. Rather than chase each one by
|
|
457
|
+
name, normalise any button nested inside a wrapper element so the
|
|
458
|
+
cluster stays uniform however a project fills it. */
|
|
459
|
+
li > div,
|
|
460
|
+
li > span {
|
|
461
|
+
display: flex;
|
|
462
|
+
align-items: center;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
li button {
|
|
466
|
+
width: 36px;
|
|
467
|
+
height: 36px;
|
|
468
|
+
min-width: 36px;
|
|
469
|
+
padding: 0;
|
|
470
|
+
border-radius: var(--radius-pill) !important;
|
|
471
|
+
background: none;
|
|
472
|
+
transform: none !important;
|
|
473
|
+
color: var(--tertiary-color);
|
|
474
|
+
|
|
475
|
+
&:hover {
|
|
476
|
+
background: var(--secondary-color) !important;
|
|
477
|
+
color: #fff;
|
|
478
|
+
|
|
479
|
+
svg {
|
|
480
|
+
color: #fff !important;
|
|
392
481
|
}
|
|
393
482
|
}
|
|
394
483
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
@use 'controls' as *;
|
|
2
|
+
|
|
3
|
+
.btn {
|
|
4
|
+
@include button-primary;
|
|
5
|
+
}
|
|
1
6
|
/* Profile.module.scss */
|
|
2
7
|
|
|
3
8
|
/* Form field label animation */
|
|
@@ -295,33 +300,7 @@ select:focus + .fi__span {
|
|
|
295
300
|
}
|
|
296
301
|
}
|
|
297
302
|
|
|
298
|
-
.btn {
|
|
299
|
-
width: max-content;
|
|
300
|
-
display: inline-block;
|
|
301
|
-
position: relative;
|
|
302
|
-
padding: 0.65rem 1rem;
|
|
303
|
-
cursor: pointer;
|
|
304
|
-
font-size: 1rem;
|
|
305
|
-
color: var(--secondary-color);
|
|
306
|
-
text-decoration: none;
|
|
307
|
-
overflow: hidden;
|
|
308
|
-
background: var(--primary-color);
|
|
309
|
-
border: 1px solid rgba(var(--primary-rgb), 1.1);
|
|
310
|
-
border-radius: var(--br);
|
|
311
|
-
outline: none;
|
|
312
|
-
transition: all 0.2s cubic-bezier(0.85, 0, 0.15, 1) 0s;
|
|
313
303
|
|
|
314
|
-
&:hover:not(:disabled) {
|
|
315
|
-
color: var(--tertiary-color);
|
|
316
|
-
background: var(--secondary-color);
|
|
317
|
-
border: 1px solid rgba(var(--secondary-color-rgb), 1.1);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
&:disabled {
|
|
321
|
-
opacity: 0.6;
|
|
322
|
-
cursor: not-allowed;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
304
|
|
|
326
305
|
.inputError {
|
|
327
306
|
border-color: red !important;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
.quickActions {
|
|
2
2
|
width: 100%;
|
|
3
|
-
background:
|
|
4
|
-
padding:
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
background: var(--surface-color);
|
|
4
|
+
padding: var(--spacing-sm) clamp(var(--spacing-md), 3vw, var(--spacing-xl));
|
|
5
|
+
/* Was a 3px tinted top rule plus a 1px bottom rule plus a shadow — three
|
|
6
|
+
separators stacked on one strip, which made it read as a heavier
|
|
7
|
+
element than the header above it. One hairline is enough. */
|
|
8
|
+
border-top: none;
|
|
9
|
+
border-bottom: 1px solid var(--border-color);
|
|
7
10
|
color: var(--paragraph-color);
|
|
8
11
|
display: flex;
|
|
9
12
|
flex-wrap: wrap;
|
|
10
13
|
align-items: center;
|
|
11
|
-
box-shadow:
|
|
14
|
+
box-shadow: none;
|
|
12
15
|
overflow: visible; /* Ensure dropdowns are visible */
|
|
13
16
|
position: relative; /* Create a stacking context */
|
|
14
17
|
z-index: 100; /* Ensure proper stacking */
|
|
@@ -20,49 +23,51 @@
|
|
|
20
23
|
display: flex;
|
|
21
24
|
align-items: center;
|
|
22
25
|
justify-content: center;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
/* A label, not a control — it does nothing when clicked, so a filled
|
|
27
|
+
circle that lights up on hover was promising an action it does not
|
|
28
|
+
have. */
|
|
29
|
+
background: none;
|
|
30
|
+
border-radius: var(--radius-sm);
|
|
31
|
+
margin-right: var(--spacing-sm);
|
|
32
|
+
padding-right: var(--spacing-sm);
|
|
26
33
|
position: relative;
|
|
27
|
-
color:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
&:hover {
|
|
31
|
-
background-color: rgba(var(--primary-rgb), 0.12);
|
|
32
|
-
transform: scale(1.05);
|
|
33
|
-
}
|
|
34
|
+
color: var(--muted-color);
|
|
35
|
+
flex: none;
|
|
34
36
|
|
|
35
37
|
&::after {
|
|
36
38
|
content: '';
|
|
37
39
|
position: absolute;
|
|
38
|
-
right:
|
|
40
|
+
right: 0;
|
|
39
41
|
top: 50%;
|
|
40
42
|
transform: translateY(-50%);
|
|
41
43
|
height: 60%;
|
|
42
44
|
width: 1px;
|
|
43
|
-
background-color:
|
|
45
|
+
background-color: var(--border-color);
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
> button {
|
|
48
50
|
appearance: none;
|
|
49
|
-
border: 1px solid
|
|
50
|
-
border-radius: var(--
|
|
51
|
-
background:
|
|
51
|
+
border: 1px solid var(--border-color);
|
|
52
|
+
border-radius: var(--radius-sm);
|
|
53
|
+
background: var(--surface-color);
|
|
52
54
|
width: max-content;
|
|
53
|
-
color: var(--
|
|
54
|
-
padding: 0
|
|
55
|
-
margin: 0
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
color: var(--text-color);
|
|
56
|
+
padding: 0 var(--spacing-md);
|
|
57
|
+
margin: 0;
|
|
58
|
+
/* Matches the button mixin used everywhere else, so quick actions and
|
|
59
|
+
page buttons are the same size and weight. */
|
|
60
|
+
font-size: var(--font-size-sm);
|
|
61
|
+
font-weight: var(--font-weight-semibold);
|
|
62
|
+
transition:
|
|
63
|
+
background-color var(--speed) var(--ease),
|
|
64
|
+
border-color var(--speed) var(--ease);
|
|
65
|
+
box-shadow: none;
|
|
60
66
|
display: flex;
|
|
61
67
|
align-items: center;
|
|
62
68
|
justify-content: center;
|
|
63
|
-
min-height:
|
|
69
|
+
min-height: 2.5rem;
|
|
64
70
|
position: relative;
|
|
65
|
-
overflow: hidden;
|
|
66
71
|
|
|
67
72
|
&::before {
|
|
68
73
|
content: '';
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared control definitions.
|
|
3
|
+
*
|
|
4
|
+
* `.btn` was copy-pasted into ten stylesheets and had drifted into seven
|
|
5
|
+
* different definitions — different paddings, font sizes, borders and hover
|
|
6
|
+
* behaviour, all called the same thing. CSS modules hash each class per file,
|
|
7
|
+
* so a single global `.btn` cannot reach them; a mixin can, and each file
|
|
8
|
+
* keeps its own scoped class while the definition lives in one place.
|
|
9
|
+
*
|
|
10
|
+
* Every variant shares a height, radius, weight and focus treatment, so they
|
|
11
|
+
* line up when placed side by side.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
@mixin button-base {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
gap: 0.4rem;
|
|
19
|
+
width: max-content;
|
|
20
|
+
min-height: 2.5rem;
|
|
21
|
+
padding: 0 var(--spacing-md);
|
|
22
|
+
border: 1px solid transparent;
|
|
23
|
+
border-radius: var(--radius-sm);
|
|
24
|
+
font-family: var(--font-family);
|
|
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);
|
|
28
|
+
line-height: 1;
|
|
29
|
+
text-decoration: none;
|
|
30
|
+
white-space: nowrap;
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
// Was `all 0.2s`, which animates layout properties too and makes hover
|
|
33
|
+
// feel laggy. Only what actually changes.
|
|
34
|
+
transition:
|
|
35
|
+
background-color var(--speed) var(--ease),
|
|
36
|
+
border-color var(--speed) var(--ease),
|
|
37
|
+
color var(--speed) var(--ease);
|
|
38
|
+
|
|
39
|
+
&:disabled,
|
|
40
|
+
&[aria-disabled='true'] {
|
|
41
|
+
opacity: 0.55;
|
|
42
|
+
cursor: not-allowed;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Focus is handled globally by the app's _focus.scss; nothing here removes
|
|
46
|
+
// the outline, which is what created the accessibility gap in the first
|
|
47
|
+
// place.
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@mixin button-primary {
|
|
51
|
+
@include button-base;
|
|
52
|
+
|
|
53
|
+
background: var(--primary-color);
|
|
54
|
+
border-color: var(--primary-color);
|
|
55
|
+
color: #fff;
|
|
56
|
+
|
|
57
|
+
&:hover:not(:disabled) {
|
|
58
|
+
background: var(--primary-color-darker);
|
|
59
|
+
border-color: var(--primary-color-darker);
|
|
60
|
+
// Was a light-blue fill with navy text, which dropped below a legible
|
|
61
|
+
// contrast on hover — the one state where feedback matters most.
|
|
62
|
+
color: #fff;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@mixin button-secondary {
|
|
67
|
+
@include button-base;
|
|
68
|
+
|
|
69
|
+
background: var(--paper);
|
|
70
|
+
border-color: var(--border-color);
|
|
71
|
+
color: var(--text-color);
|
|
72
|
+
|
|
73
|
+
&:hover:not(:disabled) {
|
|
74
|
+
border-color: var(--border-color-dark);
|
|
75
|
+
background: var(--hover-color);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@mixin button-ghost {
|
|
80
|
+
@include button-base;
|
|
81
|
+
|
|
82
|
+
background: none;
|
|
83
|
+
border-color: transparent;
|
|
84
|
+
color: var(--primary-color);
|
|
85
|
+
|
|
86
|
+
&:hover:not(:disabled) {
|
|
87
|
+
background: var(--primary-color-light);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@mixin button-danger {
|
|
92
|
+
@include button-base;
|
|
93
|
+
|
|
94
|
+
background: none;
|
|
95
|
+
border-color: transparent;
|
|
96
|
+
color: var(--danger-color);
|
|
97
|
+
|
|
98
|
+
&:hover:not(:disabled) {
|
|
99
|
+
background: var(--danger-light);
|
|
100
|
+
border-color: var(--danger-color);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@mixin button-small {
|
|
105
|
+
min-height: 2rem;
|
|
106
|
+
padding: 0 var(--spacing-sm);
|
|
107
|
+
font-size: var(--font-size-xs);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* --- Inputs -------------------------------------------------------------- */
|
|
111
|
+
|
|
112
|
+
@mixin input-base {
|
|
113
|
+
width: 100%;
|
|
114
|
+
min-height: 2.5rem;
|
|
115
|
+
padding: 0 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);
|
|
122
|
+
transition:
|
|
123
|
+
border-color var(--speed) var(--ease),
|
|
124
|
+
box-shadow var(--speed) var(--ease);
|
|
125
|
+
|
|
126
|
+
&::placeholder {
|
|
127
|
+
color: var(--muted-color);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
&:hover:not(:disabled) {
|
|
131
|
+
border-color: var(--border-color-dark);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
&:disabled {
|
|
135
|
+
background: var(--bg-color-secondary);
|
|
136
|
+
color: var(--disabled-color);
|
|
137
|
+
cursor: not-allowed;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -10,24 +10,26 @@
|
|
|
10
10
|
|
|
11
11
|
html,
|
|
12
12
|
body {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
/* Was a hardcoded system stack, which overrode the app's font because this
|
|
14
|
+
file is injected after the entry stylesheet. Through the token it
|
|
15
|
+
follows whatever the app defines. */
|
|
16
|
+
font-family: var(--font-family, system-ui, sans-serif);
|
|
16
17
|
height: 100%;
|
|
17
|
-
text-rendering:
|
|
18
|
-
font-stretch: 75% 125%;
|
|
18
|
+
text-rendering: optimizeLegibility;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
body {
|
|
22
22
|
background: var(--bg-color);
|
|
23
23
|
font-weight: var(--para-weight);
|
|
24
|
-
font-family: -
|
|
25
|
-
Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
|
26
|
-
'Segoe UI Symbol';
|
|
24
|
+
font-family: var(--font-family, system-ui, sans-serif);
|
|
27
25
|
font-style: normal;
|
|
28
26
|
overflow-x: hidden;
|
|
29
27
|
overscroll-behavior: none;
|
|
30
|
-
|
|
28
|
+
/* Was 0.85rem (13.6px) — small enough that every component had to size up
|
|
29
|
+
from it. Now the body step of the scale. */
|
|
30
|
+
font-size: var(--font-size-md, 0.9375rem);
|
|
31
|
+
line-height: var(--para-height, 1.6);
|
|
32
|
+
color: var(--text-color, #1f2a37);
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
input,
|
|
@@ -130,24 +132,61 @@ select {
|
|
|
130
132
|
appearance: none;
|
|
131
133
|
}
|
|
132
134
|
|
|
135
|
+
/* A real scale. These carried colour and weight but no size, so every heading
|
|
136
|
+
fell back to the browser default — a hierarchy inherited rather than chosen,
|
|
137
|
+
and unrelated to the body size beneath it. Sizes come from the tokens, with
|
|
138
|
+
fallbacks so this file still stands alone. */
|
|
133
139
|
h1,
|
|
134
140
|
h2,
|
|
135
141
|
h3,
|
|
136
142
|
h4,
|
|
137
143
|
h5,
|
|
138
144
|
h6 {
|
|
139
|
-
color: var(--
|
|
140
|
-
font-weight: var(--
|
|
141
|
-
line-height: var(--title-height);
|
|
142
|
-
|
|
145
|
+
color: var(--heading-color, #10192a);
|
|
146
|
+
font-weight: var(--font-weight-bold, 700);
|
|
147
|
+
line-height: var(--title-height, 1.25);
|
|
148
|
+
/* Was +0.015rem. Barlow opens up as it scales, so the display sizes want
|
|
149
|
+
pulling in, not pushing apart. */
|
|
150
|
+
letter-spacing: -0.01em;
|
|
151
|
+
margin: 0 0 var(--spacing-sm, 0.5rem);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
h1 {
|
|
155
|
+
font-size: var(--font-size-2xl, 1.75rem);
|
|
156
|
+
letter-spacing: -0.02em;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
h2 {
|
|
160
|
+
font-size: var(--font-size-xl, 1.375rem);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
h3 {
|
|
164
|
+
font-size: var(--font-size-lg, 1.125rem);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
h4 {
|
|
168
|
+
font-size: var(--font-size-md, 0.9375rem);
|
|
169
|
+
font-weight: var(--font-weight-semibold, 600);
|
|
170
|
+
letter-spacing: 0;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
h5,
|
|
174
|
+
h6 {
|
|
175
|
+
font-size: var(--font-size-sm, 0.8125rem);
|
|
176
|
+
font-weight: var(--font-weight-semibold, 600);
|
|
177
|
+
letter-spacing: 0.02em;
|
|
178
|
+
text-transform: uppercase;
|
|
179
|
+
color: var(--muted-color, #6b7688);
|
|
143
180
|
}
|
|
144
181
|
|
|
145
182
|
p {
|
|
146
|
-
|
|
183
|
+
/* Was clamp(1rem, 2vw, 1.25rem) — up to 20px, larger than the body text
|
|
184
|
+
around it, which inverted the hierarchy on every screen. */
|
|
185
|
+
font-size: inherit;
|
|
147
186
|
color: var(--paragraph-color);
|
|
148
187
|
font-weight: var(--para-weight);
|
|
149
188
|
line-height: var(--para-height);
|
|
150
|
-
margin-bottom: 1rem;
|
|
189
|
+
margin-bottom: var(--spacing-md, 1rem);
|
|
151
190
|
|
|
152
191
|
@media (max-width: 1024px) {
|
|
153
192
|
font-size: clamp(0.85rem, 2vw, 0.95rem);
|