maverick-wave 4.21.0 → 4.23.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 (53) hide show
  1. package/.claude/skills/maverick-wave/SKILL.md +9 -7
  2. package/.claude/skills/maverick-wave/references/components.md +85 -0
  3. package/.claude/skills/maverick-wave/references/layout.md +30 -7
  4. package/.claude/skills/maverick-wave/references/theming.md +1 -1
  5. package/.github/workflows/ci.yml +1 -1
  6. package/.prettierignore +2 -0
  7. package/CHANGELOG.md +17 -0
  8. package/CLAUDE.md +7 -4
  9. package/gulpfile.js +4 -4
  10. package/index.html +40 -0
  11. package/maverick-wave.min.css +3 -3
  12. package/package.json +3 -3
  13. package/release.sh +1 -1
  14. package/scripts/verify.js +15 -0
  15. package/src/assets/images/gallery-city.svg +49 -0
  16. package/src/assets/images/gallery-desert.svg +25 -0
  17. package/src/assets/images/gallery-forest.svg +46 -0
  18. package/src/assets/images/gallery-lake.svg +26 -0
  19. package/src/assets/images/gallery-mountain.svg +19 -0
  20. package/src/assets/images/gallery-ocean.svg +26 -0
  21. package/src/assets/images/gallery-oldtown.svg +41 -0
  22. package/src/assets/images/gallery-snow.svg +39 -0
  23. package/src/assets/images/slider-field.svg +124 -0
  24. package/src/assets/images/slider-forest.svg +33 -0
  25. package/src/assets/images/slider-lake.svg +35 -0
  26. package/src/assets/images/slider-mountains.svg +29 -0
  27. package/src/assets/images/slider-trees.svg +41 -0
  28. package/src/assets/images/tile-analytics.svg +22 -0
  29. package/src/assets/images/tile-cloud.svg +19 -0
  30. package/src/assets/images/tile-ecommerce.svg +14 -0
  31. package/src/assets/images/tile-enterprise.svg +22 -0
  32. package/src/assets/images/tile-marketing.svg +16 -0
  33. package/src/assets/media/demo-chime.wav +0 -0
  34. package/src/partials/announcement-container.html +67 -0
  35. package/src/partials/content-slider-container.html +5 -17
  36. package/src/partials/gallery-container.html +8 -8
  37. package/src/partials/home-container.html +11 -20
  38. package/src/partials/media-container.html +27 -0
  39. package/src/partials/prose-container.html +43 -0
  40. package/src/partials/testimonials-container.html +82 -0
  41. package/src/partials/tiles-container.html +5 -20
  42. package/src/scss/base/_base.scss +7 -1
  43. package/src/scss/components/_announcement.scss +84 -0
  44. package/src/scss/components/_index.scss +4 -0
  45. package/src/scss/components/_media.scss +26 -0
  46. package/src/scss/components/_prose.scss +42 -0
  47. package/src/scss/components/_testimonial.scss +58 -0
  48. package/src/scss/layout/_grid.scss +39 -0
  49. package/src/scss/layout/_main.scss +9 -1
  50. package/src/scss/layout/_section.scss +14 -0
  51. package/src/scss/utilities/_index.scss +1 -0
  52. package/src/scss/utilities/_reveal.scss +34 -0
  53. package/src/scss/utilities/_touch-targets.scss +10 -2
