diff --git a/.spec/specs/2026-10-24_add-blog-skeleton/tasks.md b/.spec/specs/2026-10-24_add-blog-skeleton/tasks.md index 17348ef..f0fd69c 100644 --- a/.spec/specs/2026-10-24_add-blog-skeleton/tasks.md +++ b/.spec/specs/2026-10-24_add-blog-skeleton/tasks.md @@ -35,10 +35,10 @@ - boundary: 只写 src/layouts/BaseLayout.astro 与 src/components/{Header,Footer,ThemeScript}.astro;导航 ≤4 项;页脚 ICP+built-from 槽位;inline 防闪烁脚本 - verify: `pnpm astro build && grep -q "陕ICP备2026014860号" dist/index.html` -- [ ] T6 五页型(首页/文章双模板/图库/瞬间/关于) +- [x] T6 五页型(首页/文章双模板/图库/瞬间/关于) - depends-on: task_0004, task_0005 - - claim: lane-pages(子代理,预留 src/components 与 src/pages 除 index 外路由) - - boundary: 只写页面与页面级组件(名片开场/分轨列表/书评衬线模板+引文组件/技术模板+TOC+进度条/图库 masonry+lightbox/瞬间时间线/关于含身份陈述空槽位);排版参数按报告 §3 + - claim: lane-pages(子代理)→ 超时由主会话收编 + - boundary: 只写页面与页面级组件(名片开场/分轨列表/书评衬线模板+引文组件/技术模板+TOC+进度条/图库 masonry+lightbox/瞬间时间线/关于含身份陈述空槽位);排版参数按报告 §3。豁免注记:sharp ^0.35.5 入 dependencies(supervisor 批复——Astro 7 不内置、照片管线设计依赖 astro:assets 缩略图,T1 骨架缺口) - verify: `pnpm astro build && test -f dist/archives/deng-dai-ge-duo/index.html -a -f dist/gallery/index.html -a -f dist/moments/index.html -a -f dist/about/index.html` - [ ] T7 极客层 P0(键盘+帮助/build-info/View Transitions/项目墙) diff --git a/package.json b/package.json index 9c4efd9..c3c1954 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@fontsource/noto-sans-sc": "^5.3.1", "astro": "^7.3.8", "exifr": "^7.1.3", - "lxgw-wenkai-screen-webfont": "^1.7.0" + "lxgw-wenkai-screen-webfont": "^1.7.0", + "sharp": "^0.35.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 19b4c18..aa10da9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: lxgw-wenkai-screen-webfont: specifier: ^1.7.0 version: 1.7.0 + sharp: + specifier: ^0.35.5 + version: 0.35.5 packages: @@ -1428,8 +1431,7 @@ snapshots: '@fontsource/noto-sans-sc@5.3.1': {} - '@img/colour@1.1.0': - optional: true + '@img/colour@1.1.0': {} '@img/sharp-darwin-arm64@0.35.5': optionalDependencies: @@ -2181,8 +2183,7 @@ snapshots: sax@1.6.1: {} - semver@7.8.5: - optional: true + semver@7.8.5: {} sharp@0.35.5: dependencies: @@ -2215,7 +2216,6 @@ snapshots: '@img/sharp-win32-arm64': 0.35.5 '@img/sharp-win32-ia32': 0.35.5 '@img/sharp-win32-x64': 0.35.5 - optional: true shiki@4.5.0: dependencies: diff --git a/scripts/check-responsive.sh b/scripts/check-responsive.sh index 12ade6c..dfbde7b 100644 --- a/scripts/check-responsive.sh +++ b/scripts/check-responsive.sh @@ -1,19 +1,20 @@ #!/bin/sh # 响应式结构自查(§4e):四档断点 + 触屏 44px + 安全区 + dvh 的静态断言 # 依据:docs/博客重设计调研报告.md §4e;断点 1120/820/760/560 +# 扫描用 -r 递归(src/pages 有子目录,一层 glob 会漏检 archives/gallery/moments) set -e cd "$(dirname "$0")/.." fail=0 check() { if eval "$2"; then echo " ok $1"; else echo " FAIL $1"; fail=1; fi } -CSS_SRC="src/styles/global.css src/components/*.astro src/layouts/*.astro" +DIRS="src/styles src/components src/layouts src/pages" check "断点 1120px(宽屏 TOC 常驻档)" \ - "grep -rqE 'max-width: ?1120px|min-width: ?1120px|@container' \$CSS_SRC src/pages/*.astro 2>/dev/null" + "grep -rEq '(max|min)-width: ?1120px|@container' $DIRS" check "断点 820px(笔电 TOC 收起档)" \ - "grep -rqE 'max-width: ?820px|min-width: ?820px' \$CSS_SRC src/pages/*.astro 2>/dev/null" + "grep -rEq '(max|min)-width: ?820px' $DIRS" check "断点 760px(平板竖屏档)" \ - "grep -rqE 'max-width: ?760px|min-width: ?760px' \$CSS_SRC src/pages/*.astro 2>/dev/null" + "grep -rEq '(max|min)-width: ?760px' $DIRS" check "断点 560px(手机档 + 正文降 18px)" \ "grep -rq 'max-width: 560px' src/styles/global.css" check "移动端降档:--prose-size 到 18px" \ @@ -24,8 +25,8 @@ check "安全区 env(safe-area-inset-*) 使用" \ "grep -rq 'safe-area-inset' src/styles src/components src/layouts" check "视口 viewport-fit=cover(刘海屏)" \ "grep -q 'viewport-fit=cover' src/layouts/BaseLayout.astro" -check "100dvh 或未使用视口高度陷阱(出现 100vh 即 FAIL)" \ - "! grep -rn '100vh' src/ ; true" +check "无 100vh 视口陷阱(属性值上下文;注释提及不算)" \ + "! grep -rEq ':\\s*100vh|100vh\\s*[;)]' src/ --include='*.astro' --include='*.css' && ! grep -rEq 'height:\\s*100vh|min-height:\\s*100vh' src/" check "动效总闸 prefers-reduced-motion" \ "grep -q 'prefers-reduced-motion: reduce' src/styles/global.css" check "构建产物含 viewport-fit 与主题色 meta" \ diff --git a/src/components/Avatar.astro b/src/components/Avatar.astro new file mode 100644 index 0000000..90b472b --- /dev/null +++ b/src/components/Avatar.astro @@ -0,0 +1,42 @@ +--- +// 名片头像占位:内联 SVG 渐变 60px;真实头像接入后整体替换本组件即可 +--- + + + + + + + + + + + + + w4 + + + + diff --git a/src/components/IdCard.astro b/src/components/IdCard.astro new file mode 100644 index 0000000..5e5b33c --- /dev/null +++ b/src/components/IdCard.astro @@ -0,0 +1,27 @@ +--- +// 名片区(首页/关于共用):渐变头像占位 + 称呼;图标行等内容由使用页经 slot 注入 +import Avatar from './Avatar.astro'; +--- + +
+ +
+

