maverick-wave 5.28.0 → 5.29.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 (49) hide show
  1. package/.claude/skills/mw-maverick-wave/SKILL.md +4 -2
  2. package/.claude/skills/mw-maverick-wave/references/components.md +212 -0
  3. package/.claude/skills/mw-maverick-wave/references/javascript.md +6 -1
  4. package/.claude/skills/mw-maverick-wave/references/theming.md +53 -51
  5. package/CHANGELOG.md +10 -0
  6. package/CLAUDE.md +4 -4
  7. package/README.md +2 -2
  8. package/index.html +65 -0
  9. package/maverick-wave.min.css +2 -2
  10. package/maverick-wave.min.js +1 -1
  11. package/package.json +2 -2
  12. package/scripts/verify.js +2 -1
  13. package/src/assets/images/photo-balloon.svg +35 -0
  14. package/src/assets/images/photo-forest-path.svg +31 -0
  15. package/src/assets/images/photo-lighthouse.svg +42 -0
  16. package/src/assets/images/photo-palm.svg +27 -0
  17. package/src/assets/images/photo-peak.svg +27 -0
  18. package/src/assets/images/photo-tower.svg +34 -0
  19. package/src/assets/images/photo-waterfall.svg +32 -0
  20. package/src/assets/images/story-aurora.svg +36 -0
  21. package/src/assets/images/story-beach.svg +34 -0
  22. package/src/assets/images/story-stars.svg +35 -0
  23. package/src/assets/media/story-sunrise.jpg +0 -0
  24. package/src/assets/media/story-sunrise.mp4 +0 -0
  25. package/src/js/main.js +403 -0
  26. package/src/partials/avatars-container.html +50 -0
  27. package/src/partials/calendar-container.html +36 -38
  28. package/src/partials/feed-container.html +506 -0
  29. package/src/partials/item-lists-container.html +80 -130
  30. package/src/partials/kanban-container.html +17 -294
  31. package/src/partials/mosaic-container.html +173 -0
  32. package/src/partials/panels-container.html +113 -162
  33. package/src/partials/portrait-gallery-container.html +175 -0
  34. package/src/partials/stories-container.html +182 -0
  35. package/src/partials/tables-container.html +21 -40
  36. package/src/scss/abstracts/_mixins.scss +2 -0
  37. package/src/scss/abstracts/_variables.scss +3 -0
  38. package/src/scss/components/_avatars.scss +52 -0
  39. package/src/scss/components/_cards.scss +7 -3
  40. package/src/scss/components/_feed.scss +203 -0
  41. package/src/scss/components/_index.scss +6 -0
  42. package/src/scss/components/_lightbox.scss +178 -0
  43. package/src/scss/components/_mosaic.scss +83 -0
  44. package/src/scss/components/_overlay-btn.scss +47 -0
  45. package/src/scss/components/_portrait-gallery.scss +180 -0
  46. package/src/scss/components/_stories.scss +443 -0
  47. package/src/scss/components/_tiles.scss +4 -1
  48. package/src/scss/utilities/_fit.scss +29 -0
  49. package/src/scss/utilities/_index.scss +1 -0
