Browse Source

Refactor Bento section layout and styles for improved editorial rhythm and responsiveness; enhance interlude and dark wall sections with new design elements and spacing adjustments.

beauty
npmrun 1 week ago
parent
commit
6e21d4543d
  1. 902
      app/pages/auth/index.vue
  2. 605
      app/pages/index/index.vue

902
app/pages/auth/index.vue

File diff suppressed because it is too large

605
app/pages/index/index.vue

@ -144,93 +144,151 @@ onUnmounted(() => {
</div> </div>
</section> </section>
<!-- Bento grid --> <!-- Bento grid editorial rhythm -->
<section class="bento-section"> <section class="bento-section">
<div class="bento-header">
<span class="bento-index">01</span>
<h2 class="bento-heading">碎片收藏</h2>
<p class="bento-sub">每一格都是一段被打断的思绪</p>
</div>
<div class="bento"> <div class="bento">
<!-- Row 1 --> <!-- Zone A: large left + 3-column strip right -->
<div class="b-item b-lg reveal-card" :ref="(el) => { if (el) bentoItems[0] = el as HTMLElement }"> <div class="b-zone-a">
<div class="b-img-wrap"> <div class="b-a-main reveal-card" :ref="(el) => { if (el) bentoItems[0] = el as HTMLElement }">
<img src="https://picsum.photos/id/10/700/1000" alt="午后" loading="lazy" /> <div class="b-img-wrap">
<img src="https://picsum.photos/id/10/700/1000" alt="午后" loading="lazy" />
</div>
</div> </div>
</div> <div class="b-a-side">
<div class="b-item b-col-2 reveal-card" :ref="(el) => { if (el) bentoItems[1] = el as HTMLElement }"> <div class="b-a-side-top reveal-card" :ref="(el) => { if (el) bentoItems[1] = el as HTMLElement }">
<div class="b-img-wrap"><img src="https://picsum.photos/id/20/800/500" alt="城市" loading="lazy" /></div> <div class="b-img-wrap">
<div class="b-img-wrap mt-4"><img src="https://picsum.photos/id/40/800/500" alt="远行" loading="lazy" /></div> <img src="https://picsum.photos/id/20/800/500" alt="城市" loading="lazy" />
</div> </div>
<div class="b-item b-tall reveal-card" :ref="(el) => { if (el) bentoItems[2] = el as HTMLElement }"> </div>
<div class="b-img-wrap"> <div class="b-a-side-bot reveal-card" :ref="(el) => { if (el) bentoItems[2] = el as HTMLElement }">
<img src="https://picsum.photos/id/30/600/1000" alt="海岸" loading="lazy" /> <div class="b-img-wrap">
<img src="https://picsum.photos/id/40/800/500" alt="远行" loading="lazy" />
</div>
</div>
</div> </div>
</div> </div>
<!-- Row 2 note card + medium --> <!-- Zone B: quote + 3-column photo strip -->
<div class="b-item b-note reveal-card" :ref="(el) => { if (el) bentoItems[3] = el as HTMLElement }"> <div class="b-zone-b">
<p class="note-text">"每件东西都有自己的气味,闻到就穿越了"</p> <div class="b-b-quote reveal-card" :ref="(el) => { if (el) bentoItems[3] = el as HTMLElement }">
<span class="note-source"> 手记 #1</span> <span class="note-mark">"</span>
</div> <p class="note-text">每件东西都有自己的气味闻到就穿越了</p>
<div class="b-item b-md reveal-card" :ref="(el) => { if (el) bentoItems[4] = el as HTMLElement }"> <span class="note-source"> 手记 #1</span>
<div class="b-img-wrap">
<img src="https://picsum.photos/id/50/700/700" alt="静物" loading="lazy" />
</div> </div>
</div> <div class="b-b-strip">
<div class="b-strip-item reveal-card" :ref="(el) => { if (el) bentoItems[4] = el as HTMLElement }">
<!-- Row 3 --> <div class="b-img-wrap">
<div class="b-item b-tall-right reveal-card" :ref="(el) => { if (el) bentoItems[5] = el as HTMLElement }"> <img src="https://picsum.photos/id/50/700/700" alt="静物" loading="lazy" />
<div class="b-img-wrap"> </div>
<img src="https://picsum.photos/id/60/600/1000" alt="人像" loading="lazy" /> </div>
<div class="b-strip-item reveal-card" :ref="(el) => { if (el) bentoItems[5] = el as HTMLElement }">
<div class="b-img-wrap">
<img src="https://picsum.photos/id/30/600/1000" alt="海岸" loading="lazy" />
</div>
</div>
<div class="b-strip-item reveal-card" :ref="(el) => { if (el) bentoItems[6] = el as HTMLElement }">
<div class="b-img-wrap">
<img src="https://picsum.photos/id/60/600/1000" alt="人像" loading="lazy" />
</div>
</div>
</div> </div>
</div> </div>
<div class="b-item b-wide reveal-card" :ref="(el) => { if (el) bentoItems[6] = el as HTMLElement }">
<div class="b-img-wrap"> <!-- Zone C: wide + accent number -->
<img src="https://picsum.photos/id/70/1200/600" alt="夜色" loading="lazy" /> <div class="b-zone-c">
<div class="b-c-wide reveal-card" :ref="(el) => { if (el) bentoItems[7] = el as HTMLElement }">
<div class="b-img-wrap">
<img src="https://picsum.photos/id/70/1200/600" alt="夜色" loading="lazy" />
</div>
</div> </div>
</div> <div class="b-c-accent reveal-card" :ref="(el) => { if (el) bentoItems[8] = el as HTMLElement }">
<div class="b-item b-sm reveal-card" :ref="(el) => { if (el) bentoItems[7] = el as HTMLElement }"> <div class="accent-block">
<div class="b-img-wrap"> <span class="accent-num">02</span>
<img src="https://picsum.photos/id/80/600/600" alt="山川" loading="lazy" /> <span class="accent-label">城市<br>快照</span>
</div>
</div> </div>
</div> </div>
<!-- Row 4 note + grid --> <!-- Zone D: 4-grid + quote -->
<div class="b-item b-note reveal-card" :ref="(el) => { if (el) bentoItems[8] = el as HTMLElement }"> <div class="b-zone-d">
<p class="note-text">"收集的过程比结果更重要"</p> <div class="b-d-4grid reveal-card" :ref="(el) => { if (el) bentoItems[9] = el as HTMLElement }">
<span class="note-source"> 手记 #2</span> <div class="b-img-wrap"><img src="https://picsum.photos/id/100/600/400" alt="森林" loading="lazy" /></div>
</div> <div class="b-img-wrap"><img src="https://picsum.photos/id/110/600/600" alt="街道" loading="lazy" /></div>
<div class="b-item b-4grid reveal-card" :ref="(el) => { if (el) bentoItems[9] = el as HTMLElement }"> <div class="b-img-wrap"><img src="https://picsum.photos/id/120/600/800" alt="雨季" loading="lazy" /></div>
<div class="b-img-wrap"><img src="https://picsum.photos/id/100/600/400" alt="森林" loading="lazy" /></div> <div class="b-img-wrap"><img src="https://picsum.photos/id/130/600/400" alt="晴空" loading="lazy" /></div>
<div class="b-img-wrap"><img src="https://picsum.photos/id/110/600/600" alt="街道" loading="lazy" /></div> </div>
<div class="b-img-wrap"><img src="https://picsum.photos/id/120/600/800" alt="雨季" loading="lazy" /></div> <div class="b-d-quote reveal-card" :ref="(el) => { if (el) bentoItems[10] = el as HTMLElement }">
<div class="b-img-wrap"><img src="https://picsum.photos/id/130/600/400" alt="晴空" loading="lazy" /></div> <span class="note-mark">"</span>
<p class="note-text">收集的过程比结果更重要</p>
<span class="note-source"> 手记 #2</span>
</div>
</div> </div>
<!-- Row 5 --> <!-- Zone E: 3-column row -->
<div class="b-item b-md reveal-card" :ref="(el) => { if (el) bentoItems[10] = el as HTMLElement }"> <div class="b-zone-e">
<div class="b-img-wrap"> <div class="b-e-item reveal-card" :ref="(el) => { if (el) bentoItems[11] = el as HTMLElement }">
<img src="https://picsum.photos/id/140/700/700" alt="咖啡" loading="lazy" /> <div class="b-img-wrap">
<img src="https://picsum.photos/id/140/700/700" alt="咖啡" loading="lazy" />
</div>
</div> </div>
</div> <div class="b-e-item reveal-card" :ref="(el) => { if (el) bentoItems[12] = el as HTMLElement }">
<div class="b-item b-tall reveal-card" :ref="(el) => { if (el) bentoItems[11] = el as HTMLElement }"> <div class="b-img-wrap">
<div class="b-img-wrap"> <img src="https://picsum.photos/id/150/600/1000" alt="旅途" loading="lazy" />
<img src="https://picsum.photos/id/150/600/1000" alt="旅途" loading="lazy" /> </div>
</div>
<div class="b-e-item reveal-card" :ref="(el) => { if (el) bentoItems[13] = el as HTMLElement }">
<div class="b-img-wrap">
<img src="https://picsum.photos/id/80/600/600" alt="山川" loading="lazy" />
</div>
</div> </div>
</div> </div>
<div class="b-item b-col-2-bottom reveal-card" :ref="(el) => { if (el) bentoItems[12] = el as HTMLElement }">
<div class="b-img-wrap"><img src="https://picsum.photos/id/160/800/500" alt="废墟" loading="lazy" /></div> <!-- Zone F: full-width quote -->
<div class="b-img-wrap mt-4"><img src="https://picsum.photos/id/170/800/500" alt="浪潮" loading="lazy" /></div> <div class="b-zone-f">
<div class="b-f-quote reveal-card" :ref="(el) => { if (el) bentoItems[14] = el as HTMLElement }">
<span class="note-mark">"</span>
<p class="note-text">有些东西扔不掉不是因为值钱是因为记得</p>
<span class="note-source"> 手记 #3</span>
</div>
</div> </div>
</div>
</section>
<!-- Row 6 note --> <!-- Mid-page interlude dark editorial card -->
<div class="b-item b-note b-note-last reveal-card" :ref="(el) => { if (el) bentoItems[13] = el as HTMLElement }"> <section class="interlude">
<p class="note-text">"有些东西扔不掉,不是因为值钱,是因为记得"</p> <div class="interlude-inner">
<span class="note-source"> 手记 #3</span> <div class="interlude-label">03 · 精选</div>
<div class="interlude-grid">
<div class="interlude-text">
<h2 class="interlude-heading">不是作品集<br>是私人日记</h2>
<p class="interlude-body">没有策划没有主题就是随手拍随便留三年下来发现这些碎片其实比"正经作品"更像自己</p>
<NuxtLink to="/photo" class="interlude-link">
进入全部收藏
<span class="link-arrow"></span>
</NuxtLink>
</div>
<div class="interlude-feature">
<div class="feature-img-wrap">
<img src="https://picsum.photos/id/96/800/600" alt="海岸线" loading="lazy" />
</div>
<div class="feature-tag">2022 · 午后</div>
</div>
</div> </div>
</div> </div>
</section> </section>
<!-- Dark feature wall --> <!-- Dark feature wall 6 column editorial -->
<section class="dark-wall"> <section class="dark-wall">
<div class="dark-wall-inner"> <div class="dark-wall-inner">
<div class="dw-label">最珍贵的几件</div> <div class="dw-header">
<span class="dw-index">04</span>
<span class="dw-label">最珍贵的几件</span>
</div>
<div class="dw-photos"> <div class="dw-photos">
<div <div
class="dw-photo reveal-card" class="dw-photo reveal-card"
@ -238,7 +296,9 @@ onUnmounted(() => {
:key="c.id" :key="c.id"
:ref="(el) => { if (el) dwPhotos[i] = el as HTMLElement }" :ref="(el) => { if (el) dwPhotos[i] = el as HTMLElement }"
> >
<img :src="imgSrc(c.id, c.aspect, 600)" :alt="c.title" loading="lazy" /> <div class="dw-photo-inner">
<img :src="imgSrc(c.id, c.aspect, 500)" :alt="c.title" loading="lazy" />
</div>
<div class="dw-photo-label">{{ c.title }}</div> <div class="dw-photo-label">{{ c.title }}</div>
</div> </div>
</div> </div>
@ -380,18 +440,52 @@ onUnmounted(() => {
line-height: 1.6; line-height: 1.6;
} }
/* ── Bento ── */ /* ── Bento heading ── */
.bento-section { .bento-section {
padding: 80px 40px 96px; padding: 80px 40px 96px;
max-width: 1400px; max-width: 1400px;
margin: 0 auto; margin: 0 auto;
} }
.bento-header {
display: flex;
align-items: baseline;
gap: 20px;
margin-bottom: 48px;
border-bottom: 1px solid var(--color-hairline);
padding-bottom: 32px;
}
.bento-index {
font-family: var(--font-body);
font-size: 11px;
font-weight: 500;
letter-spacing: 2px;
color: var(--color-primary);
}
.bento-heading {
font-family: var(--font-display);
font-size: clamp(28px, 4vw, 48px);
font-weight: 400;
color: var(--color-ink);
letter-spacing: -1px;
margin: 0;
}
.bento-sub {
font-family: var(--font-body);
font-size: 14px;
color: var(--color-muted);
margin: 0;
margin-left: auto;
font-style: italic;
}
.bento { .bento {
display: grid; display: flex;
grid-template-columns: repeat(12, 1fr); flex-direction: column;
gap: 16px; gap: 20px;
align-items: start;
} }
/* item helpers */ /* item helpers */
@ -414,47 +508,136 @@ onUnmounted(() => {
transform: scale(1.04); transform: scale(1.04);
} }
.mt-4 { margin-top: 16px; } /* ── Zone A: 5col main + 7col side stack ── */
.b-zone-a {
display: grid;
grid-template-columns: 5fr 7fr;
gap: 20px;
align-items: start;
}
.b-a-main .b-img-wrap {
height: 560px;
}
.b-a-side {
display: grid;
grid-template-rows: 1fr 1fr;
gap: 20px;
}
.b-a-side .b-img-wrap {
height: 270px;
}
/* ── Zone B: 4col quote + 8col 3-up strip ── */
.b-zone-b {
display: grid;
grid-template-columns: 4fr 8fr;
gap: 20px;
align-items: start;
}
.b-b-quote {
background: var(--color-surface-card);
border-radius: 8px;
padding: 40px 32px;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 320px;
}
/* Bento item sizes */ .b-b-strip {
.b-lg { grid-column: span 4; grid-row: span 2; } display: grid;
.b-lg .b-img-wrap { height: 520px; } grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
}
.b-col-2 { grid-column: span 4; } .b-strip-item .b-img-wrap {
.b-col-2 .b-img-wrap { height: 245px; } height: 320px;
.b-col-2 .mt-4 { margin-top: 16px; } }
.b-tall { grid-column: span 3; grid-row: span 2; } /* ── Zone C: 7col wide + 5col accent ── */
.b-tall .b-img-wrap { height: 520px; } .b-zone-c {
display: grid;
grid-template-columns: 7fr 5fr;
gap: 20px;
align-items: start;
}
.b-tall-right { grid-column: span 3; grid-row: span 2; } .b-c-wide .b-img-wrap {
.b-tall-right .b-img-wrap { height: 520px; } height: 380px;
}
.b-wide { grid-column: span 5; } .b-c-accent {
.b-wide .b-img-wrap { height: 320px; } background: var(--color-surface-card);
border-radius: 8px;
height: 380px;
display: flex;
align-items: center;
justify-content: center;
}
.b-sm { grid-column: span 4; } /* ── Zone D: 8col 4-grid + 4col quote ── */
.b-sm .b-img-wrap { height: 320px; } .b-zone-d {
display: grid;
grid-template-columns: 8fr 4fr;
gap: 20px;
align-items: start;
}
.b-md { grid-column: span 4; } .b-d-4grid {
.b-md .b-img-wrap { height: 400px; } display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.b-d-4grid .b-img-wrap {
height: 240px;
}
.b-note { .b-d-quote {
grid-column: span 4;
background: var(--color-surface-card); background: var(--color-surface-card);
border-radius: 8px; border-radius: 8px;
padding: 32px; padding: 40px 32px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
min-height: 200px; min-height: 260px;
} }
.b-note-last { grid-column: span 12; } /* ── Zone E: equal 3 columns ── */
.b-zone-e {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
}
.b-e-item .b-img-wrap {
height: 360px;
}
/* ── Zone F: full-width quote ── */
.b-zone-f {
width: 100%;
}
.b-f-quote {
background: var(--color-surface-card);
border-radius: 8px;
padding: 48px 56px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
min-height: 180px;
}
/* ── Shared note styles ── */
.note-text { .note-text {
font-family: var(--font-display); font-family: var(--font-display);
font-size: clamp(18px, 2.5vw, 26px); font-size: clamp(18px, 2vw, 24px);
font-weight: 400; font-weight: 400;
color: var(--color-ink); color: var(--color-ink);
letter-spacing: -0.3px; letter-spacing: -0.3px;
@ -463,20 +646,153 @@ onUnmounted(() => {
font-style: italic; font-style: italic;
} }
.note-mark {
display: block;
font-family: var(--font-display);
font-size: 56px;
line-height: 0.7;
color: var(--color-primary);
margin-bottom: 12px;
font-weight: 400;
}
.note-source { .note-source {
font-family: var(--font-body); font-family: var(--font-body);
font-size: 12px; font-size: 11px;
color: var(--color-muted); color: var(--color-muted);
letter-spacing: 1px; letter-spacing: 2px;
text-transform: uppercase; text-transform: uppercase;
} }
.b-4grid { grid-column: span 8; display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } /* Accent number block */
.b-4grid .b-img-wrap { height: 240px; } .accent-block {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.b-col-2-bottom { grid-column: span 4; } .accent-num {
.b-col-2-bottom .b-img-wrap { height: 245px; } font-family: var(--font-display);
.b-col-2-bottom .mt-4 { margin-top: 16px; } font-size: 56px;
font-weight: 400;
color: var(--color-primary);
letter-spacing: -2px;
line-height: 1;
}
.accent-label {
font-family: var(--font-body);
font-size: 10px;
font-weight: 500;
letter-spacing: 3px;
text-transform: uppercase;
color: var(--color-muted);
text-align: center;
line-height: 1.7;
}
/* ── Interlude editorial card ── */
.interlude {
background: var(--color-surface-dark);
padding: 80px 40px;
}
.interlude-inner {
max-width: 1400px;
margin: 0 auto;
}
.interlude-label {
font-family: var(--font-body);
font-size: 11px;
font-weight: 500;
letter-spacing: 3px;
text-transform: uppercase;
color: var(--color-on-dark-soft);
margin-bottom: 40px;
}
.interlude-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: center;
}
.interlude-text {
display: flex;
flex-direction: column;
gap: 24px;
}
.interlude-heading {
font-family: var(--font-display);
font-size: clamp(32px, 4vw, 52px);
font-weight: 400;
color: var(--color-on-dark);
letter-spacing: -1px;
line-height: 1.1;
margin: 0;
}
.interlude-body {
font-family: var(--font-body);
font-size: 16px;
color: var(--color-on-dark-soft);
line-height: 1.7;
margin: 0;
max-width: 42ch;
}
.interlude-link {
font-family: var(--font-body);
font-size: 14px;
font-weight: 500;
color: var(--color-primary);
text-decoration: none;
display: flex;
align-items: center;
gap: 8px;
transition: gap 0.2s;
}
.interlude-link:hover {
gap: 14px;
}
.link-arrow {
font-size: 16px;
}
.feature-img-wrap {
border-radius: 12px;
overflow: hidden;
aspect-ratio: 4/3;
}
.feature-img-wrap img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
transition: transform 0.5s var(--ease-out-quint);
}
.feature-img-wrap:hover img {
transform: scale(1.04);
}
.feature-tag {
font-family: var(--font-body);
font-size: 12px;
font-weight: 500;
letter-spacing: 2px;
text-transform: uppercase;
color: var(--color-on-dark-soft);
margin-top: 16px;
padding-left: 4px;
}
/* ── Dark wall ── */ /* ── Dark wall ── */
.dark-wall { .dark-wall {
@ -496,23 +812,45 @@ onUnmounted(() => {
letter-spacing: 3px; letter-spacing: 3px;
text-transform: uppercase; text-transform: uppercase;
color: var(--color-on-dark-soft); color: var(--color-on-dark-soft);
margin-bottom: 32px; margin-bottom: 16px;
padding-left: 4px;
} }
.dw-photos { .dw-photos {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(6, 1fr);
gap: 12px;
}
.dw-header {
display: flex;
align-items: center;
gap: 16px; gap: 16px;
margin-bottom: 32px;
}
.dw-index {
font-family: var(--font-body);
font-size: 11px;
font-weight: 500;
letter-spacing: 2px;
color: var(--color-primary);
} }
.dw-photo { .dw-photo {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
border-radius: 8px; border-radius: 8px;
aspect-ratio: 4/3; aspect-ratio: 3/4;
}
.dw-photo-inner {
width: 100%;
height: 100%;
overflow: hidden;
} }
.dw-photo img { .dw-photo-inner img {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: cover; object-fit: cover;
@ -595,6 +933,16 @@ onUnmounted(() => {
padding: 48px 16px; padding: 48px 16px;
} }
.bento-header {
flex-direction: column;
gap: 8px;
margin-bottom: 32px;
}
.bento-sub {
margin-left: 0;
}
.bento { .bento {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -602,20 +950,53 @@ onUnmounted(() => {
} }
.b-img-wrap, .b-img-wrap,
.b-lg .b-img-wrap, .b-a-main .b-img-wrap,
.b-tall .b-img-wrap, .b-a-side .b-img-wrap,
.b-tall-right .b-img-wrap { height: 260px !important; } .b-strip-item .b-img-wrap,
.b-c-wide .b-img-wrap,
.b-d-4grid .b-img-wrap,
.b-e-item .b-img-wrap {
height: 240px !important;
}
.b-zone-a,
.b-zone-b,
.b-zone-c,
.b-zone-d {
display: flex;
flex-direction: column;
gap: 12px;
}
.b-b-strip {
display: flex;
flex-direction: column;
gap: 12px;
}
.b-d-4grid {
display: flex;
flex-direction: column;
gap: 12px;
}
.b-zone-e {
display: flex;
flex-direction: column;
gap: 12px;
}
.b-f-quote {
padding: 32px 24px;
}
.b-note { min-height: 160px; } .interlude { padding: 48px 16px; }
.b-4grid { display: flex; flex-direction: column; } .interlude-grid { grid-template-columns: 1fr; gap: 32px; }
.b-col-2 .b-img-wrap, .interlude-heading { font-size: 32px; }
.b-col-2-bottom .b-img-wrap { height: 160px !important; }
.b-col-2 .mt-4,
.b-col-2-bottom .mt-4 { margin-top: 12px; }
.dark-wall { padding: 48px 16px; } .dark-wall { padding: 48px 16px; }
.dw-photos { grid-template-columns: 1fr 1fr; gap: 12px; } .dw-photos { grid-template-columns: repeat(2, 1fr); gap: 12px; }
.dw-photo { aspect-ratio: 1; } .dw-photo { aspect-ratio: 3/4; }
.site-footer { padding: 40px 24px; } .site-footer { padding: 40px 24px; }
.footer-grid { flex-direction: column; gap: 20px; } .footer-grid { flex-direction: column; gap: 20px; }

Loading…
Cancel
Save