maverick-wave 4.26.0 → 4.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.
- package/.claude/skills/mw-maverick-wave/SKILL.md +5 -3
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +2 -2
- package/.claude/skills/mw-maverick-wave/references/components.md +48 -0
- package/.claude/skills/mw-maverick-wave/references/javascript.md +1 -0
- package/CHANGELOG.md +12 -0
- package/README.md +2 -2
- package/maverick-wave.min.css +2 -2
- package/maverick-wave.min.js +1 -1
- package/package.json +2 -2
- package/src/js/main.js +51 -0
- package/src/partials/header-utilities-container.html +192 -5
- package/src/partials/techstack-bucket-container.html +2 -2
- package/src/scss/components/_flag.scss +309 -0
- package/src/scss/components/_index.scss +2 -0
- package/src/scss/components/_lang-switch.scss +116 -0
- package/src/scss/components/_techstack-bucket.scss +6 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
@use '../abstracts' as *;
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Flag
|
|
5
|
+
//
|
|
6
|
+
// A country flag drawn entirely in CSS gradients - no image, no icon font, no
|
|
7
|
+
// request. Two reasons it is not the obvious emoji: Windows ships no flag
|
|
8
|
+
// glyphs at all (Chrome and Edge render 🇩🇪 as the letters "DE" in a box), and
|
|
9
|
+
// an emoji cannot be sized to line up with text the way a box can.
|
|
10
|
+
//
|
|
11
|
+
// Every flag gets the same 4:3 box regardless of its real ratio - Switzerland
|
|
12
|
+
// is square, the US is 10:19 - because a column of switcher rows has to line
|
|
13
|
+
// up, and a correct aspect ratio per country is what breaks it.
|
|
14
|
+
//
|
|
15
|
+
// The set below covers the languages a European project actually offers. For
|
|
16
|
+
// anything else, the class is a slot: put an <img> or an inline <svg> inside
|
|
17
|
+
// and it inherits the box, the corner and the hairline.
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
// Shape values, in px - these draw a picture and have nothing to do with the
|
|
21
|
+
// spacing scale
|
|
22
|
+
$_flag-width: 20px;
|
|
23
|
+
$_flag-height: 15px;
|
|
24
|
+
|
|
25
|
+
.mw-flag {
|
|
26
|
+
display: inline-block;
|
|
27
|
+
width: $_flag-width;
|
|
28
|
+
height: $_flag-height;
|
|
29
|
+
flex-shrink: 0;
|
|
30
|
+
border-radius: radius('xs');
|
|
31
|
+
overflow: hidden;
|
|
32
|
+
// Drawn on top rather than as a border: a border would shrink the painting
|
|
33
|
+
// area and shift every gradient stop inward by a pixel. Two rings, because
|
|
34
|
+
// each theme loses a different edge - the dark one keeps white flags (Japan,
|
|
35
|
+
// Poland) off a light card, the light one keeps the black band of Germany and
|
|
36
|
+
// Belgium off a dark header. Each is invisible where it is not needed.
|
|
37
|
+
box-shadow:
|
|
38
|
+
inset 0 0 0 1px rgb(0 0 0 / 0.2),
|
|
39
|
+
0 0 0 1px rgb(255 255 255 / 0.14);
|
|
40
|
+
background-repeat: no-repeat;
|
|
41
|
+
background-size: 100% 100%;
|
|
42
|
+
vertical-align: middle;
|
|
43
|
+
|
|
44
|
+
// The slot: a real flag asset fills the same box
|
|
45
|
+
> img,
|
|
46
|
+
> svg {
|
|
47
|
+
display: block;
|
|
48
|
+
width: 100%;
|
|
49
|
+
height: 100%;
|
|
50
|
+
object-fit: cover;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// --- Three horizontal bands ------------------------------------------------
|
|
55
|
+
.mw-flag-de {
|
|
56
|
+
background-image: linear-gradient(
|
|
57
|
+
to bottom,
|
|
58
|
+
#000 0 33.34%,
|
|
59
|
+
#dd0000 33.34% 66.67%,
|
|
60
|
+
#ffce00 66.67%
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.mw-flag-at {
|
|
65
|
+
background-image: linear-gradient(
|
|
66
|
+
to bottom,
|
|
67
|
+
#ed2939 0 33.34%,
|
|
68
|
+
#fff 33.34% 66.67%,
|
|
69
|
+
#ed2939 66.67%
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.mw-flag-nl {
|
|
74
|
+
background-image: linear-gradient(
|
|
75
|
+
to bottom,
|
|
76
|
+
#ae1c28 0 33.34%,
|
|
77
|
+
#fff 33.34% 66.67%,
|
|
78
|
+
#21468b 66.67%
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.mw-flag-hu {
|
|
83
|
+
background-image: linear-gradient(
|
|
84
|
+
to bottom,
|
|
85
|
+
#ce2939 0 33.34%,
|
|
86
|
+
#fff 33.34% 66.67%,
|
|
87
|
+
#477050 66.67%
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.mw-flag-bg {
|
|
92
|
+
background-image: linear-gradient(
|
|
93
|
+
to bottom,
|
|
94
|
+
#fff 0 33.34%,
|
|
95
|
+
#00966e 33.34% 66.67%,
|
|
96
|
+
#d62612 66.67%
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Spain's bands are 1:2:1, not equal thirds - the civil flag, without the arms
|
|
101
|
+
.mw-flag-es {
|
|
102
|
+
background-image: linear-gradient(
|
|
103
|
+
to bottom,
|
|
104
|
+
#aa151b 0 25%,
|
|
105
|
+
#f1bf00 25% 75%,
|
|
106
|
+
#aa151b 75%
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// --- Three vertical bands --------------------------------------------------
|
|
111
|
+
.mw-flag-fr {
|
|
112
|
+
background-image: linear-gradient(
|
|
113
|
+
to right,
|
|
114
|
+
#002654 0 33.34%,
|
|
115
|
+
#fff 33.34% 66.67%,
|
|
116
|
+
#ed2939 66.67%
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.mw-flag-it {
|
|
121
|
+
background-image: linear-gradient(
|
|
122
|
+
to right,
|
|
123
|
+
#009246 0 33.34%,
|
|
124
|
+
#fff 33.34% 66.67%,
|
|
125
|
+
#ce2b37 66.67%
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.mw-flag-be {
|
|
130
|
+
background-image: linear-gradient(
|
|
131
|
+
to right,
|
|
132
|
+
#000 0 33.34%,
|
|
133
|
+
#fae042 33.34% 66.67%,
|
|
134
|
+
#ed2939 66.67%
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.mw-flag-ro {
|
|
139
|
+
background-image: linear-gradient(
|
|
140
|
+
to right,
|
|
141
|
+
#002b7f 0 33.34%,
|
|
142
|
+
#fcd116 33.34% 66.67%,
|
|
143
|
+
#ce1126 66.67%
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.mw-flag-ie {
|
|
148
|
+
background-image: linear-gradient(
|
|
149
|
+
to right,
|
|
150
|
+
#169b62 0 33.34%,
|
|
151
|
+
#fff 33.34% 66.67%,
|
|
152
|
+
#ff883e 66.67%
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// --- Two bands -------------------------------------------------------------
|
|
157
|
+
.mw-flag-pl {
|
|
158
|
+
background-image: linear-gradient(to bottom, #fff 0 50%, #dc143c 50%);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.mw-flag-ua {
|
|
162
|
+
background-image: linear-gradient(to bottom, #0057b7 0 50%, #ffd700 50%);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// --- Nordic cross ----------------------------------------------------------
|
|
166
|
+
// The arm sits left of centre, as it does on the real flags. Two bars laid over
|
|
167
|
+
// a solid field: the horizontal one first so the intersection is one colour.
|
|
168
|
+
@mixin nordic-cross($field, $cross) {
|
|
169
|
+
background-image:
|
|
170
|
+
linear-gradient(
|
|
171
|
+
to bottom,
|
|
172
|
+
transparent 40%,
|
|
173
|
+
$cross 40% 60%,
|
|
174
|
+
transparent 60%
|
|
175
|
+
),
|
|
176
|
+
linear-gradient(to right, transparent 26%, $cross 26% 46%, transparent 46%),
|
|
177
|
+
linear-gradient($field 0 0);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.mw-flag-se {
|
|
181
|
+
@include nordic-cross(#005293, #fecb00);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.mw-flag-dk {
|
|
185
|
+
@include nordic-cross(#c8102e, #fff);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.mw-flag-fi {
|
|
189
|
+
@include nordic-cross(#fff, #003580);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Norway's blue cross sits inside the white one, so it takes a second, thinner
|
|
193
|
+
// pair of bars on top
|
|
194
|
+
.mw-flag-no {
|
|
195
|
+
background-image:
|
|
196
|
+
linear-gradient(
|
|
197
|
+
to bottom,
|
|
198
|
+
transparent 44%,
|
|
199
|
+
#00205b 44% 56%,
|
|
200
|
+
transparent 56%
|
|
201
|
+
),
|
|
202
|
+
linear-gradient(
|
|
203
|
+
to right,
|
|
204
|
+
transparent 30%,
|
|
205
|
+
#00205b 30% 42%,
|
|
206
|
+
transparent 42%
|
|
207
|
+
),
|
|
208
|
+
linear-gradient(to bottom, transparent 40%, #fff 40% 60%, transparent 60%),
|
|
209
|
+
linear-gradient(to right, transparent 26%, #fff 26% 46%, transparent 46%),
|
|
210
|
+
linear-gradient(#ba0c2f 0 0);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Switzerland is square in reality; in a 4:3 box the arms are widened so the
|
|
214
|
+
// cross still reads as one
|
|
215
|
+
.mw-flag-ch {
|
|
216
|
+
background-image:
|
|
217
|
+
linear-gradient(to bottom, transparent 36%, #fff 36% 64%, transparent 64%),
|
|
218
|
+
linear-gradient(to right, transparent 39%, #fff 39% 61%, transparent 61%),
|
|
219
|
+
linear-gradient(#d52b1e 0 0);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// --- Everything else -------------------------------------------------------
|
|
223
|
+
// The Union Jack, from the back forward: white diagonals, red diagonals over
|
|
224
|
+
// them, then the white and red arms of St George's cross on top. The
|
|
225
|
+
// counterchange of the red diagonals is dropped - at 20px nobody sees it, and
|
|
226
|
+
// it would cost four more layers.
|
|
227
|
+
.mw-flag-gb {
|
|
228
|
+
background-image:
|
|
229
|
+
linear-gradient(
|
|
230
|
+
to right,
|
|
231
|
+
transparent 42%,
|
|
232
|
+
#c8102e 42% 58%,
|
|
233
|
+
transparent 58%
|
|
234
|
+
),
|
|
235
|
+
linear-gradient(
|
|
236
|
+
to bottom,
|
|
237
|
+
transparent 38%,
|
|
238
|
+
#c8102e 38% 62%,
|
|
239
|
+
transparent 62%
|
|
240
|
+
),
|
|
241
|
+
linear-gradient(to right, transparent 36%, #fff 36% 64%, transparent 64%),
|
|
242
|
+
linear-gradient(to bottom, transparent 30%, #fff 30% 70%, transparent 70%),
|
|
243
|
+
linear-gradient(
|
|
244
|
+
to bottom right,
|
|
245
|
+
transparent 45%,
|
|
246
|
+
#c8102e 45% 55%,
|
|
247
|
+
transparent 55%
|
|
248
|
+
),
|
|
249
|
+
linear-gradient(
|
|
250
|
+
to bottom left,
|
|
251
|
+
transparent 45%,
|
|
252
|
+
#c8102e 45% 55%,
|
|
253
|
+
transparent 55%
|
|
254
|
+
),
|
|
255
|
+
linear-gradient(
|
|
256
|
+
to bottom right,
|
|
257
|
+
transparent 38%,
|
|
258
|
+
#fff 38% 62%,
|
|
259
|
+
transparent 62%
|
|
260
|
+
),
|
|
261
|
+
linear-gradient(
|
|
262
|
+
to bottom left,
|
|
263
|
+
transparent 38%,
|
|
264
|
+
#fff 38% 62%,
|
|
265
|
+
transparent 62%
|
|
266
|
+
),
|
|
267
|
+
linear-gradient(#012169 0 0);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// 13 stripes and the canton. The stars are left out - at 15px tall they would
|
|
271
|
+
// be a grey smear, and the blue block already says which flag this is.
|
|
272
|
+
.mw-flag-us {
|
|
273
|
+
background-image:
|
|
274
|
+
linear-gradient(#3c3b6e 0 0),
|
|
275
|
+
repeating-linear-gradient(to bottom, #b31942 0 7.693%, #fff 7.693% 15.385%);
|
|
276
|
+
background-size:
|
|
277
|
+
40% 53.85%,
|
|
278
|
+
100% 100%;
|
|
279
|
+
background-position:
|
|
280
|
+
top left,
|
|
281
|
+
top left;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.mw-flag-jp {
|
|
285
|
+
background-image:
|
|
286
|
+
radial-gradient(circle at 50% 50%, #bc002d 0 29%, transparent 30%),
|
|
287
|
+
linear-gradient(#fff 0 0);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Two overlapping circles make the crescent; the star is dropped for the same
|
|
291
|
+
// reason as the US stars
|
|
292
|
+
.mw-flag-tr {
|
|
293
|
+
background-image:
|
|
294
|
+
radial-gradient(circle at 47% 50%, #e30a17 0 20%, transparent 21%),
|
|
295
|
+
radial-gradient(circle at 40% 50%, #fff 0 25%, transparent 26%),
|
|
296
|
+
linear-gradient(#e30a17 0 0);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Portugal without the armillary sphere - the ring alone carries it at this size
|
|
300
|
+
.mw-flag-pt {
|
|
301
|
+
background-image:
|
|
302
|
+
radial-gradient(
|
|
303
|
+
circle at 40% 50%,
|
|
304
|
+
transparent 0 12%,
|
|
305
|
+
#ffe900 13% 21%,
|
|
306
|
+
transparent 22%
|
|
307
|
+
),
|
|
308
|
+
linear-gradient(to right, #046a38 0 40%, #da291c 40%);
|
|
309
|
+
}
|
|
@@ -15,10 +15,12 @@
|
|
|
15
15
|
@forward 'divider';
|
|
16
16
|
@forward 'dropdown';
|
|
17
17
|
@forward 'empty-state';
|
|
18
|
+
@forward 'flag';
|
|
18
19
|
@forward 'gallery';
|
|
19
20
|
@forward 'info';
|
|
20
21
|
@forward 'kanban';
|
|
21
22
|
@forward 'kbd';
|
|
23
|
+
@forward 'lang-switch';
|
|
22
24
|
@forward 'links';
|
|
23
25
|
@forward 'lists';
|
|
24
26
|
@forward 'localhost-indicator';
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
@use '../abstracts' as *;
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Language switcher
|
|
5
|
+
//
|
|
6
|
+
// A `.mw-dropdown` underneath, so the keyboard contract, Escape, click-outside
|
|
7
|
+
// and the open state in the DOM are all inherited rather than rebuilt. What
|
|
8
|
+
// this file adds is the trigger - deliberately not a button shape: no fill, no
|
|
9
|
+
// border until it is touched, so the bar reads as logo, links, and then two
|
|
10
|
+
// quiet controls rather than a row of competing buttons.
|
|
11
|
+
//
|
|
12
|
+
// The two-letter code, not the flag, is what says which language is on. A flag
|
|
13
|
+
// is a country and never a language - which one stands for English, and which
|
|
14
|
+
// for the German a Swiss or Austrian visitor reads? The code carries the
|
|
15
|
+
// meaning and the flag is the thing the eye finds first.
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
.mw-lang-switch {
|
|
19
|
+
> summary {
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
gap: spacing('3');
|
|
23
|
+
height: 36px;
|
|
24
|
+
padding: spacing('0') spacing('3');
|
|
25
|
+
border: 1px solid transparent;
|
|
26
|
+
border-radius: radius('2xl');
|
|
27
|
+
background: transparent;
|
|
28
|
+
color: var(--mw-text-color);
|
|
29
|
+
transition: var(--mw-transition);
|
|
30
|
+
@include tappable;
|
|
31
|
+
@include focus-ring;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Open looks the same as hovered - the menu below is what says it is open
|
|
35
|
+
> summary:hover,
|
|
36
|
+
&[open] > summary {
|
|
37
|
+
background: var(--mw-surface-muted);
|
|
38
|
+
border-color: var(--mw-border);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// The code carries the state, so it is the one part that gets full ink
|
|
43
|
+
.mw-lang-switch-code {
|
|
44
|
+
font-size: font-size('xs');
|
|
45
|
+
font-weight: font-weight('bold');
|
|
46
|
+
letter-spacing: 0.08em;
|
|
47
|
+
text-transform: uppercase;
|
|
48
|
+
line-height: 1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.mw-lang-switch .mw-dropdown-caret {
|
|
52
|
+
font-size: font-size('3xs');
|
|
53
|
+
opacity: 0.6;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// A language list is short and its labels are one word - the 200px default
|
|
57
|
+
// menu leaves half of it empty. The one place it must not be narrowed is under
|
|
58
|
+
// a thumb, where the dropdown widens every menu on purpose.
|
|
59
|
+
.mw-lang-switch .mw-dropdown-menu {
|
|
60
|
+
min-width: 170px;
|
|
61
|
+
|
|
62
|
+
@media (pointer: coarse), (max-width: #{breakpoint('sm')}) {
|
|
63
|
+
min-width: max(100%, 240px);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.mw-lang-switch-name {
|
|
68
|
+
flex: 1;
|
|
69
|
+
min-width: 0;
|
|
70
|
+
white-space: nowrap;
|
|
71
|
+
overflow: hidden;
|
|
72
|
+
text-overflow: ellipsis;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// The tick is the only mark of the current choice inside the menu - it has to
|
|
76
|
+
// stay out of the muted icon column the dropdown gives every other icon.
|
|
77
|
+
// Kept in the layout while hidden, so the labels do not shift by a tick's width
|
|
78
|
+
// when the choice moves to another row.
|
|
79
|
+
.mw-lang-switch .mw-dropdown-item .mw-lang-switch-check {
|
|
80
|
+
margin-left: auto;
|
|
81
|
+
color: var(--mw-primary-text-color);
|
|
82
|
+
visibility: hidden;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.mw-lang-switch .mw-dropdown-item.mw-active .mw-lang-switch-check,
|
|
86
|
+
.mw-lang-switch .mw-dropdown-item.active .mw-lang-switch-check {
|
|
87
|
+
visibility: visible;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// In the bar the control sits on the header's own dark surface, which stays
|
|
91
|
+
// dark in the light theme too - so it cannot use the page's text and surface
|
|
92
|
+
// tokens the way it does anywhere else. The modifier is for the same surface
|
|
93
|
+
// reached another way: a project that builds its own bar instead of using
|
|
94
|
+
// `.mw-header`, or a dark footer.
|
|
95
|
+
.mw-header .mw-lang-switch,
|
|
96
|
+
.mw-lang-switch-inverted {
|
|
97
|
+
> summary {
|
|
98
|
+
color: var(--mw-header-text-color);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
> summary:hover,
|
|
102
|
+
&[open] > summary {
|
|
103
|
+
background: var(--mw-header-border);
|
|
104
|
+
border-color: var(--mw-header-border);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 36px is a comfortable target for a mouse and a miss for a finger. The caret
|
|
109
|
+
// stays - without it the control reads as a label rather than as something to
|
|
110
|
+
// press.
|
|
111
|
+
@include media-down('sm') {
|
|
112
|
+
.mw-lang-switch > summary {
|
|
113
|
+
height: 40px;
|
|
114
|
+
gap: spacing('2');
|
|
115
|
+
}
|
|
116
|
+
}
|