@@ -0,0 +1,178 @@
1
+ @use '../abstracts' as *;
2
+ @use 'overlay-btn';
3
+
4
+ @layer mw.components {
5
+ dialog.mw-lightbox {
6
+ position: fixed;
7
+ inset: 0;
8
+ width: auto;
9
+ height: auto;
10
+ max-width: none;
11
+ max-height: none;
12
+ margin: 0;
13
+ padding: 0;
14
+ border: none;
15
+ background: $fixed-stage;
16
+ color: $fixed-surface-text;
17
+ overflow: hidden;
18
+ overscroll-behavior: contain;
19
+ // The brand ink disappears on the stage
20
+ --mw-focus-ring-color: #{$fixed-surface-text};
21
+ opacity: 0;
22
+ transition:
23
+ opacity var(--mw-duration-base) var(--mw-ease-out),
24
+ overlay var(--mw-duration-base) allow-discrete,
25
+ display var(--mw-duration-base) allow-discrete;
26
+
27
+ &[open] {
28
+ opacity: 1;
29
+
30
+ @starting-style {
31
+ opacity: 0;
32
+ }
33
+ }
34
+
35
+ &::backdrop {
36
+ background: transparent;
37
+ }
38
+ }
39
+
40
+ // A <dialog> does not lock the page scroll behind it
41
+ :root:has(dialog.mw-lightbox[open]) {
42
+ overflow: hidden;
43
+ scrollbar-gutter: stable; // Or the page shifts by the hidden scrollbar
44
+ }
45
+
46
+ .mw-lightbox-track {
47
+ display: flex;
48
+ height: 100%;
49
+ overflow-x: auto;
50
+ overflow-y: hidden;
51
+ overscroll-behavior: contain;
52
+ scroll-snap-type: x mandatory;
53
+ scrollbar-width: none;
54
+
55
+ &::-webkit-scrollbar {
56
+ display: none;
57
+ }
58
+
59
+ @media (prefers-reduced-motion: no-preference) {
60
+ scroll-behavior: smooth;
61
+ }
62
+ }
63
+
64
+ .mw-lightbox-slide {
65
+ flex: 0 0 100%;
66
+ min-width: 0;
67
+ display: flex;
68
+ flex-direction: column;
69
+ align-items: center;
70
+ justify-content: center;
71
+ gap: spacing('4');
72
+ margin: spacing('0');
73
+ padding: 4.25rem spacing('3')
74
+ calc(#{spacing('6')} + env(safe-area-inset-bottom, 0px));
75
+ scroll-snap-align: center;
76
+ scroll-snap-stop: always;
77
+
78
+ img {
79
+ display: block;
80
+ flex: 0 1 auto;
81
+ min-height: 0;
82
+ max-width: 100%;
83
+ max-height: 100%;
84
+ object-fit: contain;
85
+ border-radius: radius('xs');
86
+ user-select: none;
87
+ }
88
+
89
+ figcaption {
90
+ flex: none;
91
+ max-width: 60ch;
92
+ max-height: 30%;
93
+ overflow-y: auto;
94
+ padding-inline: spacing('3');
95
+ color: rgb(239 239 239 / 88%);
96
+ font-size: font-size('sm');
97
+ line-height: 1.5;
98
+ text-align: center;
99
+
100
+ > * {
101
+ margin: spacing('0');
102
+ }
103
+
104
+ > * + * {
105
+ margin-top: spacing('2');
106
+ }
107
+
108
+ time,
109
+ small {
110
+ display: block;
111
+ color: rgb(239 239 239 / 60%);
112
+ font-size: font-size('xs');
113
+ }
114
+ }
115
+ }
116
+
117
+ // On a phone the arrows sit in the bar, off the photo
118
+ .mw-lightbox-bar {
119
+ position: absolute;
120
+ inset: 0 0 auto;
121
+ z-index: z-index('lift');
122
+ display: flex;
123
+ align-items: center;
124
+ gap: spacing('1');
125
+ padding: max(#{spacing('3')}, env(safe-area-inset-top, 0px)) spacing('3')
126
+ spacing('5');
127
+ background: linear-gradient(rgb(0 0 0 / 55%), transparent);
128
+
129
+ .mw-lightbox-close {
130
+ margin-left: auto;
131
+ }
132
+ }
133
+
134
+ .mw-lightbox-count {
135
+ min-width: 4.5em;
136
+ font-size: font-size('sm');
137
+ font-variant-numeric: tabular-nums;
138
+ text-align: center;
139
+ }
140
+
141
+ @include media-up('md') {
142
+ .mw-lightbox-slide {
143
+ padding-inline: 5.5rem;
144
+ }
145
+
146
+ .mw-lightbox-bar {
147
+ padding-left: spacing('6');
148
+ }
149
+
150
+ .mw-lightbox-count {
151
+ order: -1;
152
+ text-align: left;
153
+ }
154
+
155
+ // Fixed works because the bar has no transform or filter to trap them
156
+ .mw-lightbox-prev,
157
+ .mw-lightbox-next {
158
+ position: fixed;
159
+ top: 50%;
160
+ translate: 0 -50%;
161
+ width: 3.25rem;
162
+ height: 3.25rem;
163
+ background: rgb(255 255 255 / 10%);
164
+
165
+ &:hover {
166
+ background: rgb(255 255 255 / 20%);
167
+ }
168
+ }
169
+
170
+ .mw-lightbox-prev {
171
+ left: spacing('6');
172
+ }
173
+
174
+ .mw-lightbox-next {
175
+ right: spacing('6');
176
+ }
177
+ }
178
+ }
@@ -0,0 +1,83 @@
1
+ @use '../abstracts' as *;
2
+
3
+ @layer mw.components {
4
+ .mw-mosaic {
5
+ display: grid;
6
+ // Two columns on a phone, four at most, in whatever box it sits
7
+ grid-template-columns: repeat(auto-fill, minmax(max(120px, 22%), 1fr));
8
+ // Equal rows sized by the square tiles' aspect-ratio
9
+ grid-auto-rows: 1fr;
10
+ grid-auto-flow: dense;
11
+ // Dense packing reorders the tiles; Tab follows what the eye sees
12
+ reading-flow: grid-rows;
13
+ gap: spacing('4');
14
+ }
15
+
16
+ .mw-mosaic-gap-sm {
17
+ gap: spacing('1');
18
+ }
19
+
20
+ .mw-mosaic-gap-lg {
21
+ gap: spacing('5');
22
+ }
23
+
24
+ .mw-mosaic-item {
25
+ position: relative;
26
+ margin: spacing('0');
27
+ // Only sizes the rows; stretched both ways, or the ratio sizes the tile
28
+ aspect-ratio: 1;
29
+ place-self: stretch;
30
+ overflow: hidden;
31
+ border-radius: radius('sm');
32
+ background: var(--mw-card-background);
33
+ transition: transform var(--mw-duration-fast) var(--mw-ease-out);
34
+
35
+ > a {
36
+ position: absolute;
37
+ inset: 0;
38
+ display: block;
39
+ @include tappable;
40
+ @include focus-ring-inset(-3px);
41
+ }
42
+
43
+ img {
44
+ display: block;
45
+ width: 100%;
46
+ height: 100%;
47
+ object-fit: cover;
48
+ transition: transform var(--mw-duration-zoom) var(--mw-ease-out);
49
+ }
50
+
51
+ > figcaption {
52
+ display: none;
53
+ }
54
+
55
+ @include hover-move {
56
+ img {
57
+ transform: scale(1.05);
58
+ }
59
+ }
60
+
61
+ &:has(> a:active) {
62
+ transform: scale(0.97);
63
+ transition-duration: var(--mw-duration-instant);
64
+ }
65
+ }
66
+
67
+ // Picked by the script from the photo's shape unless one is set by hand
68
+ .mw-mosaic-wide {
69
+ grid-column: span 2;
70
+ aspect-ratio: 2;
71
+ }
72
+
73
+ .mw-mosaic-tall {
74
+ grid-row: span 2;
75
+ aspect-ratio: 1 / 2;
76
+ }
77
+
78
+ .mw-mosaic-big {
79
+ grid-column: span 2;
80
+ grid-row: span 2;
81
+ aspect-ratio: 1;
82
+ }
83
+ }
@@ -0,0 +1,47 @@
1
+ @use '../abstracts' as *;
2
+
3
+ @layer mw.components {
4
+ .mw-overlay-btn {
5
+ display: inline-flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ flex: none;
9
+ width: 2.75rem;
10
+ height: 2.75rem;
11
+ padding: spacing('0');
12
+ border: none;
13
+ border-radius: radius('full');
14
+ background: rgb(0 0 0 / 38%);
15
+ color: $fixed-surface-text;
16
+ font-size: font-size('md');
17
+ line-height: 1;
18
+ cursor: pointer;
19
+ transition: var(--mw-transition-fast);
20
+ @include tappable;
21
+ @include focus-ring;
22
+
23
+ svg {
24
+ width: 1.375rem;
25
+ height: 1.375rem;
26
+ fill: none;
27
+ stroke: currentColor;
28
+ stroke-width: 2;
29
+ stroke-linecap: round;
30
+ stroke-linejoin: round;
31
+ }
32
+
33
+ &:hover {
34
+ background: rgb(0 0 0 / 62%);
35
+ }
36
+
37
+ &:active {
38
+ transform: scale(0.9);
39
+ transition-duration: var(--mw-duration-instant);
40
+ }
41
+
42
+ &:disabled {
43
+ opacity: 0;
44
+ pointer-events: none;
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,180 @@
1
+ @use '../abstracts' as *;
2
+ @use 'overlay-btn';
3
+
4
+ @layer mw.components {
5
+ $two-up: 560px;
6
+ $three-up: 880px;
7
+ $gaps: (
8
+ '': spacing('6'),
9
+ '-gap-sm': spacing('3'),
10
+ '-gap-lg': spacing('7'),
11
+ );
12
+
13
+ // On a landscape phone the width follows from this cap
14
+ $max-height: 78svh;
15
+
16
+ .mw-portrait-gallery {
17
+ position: relative;
18
+ // Inline-size containment would collapse the box in a flex or grid slot
19
+ width: 100%;
20
+ container: mw-portrait-gallery / inline-size;
21
+ }
22
+
23
+ .mw-portrait-gallery-track {
24
+ display: flex;
25
+ overflow-x: auto;
26
+ overscroll-behavior-x: contain;
27
+ scroll-snap-type: x mandatory;
28
+ border-radius: radius('lg');
29
+ scrollbar-width: none;
30
+ @include focus-ring;
31
+
32
+ &::-webkit-scrollbar {
33
+ display: none;
34
+ }
35
+
36
+ @media (prefers-reduced-motion: no-preference) {
37
+ scroll-behavior: smooth;
38
+ }
39
+ }
40
+
41
+ .mw-portrait-gallery-slide {
42
+ position: relative;
43
+ flex: none;
44
+ // The next slide peeks in at the edge
45
+ width: min(86cqi, $max-height * 3 / 4);
46
+ aspect-ratio: 3 / 4;
47
+ margin: spacing('0');
48
+ overflow: hidden;
49
+ border-radius: radius('lg');
50
+ background: $fixed-stage;
51
+ scroll-snap-align: start;
52
+
53
+ > img,
54
+ > video {
55
+ position: absolute;
56
+ inset: 0;
57
+ width: 100%;
58
+ height: 100%;
59
+ object-fit: cover;
60
+ display: block;
61
+ }
62
+
63
+ > figcaption {
64
+ position: absolute;
65
+ inset: auto 0 0;
66
+ padding: spacing('10') spacing('5') spacing('5');
67
+ background: linear-gradient(to top, rgb(0 0 0 / 72%), transparent);
68
+ color: $fixed-surface-text;
69
+ font-size: font-size('sm');
70
+ line-height: 1.45;
71
+ text-shadow: 0 1px 3px rgb(0 0 0 / 50%);
72
+
73
+ strong {
74
+ display: block;
75
+ font-size: font-size('md');
76
+ }
77
+ }
78
+ }
79
+
80
+ .mw-portrait-gallery-tall .mw-portrait-gallery-slide {
81
+ width: min(86cqi, $max-height * 9 / 16);
82
+ aspect-ratio: 9 / 16;
83
+ }
84
+
85
+ .mw-portrait-gallery-dots {
86
+ display: flex;
87
+ justify-content: center;
88
+ gap: spacing('4');
89
+ margin-top: spacing('5');
90
+ }
91
+
92
+ .mw-portrait-gallery-dot {
93
+ width: 7px;
94
+ height: 7px;
95
+ padding: spacing('0');
96
+ border: none;
97
+ border-radius: radius('full');
98
+ background: var(--mw-gray-color);
99
+ cursor: pointer;
100
+ transition: var(--mw-transition-fast);
101
+ @include tappable;
102
+ @include hit-area(6px);
103
+ @include focus-ring;
104
+
105
+ &.mw-active {
106
+ background: var(--mw-primary-text-color);
107
+ transform: scale(1.45);
108
+ }
109
+ }
110
+
111
+ @each $suffix, $gap in $gaps {
112
+ .mw-portrait-gallery#{$suffix} .mw-portrait-gallery-track {
113
+ gap: $gap;
114
+ }
115
+ }
116
+
117
+ @container mw-portrait-gallery (width >= #{$two-up}) {
118
+ .mw-portrait-gallery-dots {
119
+ display: none;
120
+ }
121
+ }
122
+
123
+ // The widths subtract the gaps, so each gap restates them - every two-up
124
+ // rule before every three-up one, or a modifier's two-up rule would win
125
+ @each $up, $share, $gaps-in-row in ($two-up 2.25 1, $three-up 3 2) {
126
+ @container mw-portrait-gallery (width >= #{$up}) {
127
+ @each $suffix, $gap in $gaps {
128
+ $room: calc(100cqi - $gaps-in-row * $gap);
129
+
130
+ .mw-portrait-gallery#{$suffix} .mw-portrait-gallery-slide {
131
+ width: min($room / $share, $max-height * 3 / 4);
132
+ }
133
+
134
+ .mw-portrait-gallery#{$suffix}.mw-portrait-gallery-tall
135
+ .mw-portrait-gallery-slide {
136
+ width: min($room / $share, $max-height * 9 / 16);
137
+ }
138
+ }
139
+ }
140
+ }
141
+
142
+ // A finger swipes, so the arrows are for a mouse only
143
+ .mw-portrait-gallery-prev,
144
+ .mw-portrait-gallery-next {
145
+ display: none;
146
+ position: absolute;
147
+ top: 50%;
148
+ translate: 0 -50%;
149
+ z-index: z-index('lift');
150
+
151
+ @media (hover: hover) and (pointer: fine) {
152
+ display: inline-flex;
153
+ }
154
+ }
155
+
156
+ .mw-portrait-gallery-prev {
157
+ left: spacing('4');
158
+ }
159
+
160
+ .mw-portrait-gallery-next {
161
+ right: spacing('4');
162
+ }
163
+
164
+ // Centred on the photos, not on photos plus the dot row
165
+ .mw-portrait-gallery:has(.mw-portrait-gallery-dots) {
166
+ .mw-portrait-gallery-prev,
167
+ .mw-portrait-gallery-next {
168
+ translate: 0 calc(-50% - #{spacing('5')});
169
+ }
170
+ }
171
+
172
+ @container mw-portrait-gallery (width >= #{$two-up}) {
173
+ .mw-portrait-gallery:has(.mw-portrait-gallery-dots) {
174
+ .mw-portrait-gallery-prev,
175
+ .mw-portrait-gallery-next {
176
+ translate: 0 -50%;
177
+ }
178
+ }
179
+ }
180
+ }