maverick-wave 5.3.0 → 5.5.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 +13 -4
- package/.claude/skills/mw-maverick-wave/examples/angular-services.md +91 -0
- package/.claude/skills/mw-maverick-wave/examples/static-landing-page.md +5 -4
- package/.claude/skills/mw-maverick-wave/references/components.md +7 -0
- package/.claude/skills/mw-maverick-wave/references/javascript.md +20 -2
- package/.claude/skills/mw-maverick-wave/references/layout.md +81 -10
- package/.claude/skills/mw-maverick-wave/references/theming.md +10 -0
- package/CHANGELOG.md +18 -0
- package/CLAUDE.md +1 -1
- package/README.md +3 -4
- package/index.html +291 -3
- package/maverick-wave.min.css +6 -4
- package/maverick-wave.min.js +1 -1
- package/package.json +2 -2
- package/scripts/verify.js +4 -7
- package/src/js/main.js +237 -11
- package/src/partials/documentation-container.html +4 -0
- package/src/partials/footer-container.html +3 -0
- package/src/partials/history-container.html +67 -0
- package/src/partials/home-container.html +2 -0
- package/src/partials/palette-container.html +142 -0
- package/src/partials/parallax-container.html +114 -0
- package/src/scss/abstracts/_mixins.scss +6 -5
- package/src/scss/abstracts/_variables.scss +4 -0
- package/src/scss/base/_base.scss +1 -0
- package/src/scss/base/_reset.scss +4 -1
- package/src/scss/components/_accordions.scss +31 -7
- package/src/scss/components/_toasts.scss +1 -1
- package/src/scss/form-elements/_slider.scss +5 -23
- package/src/scss/layout/_header-reveal.scss +133 -0
- package/src/scss/layout/_index.scss +4 -0
- package/src/scss/layout/_main.scss +17 -2
- package/src/scss/layout/_parallax.scss +178 -0
- package/src/scss/utilities/_reveal.scss +22 -0
- package/.impeccable/config.local.json +0 -5
- package/.impeccable/hook.cache.json +0 -75
package/index.html
CHANGED
|
@@ -69,6 +69,31 @@
|
|
|
69
69
|
border: 1px solid var(--mw-border);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/* The parallax pattern demo: a gradient has no edge across the travel,
|
|
73
|
+
the second layer brings one */
|
|
74
|
+
.parallax-demo-ground {
|
|
75
|
+
background-image: linear-gradient(
|
|
76
|
+
158deg,
|
|
77
|
+
#3c4f78 0%,
|
|
78
|
+
#2a3550 45%,
|
|
79
|
+
#1b2334 100%
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.parallax-demo-lines {
|
|
84
|
+
--mw-parallax-pattern-image:
|
|
85
|
+
repeating-linear-gradient(
|
|
86
|
+
to bottom,
|
|
87
|
+
rgb(255 255 255 / 24%) 0 1px,
|
|
88
|
+
transparent 1px 34px
|
|
89
|
+
),
|
|
90
|
+
repeating-linear-gradient(
|
|
91
|
+
to right,
|
|
92
|
+
rgb(255 255 255 / 14%) 0 1px,
|
|
93
|
+
transparent 1px 34px
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
72
97
|
/* A calendar fills its container; across the full page that stretches the
|
|
73
98
|
cells to 150px, so the demos get a realistic column instead */
|
|
74
99
|
.calendar-demo {
|
|
@@ -93,6 +118,144 @@
|
|
|
93
118
|
height: 50px;
|
|
94
119
|
}
|
|
95
120
|
}
|
|
121
|
+
|
|
122
|
+
/* Palette switcher, showcase only. The framework derives every tone from
|
|
123
|
+
the root colors, so the panel writes nothing but those. */
|
|
124
|
+
.palette-fab {
|
|
125
|
+
position: fixed;
|
|
126
|
+
right: 18px;
|
|
127
|
+
bottom: 18px;
|
|
128
|
+
z-index: 400;
|
|
129
|
+
width: 52px;
|
|
130
|
+
height: 52px;
|
|
131
|
+
border-radius: 50%;
|
|
132
|
+
border: 1px solid var(--mw-border-accent);
|
|
133
|
+
background: var(--mw-primary-color);
|
|
134
|
+
color: var(--mw-primary-accent-text-color);
|
|
135
|
+
box-shadow: var(--mw-elevation-4);
|
|
136
|
+
font-size: 1.25rem;
|
|
137
|
+
cursor: pointer;
|
|
138
|
+
transition: var(--mw-transition);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.palette-fab:hover {
|
|
142
|
+
background: var(--mw-primary-color-hover);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.palette-fab:active {
|
|
146
|
+
transform: scale(0.92);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.palette-panel {
|
|
150
|
+
position: fixed;
|
|
151
|
+
right: 18px;
|
|
152
|
+
bottom: 82px;
|
|
153
|
+
z-index: 400;
|
|
154
|
+
width: 300px;
|
|
155
|
+
padding: 18px;
|
|
156
|
+
border-radius: 12px;
|
|
157
|
+
border: 1px solid var(--mw-border);
|
|
158
|
+
background: var(--mw-card-background);
|
|
159
|
+
box-shadow: var(--mw-elevation-5);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.palette-heading {
|
|
163
|
+
font-size: 1.1rem;
|
|
164
|
+
margin-bottom: 4px;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.palette-hint {
|
|
168
|
+
font-size: 0.8rem;
|
|
169
|
+
line-height: 1.35;
|
|
170
|
+
color: var(--mw-text-muted-color);
|
|
171
|
+
margin-bottom: 14px;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.palette-grid {
|
|
175
|
+
display: grid;
|
|
176
|
+
grid-template-columns: 1fr 1fr;
|
|
177
|
+
gap: 6px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.palette-item {
|
|
181
|
+
display: flex;
|
|
182
|
+
align-items: center;
|
|
183
|
+
gap: 8px;
|
|
184
|
+
padding: 6px 8px;
|
|
185
|
+
border-radius: 8px;
|
|
186
|
+
border: 1px solid var(--mw-border);
|
|
187
|
+
background: transparent;
|
|
188
|
+
color: var(--mw-text-color);
|
|
189
|
+
font-size: 0.8rem;
|
|
190
|
+
text-align: left;
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
transition: var(--mw-transition);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.palette-item::before {
|
|
196
|
+
content: '';
|
|
197
|
+
width: 16px;
|
|
198
|
+
height: 16px;
|
|
199
|
+
flex-shrink: 0;
|
|
200
|
+
border-radius: 50%;
|
|
201
|
+
background: linear-gradient(
|
|
202
|
+
135deg,
|
|
203
|
+
var(--swatch-primary) 50%,
|
|
204
|
+
var(--swatch-secondary) 50%
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.palette-item:hover,
|
|
209
|
+
.palette-item.mw-active {
|
|
210
|
+
border-color: var(--mw-primary-text-color);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.palette-item.mw-active {
|
|
214
|
+
background: var(--mw-primary-background);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.palette-custom {
|
|
218
|
+
display: flex;
|
|
219
|
+
gap: 10px;
|
|
220
|
+
margin-top: 14px;
|
|
221
|
+
padding-top: 12px;
|
|
222
|
+
border-top: 1px solid var(--mw-border);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.palette-field {
|
|
226
|
+
flex: 1;
|
|
227
|
+
display: flex;
|
|
228
|
+
flex-direction: column;
|
|
229
|
+
gap: 4px;
|
|
230
|
+
font-size: 0.75rem;
|
|
231
|
+
color: var(--mw-text-muted-color);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.palette-field input {
|
|
235
|
+
width: 100%;
|
|
236
|
+
height: 30px;
|
|
237
|
+
padding: 2px;
|
|
238
|
+
border: 1px solid var(--mw-border);
|
|
239
|
+
border-radius: 6px;
|
|
240
|
+
background: var(--mw-card-background);
|
|
241
|
+
cursor: pointer;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@media (max-width: 576px) {
|
|
245
|
+
.palette-fab {
|
|
246
|
+
right: 12px;
|
|
247
|
+
bottom: 12px;
|
|
248
|
+
width: 46px;
|
|
249
|
+
height: 46px;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.palette-panel {
|
|
253
|
+
right: 12px;
|
|
254
|
+
left: 12px;
|
|
255
|
+
bottom: 68px;
|
|
256
|
+
width: auto;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
96
259
|
</style>
|
|
97
260
|
|
|
98
261
|
<script src="maverick-wave.min.js"></script>
|
|
@@ -102,7 +265,7 @@
|
|
|
102
265
|
<a class="mw-skip-link" href="#main">Skip to content</a>
|
|
103
266
|
|
|
104
267
|
<!-- Header -->
|
|
105
|
-
<header class="mw-header mw-localhost-indicator-activated">
|
|
268
|
+
<header class="mw-header mw-header-reveal mw-localhost-indicator-activated">
|
|
106
269
|
<div class="mw-container">
|
|
107
270
|
@@include('./src/partials/header-container.html')
|
|
108
271
|
</div>
|
|
@@ -110,8 +273,8 @@
|
|
|
110
273
|
|
|
111
274
|
<main class="mw-main" id="main">
|
|
112
275
|
<!-- Home section -->
|
|
113
|
-
<section id="home" class="mw-section">
|
|
114
|
-
<div class="mw-container">
|
|
276
|
+
<section id="home" class="mw-section mw-parallax-sticky mw-parallax-rise">
|
|
277
|
+
<div class="mw-container mw-parallax">
|
|
115
278
|
@@include('./src/partials/home-container.html')
|
|
116
279
|
</div>
|
|
117
280
|
</section>
|
|
@@ -210,6 +373,7 @@
|
|
|
210
373
|
<a href="#html-lists" class="mw-section-btn">HTML Lists</a>
|
|
211
374
|
<a href="#item-lists" class="mw-section-btn">Item Lists</a>
|
|
212
375
|
<a href="#stepper" class="mw-section-btn">Stepper</a>
|
|
376
|
+
<a href="#parallax" class="mw-section-btn">Parallax</a>
|
|
213
377
|
</nav>
|
|
214
378
|
|
|
215
379
|
<!-- Grid container -->
|
|
@@ -258,6 +422,11 @@
|
|
|
258
422
|
<div id="stepper">
|
|
259
423
|
@@include('./src/partials/stepper-container.html')
|
|
260
424
|
</div>
|
|
425
|
+
|
|
426
|
+
<!-- Parallax container -->
|
|
427
|
+
<div id="parallax">
|
|
428
|
+
@@include('./src/partials/parallax-container.html')
|
|
429
|
+
</div>
|
|
261
430
|
</div>
|
|
262
431
|
</section>
|
|
263
432
|
|
|
@@ -507,6 +676,17 @@
|
|
|
507
676
|
</div>
|
|
508
677
|
</div>
|
|
509
678
|
</section>
|
|
679
|
+
<!-- History section -->
|
|
680
|
+
<section id="history" class="mw-section mw-section-alternate">
|
|
681
|
+
<div class="mw-container">
|
|
682
|
+
<h2 class="mw-section-title">History</h2>
|
|
683
|
+
<p class="mw-section-intro">
|
|
684
|
+
The major releases so far. Everything in between - the minors and
|
|
685
|
+
the patch releases - sits in the changelog.
|
|
686
|
+
</p>
|
|
687
|
+
@@include('./src/partials/history-container.html')
|
|
688
|
+
</div>
|
|
689
|
+
</section>
|
|
510
690
|
</main>
|
|
511
691
|
|
|
512
692
|
<!-- Footer -->
|
|
@@ -515,6 +695,9 @@
|
|
|
515
695
|
@@include('./src/partials/footer-container.html')
|
|
516
696
|
</div>
|
|
517
697
|
</footer>
|
|
698
|
+
|
|
699
|
+
<!-- Palette switcher -->
|
|
700
|
+
@@include('./src/partials/palette-container.html')
|
|
518
701
|
<script>
|
|
519
702
|
// just for the showcase (login button triggers login error)
|
|
520
703
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -598,6 +781,111 @@
|
|
|
598
781
|
apply(cycleSwitch.querySelector('.mw-active'));
|
|
599
782
|
});
|
|
600
783
|
|
|
784
|
+
// just for the showcase: the palette switcher. Every tone in the framework
|
|
785
|
+
// is derived from the root colors with color-mix(), so writing those on the
|
|
786
|
+
// root element repaints the page - bar, ink, borders and tints included.
|
|
787
|
+
// Nothing is persisted - a palette is for looking at, a reload is the way back.
|
|
788
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
789
|
+
const fab = document.getElementById('palette-fab');
|
|
790
|
+
const panel = document.getElementById('palette-panel');
|
|
791
|
+
const primaryInput = document.getElementById('palette-primary');
|
|
792
|
+
const secondaryInput = document.getElementById('palette-secondary');
|
|
793
|
+
const items = [...document.querySelectorAll('.palette-item')];
|
|
794
|
+
if (!fab || !panel) return;
|
|
795
|
+
|
|
796
|
+
const root = document.documentElement;
|
|
797
|
+
|
|
798
|
+
const DARK_INK = '#131925';
|
|
799
|
+
const LIGHT_INK = '#f2f6fc';
|
|
800
|
+
|
|
801
|
+
const luminance = (hex) => {
|
|
802
|
+
const [r, g, b] = [1, 3, 5].map((i) => {
|
|
803
|
+
const channel = parseInt(hex.slice(i, i + 2), 16) / 255;
|
|
804
|
+
return channel <= 0.04045
|
|
805
|
+
? channel / 12.92
|
|
806
|
+
: ((channel + 0.055) / 1.055) ** 2.4;
|
|
807
|
+
});
|
|
808
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
const contrast = (a, b) => {
|
|
812
|
+
const [high, low] = [luminance(a), luminance(b)].sort(
|
|
813
|
+
(x, y) => y - x
|
|
814
|
+
);
|
|
815
|
+
return (high + 0.05) / (low + 0.05);
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
// Measured, not thresholded - a lightness cutoff gets a saturated mid
|
|
819
|
+
// tone wrong
|
|
820
|
+
const ink = (fill) =>
|
|
821
|
+
contrast(fill, DARK_INK) > contrast(fill, LIGHT_INK)
|
|
822
|
+
? DARK_INK
|
|
823
|
+
: LIGHT_INK;
|
|
824
|
+
|
|
825
|
+
// Cuts the transition the new colours started: the whole page
|
|
826
|
+
// interpolating at once is the expensive part, and the hex labels in the
|
|
827
|
+
// Colors section read computed values, so they need the landed ones
|
|
828
|
+
const settle = () => {
|
|
829
|
+
root.classList.add('mw-theme-switching');
|
|
830
|
+
void root.offsetHeight;
|
|
831
|
+
root.classList.remove('mw-theme-switching');
|
|
832
|
+
window.mwRefreshColorSwatches?.();
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
const paint = (name, color) => {
|
|
836
|
+
root.style.setProperty(`--mw-${name}-color`, color);
|
|
837
|
+
root.style.setProperty(`--mw-${name}-accent-text-color`, ink(color));
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
items.forEach((item) => {
|
|
841
|
+
const { primary, secondary, dark, light } = item.dataset;
|
|
842
|
+
item.style.setProperty('--swatch-primary', primary);
|
|
843
|
+
item.style.setProperty('--swatch-secondary', secondary);
|
|
844
|
+
|
|
845
|
+
item.addEventListener('click', () => {
|
|
846
|
+
items.forEach((other) =>
|
|
847
|
+
other.classList.toggle('mw-active', other === item)
|
|
848
|
+
);
|
|
849
|
+
paint('primary', primary);
|
|
850
|
+
paint('secondary', secondary);
|
|
851
|
+
root.style.setProperty('--mw-dark-page-background', dark);
|
|
852
|
+
root.style.setProperty('--mw-light-page-background', light);
|
|
853
|
+
primaryInput.value = primary;
|
|
854
|
+
secondaryInput.value = secondary;
|
|
855
|
+
settle();
|
|
856
|
+
});
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
// A hand-picked color belongs to no preset - the page backgrounds stay put
|
|
860
|
+
[
|
|
861
|
+
['primary', primaryInput],
|
|
862
|
+
['secondary', secondaryInput],
|
|
863
|
+
].forEach(([name, input]) => {
|
|
864
|
+
input.addEventListener('input', () => {
|
|
865
|
+
items.forEach((item) => item.classList.remove('mw-active'));
|
|
866
|
+
paint(name, input.value);
|
|
867
|
+
});
|
|
868
|
+
// Dragging the picker fires `input` per pixel - the rest waits for the end
|
|
869
|
+
input.addEventListener('change', settle);
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
const toggle = (open) => {
|
|
873
|
+
panel.hidden = !open;
|
|
874
|
+
fab.setAttribute('aria-expanded', String(open));
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
fab.addEventListener('click', (event) => {
|
|
878
|
+
event.stopPropagation();
|
|
879
|
+
toggle(panel.hidden);
|
|
880
|
+
});
|
|
881
|
+
document.addEventListener('click', (event) => {
|
|
882
|
+
if (!panel.hidden && !panel.contains(event.target)) toggle(false);
|
|
883
|
+
});
|
|
884
|
+
document.addEventListener('keydown', (event) => {
|
|
885
|
+
if (event.key === 'Escape') toggle(false);
|
|
886
|
+
});
|
|
887
|
+
});
|
|
888
|
+
|
|
601
889
|
// for the modals - the framework handles both shapes, div and <dialog>
|
|
602
890
|
const openModal = window.mwOpenModal;
|
|
603
891
|
const closeModal = window.mwCloseModal;
|