maverick-wave 5.38.0 → 6.0.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.
Files changed (69) hide show
  1. package/README.md +63 -47
  2. package/maverick-wave.min.css +94 -68
  3. package/maverick-wave.min.js +1 -1
  4. package/package.json +7 -7
  5. package/src/js/main.js +382 -57
  6. package/src/scss/abstracts/_mixins.scss +35 -24
  7. package/src/scss/abstracts/_variables.scss +15 -0
  8. package/src/scss/base/_base.scss +107 -64
  9. package/src/scss/base/_index.scss +1 -0
  10. package/src/scss/base/_page-transitions.scss +29 -0
  11. package/src/scss/base/_reset.scss +0 -8
  12. package/src/scss/components/_accordions.scss +23 -18
  13. package/src/scss/components/_action-bar.scss +143 -0
  14. package/src/scss/components/_alerts.scss +13 -1
  15. package/src/scss/components/_avatars.scss +17 -0
  16. package/src/scss/components/_badge.scss +12 -0
  17. package/src/scss/components/_breadcrumbs.scss +10 -2
  18. package/src/scss/components/_chat.scss +250 -0
  19. package/src/scss/components/_code.scss +3 -1
  20. package/src/scss/components/_compare.scss +135 -0
  21. package/src/scss/components/_deck.scss +8 -14
  22. package/src/scss/components/_devices.scss +323 -0
  23. package/src/scss/components/_dropdown.scss +43 -2
  24. package/src/scss/components/_empty-state.scss +43 -0
  25. package/src/scss/components/_flag.scss +16 -0
  26. package/src/scss/components/_index.scss +6 -0
  27. package/src/scss/components/_lightbox.scss +1 -1
  28. package/src/scss/components/_marquee.scss +132 -0
  29. package/src/scss/components/_modals.scss +112 -83
  30. package/src/scss/components/_occasions.scss +62 -11
  31. package/src/scss/components/_pagination.scss +91 -0
  32. package/src/scss/components/_portrait-gallery.scss +1 -1
  33. package/src/scss/components/_progress.scss +122 -2
  34. package/src/scss/components/_segmented.scss +65 -2
  35. package/src/scss/components/_skeleton.scss +8 -0
  36. package/src/scss/components/_spinners.scss +38 -0
  37. package/src/scss/components/_stat.scss +232 -0
  38. package/src/scss/components/_stepper.scss +42 -2
  39. package/src/scss/components/_stories.scss +36 -22
  40. package/src/scss/components/_tables.scss +160 -17
  41. package/src/scss/components/_tabs.scss +42 -4
  42. package/src/scss/components/_tags.scss +39 -4
  43. package/src/scss/components/_tiles.scss +1 -1
  44. package/src/scss/components/_timelines.scss +138 -1
  45. package/src/scss/components/_toasts.scss +5 -1
  46. package/src/scss/components/_tooltip.scss +13 -0
  47. package/src/scss/form-elements/_checkbox.scss +40 -7
  48. package/src/scss/form-elements/_form.scss +2 -4
  49. package/src/scss/form-elements/_input.scss +9 -6
  50. package/src/scss/form-elements/_radio.scss +32 -3
  51. package/src/scss/form-elements/_select.scss +44 -1
  52. package/src/scss/form-elements/_slider.scss +18 -0
  53. package/src/scss/form-elements/_textarea.scss +9 -6
  54. package/src/scss/form-elements/_toggle.scss +37 -4
  55. package/src/scss/layout/_app-shell.scss +661 -0
  56. package/src/scss/layout/_bento.scss +43 -0
  57. package/src/scss/layout/_footer.scss +114 -2
  58. package/src/scss/layout/_grid.scss +7 -2
  59. package/src/scss/layout/_header-reveal.scss +30 -17
  60. package/src/scss/layout/_header.scss +21 -4
  61. package/src/scss/layout/_index.scss +2 -0
  62. package/src/scss/layout/_parallax.scss +13 -11
  63. package/src/scss/utilities/_accessibility.scss +4 -19
  64. package/src/scss/utilities/_index.scss +1 -0
  65. package/src/scss/utilities/_print.scss +7 -3
  66. package/src/scss/utilities/_reveal.scss +25 -17
  67. package/src/scss/utilities/_shape.scss +24 -0
  68. package/src/scss/utilities/_touch-targets.scss +23 -0
  69. package/src/scss/utilities/_variants.scss +25 -6
