maverick-wave 4.23.0 → 4.25.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.
Files changed (24) hide show
  1. package/.claude/skills/{maverick-wave → mw-maverick-wave}/SKILL.md +12 -12
  2. package/.claude/skills/{maverick-wave → mw-maverick-wave}/examples/static-landing-page.md +196 -45
  3. package/.claude/skills/{maverick-wave → mw-maverick-wave}/references/components.md +9 -0
  4. package/.claude/skills/{maverick-wave → mw-maverick-wave}/references/layout.md +42 -1
  5. package/CHANGELOG.md +13 -0
  6. package/README.md +3 -3
  7. package/index.html +7 -0
  8. package/maverick-wave.min.css +1 -1
  9. package/package.json +2 -2
  10. package/scripts/verify.js +4 -1
  11. package/src/partials/documentation-container.html +27 -0
  12. package/src/partials/highlights-container.html +69 -0
  13. package/src/partials/home-container.html +1 -1
  14. package/src/partials/testimonials-container.html +7 -1
  15. package/src/scss/abstracts/_mixins.scss +13 -0
  16. package/src/scss/components/_testimonial.scss +22 -0
  17. package/src/scss/layout/_grid.scss +53 -0
  18. package/src/scss/utilities/_reveal.scss +47 -8
  19. /package/.claude/skills/{maverick-wave → mw-maverick-wave}/examples/angular-form.md +0 -0
  20. /package/.claude/skills/{maverick-wave → mw-maverick-wave}/examples/angular-list-page.md +0 -0
  21. /package/.claude/skills/{maverick-wave → mw-maverick-wave}/examples/angular-services.md +0 -0
  22. /package/.claude/skills/{maverick-wave → mw-maverick-wave}/references/forms.md +0 -0
  23. /package/.claude/skills/{maverick-wave → mw-maverick-wave}/references/javascript.md +0 -0
  24. /package/.claude/skills/{maverick-wave → mw-maverick-wave}/references/theming.md +0 -0
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: maverick-wave
2
+ name: mw-maverick-wave
3
3
  description: Complete usage guide for the MaverickWave CSS framework - mw-* classes, --mw-* design tokens, grid, components, forms, theming and integration into Angular, other SPAs or plain HTML. Use whenever markup or styles are written in a project that loads maverick-wave (CSS/SCSS/CDN), when a mw-* class or --mw-* token appears, or when a UI has to be built with it.
4
4
  ---
5
5
 
@@ -30,12 +30,12 @@ Load the one you need - do not read them all up front.
30
30
 
31
31
  ## Examples
32
32
 
33
- | File | Content |
34
- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
35
- | `examples/angular-list-page.md` | Full list/CRUD page: page header, meta counters, filter bar, table with status tags, empty state, delete modal, toasts |
36
- | `examples/angular-form.md` | Reactive form: `mw-field`, validation states, input groups, numeric input, toggles, form actions |
37
- | `examples/angular-services.md` | Theme service, toast service, modal/scroll-lock, tabs and accordion without `main.js` |
38
- | `examples/static-landing-page.md` | Plain HTML page: header, hero, sections, cards, tiles, accordion, footer, theme toggle |
33
+ | File | Content |
34
+ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
35
+ | `examples/angular-list-page.md` | Full list/CRUD page: page header, meta counters, filter bar, table with status tags, empty state, delete modal, toasts |
36
+ | `examples/angular-form.md` | Reactive form: `mw-field`, validation states, input groups, numeric input, toggles, form actions |
37
+ | `examples/angular-services.md` | Theme service, toast service, modal/scroll-lock, tabs and accordion without `main.js` |
38
+ | `examples/static-landing-page.md` | Plain HTML page: announcement ribbon, hero with scroll cue, feature and offer cards, testimonials, scroll reveal, accordion, footer, theme toggle |
39
39
 
40
40
  ## Setup
41
41
 
