maverick-wave 5.6.0 → 5.7.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 -5
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +2 -2
- package/.claude/skills/mw-maverick-wave/references/components.md +5 -2
- package/.claude/skills/mw-maverick-wave/references/forms.md +5 -5
- package/.claude/skills/mw-maverick-wave/references/theming.md +12 -11
- package/CHANGELOG.md +11 -0
- package/README.md +8 -7
- package/index.html +168 -4
- package/maverick-wave.min.css +4 -4
- package/package.json +2 -2
- package/src/partials/history-container.html +1 -1
- package/src/partials/palette-container.html +37 -10
- package/src/partials/typography-container.html +8 -9
- package/src/partials/utilities-container.html +10 -3
- package/src/scss/abstracts/_mixins.scss +6 -1
- package/src/scss/abstracts/_variables.scss +4 -4
- package/src/scss/components/_avatars.scss +29 -0
- package/src/scss/components/_button-bar.scss +1 -1
- package/src/scss/components/_buttons.scss +1 -1
- package/src/scss/form-elements/_input.scss +1 -1
- package/src/scss/form-elements/_select.scss +1 -1
- package/src/scss/layout/_main.scss +31 -2
- package/src/scss/utilities/_reveal.scss +9 -2
- package/src/scss/utilities/_touch-targets.scss +1 -1
- package/src/scss/utilities/_variants.scss +48 -18
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "maverick-wave",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.7.0",
|
|
4
4
|
"config": {
|
|
5
|
-
"version_short": "5.
|
|
5
|
+
"version_short": "5.7"
|
|
6
6
|
},
|
|
7
7
|
"description": "A lightweight, modern CSS framework for building responsive websites with elegance and speed.",
|
|
8
8
|
"main": "src/js/main.js",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
<div class="mw-timeline-simple-date">2025-04-30</div>
|
|
57
57
|
<div class="mw-timeline-simple-content">
|
|
58
58
|
<div class="mw-card mw-card-simple">
|
|
59
|
-
<h3 class="mw-card-title">v1.
|
|
59
|
+
<h3 class="mw-card-title">v1.0.0</h3>
|
|
60
60
|
<p>
|
|
61
61
|
Let's say initial release - grid, header and a first handful of
|
|
62
62
|
components, published as they were.
|
|
@@ -143,7 +143,8 @@
|
|
|
143
143
|
<h3 class="palette-heading palette-heading-split">Variants</h3>
|
|
144
144
|
<p class="palette-hint">
|
|
145
145
|
Every switch is one class on <html> or one custom property - no build,
|
|
146
|
-
no rebuild. The
|
|
146
|
+
no rebuild. The box at the bottom is what a project would carry, and it
|
|
147
|
+
reads back: paste someone else's setup in to see it.
|
|
147
148
|
</p>
|
|
148
149
|
|
|
149
150
|
<div id="variant-list">
|
|
@@ -190,24 +191,24 @@
|
|
|
190
191
|
|
|
191
192
|
<label class="variant-row">
|
|
192
193
|
<span class="variant-label">
|
|
193
|
-
|
|
194
|
+
Glass buttons
|
|
194
195
|
<small
|
|
195
|
-
>
|
|
196
|
-
|
|
196
|
+
>Filled buttons become tinted glass - the colour drops to a
|
|
197
|
+
translucent wash with a lit top edge.</small
|
|
197
198
|
>
|
|
198
199
|
</span>
|
|
199
|
-
<input type="checkbox" data-variant-class="mw-
|
|
200
|
+
<input type="checkbox" data-variant-class="mw-btn-glass" />
|
|
200
201
|
</label>
|
|
201
202
|
|
|
202
203
|
<label class="variant-row">
|
|
203
204
|
<span class="variant-label">
|
|
204
|
-
|
|
205
|
+
Single accent color
|
|
205
206
|
<small
|
|
206
|
-
>
|
|
207
|
-
|
|
207
|
+
>Drop the second brand colour - hovers, tints and borders all come
|
|
208
|
+
from the first one.</small
|
|
208
209
|
>
|
|
209
210
|
</span>
|
|
210
|
-
<input type="checkbox" data-variant-class="mw-
|
|
211
|
+
<input type="checkbox" data-variant-class="mw-accent-single" />
|
|
211
212
|
</label>
|
|
212
213
|
|
|
213
214
|
<label class="variant-row">
|
|
@@ -256,6 +257,22 @@
|
|
|
256
257
|
<input type="checkbox" data-variant-class="mw-hover-static" />
|
|
257
258
|
</label>
|
|
258
259
|
|
|
260
|
+
<label class="variant-row">
|
|
261
|
+
<span class="variant-label">
|
|
262
|
+
Scroll reveal
|
|
263
|
+
<small
|
|
264
|
+
>Cards and sections rise into place as they scroll in. Off has
|
|
265
|
+
everything sit where it lands.</small
|
|
266
|
+
>
|
|
267
|
+
</span>
|
|
268
|
+
<input
|
|
269
|
+
type="checkbox"
|
|
270
|
+
checked
|
|
271
|
+
data-variant-class="mw-scroll-static"
|
|
272
|
+
data-variant-invert
|
|
273
|
+
/>
|
|
274
|
+
</label>
|
|
275
|
+
|
|
259
276
|
<label class="variant-row">
|
|
260
277
|
<span class="variant-label">
|
|
261
278
|
Sticky header
|
|
@@ -321,5 +338,15 @@
|
|
|
321
338
|
</label>
|
|
322
339
|
</div>
|
|
323
340
|
|
|
324
|
-
<
|
|
341
|
+
<label class="variant-setup-label" for="variant-setup">
|
|
342
|
+
Setup - editable, paste one in to load it
|
|
343
|
+
</label>
|
|
344
|
+
<textarea
|
|
345
|
+
class="variant-setup"
|
|
346
|
+
id="variant-setup"
|
|
347
|
+
rows="4"
|
|
348
|
+
spellcheck="false"
|
|
349
|
+
autocapitalize="off"
|
|
350
|
+
autocorrect="off"
|
|
351
|
+
></textarea>
|
|
325
352
|
</div>
|
|
@@ -19,6 +19,14 @@
|
|
|
19
19
|
<blockquote>
|
|
20
20
|
In the complex world of code, simplicity is the ultimate sophistication.
|
|
21
21
|
</blockquote>
|
|
22
|
+
<p>
|
|
23
|
+
<span class="mw-text-xs">Extra Small Text</span><br />
|
|
24
|
+
<span class="mw-text-sm">Small Text</span><br />
|
|
25
|
+
<span class="mw-text-base">Base Text</span><br />
|
|
26
|
+
<span class="mw-text-md">Medium Text</span><br />
|
|
27
|
+
<span class="mw-text-lg">Large Text</span><br />
|
|
28
|
+
<span class="mw-text-xl">Extra Large Text</span>
|
|
29
|
+
</p>
|
|
22
30
|
</div>
|
|
23
31
|
|
|
24
32
|
<div class="mw-grid-stack mw-gap-2">
|
|
@@ -59,14 +67,5 @@
|
|
|
59
67
|
<p class="mw-text-color-light">
|
|
60
68
|
This always remains the text color of the light theme.
|
|
61
69
|
</p>
|
|
62
|
-
|
|
63
|
-
<p>
|
|
64
|
-
<span class="mw-text-xs">Extra Small Text</span><br />
|
|
65
|
-
<span class="mw-text-sm">Small Text</span><br />
|
|
66
|
-
<span class="mw-text-base">Base Text</span><br />
|
|
67
|
-
<span class="mw-text-md">Medium Text</span><br />
|
|
68
|
-
<span class="mw-text-lg">Large Text</span><br />
|
|
69
|
-
<span class="mw-text-xl">Extra Large Text</span>
|
|
70
|
-
</p>
|
|
71
70
|
</div>
|
|
72
71
|
</div>
|
|
@@ -426,10 +426,10 @@
|
|
|
426
426
|
|
|
427
427
|
<h3 class="mw-mb-4 mw-mt-6">Site-wide Variants</h3>
|
|
428
428
|
<p class="mw-text-muted mw-text-measure">
|
|
429
|
-
|
|
429
|
+
Nine classes on <code><html></code> retune the whole look without
|
|
430
430
|
touching markup. They stack, and the palette button in the corner switches all
|
|
431
431
|
of them live - the box at the bottom of that panel prints the setup a project
|
|
432
|
-
would carry.
|
|
432
|
+
would carry, and reads it back: paste one in to see someone else's.
|
|
433
433
|
</p>
|
|
434
434
|
<ul class="mw-list mw-list-dot mw-text-measure">
|
|
435
435
|
<li>
|
|
@@ -448,6 +448,10 @@
|
|
|
448
448
|
<code>mw-hover-static</code> - no hover travels; colour and border still
|
|
449
449
|
respond
|
|
450
450
|
</li>
|
|
451
|
+
<li>
|
|
452
|
+
<code>mw-scroll-static</code> - no scroll entrance;
|
|
453
|
+
<code>mw-reveal</code> blocks sit where they land
|
|
454
|
+
</li>
|
|
451
455
|
<li>
|
|
452
456
|
<code>mw-sections-plain</code> - the hatch behind
|
|
453
457
|
<code>mw-section-alternate</code> collapses into the page colour
|
|
@@ -457,7 +461,10 @@
|
|
|
457
461
|
<code>mw-btn-pill</code> - fully rounded buttons, form fields keep their
|
|
458
462
|
radius
|
|
459
463
|
</li>
|
|
460
|
-
<li
|
|
464
|
+
<li>
|
|
465
|
+
<code>mw-btn-glass</code> - filled buttons become tinted glass with a lit
|
|
466
|
+
top edge
|
|
467
|
+
</li>
|
|
461
468
|
</ul>
|
|
462
469
|
<p class="mw-text-muted mw-text-measure">
|
|
463
470
|
Four properties do the rest: <code>--mw-radius-scale</code> multiplies every
|
|
@@ -133,9 +133,14 @@
|
|
|
133
133
|
// opt-outs than a colour change does: reduced motion, where a transform still
|
|
134
134
|
// jumps to its end position in one frame however short the duration is, and the
|
|
135
135
|
// static-hover variant. Colour and shadow belong in `hover` and stay either way.
|
|
136
|
+
//
|
|
137
|
+
// A tooltip trigger is a third: a transform makes the element a containing block
|
|
138
|
+
// for its own fixed-position descendants, and the tooltip is exactly that - so a
|
|
139
|
+
// lifted trigger drags the bubble down onto itself. The two cannot both happen,
|
|
140
|
+
// and a label that lands where it belongs beats two pixels of travel.
|
|
136
141
|
@mixin hover-move {
|
|
137
142
|
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
|
|
138
|
-
:root:not(.mw-hover-static) &:hover {
|
|
143
|
+
:root:not(.mw-hover-static) &:hover:not([data-tooltip]) {
|
|
139
144
|
@content;
|
|
140
145
|
}
|
|
141
146
|
}
|
|
@@ -91,12 +91,12 @@ $shadow-far-dark: 16% !default;
|
|
|
91
91
|
$shadow-near-light: 21% !default;
|
|
92
92
|
$shadow-far-light: 14% !default;
|
|
93
93
|
|
|
94
|
-
// Control sizes -
|
|
94
|
+
// Control sizes - 30 / 34 / 38px, shared by input, select, textarea and button so
|
|
95
95
|
// the row lines up. A minimum, not a fixed height, and it is what sets a field's
|
|
96
96
|
// height: trimming `padding-block` moves the text inside the box, not the box.
|
|
97
|
-
$control-height-sm:
|
|
98
|
-
$control-height: 2.
|
|
99
|
-
$control-height-lg: 2.
|
|
97
|
+
$control-height-sm: 1.875rem !default;
|
|
98
|
+
$control-height: 2.125rem !default;
|
|
99
|
+
$control-height-lg: 2.375rem !default;
|
|
100
100
|
|
|
101
101
|
// All three fields share it; buttons stay one step above, because a button
|
|
102
102
|
// carries a label and a field carries what the user typed
|
|
@@ -22,6 +22,35 @@
|
|
|
22
22
|
height: 100%;
|
|
23
23
|
object-fit: cover;
|
|
24
24
|
display: block;
|
|
25
|
+
transition: transform var(--mw-duration-slow) var(--mw-ease-out);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// `:has(img)` keeps the sweep off the initials variant, where it would just
|
|
29
|
+
// flash a white bar across the letters
|
|
30
|
+
&:has(img)::after {
|
|
31
|
+
content: '';
|
|
32
|
+
position: absolute;
|
|
33
|
+
inset: 0;
|
|
34
|
+
background: linear-gradient(
|
|
35
|
+
115deg,
|
|
36
|
+
transparent 38%,
|
|
37
|
+
rgb(255 255 255 / 0.45) 50%,
|
|
38
|
+
transparent 62%
|
|
39
|
+
);
|
|
40
|
+
transform: translateX(-130%);
|
|
41
|
+
pointer-events: none;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@include hover-move {
|
|
45
|
+
img {
|
|
46
|
+
transform: scale(1.12);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Transition only here, so the sweep resets instantly instead of travelling back
|
|
50
|
+
&:has(img)::after {
|
|
51
|
+
transform: translateX(130%);
|
|
52
|
+
transition: transform var(--mw-duration-slower) var(--mw-ease-out);
|
|
53
|
+
}
|
|
25
54
|
}
|
|
26
55
|
|
|
27
56
|
&-xs {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
@layer mw.forms {
|
|
4
4
|
.mw-select {
|
|
5
5
|
width: 100%;
|
|
6
|
-
padding: spacing('
|
|
6
|
+
padding: spacing('1') spacing('6') spacing('1') spacing('3');
|
|
7
7
|
font-size: var(--mw-control-font);
|
|
8
8
|
min-height: var(--mw-control-height);
|
|
9
9
|
background: var(--mw-form-elements-background);
|
|
@@ -157,8 +157,23 @@
|
|
|
157
157
|
padding: spacing('2') spacing('5');
|
|
158
158
|
border: 1px solid #{fade('hero-text-color', 22%)};
|
|
159
159
|
border-radius: 999px;
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
// A vertical ramp and not a flat tint: glass is lit from above, and the
|
|
161
|
+
// gradient is what gives the pill a thickness instead of a fogged panel
|
|
162
|
+
background: linear-gradient(
|
|
163
|
+
to bottom,
|
|
164
|
+
#{fade('hero-text-color', 16%)},
|
|
165
|
+
#{fade('hero-text-color', 5%)}
|
|
166
|
+
);
|
|
167
|
+
// saturate() is what separates glass from frosted plastic: the blur alone
|
|
168
|
+
// greys out what shows through, and pushing the chroma back up is how a
|
|
169
|
+
// real lens reads. The two inset lines are the specular highlight - light
|
|
170
|
+
// catching the top edge, a fainter bounce off the bottom - and the outer
|
|
171
|
+
// shadow is what lifts the pill off the photo instead of pasting it on.
|
|
172
|
+
backdrop-filter: blur(14px) saturate(180%);
|
|
173
|
+
box-shadow:
|
|
174
|
+
inset 0 1px 0 #{fade('hero-text-color', 40%)},
|
|
175
|
+
inset 0 -1px 0 #{fade('hero-text-color', 12%)},
|
|
176
|
+
0 2px 12px rgb(0 0 0 / 18%);
|
|
162
177
|
color: fade('hero-text-color', 88%);
|
|
163
178
|
font-size: font-size('sm');
|
|
164
179
|
font-weight: font-weight('medium');
|
|
@@ -311,6 +326,20 @@
|
|
|
311
326
|
}
|
|
312
327
|
}
|
|
313
328
|
|
|
329
|
+
// A press usually scales the trigger, and a transform makes it a containing
|
|
330
|
+
// block for the fixed-position bubble above - which would drop the label
|
|
331
|
+
// into the element being pressed. So it steps aside for the click instead;
|
|
332
|
+
// by then it has been read anyway. After the hover rule, same weight.
|
|
333
|
+
&:active::before,
|
|
334
|
+
&:active::after {
|
|
335
|
+
opacity: 0;
|
|
336
|
+
display: none;
|
|
337
|
+
// Not transitioned: `allow-discrete` holds `display: block` until the fade
|
|
338
|
+
// ends, and the bubble would spend those 180ms visibly sitting in the
|
|
339
|
+
// element. Going back out on release keeps the fade - that one is wanted.
|
|
340
|
+
transition: none;
|
|
341
|
+
}
|
|
342
|
+
|
|
314
343
|
// The clipping caveat above, lifted where the browser can do it: `fixed` takes
|
|
315
344
|
// the bubble out of the trigger's containing block, anchor positioning keeps
|
|
316
345
|
// it attached. No `anchor-name` needed - a pseudo element is implicitly
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
// `animation:` that cannot carry a timeline.
|
|
12
12
|
@supports (animation-timeline: view()) {
|
|
13
13
|
@media (prefers-reduced-motion: no-preference) {
|
|
14
|
-
.mw-reveal,
|
|
15
|
-
.mw-reveal-stagger > * {
|
|
14
|
+
:root:not(.mw-scroll-static) :is(.mw-reveal, .mw-reveal-stagger > *) {
|
|
16
15
|
animation-name: mw-reveal;
|
|
17
16
|
animation-timing-function: var(--mw-ease-out);
|
|
18
17
|
animation-fill-mode: backwards;
|
|
@@ -47,6 +46,14 @@
|
|
|
47
46
|
transform: translateY(40px);
|
|
48
47
|
}
|
|
49
48
|
|
|
49
|
+
// The script has already hidden whatever was below the fold when the class
|
|
50
|
+
// arrives, and it only ever un-hides on intersection - without this the
|
|
51
|
+
// switch would leave those elements invisible instead of static.
|
|
52
|
+
:root.mw-scroll-static .mw-reveal-hidden {
|
|
53
|
+
opacity: 1;
|
|
54
|
+
transform: none;
|
|
55
|
+
}
|
|
56
|
+
|
|
50
57
|
.mw-reveal-run {
|
|
51
58
|
// `backwards` for the reason above - a forwards fill would pin the
|
|
52
59
|
// transform and cost the card its hover lift. The delay comes inline,
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
min-height: 2.5rem;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
// The base fields sit at 2.
|
|
25
|
+
// The base fields sit at 2.125rem from the control scale, which is right under
|
|
26
26
|
// a pointer and short of a thumb. Same floor as the button beside them.
|
|
27
27
|
.mw-input,
|
|
28
28
|
.mw-select {
|
|
@@ -57,25 +57,55 @@
|
|
|
57
57
|
border-radius: 999px;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
//
|
|
61
|
-
// the
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
60
|
+
// Tinted glass: a translucent wash with a vertical ramp and a specular line
|
|
61
|
+
// along the top edge, which is what gives the button its thickness.
|
|
62
|
+
//
|
|
63
|
+
// Deliberately without `backdrop-filter`, and that omission has to stay. The
|
|
64
|
+
// filter makes the button a containing block for its own fixed-position
|
|
65
|
+
// descendants, which drops a [data-tooltip] bubble inside the button instead
|
|
66
|
+
// of above it; and nested inside the header's own blur it flickers while the
|
|
67
|
+
// page scrolls. At the tint below there was next to nothing to see through.
|
|
68
|
+
//
|
|
69
|
+
// The tint stays heavy on purpose, and that is the other trade-off: a 20%
|
|
70
|
+
// wash reads as real glass, but the label then rides on whatever is behind
|
|
71
|
+
// it, and over a light card that contrast is gone. At 88/70 the label keeps
|
|
72
|
+
// roughly the fill's contrast.
|
|
73
|
+
//
|
|
74
|
+
// Hover and active are restated rather than inherited: this sits in
|
|
75
|
+
// mw.utilities, which outranks every rule in mw.components whatever its
|
|
76
|
+
// specificity, so the states would otherwise be flattened along with the fill.
|
|
77
|
+
:root.mw-btn-glass {
|
|
78
|
+
@each $name in ('primary', 'secondary', 'danger', 'success') {
|
|
79
|
+
.mw-btn-#{$name} {
|
|
80
|
+
background: linear-gradient(
|
|
81
|
+
to bottom,
|
|
82
|
+
color-mix(in srgb, var(--mw-#{$name}-color) 88%, transparent),
|
|
83
|
+
color-mix(in srgb, var(--mw-#{$name}-color) 70%, transparent)
|
|
84
|
+
);
|
|
85
|
+
border-color: color-mix(
|
|
86
|
+
in srgb,
|
|
87
|
+
var(--mw-#{$name}-color) 70%,
|
|
88
|
+
transparent
|
|
89
|
+
);
|
|
90
|
+
box-shadow:
|
|
91
|
+
inset 0 1px 0 rgb(255 255 255 / 28%),
|
|
92
|
+
0 1px 3px rgb(0 0 0 / 14%);
|
|
73
93
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
94
|
+
&:hover:not(:disabled),
|
|
95
|
+
&.mw-active:not(:disabled),
|
|
96
|
+
&.active:not(:disabled) {
|
|
97
|
+
background: linear-gradient(
|
|
98
|
+
to bottom,
|
|
99
|
+
color-mix(in srgb, var(--mw-#{$name}-color) 97%, transparent),
|
|
100
|
+
color-mix(in srgb, var(--mw-#{$name}-color) 82%, transparent)
|
|
101
|
+
);
|
|
102
|
+
border-color: color-mix(
|
|
103
|
+
in srgb,
|
|
104
|
+
var(--mw-#{$name}-color) 85%,
|
|
105
|
+
transparent
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
79
109
|
}
|
|
80
110
|
}
|
|
81
111
|
|