wait4x

+ + +
+
+ + diff --git a/src/components/PostList.astro b/src/components/PostList.astro new file mode 100644 index 0000000..af3f718 --- /dev/null +++ b/src/components/PostList.astro @@ -0,0 +1,137 @@ +--- +// 年份分组 + 轨道分节的文章列表(首页与 /archives/ 共用) +// 轨道标签单一事实源:content.config 的 POST_TRACKS,此处不另立词表 +import type { CollectionEntry } from 'astro:content'; +import { POST_TRACKS, trackOf, type PostCategory } from '../content.config'; + +interface Props { + /** 调用方已完成 draft 过滤与 pubDate 倒序 */ + posts: CollectionEntry<'posts'>[]; +} +const { posts } = Astro.props; + +const byYear = new Map[]>(); +for (const post of posts) { + const year = post.data.pubDate.getUTCFullYear(); + const bucket = byYear.get(year); + if (bucket) bucket.push(post); + else byYear.set(year, [post]); +} +const mmdd = (d: Date) => + `${String(d.getUTCMonth() + 1).padStart(2, '0')}-${String(d.getUTCDate()).padStart(2, '0')}`; +--- + +
+ {[...byYear.entries()].map(([year, list]) => ( +
+

{year}

+ {(Object.keys(POST_TRACKS) as PostCategory[]).map((cat) => { + const rows = list.filter((post) => post.data.category === cat); + if (rows.length === 0) return null; + return ( +