maverick-wave 5.27.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.
- package/.claude/skills/mw-maverick-wave/SKILL.md +4 -2
- package/.claude/skills/mw-maverick-wave/references/components.md +212 -0
- package/.claude/skills/mw-maverick-wave/references/javascript.md +6 -1
- package/.claude/skills/mw-maverick-wave/references/theming.md +53 -51
- package/CHANGELOG.md +17 -0
- package/CLAUDE.md +4 -4
- package/README.md +2 -2
- package/index.html +65 -0
- package/maverick-wave.min.css +4 -4
- 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 +411 -8
- 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 +9 -0
- package/src/scss/components/_avatars.scss +52 -0
- package/src/scss/components/_cards.scss +7 -3
- package/src/scss/components/_feed.scss +203 -0
- package/src/scss/components/_hero-badge.scss +48 -0
- package/src/scss/components/_index.scss +8 -0
- package/src/scss/components/_leader-row.scss +24 -18
- package/src/scss/components/_lightbox.scss +178 -0
- 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/components/_tooltip.scss +193 -0
- package/src/scss/layout/_footer.scss +46 -84
- package/src/scss/layout/_grid.scss +48 -45
- package/src/scss/layout/_header-reveal.scss +1 -1
- package/src/scss/layout/_header.scss +49 -66
- package/src/scss/layout/_home.scss +5 -2
- package/src/scss/layout/_main.scss +100 -337
- package/src/scss/layout/_parallax.scss +1 -1
- package/src/scss/layout/_section.scss +24 -17
- 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;
|
|
@@ -520,7 +523,13 @@ $z-index: (
|
|
|
520
523
|
'lift': 3,
|
|
521
524
|
'card': 10,
|
|
522
525
|
'menu': 30,
|
|
526
|
+
// The scrim sits under the bar, the panel hangs off it, the logo clears the
|
|
527
|
+
// panel and the burger stays on top of all of them while it is the X.
|
|
528
|
+
'header-scrim': 99,
|
|
523
529
|
'header': 100,
|
|
530
|
+
'header-panel': 103,
|
|
531
|
+
'header-logo': 105,
|
|
532
|
+
'header-burger': 110,
|
|
524
533
|
'spinner': 300,
|
|
525
534
|
'modal': 500,
|
|
526
535
|
'tooltip': 700,
|
|
@@ -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 {
|
|
@@ -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,28 @@
|
|
|
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
|
+
// 9:16 this small reads as a sliver - wider at the same height instead
|
|
222
|
+
&-lg.mw-avatar-portrait {
|
|
223
|
+
width: auto;
|
|
224
|
+
height: calc(120px * 16 / 9);
|
|
225
|
+
aspect-ratio: 2 / 3;
|
|
226
|
+
|
|
227
|
+
@include media-up('sm') {
|
|
228
|
+
height: calc(144px * 16 / 9);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
179
231
|
}
|
|
180
232
|
|
|
181
233
|
@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`
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
@use '../abstracts' as *;
|
|
2
|
+
|
|
3
|
+
@layer mw.components {
|
|
4
|
+
// Glass rather than a fill: on a hero image a solid badge is the loudest thing
|
|
5
|
+
// on the screen and plain text sinks into the picture.
|
|
6
|
+
.mw-hero-badge {
|
|
7
|
+
display: inline-flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
gap: spacing('3');
|
|
11
|
+
max-width: 100%;
|
|
12
|
+
margin-bottom: spacing('6');
|
|
13
|
+
padding: spacing('2') spacing('5');
|
|
14
|
+
border: 1px solid #{fade('hero-text-color', 22%)};
|
|
15
|
+
border-radius: 999px;
|
|
16
|
+
// A vertical ramp and not a flat tint: glass is lit from above, and the
|
|
17
|
+
// gradient is what gives the pill a thickness instead of a fogged panel
|
|
18
|
+
background: linear-gradient(
|
|
19
|
+
to bottom,
|
|
20
|
+
#{fade('hero-text-color', 16%)},
|
|
21
|
+
#{fade('hero-text-color', 5%)}
|
|
22
|
+
);
|
|
23
|
+
// saturate() is what separates glass from frosted plastic: the blur alone
|
|
24
|
+
// greys out what shows through, and pushing the chroma back up is how a
|
|
25
|
+
// real lens reads. The two inset lines are the specular highlight - light
|
|
26
|
+
// catching the top edge, a fainter bounce off the bottom - and the outer
|
|
27
|
+
// shadow is what lifts the pill off the photo instead of pasting it on.
|
|
28
|
+
backdrop-filter: blur(14px) saturate(180%);
|
|
29
|
+
box-shadow:
|
|
30
|
+
inset 0 1px 0 #{fade('hero-text-color', 40%)},
|
|
31
|
+
inset 0 -1px 0 #{fade('hero-text-color', 12%)},
|
|
32
|
+
0 2px 12px rgb(0 0 0 / 18%);
|
|
33
|
+
color: fade('hero-text-color', 88%);
|
|
34
|
+
font-size: font-size('sm');
|
|
35
|
+
font-weight: font-weight('medium');
|
|
36
|
+
letter-spacing: 0.02em;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Carries the secondary colour, because the badge is a state, not a label -
|
|
40
|
+
// override `background` for a different one
|
|
41
|
+
.mw-hero-badge-dot {
|
|
42
|
+
width: 8px;
|
|
43
|
+
height: 8px;
|
|
44
|
+
flex-shrink: 0;
|
|
45
|
+
border-radius: radius('full');
|
|
46
|
+
background: var(--mw-secondary-color);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -17,21 +17,27 @@
|
|
|
17
17
|
@forward 'divider';
|
|
18
18
|
@forward 'dropdown';
|
|
19
19
|
@forward 'empty-state';
|
|
20
|
+
@forward 'feed';
|
|
20
21
|
@forward 'flag';
|
|
21
22
|
@forward 'gallery';
|
|
23
|
+
@forward 'hero-badge';
|
|
22
24
|
@forward 'info';
|
|
23
25
|
@forward 'kanban';
|
|
24
26
|
@forward 'kbd';
|
|
25
27
|
@forward 'lang-switch';
|
|
26
28
|
@forward 'leader-row';
|
|
29
|
+
@forward 'lightbox';
|
|
27
30
|
@forward 'links';
|
|
28
31
|
@forward 'lists';
|
|
29
32
|
@forward 'localhost-indicator';
|
|
30
33
|
@forward 'media';
|
|
31
34
|
@forward 'meta-info';
|
|
32
35
|
@forward 'modals';
|
|
36
|
+
@forward 'mosaic';
|
|
37
|
+
@forward 'overlay-btn';
|
|
33
38
|
@forward 'pagination';
|
|
34
39
|
@forward 'panels';
|
|
40
|
+
@forward 'portrait-gallery';
|
|
35
41
|
@forward 'pricing';
|
|
36
42
|
@forward 'progress';
|
|
37
43
|
@forward 'prose';
|
|
@@ -40,6 +46,7 @@
|
|
|
40
46
|
@forward 'skeleton';
|
|
41
47
|
@forward 'spinners';
|
|
42
48
|
@forward 'stepper';
|
|
49
|
+
@forward 'stories';
|
|
43
50
|
@forward 'tables';
|
|
44
51
|
@forward 'tabs';
|
|
45
52
|
@forward 'tags';
|
|
@@ -49,3 +56,4 @@
|
|
|
49
56
|
@forward 'tiles';
|
|
50
57
|
@forward 'timelines';
|
|
51
58
|
@forward 'toasts';
|
|
59
|
+
@forward 'tooltip';
|