maverick-wave 5.27.0 → 5.28.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.
@@ -1,5 +1,6 @@
1
1
  @use 'sass:map';
2
2
  @use '../abstracts' as *;
3
+ @use 'grid';
3
4
 
4
5
  @layer mw.layout {
5
6
  .mw-footer {
@@ -7,31 +8,34 @@
7
8
  padding: spacing('7') spacing('0');
8
9
  border-top: 1px solid var(--mw-border-accent);
9
10
 
11
+ // The same ramp .mw-grid-4 rides, read from the one place it is written
10
12
  &-top {
11
13
  display: grid;
12
- grid-template-columns: 1fr;
13
14
  gap: spacing('6');
14
15
  margin-bottom: spacing('6');
15
16
 
16
- @include media-up('sm') {
17
- grid-template-columns: repeat(2, 1fr);
18
- }
19
-
20
- @include media-up('lg') {
21
- grid-template-columns: repeat(4, 1fr);
22
- }
17
+ @include grid.column-grid(map.get(grid.$column-steps, 4));
23
18
  }
24
19
 
25
20
  &-column {
26
21
  h3 {
27
- font-size: font-size('lg');
28
- margin-bottom: spacing('4');
22
+ font-size: font-size('md');
23
+ margin-bottom: spacing('3');
29
24
  color: var(--mw-primary-text-color);
25
+
26
+ @include media-up('sm') {
27
+ font-size: font-size('lg');
28
+ margin-bottom: spacing('4');
29
+ }
30
30
  }
31
31
 
32
32
  p {
33
33
  color: var(--mw-text-muted-color);
34
- margin-bottom: spacing('3');
34
+ margin-bottom: spacing('2');
35
+
36
+ @include media-up('sm') {
37
+ margin-bottom: spacing('3');
38
+ }
35
39
  }
36
40
 
37
41
  ul {
@@ -48,7 +52,8 @@
48
52
  text-decoration: none;
49
53
  padding-bottom: 2px;
50
54
 
51
- // subtle default underline via box‐shadow
55
+ // Always drawn, unlike the navbar's: a footer link sits in a list of
56
+ // them and needs to read as a link without being pointed at first
52
57
  &::after {
53
58
  content: '';
54
59
  position: absolute;
@@ -88,11 +93,6 @@
88
93
  row-gap: spacing('3');
89
94
  margin: spacing('6') auto;
90
95
 
91
- &.mod-wrap {
92
- width: 330px;
93
- max-width: 100%;
94
- }
95
-
96
96
  a {
97
97
  position: relative;
98
98
  display: flex;
@@ -124,98 +124,60 @@
124
124
  transition-duration: var(--mw-duration-instant);
125
125
  }
126
126
  }
127
+
128
+ @include media-up('md') {
129
+ column-gap: spacing('8');
130
+ row-gap: spacing('4');
131
+
132
+ a {
133
+ width: 48px;
134
+ height: 48px;
135
+ font-size: font-size('xl');
136
+ }
137
+ }
127
138
  }
128
139
 
129
140
  .mw-disclaimer {
130
141
  text-align: center;
131
142
  color: var(--mw-text-muted-color);
132
- font-size: font-size('sm');
133
- width: min(85%, 700px);
143
+ font-size: font-size('xs');
144
+ width: 100%;
134
145
  margin: spacing('0') auto spacing('3') auto;
135
146
  line-height: 1.4;
147
+
148
+ // A 15% inset inside a container that already keeps a gutter only narrows
149
+ // the line to no purpose - so it waits until there is a line to narrow
150
+ @include media-up('sm') {
151
+ width: min(85%, 700px);
152
+ font-size: font-size('sm');
153
+ }
136
154
  }
137
155
 
138
156
  .mw-copyright {
139
157
  text-align: center;
140
158
  color: var(--mw-text-muted-color);
141
- font-size: font-size('sm');
159
+ font-size: font-size('xs');
142
160
  padding-top: spacing('4');
143
- margin: spacing('7') auto spacing('1') auto;
161
+ margin: spacing('5') auto spacing('1') auto;
144
162
  width: 100%;
145
163
  border-top: 1px solid var(--mw-border-accent);
164
+
165
+ @include media-up('sm') {
166
+ font-size: font-size('sm');
167
+ margin-top: spacing('7');
168
+ }
146
169
  }
147
170
 
148
171
  .mw-last-updated {
149
172
  text-align: center;
150
173
  color: var(--mw-text-muted-color);
151
- font-size: font-size('xs');
174
+ font-size: font-size('2xs');
152
175
  padding-top: spacing('0');
153
176
  margin: spacing('1') auto;
154
- }
155
177
 
156
- @include media-up('md') {
157
- .mw-social-links {
158
- column-gap: spacing('8');
159
- row-gap: spacing('4');
160
-
161
- &.mod-wrap {
162
- width: 420px;
163
- }
164
-
165
- a {
166
- width: 48px;
167
- height: 48px;
168
- font-size: font-size('xl');
169
- }
170
- }
171
- }
172
-
173
- @include media-up('lg') {
174
- .mw-social-links {
175
- &.mod-wrap {
176
- width: 510px;
177
- }
178
- }
179
- }
180
-
181
- @include media-down('sm') {
182
- &-column {
183
- h3 {
184
- font-size: font-size('md');
185
- margin-bottom: spacing('3');
186
- }
187
-
188
- p {
189
- margin-bottom: spacing('2');
190
- }
191
- }
192
-
193
- .mw-social-links {
194
- gap: spacing('3');
195
-
196
- &.mod-wrap {
197
- column-gap: spacing('6');
198
- row-gap: spacing('3');
199
- max-width: 100%;
200
- padding: spacing('0') spacing('4');
201
- }
202
- }
203
-
204
- // A second 15% inset inside a container that already keeps a gutter only
205
- // narrows the line to no purpose
206
- .mw-disclaimer {
207
- width: 100%;
208
- font-size: font-size('xs');
209
- }
210
-
211
- .mw-copyright {
212
- margin-top: spacing('5');
178
+ @include media-up('sm') {
213
179
  font-size: font-size('xs');
214
180
  }
215
-
216
- .mw-last-updated {
217
- font-size: font-size('2xs');
218
- }
219
181
  }
220
182
  }
221
183
  }
@@ -10,7 +10,7 @@
10
10
  // Outside the layer blocks below, because both read it - the columns are emitted
11
11
  // in `mw.layout`, the reveal cycle in `mw.utilities`, and a Sass variable declared
12
12
  // inside an `@layer` block is local to it.
13
- $_column-steps: (
13
+ $column-steps: (
14
14
  2: (
15
15
  ('sm', 2, null),
16
16
  ),
@@ -55,6 +55,37 @@ $_column-steps-lg: (
55
55
  // same reason as the steps above: both read it.
56
56
  $_grid-from: ('sm', 'md', 'lg', 'xl');
57
57
 
58
+ @mixin columns($count) {
59
+ grid-template-columns: repeat($count, minmax(0, 1fr));
60
+ }
61
+
62
+ @mixin single-column {
63
+ grid-template-columns: minmax(0, 1fr);
64
+ }
65
+
66
+ // Outside the layer block, because a Sass mixin declared inside one is local to
67
+ // it - and the footer builds its own columns from the same ramp.
68
+ //
69
+ // $base-gap is for the -lg ramp, whose placeholder carries the desktop gap and
70
+ // has to come back down to the default air on a phone
71
+ @mixin column-grid($steps, $base-gap: null) {
72
+ @include single-column;
73
+ @if $base-gap {
74
+ gap: spacing($base-gap);
75
+ }
76
+
77
+ @each $breakpoint, $cols, $gap in $steps {
78
+ @include media-up($breakpoint) {
79
+ @if $cols {
80
+ @include columns($cols);
81
+ }
82
+ @if $gap {
83
+ gap: spacing($gap);
84
+ }
85
+ }
86
+ }
87
+ }
88
+
58
89
  @layer mw.layout {
59
90
  %grid-base {
60
91
  display: grid;
@@ -66,34 +97,6 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
66
97
  gap: spacing('9');
67
98
  }
68
99
 
69
- @mixin _columns($count) {
70
- grid-template-columns: repeat($count, minmax(0, 1fr));
71
- }
72
-
73
- @mixin _single-column {
74
- grid-template-columns: minmax(0, 1fr);
75
- }
76
-
77
- // $base-gap is for the -lg ramp, whose placeholder carries the desktop gap and
78
- // has to come back down to the default air on a phone
79
- @mixin _column-grid($steps, $base-gap: null) {
80
- @include _single-column;
81
- @if $base-gap {
82
- gap: spacing($base-gap);
83
- }
84
-
85
- @each $breakpoint, $cols, $gap in $steps {
86
- @include media-up($breakpoint) {
87
- @if $cols {
88
- @include _columns($cols);
89
- }
90
- @if $gap {
91
- gap: spacing($gap);
92
- }
93
- }
94
- }
95
- }
96
-
97
100
  // The child reset a full-width single column needs: a card that carries its own
98
101
  // max-width would otherwise sit narrow in a column built to hold it.
99
102
  @mixin _stretch-children {
@@ -111,14 +114,14 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
111
114
 
112
115
  .mw-grid-1 {
113
116
  @extend %grid-base;
114
- @include _single-column;
117
+ @include single-column;
115
118
  @include _stretch-children;
116
119
  }
117
120
 
118
- @each $count, $steps in $_column-steps {
121
+ @each $count, $steps in $column-steps {
119
122
  .mw-grid-#{$count} {
120
123
  @extend %grid-base;
121
- @include _column-grid($steps);
124
+ @include column-grid($steps);
122
125
  }
123
126
  }
124
127
 
@@ -133,24 +136,24 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
133
136
  }
134
137
 
135
138
  .mw-tiles:not(.mw-tiles-2col):not(.mw-tiles-4col) {
136
- @include _column-grid(map.get($_column-steps, 3));
139
+ @include column-grid(map.get($column-steps, 3));
137
140
  }
138
141
 
139
142
  .mw-tiles-2col {
140
- @include _column-grid(map.get($_column-steps, 2));
143
+ @include column-grid(map.get($column-steps, 2));
141
144
  }
142
145
 
143
146
  .mw-tiles-4col {
144
- @include _column-grid(map.get($_column-steps, 4));
147
+ @include column-grid(map.get($column-steps, 4));
145
148
  }
146
149
 
147
150
  .mw-grid-flex {
148
151
  @extend %grid-base;
149
152
 
150
- @include _columns(12);
153
+ @include columns(12);
151
154
 
152
155
  @include media-down('md') {
153
- @include _single-column;
156
+ @include single-column;
154
157
 
155
158
  > * {
156
159
  grid-column: 1 / -1 !important;
@@ -197,7 +200,7 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
197
200
 
198
201
  .mw-grid-1-lg {
199
202
  @extend %grid-base-lg;
200
- @include _single-column;
203
+ @include single-column;
201
204
  @include _stretch-children;
202
205
  }
203
206
 
@@ -206,7 +209,7 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
206
209
  @extend %grid-base-lg;
207
210
  // A phone gets the same air between cards whichever ramp is used; the -lg
208
211
  // in the name is about the desktop end of it.
209
- @include _column-grid($steps, '6');
212
+ @include column-grid($steps, '6');
210
213
  }
211
214
  }
212
215
 
@@ -217,10 +220,10 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
217
220
 
218
221
  .mw-grid-flex-lg {
219
222
  @extend %grid-base-lg;
220
- @include _columns(12);
223
+ @include columns(12);
221
224
 
222
225
  @include media-down('md') {
223
- @include _single-column;
226
+ @include single-column;
224
227
  gap: spacing('5');
225
228
  > * {
226
229
  grid-column: 1 / -1 !important;
@@ -285,7 +288,7 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
285
288
  );
286
289
 
287
290
  @mixin _stack($justify, $child-width) {
288
- @include _single-column;
291
+ @include single-column;
289
292
  justify-items: $justify;
290
293
 
291
294
  > * {
@@ -324,7 +327,7 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
324
327
  @each $breakpoint in $_grid-from {
325
328
  .mw-grid-from-#{$breakpoint} {
326
329
  @include media-down($breakpoint) {
327
- @include _single-column;
330
+ @include single-column;
328
331
  }
329
332
  }
330
333
  }
@@ -334,7 +337,7 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
334
337
  // grid has to hand it over: written next to the card it would sit in
335
338
  // `mw.components` and lose to every gap above, no matter how specific.
336
339
  [class*='mw-grid-']:has(> .mw-card-feature) {
337
- row-gap: 48px;
340
+ row-gap: spacing('10');
338
341
  }
339
342
  }
340
343
 
@@ -378,7 +381,7 @@ $_grid-from: ('sm', 'md', 'lg', 'xl');
378
381
  }
379
382
  }
380
383
 
381
- @each $count, $steps in $_column-steps {
384
+ @each $count, $steps in $column-steps {
382
385
  .mw-grid-#{$count} {
383
386
  @include _reveal-ramp($steps);
384
387
  }
@@ -88,7 +88,7 @@ $float-edge: (0 0 0 1px rgb(255 255 255 / 0.22), 0 4px 14px rgb(0 0 0 / 0.4));
88
88
  // The panel hangs off the bar, so the bar has to be in place - and the burger,
89
89
  // which is the X while the panel is out, has to stay on its own position.
90
90
  //
91
- // A class the script sets, not `:has(.mw-navbar.open)`: the burger is the
91
+ // A class the script sets, not `:has(.mw-navbar.mw-active)`: the burger is the
92
92
  // control that closes the panel and cannot wait for a selector re-match, which
93
93
  // is where WebKit's invalidation has been unreliable.
94
94
  //
@@ -1,5 +1,8 @@
1
1
  @use '../abstracts' as *;
2
2
 
3
+ // Shared by the three controls in .mw-header-actions
4
+ $_control-size: 40px;
5
+
3
6
  @layer mw.layout {
4
7
  .mw-header {
5
8
  position: fixed;
@@ -36,7 +39,7 @@
36
39
  .mw-logo {
37
40
  display: flex;
38
41
  align-items: center;
39
- z-index: z-index('header') + 5;
42
+ z-index: z-index('header-logo');
40
43
  position: relative;
41
44
  flex-shrink: 1;
42
45
  min-width: 0;
@@ -49,6 +52,7 @@
49
52
  }
50
53
 
51
54
  img {
55
+ // The header height is derived from this - see $mw-header-height
52
56
  height: 42px;
53
57
  width: auto;
54
58
  max-width: 100%;
@@ -76,10 +80,13 @@
76
80
  display: flex;
77
81
  align-items: center;
78
82
  justify-content: center;
79
- height: 40px;
80
- width: 50px;
83
+ height: $_control-size;
84
+ width: $_control-size;
81
85
  flex-shrink: 0;
82
86
 
87
+ @include tappable;
88
+ @include touch-floor;
89
+
83
90
  &:hover:not(:disabled) {
84
91
  background: var(--mw-primary-color-hover);
85
92
  }
@@ -108,19 +115,20 @@
108
115
  outline: none;
109
116
  border-radius: radius('md');
110
117
  transition: var(--mw-transition);
111
- height: 40px;
112
- width: 50px;
118
+ height: $_control-size;
119
+ width: $_control-size;
113
120
  display: none;
114
121
  position: relative;
115
122
  flex-shrink: 0;
116
123
 
117
124
  // iOS
118
- -webkit-tap-highlight-color: transparent;
119
125
  -webkit-touch-callout: none;
120
126
  user-select: none;
121
- touch-action: manipulation;
122
127
 
123
- &:hover {
128
+ @include tappable;
129
+ @include touch-floor;
130
+
131
+ &:hover:not(:disabled) {
124
132
  background: var(--mw-primary-color-hover);
125
133
  }
126
134
 
@@ -134,9 +142,11 @@
134
142
 
135
143
  @include focus-ring;
136
144
 
137
- &.open {
145
+ // `.open` is what a consumer toggling the panel by hand was told to set,
146
+ // so it keeps working - drop it at the next major
147
+ &:is(.mw-active, .open) {
138
148
  background: var(--mw-secondary-color);
139
- z-index: z-index('header') + 10;
149
+ z-index: z-index('header-burger');
140
150
 
141
151
  // The surface under the burger switches to secondary, so its ink has to
142
152
  // switch with it. Set on the button, so the bar and both pseudo-elements
@@ -145,7 +155,7 @@
145
155
  --mw-header-burgerbutton-open-color
146
156
  );
147
157
 
148
- &:hover {
158
+ &:hover:not(:disabled) {
149
159
  background: var(--mw-secondary-color-hover);
150
160
  }
151
161
 
@@ -229,7 +239,7 @@
229
239
  box-shadow:
230
240
  0 6px 12px var(--mw-shadow-near),
231
241
  0 18px 40px var(--mw-shadow-far);
232
- z-index: z-index('header') + 3;
242
+ z-index: z-index('header-panel');
233
243
 
234
244
  // Rolled out from under the bar rather than slid in. A slide needs a place
235
245
  // to start, and the only direction with room is straight up through the
@@ -342,7 +352,7 @@
342
352
  }
343
353
  }
344
354
 
345
- &.open {
355
+ &:is(.mw-active, .open) {
346
356
  clip-path: inset(0 0 0 0);
347
357
  visibility: visible;
348
358
 
@@ -384,7 +394,7 @@
384
394
  inset: 0;
385
395
  background: var(--mw-overlay-background);
386
396
  backdrop-filter: blur(2px);
387
- z-index: z-index('header') - 1;
397
+ z-index: z-index('header-scrim');
388
398
  animation: mw-navbar-scrim-in var(--mw-duration-base) var(--mw-ease-out);
389
399
  }
390
400
  }
@@ -402,6 +412,14 @@
402
412
  }
403
413
  }
404
414
 
415
+ // How long the row survives before it becomes a panel: three links fit where
416
+ // six do not, so the page states the count and the modifier carries the ramp.
417
+ $_navbar-sizes: (
418
+ '': 'md',
419
+ '.mw-navbar-medium': 'lg',
420
+ '.mw-navbar-large': 'xl',
421
+ );
422
+
405
423
  .mw-navbar {
406
424
  display: flex;
407
425
 
@@ -459,60 +477,22 @@
459
477
  &:hover::after,
460
478
  &.mw-active::after,
461
479
  &.active::after {
462
- transform: scaleX(1) !important;
463
- opacity: 1 !important;
464
- }
465
- }
466
-
467
- // Auto-responsive behavior based on nav item count
468
- // Default behavior (1-3 items): collapse at md
469
- @include media-down('md') {
470
- @include navbar-top-sheet;
471
- }
472
-
473
- // Medium (4-5 items): collapse at lg
474
- &.mw-navbar-medium {
475
- @include media-down('lg') {
476
- @include navbar-top-sheet;
477
- }
478
- }
479
-
480
- // Large (6+ items): collapse at xl
481
- &.mw-navbar-large {
482
- @include media-down('xl') {
483
- @include navbar-top-sheet;
484
- }
485
- }
486
- }
487
-
488
- .mw-navbar {
489
- // Default (1-3 items): show burger at md
490
- @include media-down('md') {
491
- ~ .mw-menu-btn {
492
- display: flex;
493
- align-items: center;
494
- justify-content: center;
480
+ transform: scaleX(1);
481
+ opacity: 1;
495
482
  }
496
483
  }
497
484
 
498
- &.mw-navbar-medium {
499
- // 4-5 items: show burger at lg
500
- @include media-down('lg') {
501
- ~ .mw-menu-btn {
502
- display: flex;
503
- align-items: center;
504
- justify-content: center;
505
- }
506
- }
507
- }
485
+ // Panel and burger arrive together, so they step at one breakpoint each
486
+ @each $modifier, $breakpoint in $_navbar-sizes {
487
+ &#{$modifier} {
488
+ @include media-down($breakpoint) {
489
+ @include navbar-top-sheet;
508
490
 
509
- &.mw-navbar-large {
510
- // 6+ items: show burger at xl
511
- @include media-down('xl') {
512
- ~ .mw-menu-btn {
513
- display: flex;
514
- align-items: center;
515
- justify-content: center;
491
+ ~ .mw-menu-btn {
492
+ display: flex;
493
+ align-items: center;
494
+ justify-content: center;
495
+ }
516
496
  }
517
497
  }
518
498
  }
@@ -525,8 +505,8 @@
525
505
  align-items: center;
526
506
  justify-content: center;
527
507
  gap: spacing('3');
528
- height: 40px;
529
- width: 40px;
508
+ height: $_control-size;
509
+ width: $_control-size;
530
510
  padding: spacing('0');
531
511
  background: transparent;
532
512
  border: 1px solid var(--mw-header-border);
@@ -537,6 +517,9 @@
537
517
  flex-shrink: 0;
538
518
  max-width: 220px;
539
519
 
520
+ @include tappable;
521
+ @include touch-floor;
522
+
540
523
  // The avatar brings spacing of its own that would break the pill shape
541
524
  .mw-avatar {
542
525
  margin: spacing('0');
@@ -13,9 +13,12 @@
13
13
  margin-inline: auto;
14
14
 
15
15
  &-content {
16
- padding: spacing('9') spacing('0');
16
+ // The hero is 100dvh tall either way, so the phone - which has the least
17
+ // of it to give away - gets the smaller band, not the larger one
18
+ padding-block: spacing('6');
19
+
17
20
  @include media-up('sm') {
18
- padding-block: spacing('6');
21
+ padding-block: spacing('9');
19
22
  }
20
23
 
21
24
  &-fade {