Skip to content

Commit 260f702

Browse files
feat: 重构虚拟歌姬发布页交互体验
1 parent 7e8beec commit 260f702

23 files changed

Lines changed: 2433 additions & 620 deletions
Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
.selector {
2+
display: grid;
3+
grid-template-columns: minmax(0, 55fr) minmax(0, 45fr);
4+
grid-template-rows: auto auto;
5+
grid-template-areas: "stage copy" "stage selection";
6+
align-content: center;
7+
column-gap: clamp(24px, 4vw, 60px);
8+
width: 100%;
9+
max-width: 1100px;
10+
min-height: 600px;
11+
margin-inline: auto;
12+
color: var(--color-ink);
13+
}
14+
15+
.selector:focus-visible {
16+
outline: 2px solid var(--color-accent);
17+
outline-offset: 10px;
18+
}
19+
20+
.copy {
21+
grid-area: copy;
22+
align-self: end;
23+
}
24+
25+
.heading {
26+
margin: 0;
27+
font-family: var(--font-display);
28+
font-size: clamp(54px, 6.5vw, 92px);
29+
font-weight: 600;
30+
line-height: 1.07;
31+
letter-spacing: -0.055em;
32+
}
33+
34+
.introduction {
35+
margin: 24px 0 0;
36+
color: var(--color-muted);
37+
font-size: 15px;
38+
line-height: 1.85;
39+
}
40+
41+
.stage {
42+
position: relative;
43+
grid-area: stage;
44+
display: grid;
45+
grid-template-rows: minmax(0, 1fr) auto;
46+
height: 580px;
47+
min-width: 0;
48+
margin: 0;
49+
isolation: isolate;
50+
}
51+
52+
.orbit {
53+
position: absolute;
54+
z-index: -1;
55+
inset: 12% 9% 15%;
56+
border: 1px solid rgb(68 93 204 / 20%);
57+
border-radius: 50%;
58+
background: rgb(250 249 252 / 36%);
59+
transform: rotate(-18deg);
60+
}
61+
62+
.artWindow {
63+
display: grid;
64+
place-items: center;
65+
min-height: 0;
66+
overflow: hidden;
67+
}
68+
69+
.art {
70+
display: block;
71+
width: 100%;
72+
height: 100%;
73+
min-height: 0;
74+
object-fit: contain;
75+
object-position: center bottom;
76+
transform-origin: 50% 85%;
77+
}
78+
79+
.entering {
80+
--slide-start: 15%;
81+
--tilt-start: 5deg;
82+
animation: artEntrance 560ms cubic-bezier(0.2, 0.75, 0.2, 1) both;
83+
}
84+
85+
.entering[data-direction="previous"] {
86+
--slide-start: -15%;
87+
--tilt-start: -5deg;
88+
}
89+
90+
.caption {
91+
display: flex;
92+
flex-wrap: wrap;
93+
align-items: baseline;
94+
justify-content: center;
95+
gap: 8px 18px;
96+
padding-top: 20px;
97+
font-size: 14px;
98+
}
99+
100+
.caption strong {
101+
font-weight: 600;
102+
}
103+
104+
.caption span {
105+
color: var(--color-muted);
106+
}
107+
108+
.selection {
109+
grid-area: selection;
110+
align-self: start;
111+
min-width: 0;
112+
margin-top: 30px;
113+
}
114+
115+
.navigation {
116+
display: flex;
117+
align-items: center;
118+
justify-content: space-between;
119+
gap: 20px;
120+
margin-bottom: 18px;
121+
}
122+
123+
.counter {
124+
display: flex;
125+
align-items: baseline;
126+
gap: 12px;
127+
font-family: var(--font-display);
128+
font-variant-numeric: tabular-nums;
129+
}
130+
131+
.counter strong {
132+
font-size: 36px;
133+
font-weight: 500;
134+
line-height: 1;
135+
}
136+
137+
.counter > span {
138+
color: var(--color-muted);
139+
font-size: 15px;
140+
}
141+
142+
.arrows {
143+
display: flex;
144+
gap: 8px;
145+
}
146+
147+
.arrow {
148+
display: grid;
149+
place-items: center;
150+
width: 46px;
151+
height: 46px;
152+
padding: 11px;
153+
border: 1px solid rgb(37 42 67 / 24%);
154+
border-radius: 50%;
155+
background: transparent;
156+
color: inherit;
157+
cursor: pointer;
158+
transition: background 180ms ease, color 180ms ease;
159+
}
160+
161+
.arrow svg {
162+
width: 100%;
163+
height: 100%;
164+
stroke: currentColor;
165+
stroke-width: 1.5;
166+
stroke-linecap: round;
167+
stroke-linejoin: round;
168+
}
169+
170+
.arrow:hover {
171+
background: var(--color-ink);
172+
color: var(--color-paper);
173+
}
174+
175+
.filmstrip {
176+
display: grid;
177+
grid-template-columns: repeat(5, minmax(0, 1fr));
178+
gap: 8px;
179+
}
180+
181+
.thumbnail {
182+
position: relative;
183+
display: grid;
184+
grid-template-rows: minmax(0, 1fr) auto;
185+
justify-items: center;
186+
min-width: 0;
187+
height: 105px;
188+
padding: 6px 4px 5px;
189+
border: 1px solid transparent;
190+
border-radius: 3px;
191+
background: rgb(250 249 252 / 65%);
192+
color: var(--color-muted);
193+
font: inherit;
194+
cursor: pointer;
195+
transition: border-color 180ms ease, background 180ms ease, transform 180ms ease;
196+
}
197+
198+
.thumbnail img {
199+
display: block;
200+
width: 100%;
201+
height: 100%;
202+
min-height: 0;
203+
object-fit: contain;
204+
}
205+
206+
.thumbnail span {
207+
padding-top: 4px;
208+
font-size: 11px;
209+
font-variant-numeric: tabular-nums;
210+
}
211+
212+
.thumbnail[aria-pressed="true"] {
213+
border-color: var(--color-accent);
214+
background: var(--color-paper);
215+
color: var(--color-accent);
216+
}
217+
218+
.thumbnail:hover {
219+
border-color: var(--color-accent);
220+
transform: translateY(-3px);
221+
}
222+
223+
.links {
224+
display: flex;
225+
flex-wrap: wrap;
226+
justify-content: space-between;
227+
gap: 8px 20px;
228+
margin-top: 20px;
229+
}
230+
231+
.links a {
232+
display: inline-flex;
233+
align-items: center;
234+
gap: 14px;
235+
min-height: 44px;
236+
color: inherit;
237+
font-size: 14px;
238+
text-decoration: underline;
239+
text-decoration-color: rgb(37 42 67 / 30%);
240+
text-underline-offset: 6px;
241+
}
242+
243+
.links a:hover {
244+
color: var(--color-accent);
245+
}
246+
247+
.arrow:focus-visible,
248+
.thumbnail:focus-visible,
249+
.links a:focus-visible {
250+
outline: 3px solid var(--color-accent);
251+
outline-offset: 3px;
252+
}
253+
254+
.srOnly {
255+
position: absolute;
256+
width: 1px;
257+
height: 1px;
258+
padding: 0;
259+
overflow: hidden;
260+
clip-path: inset(50%);
261+
white-space: nowrap;
262+
}
263+
264+
@keyframes artEntrance {
265+
from {
266+
clip-path: inset(0 0 100% 0);
267+
transform: translateX(var(--slide-start)) rotate(var(--tilt-start));
268+
}
269+
to {
270+
clip-path: inset(0);
271+
transform: translateX(0) rotate(0);
272+
}
273+
}
274+
275+
@media (max-width: 700px) {
276+
.selector {
277+
grid-template-columns: minmax(0, 1fr);
278+
grid-template-rows: auto auto auto;
279+
grid-template-areas: "copy" "stage" "selection";
280+
min-height: 0;
281+
row-gap: 18px;
282+
}
283+
284+
.heading {
285+
font-size: clamp(42px, 10vw, 62px);
286+
line-height: 1.05;
287+
}
288+
289+
.heading br {
290+
display: none;
291+
}
292+
293+
.introduction {
294+
margin-top: 14px;
295+
font-size: 13px;
296+
line-height: 1.7;
297+
}
298+
299+
.stage {
300+
height: clamp(270px, 75vw, 380px);
301+
}
302+
303+
.caption {
304+
padding-top: 12px;
305+
font-size: 13px;
306+
}
307+
308+
.selection {
309+
margin-top: 0;
310+
}
311+
312+
.navigation {
313+
margin-bottom: 12px;
314+
}
315+
316+
.counter strong {
317+
font-size: 30px;
318+
}
319+
320+
.filmstrip {
321+
gap: 6px;
322+
}
323+
324+
.thumbnail {
325+
height: 82px;
326+
min-height: 44px;
327+
}
328+
329+
.links {
330+
margin-top: 8px;
331+
}
332+
}
333+
334+
@media (prefers-reduced-motion: reduce) {
335+
.entering {
336+
animation: none;
337+
}
338+
339+
.arrow,
340+
.thumbnail {
341+
transition: none;
342+
}
343+
344+
.thumbnail:hover {
345+
transform: none;
346+
}
347+
}

0 commit comments

Comments
 (0)