Files
blog/src/pages/moments/index.astro
T
wait4xandGLM-5.3 945a9ee610 feat(pages): 五页型落地——首页/文章双模板/图库 masonry/瞬间/关于
- 首页:名片+身份陈述空槽+按年分组分轨列表(情绪色/mono标签)+影像格+项目墙
- 文章 /archives/{slug}(与 Halo 旧 URL 1:1):reading→衬线纸墨 / tech→
  TOC 侧栏(≥1120 sticky)+2px 进度条+Artalk 容器占位
- 图库:grid masonry(构建期 aspect-ratio 零 JS)+原生 dialog lightbox
  (←→/Esc+EXIF 底栏)+分组筛选
- 瞬间时间线 / 关于(三轨版图+构建说明)
- sharp ^0.35.5 入依赖(Astro 7 不内置,astro:assets 缩略图管线前提)
- 裸 blockquote 默认吃 A 墨线样式(markdown 原生输出无类名的缝隙)
- 车道 30min 超时,产物完整,主会话补 sharp+断言脚本递归修正后收编

验证: pnpm astro build exit 0(7 页);五路由产物断言过;
      scripts/check-responsive.sh 11/11 ok(1120/820/760/560 全档)

Spec: 2026-10-24_add-blog-skeleton
Co-authored-by: GLM-5.3
2026-10-25 00:11:34 +08:00

143 lines
3.7 KiB
Plaintext

---
import { Image } from 'astro:assets';
import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
const moments = (await getCollection('moments')).sort(
(a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime(),
);
const iso = (d: Date) => d.toISOString();
---
<BaseLayout title="瞬间 · wait4x">
<h1 class="page-title">瞬间</h1>
<p class="page-note">零碎的记录:随手拍、一句话感想、开源动态。</p>
<ol class="tl">
{moments.map((m) => (
<li class="tl-item">
<time class="tl-date" datetime={iso(m.data.pubDate)}>
{iso(m.data.pubDate).slice(0, 10)}
</time>
<div class="mom-card">
{m.data.image && (
<figure
class:list={[
'mom-fig',
(m.data.image.width ?? 0) < (m.data.image.height ?? 0) && 'vt',
]}
>
<Image
src={m.data.image}
alt={m.data.text ?? m.data.tags.join(' ')}
widths={[480, 840]}
sizes="(min-width: 760px) 420px, calc(100vw - 140px)"
/>
</figure>
)}
{m.data.text && <p>{m.data.text}</p>}
{m.data.tags.length > 0 && (
<p class="mom-tags">
{m.data.tags.map((tag) => <code class="tag">{`#${tag}`}</code>)}
</p>
)}
</div>
</li>
))}
</ol>
</BaseLayout>
<style>
.page-title {
font-size: var(--text-h1);
line-height: var(--leading-heading);
color: var(--ink-1);
margin-top: var(--space-5);
text-wrap: balance;
}
.page-note {
font-size: 13px;
color: var(--ink-4);
margin-block: var(--space-1) var(--space-4);
}
.tl {
list-style: none;
margin: var(--space-4) 0 0;
padding: 0;
}
/* 时间线骨架:左 mono 日期 + 竖线 + --accent 节点 + 右侧内容卡 */
.tl-item {
position: relative;
margin: 0 0 var(--space-4) calc(var(--space-5) + var(--space-4));
padding-left: var(--space-4);
border-left: 1px solid var(--line);
}
.tl-item:last-child { margin-bottom: 0; }
.tl-item::before {
content: '';
position: absolute;
left: -5px;
top: 7px;
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--accent);
box-shadow: 0 0 0 3px var(--bg);
}
.tl-date {
position: absolute;
left: calc(-1 * (var(--space-5) + var(--space-4)));
top: 4px;
width: var(--space-5);
text-align: right;
font-family: var(--font-mono);
font-size: 12.5px;
color: var(--ink-4);
font-variant-numeric: tabular-nums;
}
.mom-card {
border: 1px solid var(--line);
border-radius: 12px;
padding: var(--space-3) var(--space-4);
background: var(--bg-soft);
}
.mom-card > p { font-size: 15px; color: var(--ink-2); }
.mom-fig {
border-radius: 8px;
overflow: hidden;
margin: 0 0 var(--space-2);
max-width: 420px;
}
.mom-fig.vt { max-width: 260px; }
.mom-fig :global(img) { width: 100%; height: auto; }
.mom-tags {
display: flex;
flex-wrap: wrap;
gap: var(--space-1);
margin-top: var(--space-2);
}
.tag {
font-family: var(--font-mono);
font-size: 12px;
color: var(--ink-3);
background: var(--bg);
border-radius: 5px;
padding: 1px 7px;
white-space: nowrap;
}
/* 窄屏:日期卡到卡片上方,竖线左移收窄 */
@media (max-width: 760px) {
.tl-item { margin-left: var(--space-3); }
.tl-date {
position: static;
display: block;
width: auto;
text-align: left;
margin-bottom: var(--space-1);
}
}
@media (max-width: 560px) {
.mom-card { padding: var(--space-2) var(--space-3); }
.mom-fig { max-width: 100%; }
}
</style>