maverick-wave 5.28.0 → 5.30.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 +4 -2
- package/.claude/skills/mw-maverick-wave/references/components.md +217 -4
- package/.claude/skills/mw-maverick-wave/references/javascript.md +6 -1
- package/.claude/skills/mw-maverick-wave/references/theming.md +55 -51
- package/CHANGELOG.md +16 -0
- package/CLAUDE.md +4 -4
- package/README.md +2 -2
- package/index.html +65 -0
- package/maverick-wave.min.css +2 -2
- package/maverick-wave.min.js +1 -1
- package/package.json +2 -2
- package/scripts/verify.js +2 -1
- package/src/assets/images/photo-balloon.svg +35 -0
- package/src/assets/images/photo-forest-path.svg +31 -0
- package/src/assets/images/photo-lighthouse.svg +42 -0
- package/src/assets/images/photo-palm.svg +27 -0
- package/src/assets/images/photo-peak.svg +27 -0
- package/src/assets/images/photo-tower.svg +34 -0
- package/src/assets/images/photo-waterfall.svg +32 -0
- package/src/assets/images/story-aurora.svg +36 -0
- package/src/assets/images/story-beach.svg +34 -0
- package/src/assets/images/story-stars.svg +35 -0
- package/src/assets/media/story-sunrise.jpg +0 -0
- package/src/assets/media/story-sunrise.mp4 +0 -0
- package/src/js/main.js +403 -0
- package/src/partials/avatars-container.html +50 -0
- package/src/partials/calendar-container.html +36 -38
- package/src/partials/feed-container.html +506 -0
- package/src/partials/item-lists-container.html +80 -130
- package/src/partials/kanban-container.html +17 -294
- package/src/partials/mosaic-container.html +173 -0
- package/src/partials/panels-container.html +113 -162
- package/src/partials/portrait-gallery-container.html +175 -0
- package/src/partials/stories-container.html +182 -0
- package/src/partials/tables-container.html +21 -40
- package/src/scss/abstracts/_mixins.scss +2 -0
- package/src/scss/abstracts/_variables.scss +3 -0
- package/src/scss/components/_avatars.scss +85 -1
- package/src/scss/components/_cards.scss +7 -3
- package/src/scss/components/_dropdown.scss +24 -1
- package/src/scss/components/_feed.scss +203 -0
- package/src/scss/components/_index.scss +6 -0
- package/src/scss/components/_lang-switch.scss +4 -8
- package/src/scss/components/_lightbox.scss +178 -0
- package/src/scss/components/_modals.scss +19 -5
- package/src/scss/components/_mosaic.scss +83 -0
- package/src/scss/components/_overlay-btn.scss +47 -0
- package/src/scss/components/_portrait-gallery.scss +180 -0
- package/src/scss/components/_stories.scss +443 -0
- package/src/scss/components/_tiles.scss +4 -1
- package/src/scss/utilities/_fit.scss +29 -0
- package/src/scss/utilities/_index.scss +1 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
<h3 class="mw-section-subtitle">Story Archive</h3>
|
|
2
|
+
<p class="mw-text-muted mw-text-measure">
|
|
3
|
+
Stories that stay. A circle opens its story full screen on a phone and
|
|
4
|
+
phone-shaped on a desktop; every frame shows for five seconds and a bar at the
|
|
5
|
+
top counts them off - that part is CSS alone. A few lines of script add the
|
|
6
|
+
rest: a tap on the right moves on, on the left goes back (arrows under a
|
|
7
|
+
mouse), a video starts when its frame comes up, the story closes at its end.
|
|
8
|
+
Holding a finger on it or the pause button stops it; Escape, the cross or a
|
|
9
|
+
click beside it close it. With reduced motion set in the system nothing plays
|
|
10
|
+
by itself - the frames become a strip to swipe through instead.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<div class="mw-stories" aria-label="Story archive">
|
|
14
|
+
<button type="button" class="mw-story" popovertarget="story-coast">
|
|
15
|
+
<span class="mw-story-cover"
|
|
16
|
+
><img src="images/story-beach.svg" alt=""
|
|
17
|
+
/></span>
|
|
18
|
+
<span class="mw-story-label">Coast</span>
|
|
19
|
+
</button>
|
|
20
|
+
<div class="mw-story-reel" id="story-coast" popover>
|
|
21
|
+
<div class="mw-story-reel-head">
|
|
22
|
+
<span>Coast</span>
|
|
23
|
+
<label class="mw-overlay-btn mw-story-reel-pause"
|
|
24
|
+
><input type="checkbox" aria-label="Pause"
|
|
25
|
+
/></label>
|
|
26
|
+
<button
|
|
27
|
+
type="button"
|
|
28
|
+
class="mw-overlay-btn"
|
|
29
|
+
popovertarget="story-coast"
|
|
30
|
+
popovertargetaction="hide"
|
|
31
|
+
aria-label="Close"
|
|
32
|
+
>
|
|
33
|
+
𝗫
|
|
34
|
+
</button>
|
|
35
|
+
</div>
|
|
36
|
+
<img
|
|
37
|
+
src="images/story-beach.svg"
|
|
38
|
+
alt="Beach at sunset with waves running up the sand"
|
|
39
|
+
loading="lazy"
|
|
40
|
+
/>
|
|
41
|
+
<video
|
|
42
|
+
src="media/story-sunrise.mp4"
|
|
43
|
+
poster="media/story-sunrise.jpg"
|
|
44
|
+
autoplay
|
|
45
|
+
muted
|
|
46
|
+
loop
|
|
47
|
+
playsinline
|
|
48
|
+
></video>
|
|
49
|
+
<img
|
|
50
|
+
src="images/photo-lighthouse.svg"
|
|
51
|
+
alt="Lighthouse on a cliff at dusk"
|
|
52
|
+
loading="lazy"
|
|
53
|
+
/>
|
|
54
|
+
</div>
|
|
55
|
+
<button type="button" class="mw-story" popovertarget="story-nights">
|
|
56
|
+
<span class="mw-story-cover"
|
|
57
|
+
><img src="images/story-stars.svg" alt=""
|
|
58
|
+
/></span>
|
|
59
|
+
<span class="mw-story-label">Nights</span>
|
|
60
|
+
</button>
|
|
61
|
+
<div class="mw-story-reel" id="story-nights" popover>
|
|
62
|
+
<div class="mw-story-reel-head">
|
|
63
|
+
<span>Nights</span>
|
|
64
|
+
<label class="mw-overlay-btn mw-story-reel-pause"
|
|
65
|
+
><input type="checkbox" aria-label="Pause"
|
|
66
|
+
/></label>
|
|
67
|
+
<button
|
|
68
|
+
type="button"
|
|
69
|
+
class="mw-overlay-btn"
|
|
70
|
+
popovertarget="story-nights"
|
|
71
|
+
popovertargetaction="hide"
|
|
72
|
+
aria-label="Close"
|
|
73
|
+
>
|
|
74
|
+
𝗫
|
|
75
|
+
</button>
|
|
76
|
+
</div>
|
|
77
|
+
<img
|
|
78
|
+
src="images/story-stars.svg"
|
|
79
|
+
alt="Tent glowing under the milky way"
|
|
80
|
+
loading="lazy"
|
|
81
|
+
/>
|
|
82
|
+
<img
|
|
83
|
+
src="images/photo-tower.svg"
|
|
84
|
+
alt="Television tower above the city at night"
|
|
85
|
+
loading="lazy"
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
<button type="button" class="mw-story" popovertarget="story-north">
|
|
89
|
+
<span class="mw-story-cover"
|
|
90
|
+
><img src="images/story-aurora.svg" alt=""
|
|
91
|
+
/></span>
|
|
92
|
+
<span class="mw-story-label">North</span>
|
|
93
|
+
</button>
|
|
94
|
+
<div class="mw-story-reel" id="story-north" popover>
|
|
95
|
+
<div class="mw-story-reel-head">
|
|
96
|
+
<span>North</span>
|
|
97
|
+
<label class="mw-overlay-btn mw-story-reel-pause"
|
|
98
|
+
><input type="checkbox" aria-label="Pause"
|
|
99
|
+
/></label>
|
|
100
|
+
<button
|
|
101
|
+
type="button"
|
|
102
|
+
class="mw-overlay-btn"
|
|
103
|
+
popovertarget="story-north"
|
|
104
|
+
popovertargetaction="hide"
|
|
105
|
+
aria-label="Close"
|
|
106
|
+
>
|
|
107
|
+
𝗫
|
|
108
|
+
</button>
|
|
109
|
+
</div>
|
|
110
|
+
<img
|
|
111
|
+
src="images/story-aurora.svg"
|
|
112
|
+
alt="Northern lights over a snowy forest"
|
|
113
|
+
loading="lazy"
|
|
114
|
+
/>
|
|
115
|
+
<img
|
|
116
|
+
src="images/photo-peak.svg"
|
|
117
|
+
alt="Snowy mountain peak under a starry sky"
|
|
118
|
+
loading="lazy"
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
<button type="button" class="mw-story" popovertarget="story-hikes">
|
|
122
|
+
<span class="mw-story-cover"
|
|
123
|
+
><img src="images/photo-forest-path.svg" alt=""
|
|
124
|
+
/></span>
|
|
125
|
+
<span class="mw-story-label">Hikes</span>
|
|
126
|
+
</button>
|
|
127
|
+
<div class="mw-story-reel" id="story-hikes" popover>
|
|
128
|
+
<div class="mw-story-reel-head">
|
|
129
|
+
<span>Hikes</span>
|
|
130
|
+
<label class="mw-overlay-btn mw-story-reel-pause"
|
|
131
|
+
><input type="checkbox" aria-label="Pause"
|
|
132
|
+
/></label>
|
|
133
|
+
<button
|
|
134
|
+
type="button"
|
|
135
|
+
class="mw-overlay-btn"
|
|
136
|
+
popovertarget="story-hikes"
|
|
137
|
+
popovertargetaction="hide"
|
|
138
|
+
aria-label="Close"
|
|
139
|
+
>
|
|
140
|
+
𝗫
|
|
141
|
+
</button>
|
|
142
|
+
</div>
|
|
143
|
+
<img
|
|
144
|
+
src="images/photo-forest-path.svg"
|
|
145
|
+
alt="Path through a sunlit forest"
|
|
146
|
+
loading="lazy"
|
|
147
|
+
/>
|
|
148
|
+
<img
|
|
149
|
+
src="images/photo-waterfall.svg"
|
|
150
|
+
alt="Waterfall between mossy cliffs"
|
|
151
|
+
loading="lazy"
|
|
152
|
+
/>
|
|
153
|
+
</div>
|
|
154
|
+
<button type="button" class="mw-story" popovertarget="story-sky">
|
|
155
|
+
<span class="mw-story-cover"
|
|
156
|
+
><img src="images/photo-balloon.svg" alt=""
|
|
157
|
+
/></span>
|
|
158
|
+
<span class="mw-story-label">Up high</span>
|
|
159
|
+
</button>
|
|
160
|
+
<div class="mw-story-reel" id="story-sky" popover>
|
|
161
|
+
<div class="mw-story-reel-head">
|
|
162
|
+
<span>Up high</span>
|
|
163
|
+
<label class="mw-overlay-btn mw-story-reel-pause"
|
|
164
|
+
><input type="checkbox" aria-label="Pause"
|
|
165
|
+
/></label>
|
|
166
|
+
<button
|
|
167
|
+
type="button"
|
|
168
|
+
class="mw-overlay-btn"
|
|
169
|
+
popovertarget="story-sky"
|
|
170
|
+
popovertargetaction="hide"
|
|
171
|
+
aria-label="Close"
|
|
172
|
+
>
|
|
173
|
+
𝗫
|
|
174
|
+
</button>
|
|
175
|
+
</div>
|
|
176
|
+
<img
|
|
177
|
+
src="images/photo-balloon.svg"
|
|
178
|
+
alt="Hot air balloon in a morning sky"
|
|
179
|
+
loading="lazy"
|
|
180
|
+
/>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
@@ -13,11 +13,30 @@
|
|
|
13
13
|
<p class="mw-text-muted">
|
|
14
14
|
This is the basic table that supports all functions except the complete
|
|
15
15
|
responsive feeling with the cards - five columns do not fit a phone, so it
|
|
16
|
-
sits in a <code>mw-table-responsive</code> wrapper
|
|
16
|
+
sits in a <code>mw-table-responsive</code> wrapper.
|
|
17
|
+
<code>mw-table-compact</code> is the same table with less spacing and
|
|
18
|
+
smaller type.
|
|
17
19
|
</p>
|
|
18
20
|
|
|
21
|
+
<div class="mw-segmented mw-mb-4" data-modifier-demo="table-demo">
|
|
22
|
+
<button
|
|
23
|
+
type="button"
|
|
24
|
+
class="mw-segmented-item mw-active"
|
|
25
|
+
data-modifier=""
|
|
26
|
+
>
|
|
27
|
+
Default
|
|
28
|
+
</button>
|
|
29
|
+
<button
|
|
30
|
+
type="button"
|
|
31
|
+
class="mw-segmented-item"
|
|
32
|
+
data-modifier="mw-table-compact"
|
|
33
|
+
>
|
|
34
|
+
Compact
|
|
35
|
+
</button>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
19
38
|
<div class="mw-table-responsive">
|
|
20
|
-
<table class="mw-table">
|
|
39
|
+
<table class="mw-table" id="table-demo">
|
|
21
40
|
<thead>
|
|
22
41
|
<tr>
|
|
23
42
|
<th>#</th>
|
|
@@ -64,44 +83,6 @@
|
|
|
64
83
|
</p>
|
|
65
84
|
</div>
|
|
66
85
|
|
|
67
|
-
<div class="mw-card mw-card-simple mw-mb-6">
|
|
68
|
-
<h4 class="mw-mb-2">Compact Table</h4>
|
|
69
|
-
<p class="mw-text-muted">
|
|
70
|
-
Same table as basic table but a bit with less spacing and smaller fonts
|
|
71
|
-
</p>
|
|
72
|
-
|
|
73
|
-
<table class="mw-table mw-table-compact">
|
|
74
|
-
<thead>
|
|
75
|
-
<tr>
|
|
76
|
-
<th>#</th>
|
|
77
|
-
<th>Name</th>
|
|
78
|
-
<th>Position</th>
|
|
79
|
-
<th>Location</th>
|
|
80
|
-
</tr>
|
|
81
|
-
</thead>
|
|
82
|
-
<tbody>
|
|
83
|
-
<tr>
|
|
84
|
-
<td>1</td>
|
|
85
|
-
<td>Mara Kessler</td>
|
|
86
|
-
<td>Developer</td>
|
|
87
|
-
<td>New York</td>
|
|
88
|
-
</tr>
|
|
89
|
-
<tr>
|
|
90
|
-
<td>2</td>
|
|
91
|
-
<td>Tom Aldridge</td>
|
|
92
|
-
<td>Designer</td>
|
|
93
|
-
<td>London</td>
|
|
94
|
-
</tr>
|
|
95
|
-
<tr>
|
|
96
|
-
<td>3</td>
|
|
97
|
-
<td>Jonas Reuter</td>
|
|
98
|
-
<td>Manager</td>
|
|
99
|
-
<td>Berlin</td>
|
|
100
|
-
</tr>
|
|
101
|
-
</tbody>
|
|
102
|
-
</table>
|
|
103
|
-
</div>
|
|
104
|
-
|
|
105
86
|
<div class="mw-card mw-card-simple mw-mb-6">
|
|
106
87
|
<h4 class="mw-mb-2">Subtle Header & Sticky Header</h4>
|
|
107
88
|
<p class="mw-text-muted">
|
|
@@ -47,6 +47,9 @@ $info-color: #0780ca !default;
|
|
|
47
47
|
// take --mw-accent-text-color: tooltip, mw-btn-mini, mw-info-mini, gallery arrows
|
|
48
48
|
$fixed-surface-text: #efefef !default;
|
|
49
49
|
|
|
50
|
+
// Near-black behind a photo in both themes: it is judged against black
|
|
51
|
+
$fixed-stage: #0b0d12 !default;
|
|
52
|
+
|
|
50
53
|
// Darkening in both themes: the label on a solid surface is $accent-text-color,
|
|
51
54
|
// and lightening the surface is what breaks it
|
|
52
55
|
$hover-shift: 15% !default;
|
|
@@ -25,6 +25,21 @@
|
|
|
25
25
|
transition: transform var(--mw-duration-slow) var(--mw-ease-out);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
// Inside the frame, as on a card: the clip lets nothing paint over the border
|
|
29
|
+
&::before {
|
|
30
|
+
content: '';
|
|
31
|
+
position: absolute;
|
|
32
|
+
inset: 0;
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
border: 2px solid var(--mw-corner-accent);
|
|
35
|
+
border-radius: inherit;
|
|
36
|
+
mask-image: radial-gradient(
|
|
37
|
+
ellipse 75% 50% at 100% 0,
|
|
38
|
+
#000 55%,
|
|
39
|
+
transparent 100%
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
28
43
|
// `:has(img)` keeps the sweep off the initials variant, where it would just
|
|
29
44
|
// flash a white bar across the letters
|
|
30
45
|
&:has(img)::after {
|
|
@@ -43,7 +58,7 @@
|
|
|
43
58
|
|
|
44
59
|
@include hover-move {
|
|
45
60
|
img {
|
|
46
|
-
transform: scale(1.
|
|
61
|
+
transform: scale(1.06);
|
|
47
62
|
}
|
|
48
63
|
|
|
49
64
|
// Transition only here, so the sweep resets instantly instead of travelling back
|
|
@@ -82,8 +97,23 @@
|
|
|
82
97
|
font-size: font-size('6xl');
|
|
83
98
|
}
|
|
84
99
|
|
|
100
|
+
// Above -square, so that one still sharpens them
|
|
101
|
+
&-landscape,
|
|
102
|
+
&-portrait {
|
|
103
|
+
border-radius: radius('xl');
|
|
104
|
+
|
|
105
|
+
// The card's arc, same radius - 5px stands in for the 4-6px frame of lg/xl
|
|
106
|
+
&::before {
|
|
107
|
+
@include corner-accent(5px, 'top');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
85
111
|
&-square {
|
|
86
112
|
border-radius: radius('sm');
|
|
113
|
+
|
|
114
|
+
&::before {
|
|
115
|
+
border-radius: max(0px, calc(#{radius('sm')} - 3px));
|
|
116
|
+
}
|
|
87
117
|
}
|
|
88
118
|
|
|
89
119
|
// Initials - for users without a picture. Centers its text content and puts
|
|
@@ -176,6 +206,60 @@
|
|
|
176
206
|
border-width: 6px;
|
|
177
207
|
}
|
|
178
208
|
}
|
|
209
|
+
|
|
210
|
+
// Below the size steps on purpose - they set both axes, the ratio frees one
|
|
211
|
+
&-landscape {
|
|
212
|
+
width: auto;
|
|
213
|
+
aspect-ratio: 3 / 2;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
&-portrait {
|
|
217
|
+
height: auto;
|
|
218
|
+
aspect-ratio: 9 / 16;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Width-driven, so max-width can shrink it to a narrow column at 3:2
|
|
222
|
+
&-lg.mw-avatar-landscape,
|
|
223
|
+
&-xl.mw-avatar-landscape {
|
|
224
|
+
height: auto;
|
|
225
|
+
max-width: 100%;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Over the round step - a photo shows more of the person than a face
|
|
229
|
+
&-lg.mw-avatar-landscape {
|
|
230
|
+
width: 228px;
|
|
231
|
+
|
|
232
|
+
@include media-up('sm') {
|
|
233
|
+
width: 273px;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
&-xl.mw-avatar-landscape {
|
|
238
|
+
width: 285px;
|
|
239
|
+
|
|
240
|
+
@include media-up('sm') {
|
|
241
|
+
width: 399px;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
&-xl.mw-avatar-portrait {
|
|
246
|
+
width: 172px;
|
|
247
|
+
|
|
248
|
+
@include media-up('sm') {
|
|
249
|
+
width: 242px;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// 9:16 this small reads as a sliver - wider at the same height instead
|
|
254
|
+
&-lg.mw-avatar-portrait {
|
|
255
|
+
width: auto;
|
|
256
|
+
height: calc(138px * 16 / 9);
|
|
257
|
+
aspect-ratio: 2 / 3;
|
|
258
|
+
|
|
259
|
+
@include media-up('sm') {
|
|
260
|
+
height: calc(166px * 16 / 9);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
179
263
|
}
|
|
180
264
|
|
|
181
265
|
@each $name, $col in $semantic-colors {
|
|
@@ -72,8 +72,9 @@
|
|
|
72
72
|
|
|
73
73
|
// The arc on the two round corners is the one mark that makes a card look
|
|
74
74
|
// like this framework and not like a rounded box, so it is what the hover
|
|
75
|
-
// pulls on. Recoloured through the token the mixin already reads
|
|
76
|
-
//
|
|
75
|
+
// pulls on. Recoloured through the token the mixin already reads - on the
|
|
76
|
+
// ::after alone, because set on the card it inherits into every arc inside
|
|
77
|
+
// it, an avatar's or a nested card's.
|
|
77
78
|
&::after {
|
|
78
79
|
transition: var(--mw-transition);
|
|
79
80
|
}
|
|
@@ -81,7 +82,10 @@
|
|
|
81
82
|
&:hover {
|
|
82
83
|
box-shadow: var(--mw-elevation-3);
|
|
83
84
|
border-color: var(--mw-border-accent);
|
|
84
|
-
|
|
85
|
+
|
|
86
|
+
&::after {
|
|
87
|
+
--mw-corner-accent: var(--mw-corner-accent-hover);
|
|
88
|
+
}
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
// Pointer-guarded, unlike the colour and shadow above: on touch `:hover`
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
top: calc(100% + #{spacing('2')});
|
|
44
44
|
left: 0;
|
|
45
45
|
z-index: z-index('menu');
|
|
46
|
-
min-width: 200px;
|
|
46
|
+
min-width: var(--mw-dropdown-min-width, 200px);
|
|
47
47
|
// Never wider than the screen it opens on, whatever the longest item says
|
|
48
48
|
max-width: min(320px, calc(100vw - 2 * var(--mw-container-gutter)));
|
|
49
49
|
padding: spacing('2');
|
|
@@ -252,6 +252,21 @@
|
|
|
252
252
|
.mw-dropdown-up .mw-dropdown-menu {
|
|
253
253
|
position-area: block-start span-inline-end;
|
|
254
254
|
}
|
|
255
|
+
|
|
256
|
+
// In the bar a menu hangs off the bar's lower edge, not the trigger's - the
|
|
257
|
+
// trigger sits mid-bar, and a menu a few pixels under it starts inside it.
|
|
258
|
+
// Only a sideways flip is left, a menu above the bar would be off screen.
|
|
259
|
+
.mw-header-actions .mw-dropdown-menu {
|
|
260
|
+
position-area: none;
|
|
261
|
+
position-try-fallbacks: flip-inline;
|
|
262
|
+
top: var(--mw-header-height);
|
|
263
|
+
left: anchor(left);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.mw-header-actions .mw-dropdown-end .mw-dropdown-menu {
|
|
267
|
+
left: auto;
|
|
268
|
+
right: anchor(right);
|
|
269
|
+
}
|
|
255
270
|
}
|
|
256
271
|
|
|
257
272
|
// A menu opened by a thumb needs rows a thumb can hit, and the room to show
|
|
@@ -260,6 +275,14 @@
|
|
|
260
275
|
@include touch-context('sm') {
|
|
261
276
|
.mw-dropdown-menu {
|
|
262
277
|
min-width: max(100%, 240px);
|
|
278
|
+
|
|
279
|
+
// A fixed menu's 100% is its containing block - the viewport, or a whole
|
|
280
|
+
// bar with a backdrop filter - which slid a header menu under the logo.
|
|
281
|
+
// The plain 240px is for a Safari that anchors but cannot measure yet.
|
|
282
|
+
@supports (anchor-scope: all) and (position-area: block-end) {
|
|
283
|
+
min-width: 240px;
|
|
284
|
+
min-width: max(anchor-size(width), 240px);
|
|
285
|
+
}
|
|
263
286
|
}
|
|
264
287
|
|
|
265
288
|
.mw-dropdown-item {
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
@use '../abstracts' as *;
|
|
2
|
+
@use 'overlay-btn';
|
|
3
|
+
|
|
4
|
+
@layer mw.components {
|
|
5
|
+
// A strip of the next row stays in view, so the box reads as scrollable
|
|
6
|
+
$peek: 0.3;
|
|
7
|
+
$gap: 2px;
|
|
8
|
+
$rows: (
|
|
9
|
+
'': 3,
|
|
10
|
+
'.mw-feed-rows-2': 2,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
.mw-feed {
|
|
14
|
+
display: grid;
|
|
15
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
16
|
+
// The ratio further down sizes the grid; the frame goes around it
|
|
17
|
+
box-sizing: content-box;
|
|
18
|
+
padding: spacing('3');
|
|
19
|
+
border: 1px solid var(--mw-border-accent);
|
|
20
|
+
border-radius: radius('lg');
|
|
21
|
+
background: var(--mw-card-background);
|
|
22
|
+
gap: $gap;
|
|
23
|
+
overflow-y: auto;
|
|
24
|
+
scroll-snap-type: y mandatory;
|
|
25
|
+
scroll-padding-top: spacing('3');
|
|
26
|
+
@include scrollbar;
|
|
27
|
+
|
|
28
|
+
@include media-up('md') {
|
|
29
|
+
padding: spacing('4');
|
|
30
|
+
scroll-padding-top: spacing('4');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.mw-feed-plain {
|
|
35
|
+
padding: spacing('0');
|
|
36
|
+
border: none;
|
|
37
|
+
border-radius: radius('none');
|
|
38
|
+
background: none;
|
|
39
|
+
scroll-padding-top: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Once posts overflow: box height from its width, rows splitting it exactly
|
|
43
|
+
@each $rows-modifier, $count in $rows {
|
|
44
|
+
$more: ':has(> :nth-child(#{$count * 3 + 1}))';
|
|
45
|
+
|
|
46
|
+
.mw-feed#{$rows-modifier}#{$more} {
|
|
47
|
+
aspect-ratio: #{9} / #{4 * ($count + $peek)};
|
|
48
|
+
grid-auto-rows: calc((100% - #{$count} * #{$gap}) / #{$count + $peek});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.mw-feed#{$rows-modifier}.mw-feed-square#{$more} {
|
|
52
|
+
aspect-ratio: #{3} / #{$count + $peek};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.mw-feed-item {
|
|
57
|
+
position: relative;
|
|
58
|
+
margin: spacing('0');
|
|
59
|
+
// Sizes free rows only; stretched both ways, so box-sized rows win
|
|
60
|
+
aspect-ratio: 3 / 4;
|
|
61
|
+
place-self: stretch;
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
scroll-snap-align: start;
|
|
64
|
+
background: var(--mw-card-background);
|
|
65
|
+
|
|
66
|
+
// A link to a page of its own, or a button that opens the photo in place
|
|
67
|
+
> a,
|
|
68
|
+
> button {
|
|
69
|
+
position: absolute;
|
|
70
|
+
inset: 0;
|
|
71
|
+
display: block;
|
|
72
|
+
width: 100%;
|
|
73
|
+
padding: spacing('0');
|
|
74
|
+
border: none;
|
|
75
|
+
background: none;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
@include tappable;
|
|
78
|
+
@include focus-ring-inset(-3px);
|
|
79
|
+
|
|
80
|
+
&::after {
|
|
81
|
+
content: '';
|
|
82
|
+
position: absolute;
|
|
83
|
+
inset: 0;
|
|
84
|
+
background: rgb(0 0 0 / 0%);
|
|
85
|
+
transition: background-color var(--mw-duration-fast) var(--mw-ease-out);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
&:hover::after {
|
|
89
|
+
background: rgb(0 0 0 / 18%);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
&:active::after {
|
|
93
|
+
background: rgb(0 0 0 / 30%);
|
|
94
|
+
transition-duration: var(--mw-duration-instant);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
img {
|
|
98
|
+
display: block;
|
|
99
|
+
width: 100%;
|
|
100
|
+
height: 100%;
|
|
101
|
+
object-fit: cover;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.mw-feed-square .mw-feed-item {
|
|
107
|
+
aspect-ratio: 1;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.mw-feed-post {
|
|
111
|
+
// Not only the UA rule, or a browser without popovers shows it in the grid
|
|
112
|
+
display: none;
|
|
113
|
+
width: min(32rem, 100vw - 2rem);
|
|
114
|
+
max-height: calc(100dvh - 2rem);
|
|
115
|
+
margin: auto;
|
|
116
|
+
padding: spacing('0');
|
|
117
|
+
border: none;
|
|
118
|
+
border-radius: radius('md');
|
|
119
|
+
overflow: hidden auto;
|
|
120
|
+
overscroll-behavior: contain;
|
|
121
|
+
background: var(--mw-card-background);
|
|
122
|
+
color: var(--mw-text-color);
|
|
123
|
+
box-shadow: var(--mw-elevation-5);
|
|
124
|
+
opacity: 0;
|
|
125
|
+
transform: scale(0.96);
|
|
126
|
+
transition:
|
|
127
|
+
opacity var(--mw-duration-base) var(--mw-ease-out),
|
|
128
|
+
transform var(--mw-duration-base) var(--mw-ease-out),
|
|
129
|
+
overlay var(--mw-duration-base) allow-discrete,
|
|
130
|
+
display var(--mw-duration-base) allow-discrete;
|
|
131
|
+
|
|
132
|
+
&:popover-open {
|
|
133
|
+
display: block;
|
|
134
|
+
opacity: 1;
|
|
135
|
+
transform: none;
|
|
136
|
+
|
|
137
|
+
@starting-style {
|
|
138
|
+
opacity: 0;
|
|
139
|
+
transform: scale(0.96);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
&::backdrop {
|
|
144
|
+
background: var(--mw-overlay-background);
|
|
145
|
+
backdrop-filter: blur(3px);
|
|
146
|
+
opacity: 0;
|
|
147
|
+
transition:
|
|
148
|
+
opacity var(--mw-duration-base) var(--mw-ease-out),
|
|
149
|
+
overlay var(--mw-duration-base) allow-discrete,
|
|
150
|
+
display var(--mw-duration-base) allow-discrete;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
&:popover-open::backdrop {
|
|
154
|
+
opacity: 1;
|
|
155
|
+
|
|
156
|
+
@starting-style {
|
|
157
|
+
opacity: 0;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
> img {
|
|
162
|
+
display: block;
|
|
163
|
+
width: 100%;
|
|
164
|
+
height: auto;
|
|
165
|
+
max-height: 78dvh;
|
|
166
|
+
object-fit: contain;
|
|
167
|
+
background: $fixed-stage;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
> figcaption {
|
|
171
|
+
padding: spacing('4') spacing('5') spacing('5');
|
|
172
|
+
font-size: font-size('sm');
|
|
173
|
+
line-height: 1.55;
|
|
174
|
+
|
|
175
|
+
> * {
|
|
176
|
+
margin: spacing('0');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
> * + * {
|
|
180
|
+
margin-top: spacing('2');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
time,
|
|
184
|
+
small {
|
|
185
|
+
display: block;
|
|
186
|
+
color: var(--mw-text-muted-color);
|
|
187
|
+
font-size: font-size('xs');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.mw-feed-post-close {
|
|
193
|
+
position: absolute;
|
|
194
|
+
top: spacing('3');
|
|
195
|
+
right: spacing('3');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// A popover does not lock the page scroll behind it
|
|
199
|
+
:root:has(.mw-feed-post:popover-open) {
|
|
200
|
+
overflow: hidden;
|
|
201
|
+
scrollbar-gutter: stable; // Or the page shifts by the hidden scrollbar
|
|
202
|
+
}
|
|
203
|
+
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
@forward 'divider';
|
|
18
18
|
@forward 'dropdown';
|
|
19
19
|
@forward 'empty-state';
|
|
20
|
+
@forward 'feed';
|
|
20
21
|
@forward 'flag';
|
|
21
22
|
@forward 'gallery';
|
|
22
23
|
@forward 'hero-badge';
|
|
@@ -25,14 +26,18 @@
|
|
|
25
26
|
@forward 'kbd';
|
|
26
27
|
@forward 'lang-switch';
|
|
27
28
|
@forward 'leader-row';
|
|
29
|
+
@forward 'lightbox';
|
|
28
30
|
@forward 'links';
|
|
29
31
|
@forward 'lists';
|
|
30
32
|
@forward 'localhost-indicator';
|
|
31
33
|
@forward 'media';
|
|
32
34
|
@forward 'meta-info';
|
|
33
35
|
@forward 'modals';
|
|
36
|
+
@forward 'mosaic';
|
|
37
|
+
@forward 'overlay-btn';
|
|
34
38
|
@forward 'pagination';
|
|
35
39
|
@forward 'panels';
|
|
40
|
+
@forward 'portrait-gallery';
|
|
36
41
|
@forward 'pricing';
|
|
37
42
|
@forward 'progress';
|
|
38
43
|
@forward 'prose';
|
|
@@ -41,6 +46,7 @@
|
|
|
41
46
|
@forward 'skeleton';
|
|
42
47
|
@forward 'spinners';
|
|
43
48
|
@forward 'stepper';
|
|
49
|
+
@forward 'stories';
|
|
44
50
|
@forward 'tables';
|
|
45
51
|
@forward 'tabs';
|
|
46
52
|
@forward 'tags';
|