@@ -44,14 +44,14 @@ Load the one you need - do not read them all up front.
44
44
  ```html
45
45
  <link
46
46
  rel="stylesheet"
47
- href="https://cdn.jsdelivr.net/npm/maverick-wave@4.0.0/maverick-wave.min.css"
47
+ href="https://cdn.jsdelivr.net/npm/maverick-wave@4.24.0/maverick-wave.min.css"
48
48
  />
49
49
  <link
50
50
  rel="stylesheet"
51
51
  href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"
52
52
  />
53
53
  ...
54
- <script src="https://cdn.jsdelivr.net/npm/maverick-wave@4.0.0/maverick-wave.min.js"></script>
54
+ <script src="https://cdn.jsdelivr.net/npm/maverick-wave@4.24.0/maverick-wave.min.js"></script>
55
55
  ```
56
56
 
57
57
  Pin the version. The JS file is optional and only for server-rendered/static pages -
@@ -225,7 +225,7 @@ feature frame) ·
225
225
 
226
226
  **Media & content** `mw-avatar` (+ `initials`, `group`) · `mw-gallery` ·
227
227
  `mw-image-slider` · `mw-blog-post` · `mw-testimonial` (+ `-source`, `-detail`,
228
- `-featured`) · `mw-prose` · `mw-media` (+ `-caption`) · `mw-code-block` /
228
+ `-date`, `-featured`) · `mw-prose` · `mw-media` (+ `-caption`) · `mw-code-block` /
229
229
  `mw-terminal` · `mw-techstack-bucket` · `mw-coming-soon` · `mw-divider` ·
230
230
  `mw-kbd` · `mw-list` family
231
231
 
@@ -236,7 +236,7 @@ feature frame) ·
236
236
 
237
237
  **Layout** (`references/layout.md`) `mw-main` · `mw-container` · `mw-content` ·
238
238
  `mw-section` (+ `mw-section-intro`) · `mw-page-header` · `mw-grid-*` ·
239
- `mw-columns-2/3` · `mw-row-split` · `mw-hero` · `mw-footer`
239
+ `mw-columns-2/3` · `mw-row-split` · `mw-hero` (+ `mw-scroll-hint`, `-end`) · `mw-footer`
240
240
 
241
241
  **Utilities** (`references/layout.md`) `mw-sr-only` / `mw-sr-only-focusable` /
242
242
  `mw-skip-link` · `mw-row-split` (+ `center`) · `mw-text-numeric` /
@@ -246,7 +246,7 @@ feature frame) ·
246
246
  `mw-corner-plain` ·
247
247
  `mw-aspect-square|video|wide|portrait|photo` · `mw-d-{sm,md,lg,xl}-*` /
248
248
  `mw-hide-mobile` / `mw-hide-desktop` · `mw-overflow-*` / `mw-snap-x` ·
249
- `mw-reveal` · spacing, flex, display, text
249
+ `mw-reveal` / `mw-reveal-stagger` · spacing, flex, display, text
250
250
 
251
251
  ## Pitfalls
252
252
 
@@ -1,9 +1,14 @@
1
1
  # Example: static landing page
2
2
 
3
3
  A complete page without a framework - this is the case the shipped
4
- `maverick-wave.min.js` is built for: accordion, tabs, mobile navigation, theme
5
- toggle and scroll spy all work by themselves. Only opening a modal has to be
6
- wired up by hand.
4
+ `maverick-wave.min.js` is built for: accordion, mobile navigation, theme toggle
5
+ and scroll spy all work by themselves. Only opening a modal has to be wired up
6
+ by hand.
7
+
8
+ The page uses what a landing page reaches for first: an announcement ribbon
9
+ under the header, a hero with a scroll cue, feature cards and testimonials that
10
+ rise into view as the visitor scrolls, offer cards with a real price row, and an
11
+ accordion FAQ.
7
12
 
