maverick-wave 5.16.0 → 5.19.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 +12 -9
- package/.claude/skills/mw-maverick-wave/examples/angular-list-page.md +40 -35
- package/.claude/skills/mw-maverick-wave/examples/angular-services.md +95 -33
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +38 -53
- package/.claude/skills/mw-maverick-wave/references/components.md +45 -46
- package/.claude/skills/mw-maverick-wave/references/javascript.md +16 -17
- package/.claude/skills/mw-maverick-wave/references/layout.md +24 -0
- package/CHANGELOG.md +19 -0
- package/README.md +2 -2
- package/index.html +1 -5
- package/maverick-wave.min.css +3 -3
- package/package.json +2 -2
- package/release.sh +5 -0
- package/scripts/verify.js +23 -10
- package/src/partials/get-started-container.html +5 -3
- package/src/partials/header-container.html +12 -2
- package/src/partials/modals-container.html +137 -186
- package/src/partials/parallax-container.html +13 -2
- package/src/scss/abstracts/_mixins.scss +34 -6
- package/src/scss/components/_modals.scss +13 -2
- package/src/scss/layout/_header-reveal.scss +106 -1
- package/src/scss/layout/_main.scss +18 -0
- package/src/scss/utilities/_touch-targets.scss +5 -4
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
// Floating free over a picture, a control has to carry its own edge - the burger
|
|
2
|
+
// and the login button bring a primary surface, the theme toggle is a dark pill
|
|
3
|
+
// that a dark photo swallows. It travels with the float and not with the class,
|
|
4
|
+
// or the ring would still be there in the arrived bar, on one control and not
|
|
5
|
+
// its neighbour. Fixed values and not the elevation ramp, the same call the
|
|
6
|
+
// parallax shadow makes: this lands on the picture, not on a theme surface, and
|
|
7
|
+
// the light theme cuts its shadows for paper.
|
|
8
|
+
$float-edge: (0 0 0 1px rgb(255 255 255 / 0.22), 0 4px 14px rgb(0 0 0 / 0.4));
|
|
9
|
+
|
|
1
10
|
@layer mw.layout {
|
|
2
11
|
// For a page that opens on a full-bleed picture and wants nothing on top of
|
|
3
12
|
// it: the bar starts above the screen and rides in over the first stretch of
|
|
@@ -17,6 +26,28 @@
|
|
|
17
26
|
animation-range: 0 420px;
|
|
18
27
|
}
|
|
19
28
|
|
|
29
|
+
// Anything carrying mw-header-keep sits the ride out: the bar travels,
|
|
30
|
+
// the element travels the same distance back and stays where it is. The
|
|
31
|
+
// distance is the bar's own, so it waits at the position it will hold in
|
|
32
|
+
// the arrived bar - nothing jumps at the end, the bar just closes in
|
|
33
|
+
// behind it. For a login or burger button that has to be reachable while
|
|
34
|
+
// the hero is still untouched.
|
|
35
|
+
.mw-header-reveal .mw-header-keep {
|
|
36
|
+
animation-name: mw-header-keep;
|
|
37
|
+
animation-timing-function: var(--mw-ease-out);
|
|
38
|
+
animation-fill-mode: both;
|
|
39
|
+
animation-timeline: scroll(root);
|
|
40
|
+
animation-range: 0 420px;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// A group's opacity cannot be taken back by a child, so the fade has to
|
|
44
|
+
// go as soon as something is meant to stay visible through it. No loss:
|
|
45
|
+
// the bar is off screen for that stretch anyway, the fade only softened
|
|
46
|
+
// the last few pixels of the arrival.
|
|
47
|
+
.mw-header-reveal:has(.mw-header-keep) {
|
|
48
|
+
animation-name: mw-header-slide;
|
|
49
|
+
}
|
|
50
|
+
|
|
20
51
|
// The ribbon is glued under the bar, so it has to leave and arrive with
|
|
21
52
|
// it - left behind it would hang alone at the top of an otherwise clean
|
|
22
53
|
// hero. No class of its own: a ribbon on a page with a revealing header
|
|
@@ -51,18 +82,48 @@
|
|
|
51
82
|
// author declaration that outranks a running animation; dropping
|
|
52
83
|
// `animation-name` instead leaves the element stuck on its last value, because
|
|
53
84
|
// a restarted scroll timeline only catches up on the next scroll.
|
|
54
|
-
|
|
85
|
+
//
|
|
86
|
+
// A keep element is on screen already and needs no rescue, so it is left out -
|
|
87
|
+
// otherwise a click on the theme toggle, which focuses it, would haul in the
|
|
88
|
+
// whole bar. It takes `:focus` on a descendant and not `:focus-within` on the
|
|
89
|
+
// header: within also matches every wrapper around the focused control, and no
|
|
90
|
+
// `:not()` on those can tell which one holds the keep.
|
|
91
|
+
body:has(
|
|
92
|
+
.mw-header-reveal :focus:not(.mw-header-keep, .mw-header-keep *),
|
|
93
|
+
.mw-announcement:focus-within
|
|
94
|
+
) {
|
|
55
95
|
.mw-header-reveal {
|
|
56
96
|
top: 0 !important;
|
|
57
97
|
opacity: 1 !important;
|
|
58
98
|
}
|
|
59
99
|
|
|
100
|
+
.mw-header-keep {
|
|
101
|
+
translate: none !important;
|
|
102
|
+
box-shadow: none !important;
|
|
103
|
+
}
|
|
104
|
+
|
|
60
105
|
.mw-announcement:not(.mw-announcement-static) {
|
|
61
106
|
transform: none !important;
|
|
62
107
|
opacity: 1 !important;
|
|
63
108
|
}
|
|
64
109
|
}
|
|
65
110
|
|
|
111
|
+
// Same treatment while the drawer is open, which mw-header-keep makes
|
|
112
|
+
// reachable long before the bar arrives. The drawer is fixed but hangs off
|
|
113
|
+
// the header - backdrop-filter makes that one its containing block, the way a
|
|
114
|
+
// transform would - so with the bar still away it would sit a header height
|
|
115
|
+
// too high.
|
|
116
|
+
body:has(.mw-header-reveal):has(.mw-navbar.open) {
|
|
117
|
+
.mw-header-reveal {
|
|
118
|
+
top: 0 !important;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.mw-header-keep {
|
|
122
|
+
translate: none !important;
|
|
123
|
+
box-shadow: none !important;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
66
127
|
// Older Safari and Firefox ship no scroll timelines, so there the script
|
|
67
128
|
// toggles these classes instead (main.js) - the same two positions,
|
|
68
129
|
// triggered instead of scrubbed. State and transition are separate because
|
|
@@ -72,6 +133,15 @@
|
|
|
72
133
|
.mw-header-reveal.mw-header-away {
|
|
73
134
|
top: calc(-1 * var(--mw-header-reveal-offset));
|
|
74
135
|
opacity: 0;
|
|
136
|
+
|
|
137
|
+
&:has(.mw-header-keep) {
|
|
138
|
+
opacity: 1;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.mw-header-keep {
|
|
142
|
+
translate: 0 var(--mw-header-reveal-offset);
|
|
143
|
+
box-shadow: $float-edge;
|
|
144
|
+
}
|
|
75
145
|
}
|
|
76
146
|
|
|
77
147
|
.mw-header-driven {
|
|
@@ -80,6 +150,12 @@
|
|
|
80
150
|
transition:
|
|
81
151
|
var(--mw-transition),
|
|
82
152
|
top var(--mw-duration-slow) var(--mw-ease-out);
|
|
153
|
+
|
|
154
|
+
.mw-header-keep {
|
|
155
|
+
transition:
|
|
156
|
+
translate var(--mw-duration-slow) var(--mw-ease-out),
|
|
157
|
+
box-shadow var(--mw-duration-slow) var(--mw-ease-out);
|
|
158
|
+
}
|
|
83
159
|
}
|
|
84
160
|
|
|
85
161
|
.mw-announcement.mw-announcement-away {
|
|
@@ -115,6 +191,35 @@
|
|
|
115
191
|
}
|
|
116
192
|
}
|
|
117
193
|
|
|
194
|
+
// The same ride without the fade, for a bar something stays visible through
|
|
195
|
+
@keyframes mw-header-slide {
|
|
196
|
+
0%,
|
|
197
|
+
30% {
|
|
198
|
+
top: calc(-1 * var(--mw-header-reveal-offset));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
100% {
|
|
202
|
+
top: 0;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// `translate` and not `transform`: the burger puts its hover lift and its
|
|
207
|
+
// press on transform, and a running animation outranks an author declaration
|
|
208
|
+
// - it would hold the button flat for the rest of the page. The standalone
|
|
209
|
+
// property stacks with the shorthand instead of replacing it.
|
|
210
|
+
@keyframes mw-header-keep {
|
|
211
|
+
0%,
|
|
212
|
+
30% {
|
|
213
|
+
translate: 0 var(--mw-header-reveal-offset);
|
|
214
|
+
box-shadow: $float-edge;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
100% {
|
|
218
|
+
translate: none;
|
|
219
|
+
box-shadow: none;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
118
223
|
// The ribbon holds nothing fixed, so it can use the cheaper transform
|
|
119
224
|
@keyframes mw-announcement-reveal {
|
|
120
225
|
0%,
|
|
@@ -338,11 +338,29 @@
|
|
|
338
338
|
// bottom edge, the bubble does not fit, and it gets pushed back over the
|
|
339
339
|
// trigger it belongs to. What this gives up is the clipping immunity the
|
|
340
340
|
// anchored path buys - a modifier inside a scroll container is cut off.
|
|
341
|
+
//
|
|
342
|
+
// Opting out has to restore the placement, not just the positioning scheme:
|
|
343
|
+
// the anchored path below is the later rule and clears `bottom`, `top`,
|
|
344
|
+
// `left` and the centring transform so `position-area` can resolve them
|
|
345
|
+
// itself. Leave that cleared and the box falls to its static position, which
|
|
346
|
+
// for a pseudo element is inside the trigger it is supposed to sit above.
|
|
347
|
+
// The three rules under this one then move the one edge each of them owns.
|
|
341
348
|
&:is(.mw-tooltip-below, .mw-tooltip-end, .mw-tooltip-start) {
|
|
342
349
|
&::before,
|
|
343
350
|
&::after {
|
|
344
351
|
position: absolute;
|
|
345
352
|
position-area: none;
|
|
353
|
+
bottom: 100%;
|
|
354
|
+
top: auto;
|
|
355
|
+
left: 50%;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
&::before {
|
|
359
|
+
transform: translateX(-50%);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
&::after {
|
|
363
|
+
transform: translateX(-50%) rotate(45deg);
|
|
346
364
|
}
|
|
347
365
|
}
|
|
348
366
|
|
|
@@ -100,7 +100,8 @@
|
|
|
100
100
|
// The 18px silhouette stays: mini buttons sit in tag rows and table cells,
|
|
101
101
|
// where growing the circle would shift the layout around them. Only the hit
|
|
102
102
|
// area grows, to 28px - clear of the 24px floor. The extra margin keeps two
|
|
103
|
-
// neighbouring hit areas from overlapping.
|
|
103
|
+
// neighbouring hit areas from overlapping. One with a `data-tooltip` is the
|
|
104
|
+
// exception the mixin makes and goes to a 24px circle instead.
|
|
104
105
|
.mw-btn-mini {
|
|
105
106
|
margin-left: spacing('4');
|
|
106
107
|
@include hit-area(5px);
|
|
@@ -117,9 +118,9 @@
|
|
|
117
118
|
@include hit-area(6px);
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
//
|
|
121
|
-
// `data-tooltip`,
|
|
122
|
-
//
|
|
121
|
+
// One size for the whole row rather than hit-area(): half of these carry a
|
|
122
|
+
// `data-tooltip`, and the mixin treats those differently by design - a row
|
|
123
|
+
// of logos where some grew and some did not reads as a rendering fault.
|
|
123
124
|
.mw-techstack-item-sm {
|
|
124
125
|
min-width: 2.5rem;
|
|
125
126
|
min-height: 2.5rem;
|