@@ -0,0 +1,661 @@
1
+ @use '../abstracts' as *;
2
+
3
+ @layer mw.layout {
4
+ .mw-app {
5
+ --mw-app-height: 100dvh;
6
+ --mw-app-sidebar-width: 16rem;
7
+ --mw-app-rail-width: 4.25rem;
8
+ --mw-app-aside-width: 22rem;
9
+ --mw-app-topbar-height: 3.5rem;
10
+ --mw-app-gutter: #{spacing('5')};
11
+ // The tracks read these, so collapsing and opening stay one animatable value
12
+ --_sidebar: var(--mw-app-sidebar-width);
13
+ --_aside: 0px;
14
+
15
+ position: relative;
16
+ // Keeps the sidebar and scrim z-indices out of the page's own stacking
17
+ isolation: isolate;
18
+ display: grid;
19
+ grid-template:
20
+ 'main' minmax(0, 1fr)
21
+ 'tabbar' auto
22
+ / minmax(0, 1fr);
23
+ height: var(--mw-app-height);
24
+ overflow: hidden;
25
+ background: var(--mw-page-background);
26
+ color: var(--mw-text-color);
27
+
28
+ @include media-up('md') {
29
+ --mw-app-gutter: #{spacing('7')};
30
+ }
31
+
32
+ @include media-up('lg') {
33
+ grid-template:
34
+ 'sidebar main aside' minmax(0, 1fr)
35
+ / var(--_sidebar) minmax(0, 1fr) var(--_aside);
36
+ transition: grid-template-columns var(--mw-duration-base)
37
+ var(--mw-ease-out);
38
+
39
+ &.mw-app-collapsed {
40
+ --_sidebar: var(--mw-app-rail-width);
41
+ }
42
+ }
43
+
44
+ @include media-up('xl') {
45
+ &.mw-app-aside-open {
46
+ --_aside: var(--mw-app-aside-width);
47
+ }
48
+ }
49
+
50
+ // The scrim lives on the app, so a tap on it lands on `.mw-app` itself
51
+ &::after {
52
+ content: '';
53
+ position: absolute;
54
+ inset: 0;
55
+ z-index: z-index('menu');
56
+ background: var(--mw-overlay-background);
57
+ opacity: 0;
58
+ visibility: hidden;
59
+ transition:
60
+ opacity var(--mw-duration-slow) var(--mw-ease-out),
61
+ visibility var(--mw-duration-slow);
62
+ }
63
+
64
+ &:is(.mw-app-sidebar-open, .mw-app-aside-open)::after {
65
+ opacity: 1;
66
+ visibility: visible;
67
+ }
68
+
69
+ // From lg only the aside still lays itself over the content, from xl nothing
70
+ @include media-up('lg') {
71
+ &:not(.mw-app-aside-open)::after {
72
+ display: none;
73
+ }
74
+ }
75
+
76
+ @include media-up('xl') {
77
+ &::after {
78
+ display: none;
79
+ }
80
+ }
81
+ }
82
+
83
+ // A remembered state is applied without animating into it (main.js)
84
+ .mw-app-restoring,
85
+ .mw-app-restoring * {
86
+ transition: none !important;
87
+ }
88
+
89
+ .mw-app-sidebar {
90
+ --mw-app-nav-color: var(--mw-text-muted-color);
91
+ --mw-app-nav-hover-color: var(--mw-text-color);
92
+ --mw-app-nav-hover-background: var(--mw-gray-background);
93
+ --mw-app-nav-active-color: var(--mw-primary-text-color);
94
+ --mw-app-nav-active-background: var(--mw-primary-background);
95
+
96
+ position: absolute;
97
+ inset-block: 0;
98
+ left: 0;
99
+ z-index: z-index('menu') + 1;
100
+ display: flex;
101
+ flex-direction: column;
102
+ width: min(var(--mw-app-sidebar-width), 85%);
103
+ min-height: 0;
104
+ padding-bottom: env(safe-area-inset-bottom, 0px);
105
+ padding-left: env(safe-area-inset-left, 0px);
106
+ background: var(--mw-footer-background);
107
+ border-right: 1px solid var(--mw-border);
108
+ // `visibility` rides along so the closed panel's links leave the tab order
109
+ transform: translateX(-100%);
110
+ visibility: hidden;
111
+ transition:
112
+ transform var(--mw-duration-slow) var(--mw-ease-out),
113
+ visibility var(--mw-duration-slow),
114
+ box-shadow var(--mw-duration-slow) var(--mw-ease-out);
115
+
116
+ // Visible at once on the way in, or the script's focus() hits a hidden panel
117
+ .mw-app-sidebar-open & {
118
+ transform: none;
119
+ visibility: visible;
120
+ box-shadow: var(--mw-elevation-4);
121
+ transition-duration: var(--mw-duration-slow), 0s, var(--mw-duration-slow);
122
+ }
123
+
124
+ @include media-up('lg') {
125
+ grid-area: sidebar;
126
+ position: relative;
127
+ inset: auto;
128
+ z-index: auto;
129
+ width: auto;
130
+ overflow: hidden;
131
+ transform: none;
132
+ visibility: visible;
133
+ transition: none;
134
+
135
+ .mw-app-sidebar-open & {
136
+ box-shadow: none;
137
+ }
138
+ }
139
+ }
140
+
141
+ // Dark in both themes, from the header bar tokens
142
+ .mw-app-sidebar-dark {
143
+ --mw-app-nav-color: var(--mw-header-navbar-list-color);
144
+ --mw-app-nav-hover-color: var(--mw-header-text-color);
145
+ --mw-app-nav-hover-background: #{fade('header-text-color', 10%)};
146
+ --mw-app-nav-active-color: var(--mw-header-navbar-list-active-color);
147
+ --mw-focus-ring-color: var(--mw-header-navbar-list-active-color);
148
+
149
+ background: var(--mw-header-background);
150
+ color: var(--mw-header-text-color);
151
+ border-color: var(--mw-header-border);
152
+ color-scheme: dark;
153
+
154
+ .mw-app-brand,
155
+ .mw-app-sidebar-footer {
156
+ border-color: var(--mw-header-border);
157
+ }
158
+ }
159
+
160
+ // Brand and topbar share the height and the notch inset, so their rules align
161
+ .mw-app-brand {
162
+ display: flex;
163
+ align-items: center;
164
+ gap: spacing('3');
165
+ flex-shrink: 0;
166
+ min-height: calc(
167
+ var(--mw-app-topbar-height) + env(safe-area-inset-top, 0px)
168
+ );
169
+ padding: env(safe-area-inset-top, 0px) spacing('5') 0;
170
+ border-bottom: 1px solid var(--mw-border);
171
+ font-size: font-size('md');
172
+ font-weight: font-weight('bold');
173
+ color: inherit;
174
+ text-decoration: none;
175
+
176
+ > i,
177
+ > svg,
178
+ > img {
179
+ flex-shrink: 0;
180
+ width: 1.75rem;
181
+ height: 1.75rem;
182
+ font-size: font-size('xl');
183
+ line-height: 1.75rem;
184
+ text-align: center;
185
+ color: var(--mw-primary-text-color);
186
+ object-fit: contain;
187
+ }
188
+ }
189
+
190
+ .mw-app-nav {
191
+ display: flex;
192
+ flex-direction: column;
193
+ flex: 1 1 auto;
194
+ min-height: 0;
195
+ gap: spacing('1');
196
+ padding: spacing('4') spacing('3');
197
+ overflow-y: auto;
198
+ overscroll-behavior: contain;
199
+ @include scrollbar;
200
+ }
201
+
202
+ .mw-app-nav-title {
203
+ margin: spacing('5') spacing('3') spacing('2');
204
+ font-size: font-size('2xs');
205
+ font-weight: font-weight('bold');
206
+ letter-spacing: 0.08em;
207
+ text-transform: uppercase;
208
+ color: var(--mw-app-nav-color);
209
+ @include truncate;
210
+
211
+ &:first-child {
212
+ margin-top: 0;
213
+ }
214
+ }
215
+
216
+ .mw-app-nav-link {
217
+ position: relative;
218
+ display: flex;
219
+ align-items: center;
220
+ gap: spacing('4');
221
+ min-height: 2.5rem;
222
+ padding: spacing('2') spacing('4');
223
+ // The framework silhouette at link size: sharp and round on the two diagonals
224
+ border-radius: radius-sharp() radius('lg') radius-sharp() radius('lg');
225
+ color: var(--mw-app-nav-color);
226
+ font-size: font-size('sm');
227
+ font-weight: font-weight('medium');
228
+ text-decoration: none;
229
+ transition: var(--mw-transition-fast);
230
+ @include tappable;
231
+ @include touch-floor;
232
+ @include focus-ring;
233
+
234
+ > i,
235
+ > svg {
236
+ flex-shrink: 0;
237
+ width: 1.25rem;
238
+ font-size: font-size('md');
239
+ text-align: center;
240
+ }
241
+
242
+ > .mw-badge {
243
+ margin-left: auto;
244
+ }
245
+
246
+ &:hover {
247
+ color: var(--mw-app-nav-hover-color);
248
+ background: var(--mw-app-nav-hover-background);
249
+ }
250
+
251
+ &[aria-current='page'] {
252
+ color: var(--mw-app-nav-active-color);
253
+ background: var(--mw-app-nav-active-background);
254
+ }
255
+
256
+ @include active {
257
+ color: var(--mw-app-nav-active-color);
258
+ background: var(--mw-app-nav-active-background);
259
+ }
260
+
261
+ // The label says it already; mw.layout outranks the tooltip's layer
262
+ &[data-tooltip]::before,
263
+ &[data-tooltip]::after {
264
+ display: none;
265
+ }
266
+ }
267
+
268
+ .mw-app-nav-link .mw-app-label {
269
+ min-width: 0;
270
+ @include truncate;
271
+ }
272
+
273
+ .mw-app-sidebar-footer {
274
+ display: flex;
275
+ align-items: center;
276
+ gap: spacing('3');
277
+ flex-shrink: 0;
278
+ padding: spacing('4') spacing('5');
279
+ border-top: 1px solid var(--mw-border);
280
+ font-size: font-size('sm');
281
+
282
+ .mw-avatar {
283
+ flex-shrink: 0;
284
+ margin: 0;
285
+ }
286
+
287
+ .mw-app-label {
288
+ min-width: 0;
289
+ @include truncate;
290
+ }
291
+ }
292
+
293
+ .mw-app-main {
294
+ grid-area: main;
295
+ display: flex;
296
+ flex-direction: column;
297
+ min-width: 0;
298
+ min-height: 0;
299
+ overflow-y: auto;
300
+ overscroll-behavior: contain;
301
+ scroll-padding-top: calc(
302
+ var(--mw-app-topbar-height) + env(safe-area-inset-top, 0px)
303
+ );
304
+ // Below lg the column reaches both screen edges, notch included
305
+ --_gutter-start: max(var(--mw-app-gutter), env(safe-area-inset-left, 0px));
306
+ --_gutter-end: max(var(--mw-app-gutter), env(safe-area-inset-right, 0px));
307
+ @include scrollbar;
308
+ }
309
+
310
+ .mw-app-topbar {
311
+ position: sticky;
312
+ top: 0;
313
+ z-index: z-index('menu') - 1;
314
+ display: flex;
315
+ align-items: center;
316
+ gap: spacing('3');
317
+ flex-shrink: 0;
318
+ min-height: calc(
319
+ var(--mw-app-topbar-height) + env(safe-area-inset-top, 0px)
320
+ );
321
+ padding: calc(#{spacing('2')} + env(safe-area-inset-top, 0px))
322
+ var(--_gutter-end) spacing('2') var(--_gutter-start);
323
+ background: var(--mw-page-background);
324
+ border-bottom: 1px solid var(--mw-border);
325
+ }
326
+
327
+ .mw-app-title {
328
+ flex: 1 1 auto;
329
+ min-width: 0;
330
+ margin: 0;
331
+ font-size: font-size('lg');
332
+ line-height: 1.2;
333
+ @include truncate;
334
+ }
335
+
336
+ .mw-app-actions {
337
+ display: flex;
338
+ align-items: center;
339
+ gap: spacing('2');
340
+ flex-shrink: 0;
341
+ margin-left: auto;
342
+ }
343
+
344
+ .mw-app-content {
345
+ flex: 1 0 auto;
346
+ padding: spacing('6') var(--_gutter-end) spacing('6') var(--_gutter-start);
347
+ }
348
+
349
+ // A footer under the content sits on the column's gutter, not a container's
350
+ .mw-app-main > .mw-footer {
351
+ padding-inline: var(--_gutter-start) var(--_gutter-end);
352
+ }
353
+
354
+ // A game board or a canvas: the whole column, no gutter, no page scroll
355
+ .mw-app-content-flush {
356
+ display: flex;
357
+ flex: 1 1 0;
358
+ flex-direction: column;
359
+ min-height: 0;
360
+ padding: 0;
361
+ overflow: hidden;
362
+
363
+ > :only-child {
364
+ flex: 1 1 auto;
365
+ min-height: 0;
366
+ }
367
+ }
368
+
369
+ .mw-app-toggle {
370
+ display: inline-flex;
371
+ align-items: center;
372
+ justify-content: center;
373
+ flex-shrink: 0;
374
+ width: 2.5rem;
375
+ height: 2.5rem;
376
+ padding: 0;
377
+ background: transparent;
378
+ border: 1px solid var(--mw-border);
379
+ border-radius: radius('md');
380
+ color: var(--mw-text-color);
381
+ font: inherit;
382
+ cursor: pointer;
383
+ transition: var(--mw-transition-fast);
384
+ @include tappable;
385
+ @include touch-floor {
386
+ min-width: 2.75rem;
387
+ }
388
+ @include focus-ring;
389
+
390
+ &:hover {
391
+ background: var(--mw-gray-background);
392
+ }
393
+ }
394
+
395
+ // Three bars drawn from one element, so the toggle needs no icon font
396
+ .mw-app-toggle-icon {
397
+ display: block;
398
+ width: 18px;
399
+ height: 12px;
400
+ background:
401
+ linear-gradient(currentColor 0 0) top / 100% 2px no-repeat,
402
+ linear-gradient(currentColor 0 0) center / 100% 2px no-repeat,
403
+ linear-gradient(currentColor 0 0) bottom / 100% 2px no-repeat;
404
+ }
405
+
406
+ // Beside the content from xl, over it below - the same panel either way
407
+ .mw-app-aside {
408
+ position: absolute;
409
+ inset-block: 0;
410
+ right: 0;
411
+ z-index: z-index('menu') + 1;
412
+ display: flex;
413
+ flex-direction: column;
414
+ width: min(var(--mw-app-aside-width), 90%);
415
+ min-height: 0;
416
+ padding-right: env(safe-area-inset-right, 0px);
417
+ padding-bottom: env(safe-area-inset-bottom, 0px);
418
+ background: var(--mw-card-background);
419
+ border-left: 1px solid var(--mw-border);
420
+ transform: translateX(100%);
421
+ visibility: hidden;
422
+ transition:
423
+ transform var(--mw-duration-slow) var(--mw-ease-out),
424
+ visibility var(--mw-duration-slow),
425
+ box-shadow var(--mw-duration-slow) var(--mw-ease-out);
426
+
427
+ .mw-app-aside-open & {
428
+ transform: none;
429
+ visibility: visible;
430
+ box-shadow: var(--mw-elevation-4);
431
+ transition-duration: var(--mw-duration-slow), 0s, var(--mw-duration-slow);
432
+ }
433
+
434
+ // Own width in a track growing from 0: slides in, no reflow on every frame
435
+ @include media-up('xl') {
436
+ grid-area: aside;
437
+ position: relative;
438
+ inset: auto;
439
+ z-index: auto;
440
+ width: var(--mw-app-aside-width);
441
+ transform: none;
442
+ transition: visibility 0s var(--mw-duration-base);
443
+
444
+ .mw-app-aside-open & {
445
+ box-shadow: none;
446
+ transition-delay: 0s;
447
+ }
448
+ }
449
+ }
450
+
451
+ .mw-app-aside-header {
452
+ display: flex;
453
+ align-items: center;
454
+ gap: spacing('3');
455
+ flex-shrink: 0;
456
+ min-height: calc(
457
+ var(--mw-app-topbar-height) + env(safe-area-inset-top, 0px)
458
+ );
459
+ padding: env(safe-area-inset-top, 0px) spacing('4') 0 spacing('5');
460
+ border-bottom: 1px solid var(--mw-border);
461
+
462
+ > :is(h1, h2, h3, h4, h5, h6) {
463
+ flex: 1 1 auto;
464
+ min-width: 0;
465
+ margin: 0;
466
+ font-size: font-size('md');
467
+ line-height: 1.2;
468
+ @include truncate;
469
+ }
470
+ }
471
+
472
+ .mw-app-aside-body {
473
+ flex: 1 1 auto;
474
+ min-height: 0;
475
+ padding: spacing('5');
476
+ overflow-y: auto;
477
+ overscroll-behavior: contain;
478
+ @include scrollbar;
479
+ }
480
+
481
+ // A grid row, not fixed: nothing scrolls under it, no keyboard pushes it up
482
+ .mw-app-tabbar {
483
+ grid-area: tabbar;
484
+ display: grid;
485
+ grid-auto-flow: column;
486
+ grid-auto-columns: minmax(0, 1fr);
487
+ gap: spacing('1');
488
+ padding: spacing('1') max(#{spacing('2')}, env(safe-area-inset-right, 0px))
489
+ calc(#{spacing('1')} + env(safe-area-inset-bottom, 0px))
490
+ max(#{spacing('2')}, env(safe-area-inset-left, 0px));
491
+ background: var(--mw-footer-background);
492
+ border-top: 1px solid var(--mw-border);
493
+
494
+ @include media-up('lg') {
495
+ display: none;
496
+ }
497
+ }
498
+
499
+ .mw-app-tabbar-item {
500
+ position: relative;
501
+ display: flex;
502
+ flex-direction: column;
503
+ align-items: center;
504
+ justify-content: center;
505
+ gap: spacing('1');
506
+ min-width: 0;
507
+ min-height: 3.25rem;
508
+ padding: spacing('1');
509
+ border-radius: radius('md');
510
+ color: var(--mw-text-muted-color);
511
+ font-size: font-size('2xs');
512
+ font-weight: font-weight('medium');
513
+ line-height: 1.1;
514
+ text-decoration: none;
515
+ transition: var(--mw-transition-fast);
516
+ @include tappable;
517
+ @include focus-ring-inset;
518
+
519
+ // A pill by padding: an icon font's own display cannot push the glyph aside
520
+ > i,
521
+ > svg {
522
+ padding: 0.35rem 1.1rem;
523
+ border-radius: radius-sharp() radius('lg') radius-sharp() radius('lg');
524
+ font-size: font-size('md');
525
+ line-height: 1;
526
+ transition: var(--mw-transition-fast);
527
+ }
528
+
529
+ > svg {
530
+ width: 1.25em;
531
+ height: 1.25em;
532
+ box-sizing: content-box;
533
+ }
534
+
535
+ > .mw-app-label {
536
+ max-width: 100%;
537
+ @include truncate;
538
+ }
539
+
540
+ // On the pill's top right corner, wherever the column puts the pill
541
+ > .mw-badge {
542
+ position: absolute;
543
+ top: 0;
544
+ left: calc(50% + 0.9rem);
545
+ }
546
+
547
+ &:hover {
548
+ color: var(--mw-text-color);
549
+ }
550
+
551
+ &:active {
552
+ transform: scale(0.96);
553
+ transition-duration: var(--mw-duration-instant);
554
+ }
555
+
556
+ &[aria-current='page'] {
557
+ color: var(--mw-primary-text-color);
558
+
559
+ > :is(i, svg) {
560
+ background: var(--mw-primary-background);
561
+ }
562
+ }
563
+
564
+ @include active {
565
+ color: var(--mw-primary-text-color);
566
+
567
+ > :is(i, svg) {
568
+ background: var(--mw-primary-background);
569
+ }
570
+ }
571
+ }
572
+
573
+ @include media-up('lg') {
574
+ .mw-app-collapsed {
575
+ .mw-app-brand,
576
+ .mw-app-sidebar-footer {
577
+ justify-content: center;
578
+ padding-inline: 0;
579
+ }
580
+
581
+ .mw-app-nav {
582
+ padding-inline: spacing('2');
583
+ }
584
+
585
+ .mw-app-nav-link {
586
+ justify-content: center;
587
+ padding-inline: 0;
588
+
589
+ // A dot on the icon; the count stays for a screen reader
590
+ > .mw-badge {
591
+ position: absolute;
592
+ top: spacing('1');
593
+ left: calc(50% + 0.35rem);
594
+ width: 0.6rem;
595
+ height: 0.6rem;
596
+ min-width: 0;
597
+ padding: 0;
598
+ font-size: 0;
599
+ }
600
+
601
+ // Only where it can be anchored: placed above, the rail's scroller cuts it
602
+ @supports (position-area: block-start) {
603
+ &[data-tooltip]::before,
604
+ &[data-tooltip]::after {
605
+ display: revert-layer;
606
+ }
607
+ }
608
+ }
609
+
610
+ // Kept as a rule between the groups - the text stays for a screen reader
611
+ .mw-app-nav-title {
612
+ height: 1px;
613
+ margin-inline: spacing('3');
614
+ background: var(--mw-border);
615
+ color: transparent;
616
+ }
617
+
618
+ .mw-app-label {
619
+ @include visually-hidden;
620
+ }
621
+ }
622
+ }
623
+
624
+ // Forced colours drop the fill that marks the current page; not while focused
625
+ @media (forced-colors: active) {
626
+ :is(.mw-app-nav-link, .mw-app-tabbar-item):is(
627
+ [aria-current='page'],
628
+ .mw-active,
629
+ .active
630
+ ):not(:focus-visible) {
631
+ outline: 2px solid;
632
+ outline-offset: -2px;
633
+ }
634
+ }
635
+
636
+ // The contained scroll would print one screen: the page gets its length back
637
+ @media print {
638
+ .mw-app {
639
+ display: block;
640
+ height: auto;
641
+ overflow: visible;
642
+ }
643
+
644
+ .mw-app::after,
645
+ .mw-app-sidebar,
646
+ .mw-app-aside,
647
+ .mw-app-tabbar,
648
+ .mw-app-toggle,
649
+ .mw-app-actions {
650
+ display: none;
651
+ }
652
+
653
+ .mw-app-main {
654
+ overflow: visible;
655
+ }
656
+
657
+ .mw-app-topbar {
658
+ position: static;
659
+ }
660
+ }
661
+ }
@@ -0,0 +1,43 @@
1
+ @use '../abstracts' as *;
2
+
3
+ @layer mw.layout {
4
+ .mw-bento {
5
+ display: grid;
6
+ grid-template-columns: minmax(0, 1fr);
7
+ grid-auto-flow: dense;
8
+ gap: spacing('6');
9
+
10
+ > * {
11
+ min-width: 0;
12
+ }
13
+
14
+ // The rhythm starts with the second column; a stack keeps content height
15
+ @include media-up('sm') {
16
+ grid-template-columns: repeat(2, minmax(0, 1fr));
17
+ grid-auto-rows: minmax(var(--mw-bento-row, 11rem), auto);
18
+
19
+ > .mw-bento-wide,
20
+ > .mw-bento-lg {
21
+ grid-column: span 2;
22
+ }
23
+
24
+ > .mw-bento-tall,
25
+ > .mw-bento-lg {
26
+ grid-row: span 2;
27
+ }
28
+ }
29
+
30
+ @include media-up('lg') {
31
+ grid-template-columns: repeat(4, minmax(0, 1fr));
32
+ }
33
+
34
+ > .mw-bento-full {
35
+ grid-column: 1 / -1;
36
+ }
37
+ }
38
+
39
+ // Short tiles - a row of figures on a dashboard
40
+ .mw-bento-compact {
41
+ --mw-bento-row: 7rem;
42
+ }
43
+ }