@@ -0,0 +1,26 @@
1
+ @use '../abstracts' as *;
2
+
3
+ // Self-hosted audio and video. The framework ships no player - the native
4
+ // controls are the player, and `accent-color` on :root already brands them.
5
+ // This only makes the element sit right: full width, block, and a video gets
6
+ // the surface silhouette so it reads as part of the family.
7
+ .mw-media {
8
+ audio,
9
+ video {
10
+ display: block;
11
+ width: 100%;
12
+ }
13
+
14
+ video {
15
+ height: auto;
16
+ border-radius: radius('sm') radius('xl') radius('sm') radius('xl');
17
+ box-shadow: var(--mw-elevation-2);
18
+ }
19
+ }
20
+
21
+ .mw-media-caption {
22
+ margin-top: spacing('2');
23
+ font-size: font-size('sm');
24
+ color: var(--mw-text-muted-color);
25
+ text-align: center;
26
+ }
@@ -0,0 +1,42 @@
1
+ @use '../abstracts' as *;
2
+
3
+ // Long-form running text - a legal page, terms, a plain article. One class on
4
+ // the container instead of a utility chain on every heading: the markup inside
5
+ // stays bare h2/h3/p/ul, which is exactly what a CMS or a JSON-driven page
6
+ // produces anyway.
7
+ //
8
+ // Headings are deliberately small: in a document they structure the reading,
9
+ // they do not compete with the page title.
10
+ .mw-prose {
11
+ h2 {
12
+ font-size: font-size('lg');
13
+ color: var(--mw-primary-text-color);
14
+ margin: spacing('8') 0 spacing('3');
15
+ }
16
+
17
+ h3 {
18
+ font-size: font-size('md');
19
+ color: var(--mw-primary-text-color);
20
+ margin: spacing('6') 0 spacing('2');
21
+ }
22
+
23
+ ul,
24
+ ol {
25
+ margin: 0 0 spacing('3') spacing('7');
26
+ }
27
+
28
+ li {
29
+ margin-bottom: spacing('1');
30
+ }
31
+
32
+ // The first heading in a card already sits on the card's padding, the last
33
+ // paragraph on its bottom edge - without these the container carries double
34
+ // spacing at both ends.
35
+ > :first-child {
36
+ margin-top: 0;
37
+ }
38
+
39
+ > :last-child {
40
+ margin-bottom: 0;
41
+ }
42
+ }
@@ -0,0 +1,58 @@
1
+ @use '../abstracts' as *;
2
+
3
+ // A voice about the product - a quote card with its source. A figure, because
4
+ // quote and attribution belong together and that is the element that says so:
5
+ //
6
+ // <figure class="mw-testimonial">
7
+ // <blockquote>...</blockquote>
8
+ // <figcaption class="mw-testimonial-source">
9
+ // Name <span class="mw-testimonial-detail">&middot; role or occasion</span>
10
+ // </figcaption>
11
+ // </figure>
12
+ .mw-testimonial {
13
+ @include surface;
14
+ display: flex;
15
+ flex-direction: column;
16
+ padding: spacing('5');
17
+ background: var(--mw-card-background);
18
+ border: 1px solid var(--mw-border);
19
+ box-shadow: var(--mw-elevation-2);
20
+
21
+ // Several of these in a row, each quote on the base blockquote tint, add up
22
+ // to a solid colored wall nobody reads through. The card already carries the
23
+ // surface - inside it the quote keeps only the edge and the quotation marks
24
+ // as its sign.
25
+ blockquote {
26
+ background: color-mix(in srgb, var(--mw-secondary-color) 6%, transparent);
27
+ border-left-color: color-mix(
28
+ in srgb,
29
+ var(--mw-secondary-color) 45%,
30
+ transparent
31
+ );
32
+ padding-block: spacing('2');
33
+ font-size: font-size('base');
34
+ line-height: 1.6;
35
+ }
36
+ }
37
+
38
+ // margin-top: auto, so in a grid of equal-height cards every source line sits
39
+ // on its card's bottom edge instead of floating under quotes of random length.
40
+ .mw-testimonial-source {
41
+ margin-top: auto;
42
+ padding-top: spacing('5');
43
+ font-size: font-size('sm');
44
+ font-weight: font-weight('bold');
45
+ color: var(--mw-primary-text-color);
46
+ }
47
+
48
+ .mw-testimonial-detail {
49
+ font-weight: font-weight('normal');
50
+ color: var(--mw-text-muted-color);
51
+ }
52
+
53
+ // The one voice lifted above the grid - it may speak a size louder.
54
+ .mw-testimonial-featured {
55
+ blockquote {
56
+ font-size: font-size('md');
57
+ }
58
+ }
@@ -220,6 +220,45 @@
220
220
  }
221
221
  }
222
222
 
223
+ // Masonry columns - for cards of unequal height, where a row grid tears a gap
224
+ // under every short one. CSS multi-column instead: entries flow into columns
225
+ // and close up, the column count steps down with the viewport. break-inside
226
+ // keeps each child whole - without it a page break lands mid-card.
227
+ //
228
+ // Reading order caveat: columns read top to bottom, then across. Right for
229
+ // testimonials and galleries, wrong for anything ranked or chronological -
230
+ // that stays in a grid.
231
+ %columns-base {
232
+ column-gap: spacing('6');
233
+
234
+ > * {
235
+ break-inside: avoid;
236
+ margin-bottom: spacing('6');
237
+ }
238
+ }
239
+
240
+ .mw-columns-2 {
241
+ @extend %columns-base;
242
+ columns: 2;
243
+
244
+ @include media-down('sm') {
245
+ columns: 1;
246
+ }
247
+ }
248
+
249
+ .mw-columns-3 {
250
+ @extend %columns-base;
251
+ columns: 3;
252
+
253
+ @include media-down('lg') {
254
+ columns: 2;
255
+ }
256
+
257
+ @include media-down('sm') {
258
+ columns: 1;
259
+ }
260
+ }
261
+
223
262
  // Base stack - items keep their natural width
