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.
- package/.claude/skills/maverick-wave/SKILL.md +9 -7
- package/.claude/skills/maverick-wave/references/components.md +85 -0
- package/.claude/skills/maverick-wave/references/layout.md +30 -7
- package/.claude/skills/maverick-wave/references/theming.md +1 -1
- package/.github/workflows/ci.yml +1 -1
- package/.prettierignore +2 -0
- package/CHANGELOG.md +17 -0
- package/CLAUDE.md +7 -4
- package/gulpfile.js +4 -4
- package/index.html +40 -0
- package/maverick-wave.min.css +3 -3
- package/package.json +3 -3
- package/release.sh +1 -1
- package/scripts/verify.js +15 -0
- package/src/assets/images/gallery-city.svg +49 -0
- package/src/assets/images/gallery-desert.svg +25 -0
- package/src/assets/images/gallery-forest.svg +46 -0
- package/src/assets/images/gallery-lake.svg +26 -0
- package/src/assets/images/gallery-mountain.svg +19 -0
- package/src/assets/images/gallery-ocean.svg +26 -0
- package/src/assets/images/gallery-oldtown.svg +41 -0
- package/src/assets/images/gallery-snow.svg +39 -0
- package/src/assets/images/slider-field.svg +124 -0
- package/src/assets/images/slider-forest.svg +33 -0
- package/src/assets/images/slider-lake.svg +35 -0
- package/src/assets/images/slider-mountains.svg +29 -0
- package/src/assets/images/slider-trees.svg +41 -0
- package/src/assets/images/tile-analytics.svg +22 -0
- package/src/assets/images/tile-cloud.svg +19 -0
- package/src/assets/images/tile-ecommerce.svg +14 -0
- package/src/assets/images/tile-enterprise.svg +22 -0
- package/src/assets/images/tile-marketing.svg +16 -0
- package/src/assets/media/demo-chime.wav +0 -0
- package/src/partials/announcement-container.html +67 -0
- package/src/partials/content-slider-container.html +5 -17
- package/src/partials/gallery-container.html +8 -8
- package/src/partials/home-container.html +11 -20
- package/src/partials/media-container.html +27 -0
- package/src/partials/prose-container.html +43 -0
- package/src/partials/testimonials-container.html +82 -0
- package/src/partials/tiles-container.html +5 -20
- package/src/scss/base/_base.scss +7 -1
- package/src/scss/components/_announcement.scss +84 -0
- package/src/scss/components/_index.scss +4 -0
- package/src/scss/components/_media.scss +26 -0
- package/src/scss/components/_prose.scss +42 -0
- package/src/scss/components/_testimonial.scss +58 -0
- package/src/scss/layout/_grid.scss +39 -0
- package/src/scss/layout/_main.scss +9 -1
- package/src/scss/layout/_section.scss +14 -0
- package/src/scss/utilities/_index.scss +1 -0
- package/src/scss/utilities/_reveal.scss +34 -0
- 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">· 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)
|
|
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');
|
|
@@ -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('
|
|
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
|
|