8
13
  ```html
9
14
  <!doctype html>
@@ -15,7 +20,7 @@ wired up by hand.
15
20
 
16
21
  <link
17
22
  rel="stylesheet"
18
- href="https://cdn.jsdelivr.net/npm/maverick-wave@4.0.0/maverick-wave.min.css"
23
+ href="https://cdn.jsdelivr.net/npm/maverick-wave@4.24.0/maverick-wave.min.css"
19
24
  />
20
25
  <link
21
26
  rel="stylesheet"
@@ -42,7 +47,9 @@ wired up by hand.
42
47
  </div>
43
48
 
44
49
  <div class="mw-header-actions">
45
- <nav class="mw-navbar">
50
+ <!-- Four links: mw-navbar-medium, so the drawer kicks in one
51
+ breakpoint later than the bare navbar would -->
52
+ <nav class="mw-navbar mw-navbar-medium">
46
53
  <ul class="mw-navbar-list">
47
54
  <li class="mw-navbar-item">
48
55
  <a href="#features" class="mw-navbar-link">Features</a>
@@ -50,36 +57,58 @@ wired up by hand.
50
57
  <li class="mw-navbar-item">
51
58
  <a href="#pricing" class="mw-navbar-link">Pricing</a>
52
59
  </li>
60
+ <li class="mw-navbar-item">
61
+ <a href="#voices" class="mw-navbar-link">Voices</a>
62
+ </li>
53
63
  <li class="mw-navbar-item">
54
64
  <a href="#faq" class="mw-navbar-link">FAQ</a>
55
65
  </li>
56
66
  </ul>
57
67
  </nav>
58
68
 
59
- <div class="mw-theme-toggle mw-ml-5">
69
+ <button
70
+ type="button"
71
+ class="mw-theme-toggle mw-ml-5"
72
+ aria-label="Toggle light and dark theme"
73
+ >
60
74
  <div class="mw-theme-toggle-slider">
61
75
  <div class="mw-theme-toggle-icon">
62
76
  <i class="fas fa-moon"></i>
63
77
  </div>
64
78
  </div>
65
- </div>
79
+ </button>
66
80
 
67
81
  <div class="mw-menu-btn"><div class="mw-menu-btn-burger"></div></div>
68
82
  </div>
69
83
  </div>
70
84
  </header>
71
85
 
86
+ <!-- The ribbon under the fixed header. It stays put while the page scrolls
87
+ beneath it, and the anchor scroll offset grows by its height on its
88
+ own - #pricing lands below it, not under it -->
89
+ <aside class="mw-announcement mw-announcement-secondary">
90
+ <a class="mw-announcement-content" href="#pricing">
91
+ <span class="mw-announcement-highlight">-20 %</span>
92
+ <span>Launch offer on every plan until 30.09.</span>
93
+ </a>
94
+ </aside>
95
+
72
96
  <main class="mw-main">
73
- <!-- Hero: the container goes full-bleed because it contains mw-hero -->
97
+ <!-- Hero: the container goes full-bleed because it contains mw-hero.
98
+ The scroll cue is a sibling of the hero inside that container, and
99
+ the hero keeps a strip at its bottom free for it -->
74
100
  <section id="home" class="mw-section">
75
101
  <div class="mw-container">
76
102
  <div class="mw-hero">
77
103
  <div class="mw-home mw-home-content-fade">
78
104
  <div class="mw-home-text">
79
105
  <h1>Acme <span class="mw-text-primary">Analytics</span></h1>
80
- <p>Numbers that answer questions instead of raising them.</p>
106
+ <p>
107
+ Numbers that answer questions instead of raising them. One
108
+ dashboard for the whole company, live in an afternoon.
109
+ </p>
81
110
  </div>
82
- <div class="mw-d-flex mw-gap-8 mw-justify-center mw-mb-7">
111
+ <div class="mw-d-flex mw-gap-8 mw-justify-center">
83
112
  <button
84
113
  type="button"
85
114
  class="mw-btn mw-btn-primary mw-btn-lg"
@@ -87,12 +116,16 @@ wired up by hand.
87
116
  >
88
117
  Book a demo
89
118
  </button>
90
- <a href="#features" class="mw-btn mw-btn-outline mw-btn-lg"
119
+ <a href="#features" class="mw-btn mw-btn-secondary mw-btn-lg"
91
120
  >Learn more</a
92
121
  >
93
122
  </div>
94
123
  </div>
95
124
  </div>
125
+
126
+ <a class="mw-scroll-hint" href="#features">
127
+ More <i class="fas fa-chevron-down"></i>
128
+ </a>
96
129
  </div>
97
130
  </section>
98
131
 
@@ -100,8 +133,14 @@ wired up by hand.
100
133
  <section id="features" class="mw-section mw-section-alternate">
101
134
  <div class="mw-container">
102
135
  <h2 class="mw-section-title">Features</h2>
136
+ <p class="mw-section-intro">
137
+ Three things every team asks about on the first call - and the
138
+ numbers behind them.
139
+ </p>
103
140
 
104
- <div class="mw-grid-3">
141
+ <!-- mw-reveal-stagger on the grid: every card rises as it scrolls
142
+ in, the second and third of each row a beat later -->
143
+ <div class="mw-grid-3 mw-reveal-stagger">
105
144
  <div class="mw-card mw-card-stack">
106
145
  <div class="mw-card-stack-header">
107
146
  <div class="mw-card-stack-icon">
@@ -146,7 +185,8 @@ wired up by hand.
146
185
  </div>
147
186
  </div>
148
187
 
149
- <div class="mw-grid-3 mw-mt-8">
188
+ <!-- A single block reveals as one: plain mw-reveal -->
189
+ <div class="mw-grid-3 mw-mt-8 mw-reveal">
150
190
  <div class="mw-info mw-info-counter mw-info-primary">
151
191
  <div class="mw-info-value">120+</div>
152
192
  <div class="mw-info-label">Teams</div>
@@ -167,9 +207,16 @@ wired up by hand.
167
207
  <section id="pricing" class="mw-section">
168
208
  <div class="mw-container">
169
209
  <h2 class="mw-section-title">Pricing</h2>
210
+ <p class="mw-section-intro">
211
+ Per workspace, per month. Every plan starts with a 14 day trial.
212
+ </p>
170
213
 
171
- <div class="mw-grid-3">
172
- <div class="mw-card">
214
+ <!-- mw-offer pushes the price row to the bottom of the body, so the
215
+ three prices line up although the lists differ in length. The
216
+ feature frame reaches above its card - that is what mw-mt-10 is
217
+ for -->
218
+ <div class="mw-grid-3 mw-mt-10 mw-reveal-stagger">
219
+ <article class="mw-card mw-offer">
173
220
  <div class="mw-card-body">
174
221
  <h3 class="mw-card-title">Starter</h3>
175
222
  <hr class="mw-card-title-divider" />
@@ -178,40 +225,68 @@ wired up by hand.
178
225
  <li>3 dashboards</li>
179
226
  <li>1 data source</li>
180
227
  </ul>
228
+ <p class="mw-price mw-price-sm">
229
+ <span class="mw-price-amount">29</span>
230
+ <span class="mw-price-currency">Euro</span>
231
+ <span class="mw-price-period">/ month</span>
232
+ </p>
233
+ <p class="mw-price-note">Cancel any time.</p>
181
234
  <div class="mw-card-footer">
182
235
  <button type="button" class="mw-btn mw-btn-outline">
183
- Choose
236
+ Choose Starter
184
237
  </button>
185
- <span class="mw-text-numeric mw-text-lg">29 €</span>
186
238
  </div>
187
239
  </div>
188
- </div>
240
+ </article>
189
241
 
190
- <div class="mw-card">
191
- <div class="mw-card-badge mw-card-addon-success">Popular</div>
192
- <div class="mw-card-body">
193
- <h3 class="mw-card-title">Team</h3>
194
- <hr class="mw-card-title-divider" />
195
- <p class="mw-card-text">For growing organisations.</p>
196
- <ul class="mw-list mw-list-check">
197
- <li>Unlimited dashboards</li>
198
- <li>SSO</li>
199
- </ul>
200
- <div class="mw-card-footer">
201
- <button type="button" class="mw-btn mw-btn-primary">
202
- Choose
203
- </button>
204
- <span class="mw-text-numeric mw-text-lg">99 €</span>
242
+ <div class="mw-card-feature mw-card-feature-secondary">
243
+ <p class="mw-card-feature-label">Most booked</p>
244
+ <article class="mw-card mw-offer">
245
+ <div class="mw-card-body">
246
+ <h3 class="mw-card-title">Team</h3>
247
+ <hr class="mw-card-title-divider" />
248
+ <p class="mw-card-text">For growing organisations.</p>
249
+ <ul class="mw-list mw-list-check">
250
+ <li>Unlimited dashboards</li>
251
+ <li>SSO</li>
252
+ <li>Priority support</li>
253
+ </ul>
254
+ <!-- A struck price is invisible to a screen reader - name
255
+ both prices with mw-sr-only -->
256
+ <p class="mw-price mw-price-sm">
257
+ <span class="mw-price-original">
258
+ <span class="mw-sr-only">Regular price:</span>99 Euro
259
+ </span>
260
+ <span class="mw-sr-only">Now:</span>
261
+ <span class="mw-price-amount">79</span>
262
+ <span class="mw-price-currency">Euro</span>
263
+ <span class="mw-tag mw-tag-secondary">-20%</span>
264
+ </p>
265
+ <p class="mw-price-note">
266
+ Per month, launch offer until 30.09.
267
+ </p>
268
+ <div class="mw-card-footer">
269
+ <button type="button" class="mw-btn mw-btn-primary">
270
+ Choose Team
271
+ </button>
272
+ </div>
205
273
  </div>
206
- </div>
274
+ </article>
207
275
  </div>
208
276
 
209
- <div class="mw-card">
210
- <div class="mw-card-ribbon mw-card-addon-primary">Enterprise</div>
277
+ <article class="mw-card mw-offer">
211
278
  <div class="mw-card-body">
212
- <h3 class="mw-card-title">Custom</h3>
279
+ <h3 class="mw-card-title">Enterprise</h3>
213
280
  <hr class="mw-card-title-divider" />
214
281
  <p class="mw-card-text">On premise, custom SLA.</p>
282
+ <ul class="mw-list mw-list-check">
283
+ <li>Everything in Team</li>
284
+ <li>Named contact</li>
285
+ </ul>
286
+ <p class="mw-price mw-price-sm">
287
+ <span class="mw-price-word">On request</span>
288
+ </p>
289
+ <p class="mw-price-note">Priced per seat, yearly term.</p>
215
290
  <div class="mw-card-footer">
216
291
  <button
217
292
  type="button"
@@ -222,13 +297,64 @@ wired up by hand.
222
297
  </button>
223
298
  </div>
224
299
  </div>
225
- </div>
300
+ </article>
301
+ </div>
302
+ </div>
303
+ </section>
304
+
305
+ <!-- Voices -->
306
+ <section id="voices" class="mw-section mw-section-alternate">
307
+ <div class="mw-container">
308
+ <h2 class="mw-section-title">Voices</h2>
309
+ <p class="mw-section-intro">
310
+ What teams say after the first quarter.
311
+ </p>
312
+
313
+ <!-- Quotes of unequal length: columns, not a grid. The stagger
314
+ works on the column children just the same -->
315
+ <div class="mw-columns-3 mw-reveal-stagger">
316
+ <figure class="mw-testimonial">
317
+ <blockquote>
318
+ The first dashboard was live before the kickoff meeting ended.
319
+ </blockquote>
320
+ <figcaption class="mw-testimonial-source">
321
+ Lena B.
322
+ <span class="mw-testimonial-detail"
323
+ >&middot; Head of Operations</span
324
+ >
325
+ <time class="mw-testimonial-date" datetime="2026-06"
326
+ >June 2026</time
327
+ >
328
+ </figcaption>
329
+ </figure>
330
+
331
+ <figure class="mw-testimonial">
332
+ <blockquote>
333
+ We replaced three reporting tools with one. Finance stopped
334
+ asking for exports, they open the dashboard themselves - and for
335
+ the first time everyone quotes the same number.
336
+ </blockquote>
337
+ <figcaption class="mw-testimonial-source">
338
+ Daniel K.
339
+ <span class="mw-testimonial-detail">&middot; CFO</span>
340
+ </figcaption>
341
+ </figure>
342
+
343
+ <figure class="mw-testimonial">
344
+ <blockquote>Connected our warehouse in an afternoon.</blockquote>
345
+ <figcaption class="mw-testimonial-source">
346
+ Sofia R.
347
+ <span class="mw-testimonial-detail"
348
+ >&middot; Data Engineer</span
349
+ >
350
+ </figcaption>
351
+ </figure>
226
352
  </div>
227
353
  </div>
228
354
  </section>
229
355
 
230
356
  <!-- FAQ -->
231
- <section id="faq" class="mw-section mw-section-alternate">
357
+ <section id="faq" class="mw-section">
232
358
  <div class="mw-container">
233
359
  <h2 class="mw-section-title">FAQ</h2>
234
360
 
@@ -272,7 +398,17 @@ wired up by hand.
272
398
  <div class="mw-alert-icon"><i class="fas fa-lightbulb"></i></div>
273
399
  <div class="mw-alert-content">
274
400
  <span class="mw-alert-title">Still unsure?</span>
275
- <p>Book a 20 minute demo - no sales pitch.</p>
401
+ <!-- A link in running text is mw-link, not a button class - it
402
+ keeps the line height of the paragraph around it -->
403
+ <p>
404
+ <button
405
+ type="button"
406
+ class="mw-link"
407
+ onclick="openModal('demo')"
408
+ >
409
+ Book a 20 minute demo</button
410
+ >, no sales pitch.
411
+ </p>
276
412
  </div>
277
413
  </div>
278
414
  </div>
@@ -291,6 +427,7 @@ wired up by hand.
291
427
  <ul>
292
428
  <li><a href="#features">Features</a></li>
293
429
  <li><a href="#pricing">Pricing</a></li>
430
+ <li><a href="#faq">FAQ</a></li>
294
431
  </ul>
295
432
  </div>
296
433
  </div>
@@ -342,7 +479,7 @@ wired up by hand.
342
479
  <div class="mw-modal-backdrop" onclick="closeModal('demo')"></div>
343
480
  </div>
344
481
 
345
- <script src="https://cdn.jsdelivr.net/npm/maverick-wave@4.0.0/maverick-wave.min.js"></script>
482
+ <script src="https://cdn.jsdelivr.net/npm/maverick-wave@4.24.0/maverick-wave.min.js"></script>
346
483
  <script>
347
484
  // The only thing the shipped script does not cover: opening a modal.
348
485
  // Closing works through .mw-modal-close, the backdrop is wired above.
@@ -361,12 +498,26 @@ wired up by hand.
361
498
 
362
499
  - The theme toggle needs no code - the script persists the choice under
363
500
  `localStorage['mw-theme']` and toggles `mw-theme-light` on `<body>`.
364
- - The scroll spy sets `active` on the `mw-navbar-link` whose `href` matches the
365
- `section[id]` currently in view - the `<section id="…">` elements are the
366
- contract.
501
+ - The scroll spy sets `mw-active` on the `mw-navbar-link` whose `href` matches
502
+ the `section[id]` currently in view - the `<section id="…">` elements are
503
+ the contract.
367
504
  - `mw-navbar` without a size class collapses at `md`. With four to five links
368
505
  use `mw-navbar-medium`, with six or more `mw-navbar-large`.
369
506
  - The hero container becomes full-bleed only because it contains `mw-hero`; the
370
- other `mw-container` elements stay at `min(1200px, 89%)`.
507
+ other `mw-container` elements stay at `min(1200px, 89%)`. The scroll cue is a
508
+ sibling of `mw-hero` in that container - the hero reserves a strip at its
509
+ bottom for it, so the buttons never sit on top of the cue.
510
+ - `mw-announcement` is fixed below the header. `scroll-padding-top` grows by
511
+ `--mw-announcement-height` automatically, so an anchor scrolled to lands
512
+ below the ribbon. One per page; `mw-announcement-static` puts it in the flow
513
+ instead.
514
+ - `mw-reveal-stagger` goes on the grid (or `mw-columns-*`) and reveals every
515
+ child as it scrolls in, the second and third of each three a beat later.
516
+ `mw-reveal` on a single block reveals that block as one. Both are off under
517
+ `prefers-reduced-motion`, and a browser without scroll timelines renders the
518
+ blocks in place - never invisible.
519
+ - `mw-offer` on a card pushes the price row to the bottom of the body, so the
520
+ prices in a row line up. The `mw-card-feature` frame around the middle plan
521
+ reaches 29px above its card - the `mw-mt-10` on the grid is that room.
371
522
  - Overriding `--mw-primary-color` in a `<style>` block is enough - hover tones,
372
523
  translucent backgrounds and the border accent follow via `color-mix()`.
@@ -1599,6 +1599,7 @@ quote and attribution belong together:
1599
1599
  </blockquote>
1600
1600
  <figcaption class="mw-testimonial-source">
1601
1601
  Anna M. <span class="mw-testimonial-detail">&middot; voice workshop</span>
1602
+ <time class="mw-testimonial-date" datetime="2026-03">March 2026</time>
1602
1603
  </figcaption>
1603
1604
  </figure>
1604
1605
  ```