224
263
  .mw-grid-stack {
225
264
  @extend %grid-base;
@@ -131,12 +131,20 @@
131
131
  flex-direction: column;
132
132
  align-items: center;
133
133
  gap: spacing('2');
134
- color: color-mix(in srgb, var(--mw-hero-text-color) 45%, transparent);
134
+ color: color-mix(in srgb, var(--mw-hero-text-color) 72%, transparent);
135
135
  font-size: font-size('xs');
136
136
  letter-spacing: 0.08em;
137
137
  text-transform: uppercase;
138
138
  text-decoration: none;
139
139
  animation: mw-scroll-hint-float 2.2s var(--mw-ease-in-out) infinite;
140
+ text-shadow: 0 1px 4px rgb(0 0 0 / 65%);
141
+
142
+ // The arrow carries the meaning, the word only confirms it - so it is the
143
+ // arrow that gets the size, and the label stays quiet at 'xs'.
144
+ > i,
145
+ > svg {
146
+ font-size: font-size('lg');
147
+ }
140
148
 
141
149
  @include hover {
142
150
  color: var(--mw-hero-text-color);
@@ -22,6 +22,20 @@
22
22
  }
23
23
  }
24
24
 
25
+ // The lead line under a section title. Every landing page writes this
26
+ // paragraph, and it always wants the same four things: centred, muted,
27
+ // narrower than the container so it reads as a line rather than a block, and
28
+ // pulled up toward the title it belongs to - the title's gap is sized for the
29
+ // content below, not for its own subtitle.
30
+ .mw-section-intro {
31
+ max-width: 46rem;
32
+ margin: spacing('-3') auto spacing('9');
33
+ font-size: font-size('md');
34
+ color: var(--mw-text-muted-color);
35
+ text-align: center;
36
+ text-wrap: balance;
37
+ }
38
+
25
39
  .mw-section-subtitle {
26
40
  font-size: font-size('2xl');
27
41
  margin: spacing('8') spacing('0') spacing('6') spacing('0');
@@ -4,6 +4,7 @@
4
4
  @forward 'display';
5
5
  @forward 'elevation';
6
6
  @forward 'flex';
7
+ @forward 'reveal';
7
8
  @forward 'spacing';
8
9
  @forward 'text';
9
10
  @forward 'touch-targets';
@@ -0,0 +1,34 @@
1
+ @use '../abstracts' as *;
2
+
3
+ // Scroll entrance: a block rises briefly as it scrolls into view. Driven by
4
+ // the browser's scroll timeline - no JavaScript, no IntersectionObserver
5
+ // recalculating on every scroll step.
6
+ //
7
+ // Both guards matter. `prefers-reduced-motion` is the obvious one. The
8
+ // @supports guard is the safety net: a browser without scroll timelines would
9
+ // otherwise apply `both` fill on an animation that never runs and leave the
10
+ // block invisible forever - guarded, it simply renders in place.
11
+ //
12
+ // The range ends well before the block reaches the middle of the screen, so
13
+ // nothing is still moving while someone already reads it.
14
+ @supports (animation-timeline: view()) {
15
+ @media (prefers-reduced-motion: no-preference) {
16
+ .mw-reveal {
17
+ animation: mw-reveal linear both;
18
+ animation-timeline: view();
19
+ animation-range: entry 2% entry 62%;
20
+ }
21
+ }
22
+ }
23
+
24
+ @keyframes mw-reveal {
25
+ from {
26
+ opacity: 0;
27
+ transform: translateY(26px);
28
+ }
29
+
30
+ to {
31
+ opacity: 1;
32
+ transform: translateY(0);
33
+ }
34
+ }
@@ -140,10 +140,18 @@
140
140
  -webkit-overflow-scrolling: touch;
141
141
  }
142
142
 
143
- // Phone layout
143
+ // Phone layout. The section rhythm steps down twice: a tablet keeps a middle
144
+ // value, a phone drops further - every rem here is one the reader has to
145
+ // scroll past on a screen that is already all scrolling.
144
146
  @include media-down('md') {
145
147
  :root {
146
- --mw-section-padding-block: #{spacing('6')};
148
+ --mw-section-padding-block: #{spacing('9')};
149
+ }
150
+ }
151
+
152
+ @include media-down('sm') {
153
+ :root {
154
+ --mw-section-padding-block: #{spacing('7')};
147
155
  }
148
156
  }
149
157