@webority/theme 0.7.5 → 0.7.6
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/webority-theme.css +1 -1
- package/package.json +1 -1
- package/scss/_components.scss +13 -8
- package/scss/_tokens.scss +10 -2
- package/scss/_wui-aliases.scss +11 -3
- package/scss/wui/_card.scss +138 -0
- package/scss/wui/_choice.scss +124 -2
- package/scss/wui/_controls.scss +228 -3
- package/scss/wui/_data.scss +26 -13
- package/scss/wui/_display.scss +160 -1
- package/scss/wui/_flow.scss +216 -7
- package/scss/wui/_media.scss +264 -14
- package/scss/wui/_navigation.scss +1 -1
- package/scss/wui/_overlays.scss +45 -1
- package/scss/wui/_typography.scss +16 -0
- package/scss/wui/_utilities.scss +141 -6
package/scss/wui/_media.scss
CHANGED
|
@@ -6,26 +6,55 @@
|
|
|
6
6
|
// here may be overridden by a later partial. Never reorder the imports.
|
|
7
7
|
|
|
8
8
|
// ── Avatar ──
|
|
9
|
-
//
|
|
10
|
-
// the
|
|
9
|
+
// The initials/icon face is the base layer; a photo overlays it edge to edge, cropped
|
|
10
|
+
// to the disc. While the photo loads — or if it breaks — the face shows through.
|
|
11
|
+
.avatar-face {
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
line-height: 1;
|
|
16
|
+
}
|
|
11
17
|
.avatar > .avatar-img {
|
|
18
|
+
position: absolute;
|
|
19
|
+
inset: 0;
|
|
12
20
|
width: 100%;
|
|
13
21
|
height: 100%;
|
|
14
22
|
border-radius: inherit;
|
|
15
23
|
object-fit: cover;
|
|
16
24
|
display: block;
|
|
25
|
+
// Photo fades + scales in so a late-arriving blob doesn't pop.
|
|
26
|
+
animation: wui-avatar-in 0.28s var(--wui-ease-out-quart, ease) both;
|
|
17
27
|
}
|
|
18
28
|
.avatar {
|
|
19
|
-
|
|
20
|
-
|
|
29
|
+
// `--avatar-size` drives the default (md, its 32px fallback) and any custom size. It is
|
|
30
|
+
// read via `var(… , 32px)` rather than declared here, so an avatar with no size INHERITS
|
|
31
|
+
// one from an AppAvatarGroup that sets it — while a preset class (explicit width below) or
|
|
32
|
+
// an avatar's own inline `--avatar-size` still wins. Never re-declare it on `.avatar`.
|
|
33
|
+
position: relative;
|
|
34
|
+
width: var(--avatar-size, 32px);
|
|
35
|
+
height: var(--avatar-size, 32px);
|
|
21
36
|
border-radius: 999px;
|
|
22
37
|
background: color-mix(in srgb, var(--color-primary) 15%, var(--color-surface));
|
|
23
38
|
color: var(--color-primary);
|
|
24
|
-
font-size:
|
|
39
|
+
font-size: calc(var(--avatar-size, 32px) * 0.375);
|
|
25
40
|
font-weight: 600;
|
|
26
41
|
display: inline-flex;
|
|
27
42
|
align-items: center;
|
|
28
43
|
justify-content: center;
|
|
44
|
+
flex: none;
|
|
45
|
+
user-select: none;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ── Size scale ──
|
|
49
|
+
.avatar-xs {
|
|
50
|
+
width: 20px;
|
|
51
|
+
height: 20px;
|
|
52
|
+
font-size: 8px;
|
|
53
|
+
}
|
|
54
|
+
.avatar-sm {
|
|
55
|
+
width: 24px;
|
|
56
|
+
height: 24px;
|
|
57
|
+
font-size: 10px;
|
|
29
58
|
}
|
|
30
59
|
.avatar-lg {
|
|
31
60
|
width: 48px;
|
|
@@ -37,10 +66,230 @@
|
|
|
37
66
|
height: 64px;
|
|
38
67
|
font-size: 22px;
|
|
39
68
|
}
|
|
40
|
-
.avatar-
|
|
41
|
-
width:
|
|
42
|
-
height:
|
|
69
|
+
.avatar-2xl {
|
|
70
|
+
width: 96px;
|
|
71
|
+
height: 96px;
|
|
72
|
+
font-size: 34px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ── Shape ── (`shape`): the disc is the default; rounded/square are card-like.
|
|
76
|
+
.avatar-rounded {
|
|
77
|
+
border-radius: 25%;
|
|
78
|
+
}
|
|
79
|
+
.avatar-square {
|
|
80
|
+
border-radius: 12%;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ── Tone ── (`tone`): the initials fill. `auto` derives a stable hue from the name.
|
|
84
|
+
.avatar-neutral {
|
|
85
|
+
background: color-mix(in srgb, var(--color-text-muted) 16%, var(--color-surface));
|
|
86
|
+
color: var(--color-text-muted);
|
|
87
|
+
}
|
|
88
|
+
.avatar-success {
|
|
89
|
+
background: var(--color-success-soft);
|
|
90
|
+
color: var(--color-success-text);
|
|
91
|
+
}
|
|
92
|
+
.avatar-warning {
|
|
93
|
+
background: var(--color-warning-soft);
|
|
94
|
+
color: var(--color-warning-text);
|
|
95
|
+
}
|
|
96
|
+
.avatar-danger {
|
|
97
|
+
background: var(--color-danger-soft);
|
|
98
|
+
color: var(--color-danger-text);
|
|
99
|
+
}
|
|
100
|
+
.avatar-info {
|
|
101
|
+
background: var(--color-info-soft);
|
|
102
|
+
color: var(--color-info-text);
|
|
103
|
+
}
|
|
104
|
+
.avatar-auto {
|
|
105
|
+
background: hsl(var(--avatar-hue, 0) 60% 90%);
|
|
106
|
+
color: hsl(var(--avatar-hue, 0) 42% 32%);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ── Ring ── (`ring`): a tone-coloured ring with a surface gap, separating stacked
|
|
110
|
+
// avatars or marking an active one.
|
|
111
|
+
.avatar-ring {
|
|
112
|
+
box-shadow:
|
|
113
|
+
0 0 0 2px var(--color-surface),
|
|
114
|
+
0 0 0 4px currentColor;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ── Corner badge ── (`badge`): a small count/marker at the top-right.
|
|
118
|
+
.avatar-badge {
|
|
119
|
+
position: absolute;
|
|
120
|
+
top: -2px;
|
|
121
|
+
right: -2px;
|
|
122
|
+
display: inline-flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
justify-content: center;
|
|
125
|
+
min-width: 16px;
|
|
126
|
+
height: 16px;
|
|
127
|
+
padding: 0 4px;
|
|
128
|
+
border-radius: 999px;
|
|
129
|
+
background: var(--color-danger);
|
|
130
|
+
color: #fff;
|
|
43
131
|
font-size: 10px;
|
|
132
|
+
font-weight: 700;
|
|
133
|
+
line-height: 1;
|
|
134
|
+
box-shadow: 0 0 0 2px var(--color-surface);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ── Clickable ── (`href` / `onClick`): the whole disc is one control.
|
|
138
|
+
.avatar-clickable {
|
|
139
|
+
padding: 0;
|
|
140
|
+
border: 0;
|
|
141
|
+
font: inherit;
|
|
142
|
+
text-decoration: none;
|
|
143
|
+
cursor: pointer;
|
|
144
|
+
-webkit-appearance: none;
|
|
145
|
+
appearance: none;
|
|
146
|
+
transition:
|
|
147
|
+
transform 0.15s var(--wui-ease-out-quart, ease),
|
|
148
|
+
box-shadow 0.15s ease;
|
|
149
|
+
}
|
|
150
|
+
.avatar-clickable:hover {
|
|
151
|
+
transform: scale(1.06);
|
|
152
|
+
}
|
|
153
|
+
.avatar-clickable:focus-visible {
|
|
154
|
+
outline: 2px solid var(--color-primary);
|
|
155
|
+
outline-offset: 2px;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ── Presence status ── (`status`): a dot at the lower-right, ringed in the surface
|
|
159
|
+
// colour so it reads on a photo. Online quietly pulses.
|
|
160
|
+
.avatar-status {
|
|
161
|
+
position: absolute;
|
|
162
|
+
right: 2%;
|
|
163
|
+
bottom: 2%;
|
|
164
|
+
width: 28%;
|
|
165
|
+
height: 28%;
|
|
166
|
+
min-width: 8px;
|
|
167
|
+
min-height: 8px;
|
|
168
|
+
max-width: 16px;
|
|
169
|
+
max-height: 16px;
|
|
170
|
+
border-radius: 999px;
|
|
171
|
+
box-shadow: 0 0 0 2px var(--color-surface);
|
|
172
|
+
}
|
|
173
|
+
.avatar-status-online {
|
|
174
|
+
background: var(--color-success);
|
|
175
|
+
}
|
|
176
|
+
.avatar-status-away {
|
|
177
|
+
background: var(--color-warning);
|
|
178
|
+
}
|
|
179
|
+
.avatar-status-busy {
|
|
180
|
+
background: var(--color-danger);
|
|
181
|
+
}
|
|
182
|
+
.avatar-status-offline {
|
|
183
|
+
background: color-mix(in srgb, var(--color-text-muted) 55%, var(--color-surface));
|
|
184
|
+
}
|
|
185
|
+
.avatar-status-online::after {
|
|
186
|
+
content: "";
|
|
187
|
+
position: absolute;
|
|
188
|
+
inset: 0;
|
|
189
|
+
border-radius: inherit;
|
|
190
|
+
background: var(--color-success);
|
|
191
|
+
animation: wui-avatar-ping 1.8s cubic-bezier(0, 0, 0.2, 1) infinite;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ── Hover label ── (`label`): a tooltip above the avatar, revealed on hover/focus.
|
|
195
|
+
.avatar-label {
|
|
196
|
+
position: absolute;
|
|
197
|
+
bottom: calc(100% + 8px);
|
|
198
|
+
left: 50%;
|
|
199
|
+
transform: translateX(-50%) translateY(4px);
|
|
200
|
+
padding: 4px 8px;
|
|
201
|
+
border-radius: var(--radius-sm);
|
|
202
|
+
background: var(--color-text);
|
|
203
|
+
color: var(--color-surface);
|
|
204
|
+
font-size: 12px;
|
|
205
|
+
font-weight: 500;
|
|
206
|
+
line-height: 1.2;
|
|
207
|
+
white-space: nowrap;
|
|
208
|
+
opacity: 0;
|
|
209
|
+
pointer-events: none;
|
|
210
|
+
z-index: 30;
|
|
211
|
+
transition:
|
|
212
|
+
opacity 0.16s ease,
|
|
213
|
+
transform 0.16s var(--wui-ease-out-quart, ease);
|
|
214
|
+
}
|
|
215
|
+
.avatar-label::after {
|
|
216
|
+
content: "";
|
|
217
|
+
position: absolute;
|
|
218
|
+
top: 100%;
|
|
219
|
+
left: 50%;
|
|
220
|
+
transform: translateX(-50%);
|
|
221
|
+
border: 4px solid transparent;
|
|
222
|
+
border-top-color: var(--color-text);
|
|
223
|
+
}
|
|
224
|
+
.avatar:hover > .avatar-label,
|
|
225
|
+
.avatar:focus-visible > .avatar-label,
|
|
226
|
+
.avatar:focus-within > .avatar-label {
|
|
227
|
+
opacity: 1;
|
|
228
|
+
transform: translateX(-50%) translateY(0);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ── Avatar group ── (AppAvatarGroup): a row of overlapping avatars, each ringed in the
|
|
232
|
+
// surface colour so it reads against its neighbour. Hover raises one to the front.
|
|
233
|
+
.avatar-group {
|
|
234
|
+
display: inline-flex;
|
|
235
|
+
align-items: center;
|
|
236
|
+
}
|
|
237
|
+
.avatar-group > .avatar {
|
|
238
|
+
margin-left: -10px;
|
|
239
|
+
box-shadow: 0 0 0 2px var(--color-surface);
|
|
240
|
+
transition: transform 0.15s var(--wui-ease-out-quart, ease);
|
|
241
|
+
}
|
|
242
|
+
.avatar-group > .avatar:first-child {
|
|
243
|
+
margin-left: 0;
|
|
244
|
+
}
|
|
245
|
+
.avatar-group > .avatar:hover {
|
|
246
|
+
z-index: 1;
|
|
247
|
+
transform: translateY(-2px);
|
|
248
|
+
}
|
|
249
|
+
.avatar-group-tight > .avatar {
|
|
250
|
+
margin-left: -14px;
|
|
251
|
+
}
|
|
252
|
+
.avatar-group-loose > .avatar {
|
|
253
|
+
margin-left: -4px;
|
|
254
|
+
}
|
|
255
|
+
// The "+N" overflow chip — a muted avatar-shaped tail.
|
|
256
|
+
.avatar-more {
|
|
257
|
+
background: color-mix(in srgb, var(--color-text-muted) 16%, var(--color-surface));
|
|
258
|
+
color: var(--color-text-muted);
|
|
259
|
+
font-weight: 600;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
@keyframes wui-avatar-in {
|
|
263
|
+
from {
|
|
264
|
+
opacity: 0;
|
|
265
|
+
transform: scale(0.92);
|
|
266
|
+
}
|
|
267
|
+
to {
|
|
268
|
+
opacity: 1;
|
|
269
|
+
transform: scale(1);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
@keyframes wui-avatar-ping {
|
|
273
|
+
0% {
|
|
274
|
+
opacity: 0.5;
|
|
275
|
+
transform: scale(1);
|
|
276
|
+
}
|
|
277
|
+
70%,
|
|
278
|
+
100% {
|
|
279
|
+
opacity: 0;
|
|
280
|
+
transform: scale(2.2);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
@media (prefers-reduced-motion: reduce) {
|
|
284
|
+
.avatar > .avatar-img {
|
|
285
|
+
animation: none;
|
|
286
|
+
}
|
|
287
|
+
.avatar-status-online::after {
|
|
288
|
+
animation: none;
|
|
289
|
+
}
|
|
290
|
+
.avatar-label {
|
|
291
|
+
transition: opacity 0.16s ease;
|
|
292
|
+
}
|
|
44
293
|
}
|
|
45
294
|
|
|
46
295
|
// ── File attach ──
|
|
@@ -161,7 +410,7 @@
|
|
|
161
410
|
width: 28px;
|
|
162
411
|
height: 28px;
|
|
163
412
|
border: 0;
|
|
164
|
-
background:
|
|
413
|
+
background: var(--color-scrim-strong);
|
|
165
414
|
backdrop-filter: blur(10px);
|
|
166
415
|
-webkit-backdrop-filter: blur(10px);
|
|
167
416
|
color: #fff;
|
|
@@ -524,8 +773,9 @@
|
|
|
524
773
|
display: flex;
|
|
525
774
|
align-items: center;
|
|
526
775
|
justify-content: center;
|
|
527
|
-
// Subtle dim so the glassy CTA reads on any image, without hiding it
|
|
528
|
-
|
|
776
|
+
// Subtle dim so the glassy CTA reads on any image, without hiding it —
|
|
777
|
+
// half the standard scrim strength.
|
|
778
|
+
background: color-mix(in srgb, var(--color-scrim) 50%, transparent);
|
|
529
779
|
opacity: 0;
|
|
530
780
|
transition: opacity 0.15s ease;
|
|
531
781
|
}
|
|
@@ -560,7 +810,7 @@
|
|
|
560
810
|
padding: 0;
|
|
561
811
|
border: 2px solid transparent;
|
|
562
812
|
border-radius: 50%;
|
|
563
|
-
background:
|
|
813
|
+
background: var(--color-scrim-strong);
|
|
564
814
|
color: #fff;
|
|
565
815
|
cursor: pointer;
|
|
566
816
|
opacity: 0;
|
|
@@ -646,7 +896,7 @@
|
|
|
646
896
|
align-items: center;
|
|
647
897
|
justify-content: center;
|
|
648
898
|
gap: 4px;
|
|
649
|
-
background:
|
|
899
|
+
background: var(--color-scrim-strong);
|
|
650
900
|
color: #fff;
|
|
651
901
|
font-size: 11px;
|
|
652
902
|
font-weight: 600;
|
|
@@ -794,7 +1044,7 @@
|
|
|
794
1044
|
align-items: center;
|
|
795
1045
|
justify-content: center;
|
|
796
1046
|
gap: 4px;
|
|
797
|
-
background: var(--color-scrim);
|
|
1047
|
+
background: var(--color-scrim-strong);
|
|
798
1048
|
color: var(--color-on-scrim);
|
|
799
1049
|
font-size: 12px;
|
|
800
1050
|
font-weight: 600;
|
package/scss/wui/_overlays.scss
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// Do NOT put layout on backdropClassName — that targets a sibling, not
|
|
16
16
|
// .modal.
|
|
17
17
|
.modal-backdrop.wui-modal-dim {
|
|
18
|
-
background:
|
|
18
|
+
background: var(--color-scrim);
|
|
19
19
|
z-index: var(--wui-z-modal-backdrop);
|
|
20
20
|
}
|
|
21
21
|
.modal.wui-modal-shell {
|
|
@@ -328,3 +328,47 @@
|
|
|
328
328
|
font-size: 14px;
|
|
329
329
|
font-weight: 500;
|
|
330
330
|
}
|
|
331
|
+
|
|
332
|
+
// ── Toast (notifications) ──
|
|
333
|
+
// Bootstrap toast styling + wui extensions for title/action buttons.
|
|
334
|
+
// Used by both React AppToastContainer and Razor WUI.toast.
|
|
335
|
+
|
|
336
|
+
// Toast header with title
|
|
337
|
+
.wui-toast-header {
|
|
338
|
+
display: flex;
|
|
339
|
+
align-items: center;
|
|
340
|
+
justify-content: space-between;
|
|
341
|
+
gap: 12px;
|
|
342
|
+
padding: 10px 12px;
|
|
343
|
+
border: none;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.wui-toast-header strong {
|
|
347
|
+
font-size: 14px;
|
|
348
|
+
font-weight: 600;
|
|
349
|
+
color: inherit;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Toast action button — inherits text color from the variant tone. Scoped to the
|
|
353
|
+
// component class, not every .btn-link a consumer might place in a toast body.
|
|
354
|
+
.toast .wui-toast-action {
|
|
355
|
+
color: inherit;
|
|
356
|
+
text-decoration: none;
|
|
357
|
+
font-size: 13px;
|
|
358
|
+
font-weight: 500;
|
|
359
|
+
padding: 2px 8px;
|
|
360
|
+
white-space: nowrap;
|
|
361
|
+
flex: none;
|
|
362
|
+
opacity: 0.9;
|
|
363
|
+
transition: opacity 150ms;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.toast .wui-toast-action:hover {
|
|
367
|
+
opacity: 1;
|
|
368
|
+
text-decoration: underline;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.toast .wui-toast-action:focus-visible {
|
|
372
|
+
outline: 2px solid currentColor;
|
|
373
|
+
outline-offset: 2px;
|
|
374
|
+
}
|
|
@@ -279,6 +279,22 @@ wui-multiselect[collapse-chips] .ms-chips {
|
|
|
279
279
|
align-items: center;
|
|
280
280
|
gap: 8px;
|
|
281
281
|
}
|
|
282
|
+
.ms-input {
|
|
283
|
+
flex: 1;
|
|
284
|
+
min-width: 60px;
|
|
285
|
+
border: none;
|
|
286
|
+
background: transparent;
|
|
287
|
+
font: inherit;
|
|
288
|
+
color: inherit;
|
|
289
|
+
padding: 0;
|
|
290
|
+
margin: 0;
|
|
291
|
+
}
|
|
292
|
+
.ms-input::placeholder {
|
|
293
|
+
color: var(--color-text-subtle);
|
|
294
|
+
}
|
|
295
|
+
.ms-input:focus {
|
|
296
|
+
outline: none;
|
|
297
|
+
}
|
|
282
298
|
|
|
283
299
|
/* ── Choice card: image / custom-template variant ── */
|
|
284
300
|
.struct-card-img-card {
|
package/scss/wui/_utilities.scss
CHANGED
|
@@ -76,10 +76,13 @@
|
|
|
76
76
|
transform: scaleY(-1);
|
|
77
77
|
transition: color 0.15s;
|
|
78
78
|
}
|
|
79
|
-
.infotip-btn:hover
|
|
79
|
+
.infotip-btn:hover {
|
|
80
|
+
color: var(--color-primary);
|
|
81
|
+
}
|
|
80
82
|
.infotip-btn:focus-visible {
|
|
81
83
|
color: var(--color-primary);
|
|
82
|
-
outline:
|
|
84
|
+
outline: 2px solid var(--color-primary);
|
|
85
|
+
outline-offset: 2px;
|
|
83
86
|
}
|
|
84
87
|
.infotip-pop {
|
|
85
88
|
position: absolute;
|
|
@@ -141,9 +144,91 @@
|
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
// ── Page header ──
|
|
147
|
+
// `.page-header` stacks an optional breadcrumbs row above `.page-header-bar` — the
|
|
148
|
+
// flex row that holds the title block on the left and the page actions on the right.
|
|
144
149
|
.page-header {
|
|
145
150
|
margin-bottom: 24px;
|
|
146
151
|
}
|
|
152
|
+
.page-header-bar {
|
|
153
|
+
display: flex;
|
|
154
|
+
align-items: flex-end;
|
|
155
|
+
justify-content: space-between;
|
|
156
|
+
gap: 16px;
|
|
157
|
+
}
|
|
158
|
+
// Left block: an optional leading icon tile + the title stack, kept together.
|
|
159
|
+
.page-header-lead {
|
|
160
|
+
display: flex;
|
|
161
|
+
align-items: center;
|
|
162
|
+
gap: 12px;
|
|
163
|
+
min-width: 0;
|
|
164
|
+
}
|
|
165
|
+
// A breadcrumbs row above the masthead row.
|
|
166
|
+
.page-breadcrumbs {
|
|
167
|
+
margin-bottom: 10px;
|
|
168
|
+
}
|
|
169
|
+
// Leading icon tile — tinted by `tone` (default primary), matching the modal head icon.
|
|
170
|
+
.page-header-icon {
|
|
171
|
+
flex: none;
|
|
172
|
+
display: inline-grid;
|
|
173
|
+
place-items: center;
|
|
174
|
+
width: 40px;
|
|
175
|
+
height: 40px;
|
|
176
|
+
border-radius: var(--radius);
|
|
177
|
+
corner-shape: squircle;
|
|
178
|
+
background: var(--color-primary-soft);
|
|
179
|
+
color: var(--color-primary);
|
|
180
|
+
}
|
|
181
|
+
.page-header.tone-success .page-header-icon {
|
|
182
|
+
background: var(--color-success-soft);
|
|
183
|
+
color: var(--color-success-text);
|
|
184
|
+
}
|
|
185
|
+
.page-header.tone-warning .page-header-icon {
|
|
186
|
+
background: var(--color-warning-soft);
|
|
187
|
+
color: var(--color-warning-text);
|
|
188
|
+
}
|
|
189
|
+
.page-header.tone-danger .page-header-icon {
|
|
190
|
+
background: var(--color-danger-soft);
|
|
191
|
+
color: var(--color-danger-text);
|
|
192
|
+
}
|
|
193
|
+
.page-header.tone-info .page-header-icon {
|
|
194
|
+
background: var(--color-info-soft);
|
|
195
|
+
color: var(--color-info-text);
|
|
196
|
+
}
|
|
197
|
+
.page-header-titles {
|
|
198
|
+
min-width: 0;
|
|
199
|
+
}
|
|
200
|
+
// Eyebrow — a small kicker label above the title (a section / category marker).
|
|
201
|
+
.page-eyebrow {
|
|
202
|
+
font-size: 12px;
|
|
203
|
+
font-weight: 700;
|
|
204
|
+
letter-spacing: 0.06em;
|
|
205
|
+
text-transform: uppercase;
|
|
206
|
+
color: var(--color-primary);
|
|
207
|
+
margin-bottom: 3px;
|
|
208
|
+
}
|
|
209
|
+
.page-header.tone-success .page-eyebrow {
|
|
210
|
+
color: var(--color-success-text);
|
|
211
|
+
}
|
|
212
|
+
.page-header.tone-warning .page-eyebrow {
|
|
213
|
+
color: var(--color-warning-text);
|
|
214
|
+
}
|
|
215
|
+
.page-header.tone-danger .page-eyebrow {
|
|
216
|
+
color: var(--color-danger-text);
|
|
217
|
+
}
|
|
218
|
+
.page-header.tone-info .page-eyebrow {
|
|
219
|
+
color: var(--color-info-text);
|
|
220
|
+
}
|
|
221
|
+
// Title + an optional inline status pill, on one baseline.
|
|
222
|
+
.page-titlebar {
|
|
223
|
+
display: flex;
|
|
224
|
+
align-items: center;
|
|
225
|
+
gap: 10px;
|
|
226
|
+
flex-wrap: wrap;
|
|
227
|
+
}
|
|
228
|
+
.page-status {
|
|
229
|
+
display: inline-flex;
|
|
230
|
+
align-items: center;
|
|
231
|
+
}
|
|
147
232
|
.page-title {
|
|
148
233
|
font-size: 24px;
|
|
149
234
|
font-weight: 600;
|
|
@@ -162,17 +247,67 @@
|
|
|
162
247
|
align-items: center;
|
|
163
248
|
}
|
|
164
249
|
|
|
250
|
+
// ── Size scale ── (`size`): the title and the block's rhythm scale together.
|
|
251
|
+
.page-header-sm {
|
|
252
|
+
margin-bottom: 16px;
|
|
253
|
+
}
|
|
254
|
+
.page-header-sm .page-title {
|
|
255
|
+
font-size: 20px;
|
|
256
|
+
}
|
|
257
|
+
.page-header-sm .page-header-icon {
|
|
258
|
+
width: 34px;
|
|
259
|
+
height: 34px;
|
|
260
|
+
}
|
|
261
|
+
.page-header-lg {
|
|
262
|
+
margin-bottom: 32px;
|
|
263
|
+
}
|
|
264
|
+
.page-header-lg .page-title {
|
|
265
|
+
font-size: 30px;
|
|
266
|
+
}
|
|
267
|
+
.page-header-lg .page-header-icon {
|
|
268
|
+
width: 48px;
|
|
269
|
+
height: 48px;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ── Centre alignment ── (`align="center"`): for empty-state and wizard mastheads.
|
|
273
|
+
.page-header-center .page-header-bar {
|
|
274
|
+
justify-content: center;
|
|
275
|
+
text-align: center;
|
|
276
|
+
}
|
|
277
|
+
.page-header-center .page-header-lead {
|
|
278
|
+
flex-direction: column;
|
|
279
|
+
align-items: center;
|
|
280
|
+
}
|
|
281
|
+
.page-header-center .page-titlebar {
|
|
282
|
+
justify-content: center;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// ── Divider ── (`divider`): a hairline rule under the masthead.
|
|
286
|
+
.page-header-divider {
|
|
287
|
+
border-bottom: 1px solid var(--color-border);
|
|
288
|
+
padding-bottom: 16px;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// ── Sticky ── (`sticky`): pins the masthead to the top of its scroll container.
|
|
292
|
+
.page-header-sticky {
|
|
293
|
+
position: sticky;
|
|
294
|
+
top: 0;
|
|
295
|
+
z-index: 20;
|
|
296
|
+
background: var(--color-surface);
|
|
297
|
+
padding-top: 12px;
|
|
298
|
+
}
|
|
299
|
+
|
|
165
300
|
// Tablet and below: the masthead stops being a single row — the title block and
|
|
166
301
|
// its actions stack, and the actions stretch to the full width rather than
|
|
167
302
|
// crowding the title. Bootstrap's lg tier (991.98px), not an invented breakpoint.
|
|
168
303
|
//
|
|
169
|
-
// Selectors are DOUBLED (`.page-header.page-header`) on purpose. A media
|
|
170
|
-
// adds no specificity, so a consumer's own single-class rule — written later
|
|
171
|
-
// the cascade, as a consuming app's stylesheet always is — silently beats the
|
|
304
|
+
// Selectors are DOUBLED (`.page-header-bar.page-header-bar`) on purpose. A media
|
|
305
|
+
// query adds no specificity, so a consumer's own single-class rule — written later
|
|
306
|
+
// in the cascade, as a consuming app's stylesheet always is — silently beats the
|
|
172
307
|
// responsive rule and the layout never collapses. Doubling puts these at (0,2,0)
|
|
173
308
|
// so they hold, while still leaving a consumer free to override deliberately.
|
|
174
309
|
@media (max-width: 991.98px) {
|
|
175
|
-
.page-header.page-header {
|
|
310
|
+
.page-header-bar.page-header-bar {
|
|
176
311
|
flex-direction: column;
|
|
177
312
|
align-items: stretch;
|
|
178
313
|
gap: 12px;
|