@@ -1609,6 +1610,14 @@ uses `margin-top: auto` - in a grid of equal-height cards every source line
1609
1610
  sits on its card's bottom edge. `mw-testimonial-featured` sets the quote a
1610
1611
  size larger, for the one voice lifted above the grid.
1611
1612
 
1613
+ `mw-testimonial-date` is optional: a `<time>` on the right edge of the source
1614
+ line, month and year - a full date is review-platform optics, a bare year
1615
+ reads as a footnote. It drops to its own line, still right-aligned, when the
1616
+ source line runs out of room. Leave it out unless the voices are kept fresh: a
1617
+ dated quote ages, and three from years ago say more about the page than about
1618
+ the product. The `datetime` attribute is what Schema.org's `datePublished`
1619
+ would read.
1620
+
1612
1621
  For a wall of testimonials of unequal length, put them in `mw-columns-2` or
1613
1622
  `mw-columns-3` (`references/layout.md`) instead of a grid.
1614
1623
 
@@ -264,6 +264,25 @@ Components that paint their own surface (`mw-card`, `mw-panel`, `mw-modal`,
264
264
  `mw-tile`, `mw-calendar`) are exempt and keep the theme's ink - a card in the
265
265
  hero is still a card.
266
266
 
267
+ **Scroll cue** - `mw-scroll-hint` is the "scroll down" cue on the lower edge of
268
+ the hero. An `<a>` that is a sibling of `mw-hero`, directly in the container:
269
+
270
+ ```html
271
+ <div class="mw-container">
272
+ <div class="mw-hero">...</div>
273
+ <a class="mw-scroll-hint" href="#features">
274
+ More <i class="fas fa-chevron-down"></i>
275
+ </a>
276
+ </div>
277
+ ```
278
+
279
+ It is taken out of the flow, and the hero keeps a strip at its bottom free for
280
+ it, so buttons under the hero text never land on top of the cue.
281
+ `mw-scroll-hint-end` puts it in the bottom right corner instead - for a hero
282
+ whose text is not centred either - and gives the hero its full height back.
283
+ Below `md` both variants sit in the corner, because the middle under the text
284
+ is taken on a phone. The bobbing stops under `prefers-reduced-motion`.
285
+
267
286
  ## Grid
268
287
 
269
288
  All grid classes are `display: grid` with a preset gap (`mw-gap-*` overrides
@@ -358,11 +377,33 @@ uses. See the scale table in `SKILL.md`. Never hand-roll a `box-shadow`.
358
377
 
359
378
  **Scroll entrance** - `mw-reveal` lets a block rise briefly as it scrolls into
360
379
  view, driven by the browser's scroll timeline (`animation-timeline: view()`) -
361
- no JavaScript, no observer. Doubly guarded: `prefers-reduced-motion` turns it
380
+ no JavaScript, no observer. The block stays hidden until it is 8dvh above the
381
+ bottom edge and has arrived by 34dvh, the same zone for every block whatever
382
+ its height, so the motion happens where the eye is and is over before the
383
+ block is read. Doubly guarded: `prefers-reduced-motion` turns it
362
384
  off, and a browser without scroll timelines renders the block in place instead
363
385
  of leaving it invisible. Put it on section content, not on the section itself -
364
386
  a screen-high band finishes its entrance before its content is halfway up.
365
387
 
388
+ A row of cards crosses the viewport edge together, so `mw-reveal` on each of
389
+ them rises as one slab. `mw-reveal-stagger` goes on the **grid** instead: every
390
+ child reveals, and each one in a row 4dvh of scroll after the one before it -
391
+ a wave across the row. One class, nothing per card. On `mw-grid-2` to `mw-grid-5` and
392
+ their `-lg` variants the wave follows the actual columns at every breakpoint:
393
+ four steps in a four-column row, two once it has collapsed to two. Any other
394
+ container - `mw-columns-*`, a layout of your own - gets a fixed cycle of three.
395
+
396
+ ```html
397
+ <div class="mw-grid-3 mw-reveal-stagger">
398
+ <div class="mw-card">...</div>
399
+ <div class="mw-card">...</div>
400
+ <div class="mw-card">...</div>
401
+ </div>
402
+ ```
403
+
404
+ The animation lets go once the entrance is done, so a card keeps its hover
405
+ lift and an open dropdown inside it is not trapped under the next card.
406
+
366
407
  **Corner accent** - `mw-corner-plain` drops the accent arc that sits on the
367
408
  two round corners of every card, panel, modal, tile, accordion, calendar,
368
409
  pagination and login box. Everything else stays: the radii, the border, the
package/CHANGELOG.md CHANGED
@@ -6,6 +6,19 @@ Patch releases are only for test purposes - here I only document major and minor
6
6
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
7
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
+ ## [4.25.0] - 2026-09-02
10
+
11
+ ### Changed
12
+
13
+ - small fixes
14
+ - updated skill
15
+
16
+ ## [4.24.0] - 2026-09-01
17
+
18
+ ### Fixed
19
+
20
+ - `mw-reveal` is written as animation longhands
21
+
9
22
  ## [4.23.0] - 2026-09-01
10
23
 
11
24
  ### Changed
package/README.md CHANGED
@@ -40,12 +40,12 @@ The result is a framework that balances utility with simplicity, offering develo
40
40
  <title>My MaverickWave Project</title>
41
41
  <link
42
42
  rel="stylesheet"
43
- href="https://cdn.jsdelivr.net/npm/maverick-wave@4.4.1/maverick-wave.min.css"
43
+ href="https://cdn.jsdelivr.net/npm/maverick-wave@4.24.0/maverick-wave.min.css"
44
44
  />
45
45
  </head>
46
46
  <body>
47
47
  <!-- Your content here -->
48
- <script src="https://cdn.jsdelivr.net/npm/maverick-wave@4.4.1/maverick-wave.min.js"></script>
48
+ <script src="https://cdn.jsdelivr.net/npm/maverick-wave@4.24.0/maverick-wave.min.js"></script>
49
49
  </body>
50
50
  </html>
51
51
  ```
@@ -420,7 +420,7 @@ state yourself - the framework does not style Angular's `ng-invalid` /
420
420
 
421
421
  A complete usage guide for AI coding assistants - every component, token,
422
422
  integration pattern and example - ships with the package as a Claude Code skill
423
- in `.claude/skills/maverick-wave/`.
423
+ in `.claude/skills/mw-maverick-wave/`.
424
424
 
425
425
  ## Development
426
426
 
package/index.html CHANGED
@@ -130,6 +130,13 @@
130
130
  </div>
131
131
  </section>
132
132
 
133
+ <!-- Highlights section -->
134
+ <section id="highlights" class="mw-section mw-section-alternate">
135
+ <div class="mw-container">
136
+ @@include('./src/partials/highlights-container.html')
137
+ </div>
138
+ </section>
139
+
133
140
  <!-- Get started section -->
134
141
  <section id="get-started" class="mw-section">
135
142
  <div class="mw-container">