Skip to content

Latest commit

 

History

History
550 lines (419 loc) · 39.7 KB

File metadata and controls

550 lines (419 loc) · 39.7 KB

首页编辑调整与船坞待办(2026-09-07,本地实现,未发布)

  • 首页改为 Hero → 本期重点 → 最新三篇文章 → 开源项目 → 船坞 → 页脚;替换技能展示和旧潮汐重复区块,保留 Hero、导航与已有视觉系统。
  • 本期重点服务端输出,采用人工双语类型配置;首期“让模型榜自己更新”明确标记尚待生产验证,不依赖模型 API 或动画加载。当前没有验收截图,使用文字版,不伪造榜单图片。
  • 近期文章使用普通响应式网格,保留原始发布日期;空列表省略区块。已验证截图配置要求证据,图片加载失败不影响文字和入口。
  • 定向验收:新增首页和编辑区块 8 项测试通过,相关文件 ESLint 通过;生产、全站构建、真实设备与浏览器视觉验收单独记录,不由单元测试替代。
  • 维护说明:首页编辑结构。未来实验与小游戏仅记录为未排期:船坞玩法待办
  • 边界:未提交、推送或部署;自动更新正式文案及真实截图必须等待后端生产定时任务验收后启用。

页脚外链纵向布局修复(2026-08-30,已完成并上线)

  • ✅ 根因:SiteFooter 外链容器使用 space-y-1,但两个链接是 inline-flex,导致 GitHub 与 Cloudborne 在同一行粘连。
  • ✅ 修复:将外链容器改为 flex flex-col items-start gap-1,保留两个链接各自的 min-h-11 触控高度与焦点样式。
  • ✅ 回归覆盖:SiteFooter.test.tsx 增加外链容器纵向布局 class 断言;外链地址、target、rel 与可访问名称保持不变。
  • ✅ 验证:本地定向 Vitest 通过;GitHub CI 33304467868 的完整测试、lint、TypeScript、production build 与 audit 通过;生产部署 workflow 33304527474 成功;git diff --check 通过。
  • ✅ 生产核对:Vercel deployment pier-blog-euq3t4sfl-jia-ethans-projects.vercel.app Ready 并 alias 到 https://ethanpier.com/zh/portfolio 返回 200,线上 HTML 已确认 flex flex-col items-start gap-1
  • ➖ 边界:本轮完成线上结构核对,未重复执行 Safari、真实设备与主观视觉验收。

博客内容改写与全站只读选择边界(2026-08-30,已完成并上线)

  • ✅ 24 篇 MDX(12 主题 × 中英)从教程/技术说明改写为第一人称随笔;slug 与 date 保留,性能文 updatedAt 改为 2026-08-30。
  • ✅ 去掉正文代码围栏与「测试环境」字段;系列改为「做这个站的时候 / 使用笔记」或留空;标签收成读者向词汇;博客列表、RSS、JSON-LD 介绍文案改为「工作、界面、等待和写作的观察」。
  • ✅ 全站 body.site-readonly-selection 默认禁止静态文案拖选,链接、按钮、输入框、滑杆、代码块和显式允许区域保持可用;博客正文原有 BlogProseGuard 继续负责复制边界。
  • ✅ 页脚移除 RSS — EnglishRSS — 中文 两个可见入口;/feed.xml/feed-zh.xml 服务端点及相关 RSS 能力保留,线上均返回 200 application/rss+xml
  • ✅ 验证:npm test 46 files / 327 tests、npm run lintnpx tsc --noEmitnpm run build 65 页、git diff --check 通过;GitHub CI 33303207224 与生产部署 workflow 33303271473 成功。
  • ✅ 交付:commits d5aef30cea74495c90585dada316734c9853d3e424439036075117423ed30b4fe7e4bdcd5631c9eeb1b61257f2c73307d673929ccd75867e337c1959 已推送到 origin/main;生产 deployment pier-blog-p3p87v8zo-jia-ethans-projects.vercel.app 已 alias 到 https://ethanpier.com
  • ✅ 线上核对:/zh/lab/en/lab/zh/blog/en/blog 均为 200,HTML 含 site-readonly-selection 且页脚无 RSS anchor;两个 RSS endpoint 仍为 200。
  • ➖ 边界:只读选择是降低公开内容复制便利度,不是加密或绝对防复制;源码、网络响应、截图、Reader Mode 与禁用脚本仍可取得公开内容。原文备份保留在仓库外 /Users/ethan/Documents/Codex/pier-blog-article-backups/20260830-essay-rewrite/

博客与 Cloudborne 导流优化(2026-08-28,已完成并上线)

  • ✅ 独立站入口:在 /zh/about/en/about 首屏介绍下加入低强调入口;在工作经历之后、联系我之前加入 Cloudborne 产品卡片;页脚加入外部链接。链接固定为 https://cloudborne.cn,新窗口打开并带 noopener noreferrer,不加入 UTM。
  • ✅ 导航边界:顶部主导航继续保持五项;Cloudborne 作为个人作品与产品延伸,不加入站内诗意栏目导航。
  • ✅ 页面级 SEO:为首页、About、Portfolio、Blog、Currents 补齐双语 metadata、canonical、en/zh/x-default hreflang、Open Graph/Twitter;Currents 补充 CollectionPage JSON-LD。
  • ✅ 内容与交互修复:博客 ?tag= 筛选可通过 URL 恢复;文章目录统一为中文「本文目录」与英文「Table of Contents」,移动端不可见目录同步 inert/aria-hidden;文章 JSON-LD 的 dateModified 与 frontmatter updatedAt 对齐。
  • ✅ 文章准确性:性能文章拆分 FID/INP 并补充 INP ≤200ms 阈值;AI 界面文章补齐 AbortControllerfetch(..., { signal })、reducer/imports 与示例边界说明。
  • ✅ 验证:npm test 通过(44 个测试文件、322 个测试),npm run lintnpm run buildgit diff --check 均通过;PR CI run 33141843457 成功。
  • ✅ 交付:PR #30(GitHub)已合并,merge commit 为 dec6817aed44e9f709dd54bf26d8498663fc96ca;生产部署 run 33141996900 成功,Vercel deployment pier-blog-d5ylngstu-jia-ethans-projects.vercel.app 已 alias 到 https://ethanpier.com
  • ✅ 线上技术核对:2026-08-28 /zh/about/en/about/zh/currents 均返回 HTTP 200,About 页面包含 Cloudborne 入口,Currents 页面包含 JSON-LD。
  • ➖ 验收边界:上述为代码、CI、部署和线上技术核对,不替代橋对桌面/移动端视觉、Safari/真实设备、键盘触控和业务转化的主观验收;未执行 Cloudborne 官网改动。
  • ➖ 后续范围:原方案 Phase 2/3 的主题页、系列索引、URL 筛选体系、文章上下文 CTA 与跨域点击观测尚未实现。

博客文章排版与卡片视觉优化(2026-08-26,已完成并上线)

  • ✅ 统一博客 MDX 与潮汐深度解读的正文排版 token,补齐标题层级、段落节奏、列表、引用、表格、代码、链接和窄屏溢出处理;卡片表面改为更稳定的双主题暖纸/深色层级。
  • ✅ 新增 CJK Markdown 强调修复,中文 **加粗** 不再把星号直接输出到页面;补齐 Markdown/MDX 回归覆盖。
  • ✅ 移动端文章目录改为抽屉交互:背景滚动锁定、Escape 关闭、焦点移入、Tab 循环与关闭后焦点恢复;主题切换移除会产生巨大黑色圆形遮罩的 root clip-path,改用受视口约束的淡入淡出并支持 reduced-motion 直切。
  • ✅ 验证:40 个测试文件、308 项测试、lint、TypeScript、production build 与 git diff --check 通过;Chrome 桌面主题切换与 390×844 移动端目录抽屉已复核。
  • ✅ 交付:PR #29,功能 commit 827c442(北京时间 2026-08-26),merge commit 4327579f1b266bed5433507768a156093305700f(GitHub 记录为 2026-08-25 23:52 UTC / 北京时间 2026-08-26 07:52);main CI 32912708238 与 production deploy 32912798073 成功,Vercel deployment pier-blog-4vp6jrhme-jia-ethans-projects.vercel.app Ready 并 alias 到 ethanpier.com
  • ➖ 验收边界:线上文章页返回 200 且 x-vercel-cache: HIT;正式站技术验证不替代 Safari、真实设备与主观视觉验收。

首页 Hero 与第二屏背景过渡(2026-08-24,已完成并上线)

  • ✅ 根因:Hero 在 100vh 边界裁切独立光场,并用不透明的站点底色渐变收尾;进入使用 fixed ambient background 的第二屏时,两套背景在同一水平线硬切。
  • ✅ 实现:将 Hero 光场拆为锁定 100vh 的画布与约 30vh 的共享尾段,通过 CSS mask-image 做 alpha 渐隐;静态降级背景移除实色底,过渡层不增加页面高度、不拦截交互。
  • ✅ 回归修复:Hero 仅开放纵向溢出,横向继续使用 overflow-x: clipprefers-reduced-motion 下停止滚动关联的背景缩放,避免移动端横向滚动和减弱动效回归。
  • ✅ 验证:本地 37 个测试文件、281 项测试、lint、TypeScript、51 页 production build、audit 0 与 git diff --check 通过;PR CI 32711828818 与 main CI 32712020216 成功。
  • ✅ 交付:PR #27,功能 commit 9dc724ca332e2f478397fc3f54673da27b94b730,merge commit 1445fc61a88ef49b6cd9df99ad4c71938cdaeef8;deploy run 32712116429 成功,Vercel deployment pier-blog-9wxd1v2ux-jia-ethans-projects.vercel.app Ready 并 alias 到 ethanpier.com
  • ✅ 生产技术验收:/zh/en 返回 200,www.ethanpier.com/zhpier-blog.vercel.app/zh 正确 308 到 canonical;Chrome 390x844 实测 clientWidth=384scrollWidth=384scrollX=0,Hero、过渡层与第二屏样式均已上线。
  • ➖ 验收边界:本轮完成 Chrome 桌面/移动技术验证,不等于橋的主观视觉验收;Safari 真机、真实设备帧率与完整 Lighthouse 仍按既有 Phase 9 清单独立保留。

Phase 11: 网站与服务器安全加固

Tailscale 自定义 OIDC WebFinger(2026-08-17,已完成并上线)

  • ✅ 新增固定 JRD 端点 /.well-known/webfinger,将 acct:ethan@ethanpier.com 映射到 Auth0 issuer;Issuer 与 Auth0 /.well-known/openid-configuration 精确一致。
  • ✅ 端点使用 application/jrd+json、5 分钟公开缓存与 CORS,只发布发现元数据;Client ID、Client Secret、密码和 Token 均不进入仓库或项目文档。
  • ✅ 防索引边界同步扩展到 WebFinger:正式端点返回 X-Robots-Tag: noindex,不影响 Tailscale 读取。
  • ✅ 验证:33 个测试文件、265 项测试与 51 页 production build 通过;GitHub Actions validateauthorizedeploy 均成功;最终自动部署 pier-blog-134t3vk2v-jia-ethans-projects.vercel.app Ready 并 alias 到 ethanpier.com
  • ✅ 生产验收:https://ethanpier.com/.well-known/webfinger 返回 200 与有效 JRD;Auth0 回调和 Tailscale OIDC 登录已打通,新 Tailnet ethanpier.com 创建成功。
  • ➖ 2026-08-17 注册后显示 Enterprise trial;这是可漂移的计费状态,不影响账号或域名持续存在。Tailnet 尚未接入设备,后续可按个人非商业用途另行选择 Personal 方案。

潮汐模型榜(2026-08-13,已完成并上线)

  • ✅ 五类榜单:综合/编程/Agent/推理/性价比,正式发布与 Preview 独立视图;双语 /currents/models(SSG 壳 + 客户端数据岛)。
  • ✅ 模型详情页 /currents/models/[slug]:ISR 300s + 运行时契约守卫 + 404/可重试错误边界;官方信息、各类别名次与历史迷你曲线、来源分项、价格说明、别名清单。
  • ✅ 方法页 /currents/models/methodology:收录规则、评分/可信度/性价比公式(与后端 mlv1 冻结参数一致)、六来源登记、当前参数与待审核计数。
  • ✅ 接入面:CurrentsShell 主导航「模型榜」、搜索索引、静态 sitemap(双语)、canonical/hreflang/metadata、i18n 新增 97 组中英文案。
  • ✅ 验证:测试 +13(32 个测试文件 264 项)、lint 0 error、TypeScript、50 页 production build 通过。
  • ✅ 交付:PR #18,merge commit 7e6617f;PR CI 31715972710、main CI 31717663112、production deploy 31717796886 均成功;正式站 /zh/currents/models 返回 200,sitemap 已含 models 条目。

Currents 桌面筛选栏滚动折叠修复(2026-08-13,已完成并上线)

  • ✅ 根因:展开筛选区与紧凑工具栏共用一个 sticky 容器,折叠时高度约 105px → 56px,实际滚动 22px 会让正文额外跳动约 49px;单阈值检测与被中断的布局动画进一步放大临界点抖动。
  • ✅ 修复:展开区保留普通文档流并自然滚出,紧凑栏改为零高度 sticky overlay;折叠 marker 移到完整展开区之后,并加入 32px 滞回,切换不再改变正文布局高度。
  • ✅ 交互:桌面「更多筛选」补齐 Escape、点击外部、跨 1280px 断点与恢复展开态关闭,退出期同步 inert / aria-hidden 并恢复触发按钮焦点。
  • ✅ 验证:29 个测试文件、238 项测试、lint、TypeScript、46 页 production build 与 git diff --check 通过;浏览器复核 marker/nav 阈值与滞回符合预期,未发现新的实现级问题。
  • ✅ 交付:commits 09ae43d / 5700daf;main CI 31676427400、production deploy 31676514210 与 GitHub production deployment 5883533060 均成功;Vercel deployment pier-blog-egig3bfu6-jia-ethans-projects.vercel.app Ready 并 alias 到 ethanpier.com
  • ✅ 收尾:更新公开双语更新日志,并拆分 sitemap 的 changelog/Agent/Feedback lastmod,避免更新日志变化误报未改页面的更新时间。
  • ✅ 文档部署:收尾 commit 41ae3be 已推送;main CI 31677850065、production deploy 31677950964 与 GitHub production deployment 5883786075 均成功,Vercel deployment pier-blog-61pmwewxk-jia-ethans-projects.vercel.app Ready;正式站双语更新日志与 sitemap 已复验为 200。部署证据回填 commit 0949a3c 的 CI 31678366704 成功,deploy workflow 31678447155 按预期跳过无可部署变更。
  • ➖ 验收边界:正式站 /zh/currents?view=all 返回 200;本地真实长列表曾受数据 API 报错限制,未把单次本地数据状态当作完整业务验收。

依赖维护(2026-08-13,已完成并上线)

  • ✅ 将 Vitest 3.2.7 → 4.1.10 与 next-intl 4.13.4 → 4.13.5 合并为 PR #17,最终范围仅为 package.jsonpackage-lock.json;原 Dependabot PR #9、#10 已关闭。
  • ✅ 验证:29 个测试文件、227 项测试、TypeScript、46 页 production build、audit 0、git diff --check 通过;lint 0 error(2 个既有 warning)。
  • ✅ 交付:merge commit 554b940;PR CI 31658307844、main CI 31658523093、production deploy 31658586428 与 GitHub production deployment 5880393475 均成功;正式站关键路由返回 200。
  • ➖ Vitest 配置的 ESM 前瞻提示与 next-intl setRequestLocale 弃用迁移不阻塞当前版本,后续分别处理;主仓本地环境已于 2026-08-14 对齐:Node 22.23.2(brew keg-only node@22,全局 Node 25 不动)下完成 npm ci,audit 0 漏洞;FluidSim 未使用导入清理后 lint 0 error / 0 warning,264/264 测试与 production build 通过。

Phase 11A:安全事务升级(2026-08-11,已完成并上线)

  • ✅ 应用边界:Markdown 协议边界、生产 sanitizer 依赖、强制 CSP 与同源报告端点。
  • ✅ 依赖与工具链:Node 22.23.1 / npm 10.9.8、标准 npm ci、本地精确 Vercel CLI、完整 audit 0 漏洞。
  • ✅ CI/CD:PR/main CI 与 production deploy 分离,Environment Secret、同 SHA门禁、文档-only 跳过、--archive=tgz
  • ✅ 仓库安全:Actions 仅 GitHub-owned + SHA pinning;前后端 Dependabot;后端/MCP 持续 audit。
  • ✅ Cloudflare:完整 4 条 DNS 盘点;Always Use HTTPS、TLS 1.2/1.3;HSTS includeSubDomains=false
  • ✅ Vercel:Project Node 由 24.x 统一为 22.x
  • ✅ 最终代码与部署门禁:前端 CI 31484988819、部署 31485088215、deployment dpl_GyeRS81zD6QPxZmfYb1FwxHGZ44X、后端/MCP CI 31484031774 均成功;生产 alias 为 ethanpier.com
  • ✅ 线上与浏览器验收:14 个路由 200;强制 CSP 与报告端点、4 个 Canvas、主题往返、Currents 数据、Agent 复制、Giscus、API/MCP、HTTP→HTTPS、HSTS 与 TLS 协议边界均通过。
  • ✅ 仓库与本地收尾:前端 main-protection ruleset 已启用;仓库级 Vercel Secret 已删除;6 个历史 Token 值从 4 个 Pi JSONL 原子化脱敏;Git 不可达敏感对象与任务临时环境已清理。
  • ℹ️ 后续状态:另一 Cloudflare 身份下的残留 Token 已由橋撤销;Phase 11B 及后续任务未复验该外部状态。
  • ✅ 闭环记录:文档提交 5633dd2;CI 31489111025 成功;docs-only deploy workflow 31489223884authorize 成功、deploy 跳过,未产生额外生产部署。

Phase 11E P1:原创正文复制阻力(2026-08-12,已完成并上线)

  • ✅ 仅保护中英文博客 MDX 正文;Currents、Agent、反馈、搜索、导航、Lab 与 Portfolio 不受影响。
  • ✅ 普通正文选择、复制与右键增加阻力;代码块、链接、表单、有效 contenteditable 与 [data-copy-allow] 保持可用。
  • ✅ 修复完整 selectNode 允许区域被误阻止、contenteditable="false" 穿透及嵌套编辑边界;补齐代码块 Clipboard 失败降级和表单回归。
  • ✅ 验证:29 个测试文件、227 项测试、TypeScript、46 页 production build、audit 0、git diff --check 通过;lint 0 error(2 个既有 warning)。
  • ✅ 交付:PR #14,merge commit 2e732bc;PR CI 31585724257、main CI 31585892119、production deploy 31586012037 均成功,deployment pier-blog-m491kqy8y-jia-ethans-projects.vercel.app 已 alias 到 ethanpier.com
  • ✅ 生产低频复验:中英文博客文章、Currents、Agent 与反馈入口均为 200;文章 HTML 包含复制边界标记与双语提示。
  • ➖ 定位为复制阻力,不保证公开内容不可复制;SEO、RSS、浏览器查找、屏幕阅读与开发者工具边界不变。

后续阶段:Tailscale 新 Tailnet 首台设备接入;服务器 SSH/防火墙/更新/备份恢复/运行权限审计;CSP nonce/hash 与 Trusted Types 增强。


Phase 1: 核心动效引擎 ✅

已完成的功能

1. Lenis 平滑滚动

  • ✅ 丝滑的滚动体验(1.2s duration + easeOutExpo)
  • ✅ 与 GSAP ScrollTrigger 完美同步
  • ✅ 自动管理生命周期

2. 自定义光标系统

  • ✅ 双层光标(延迟跟随外圈 + 即时跟随内点)
  • ✅ 磁性效果(悬停可点击元素时放大)
  • ✅ mix-blend-mode 实现跨主题适配
  • ✅ 移动端自动禁用

3. 性能监控

  • ✅ 实时 FPS 计数器
  • ✅ 开发环境专属(生产环境自动隐藏)
  • ✅ Shift+P 快捷键切换显示
  • ✅ 颜色编码性能警示(绿/黄/红)

4. GSAP 工具函数库

  • fadeInUp() - 淡入上升动画
  • scrollFadeIn() - 滚动触发淡入
  • parallax() - 视差滚动
  • magneticEffect() - 磁性吸附
  • pinSection() - 分段钉住
  • flip() - FLIP 动画辅助
  • splitText() - 文字逐字符动画

5. 全局样式增强

  • ✅ View Transitions API 支持
  • ✅ 液态按钮效果类(.liquid-button)
  • ✅ 磁性交互辅助类(.magnetic)
  • ✅ GPU 加速优化类(.gpu-accelerate)
  • ✅ 粒子轨迹容器预留
  • ✅ 自定义光标全局启用(移动端降级)

技术栈

  • Lenis 3.x - 平滑滚动引擎
  • GSAP 3.15 + ScrollTrigger - 动画核心
  • View Transitions API - 页面转场
  • React 19 + Next.js 15 - 框架支持

测试方法

  1. 启动开发服务器:npm run dev
  2. 访问 http://localhost:3000
  3. 观察:
    • 光标变为自定义样式(外圈 + 内点)
    • 滚动体验极其丝滑
    • 悬停链接/按钮时光标放大
    • 按 Shift+P 显示 FPS 监控

下一步:Phase 2

准备实现页面转场与流体动画:

  • 文章卡片到全文的变形飞行
  • 导航切换的创意过渡
  • 液态按钮与卡片悬停
  • 页面滚动分段动画

构建时间:约 30 分钟 状态:✅ 已完成并验证


Phase 2: 页面转场与流体动画 ✅

已完成的功能

1. View Transitions 页面转场

  • ✅ TransitionLink 组件(View Transitions API + 修饰键/不支持时降级)
  • ✅ Navbar 与首页 CTA 全部接入转场链接
  • ✅ BlogCard 点击进入文章页平滑过渡

2. 卡片流体动画

  • ✅ AnimatedCard:入场淡入上升 + 鼠标 3D 倾斜(elastic 回弹)
  • ✅ BlogCard 已包裹 3D 悬停效果

3. 液态按钮

  • ✅ LiquidButton 组件(鼠标入点液态扩散填充)
  • ✅ 首页主 CTA 按钮应用 liquid-button 效果类

4. 磁性交互

  • ✅ MagneticWrapper 组件(封装 Phase 1 magneticEffect)
  • ✅ Navbar Logo 与首页 CTA 磁性吸附

5. 滚动动画系统

  • ✅ ScrollReveal:ScrollTrigger 驱动的方向性滚动显示(支持 stagger)
  • ✅ ScrollProgress:文章页顶部渐变阅读进度条(RAF 节流)
  • ✅ 文章页 header 与正文分段进场

验证

  • npm run build 通过(TypeScript 严格检查通过)
  • 全路由运行时 200(/ /blog /blog/[slug] /about /showcase)
  • 修复:LiquidButton 联合 ref 类型导致的 addEventListener 类型错误

下一步:Phase 3

WebGL 视觉系统(3D 粒子星空、Shader 渐变、3D 卡片堆叠)


Phase 3: WebGL 视觉系统 ✅

已完成的功能

1. WebGL 能力检测与性能降级(src/lib/webgl/

  • capabilities.ts:context 探测(结果缓存)+ prefers-reduced-motion + 设备分级(deviceMemory / hardwareConcurrency / pointer 启发式,high/medium/low)
  • ✅ 分级输出统一渲染参数:dpr(high 最高 2,其余 1)、particleMultiplier(1 / 0.6 / 0.35)、mouseInteraction(触控设备关闭)
  • enabled = webglSupported && !reducedMotion && tier !== 'low':false 时组件不创建 WebGL context,渲染静态 CSS 降级背景
  • useWebGLQuality() hook:SSR 返回 null(兼作水合门),响应 reduced-motion 实时变化
  • visibility.ts 渲染门控:IntersectionObserver + visibilitychange,canvas 视口外/标签页隐藏时暂停 RAF,恢复时时间累积不跳变

2. 存量 WebGL 组件接入降级与门控

  • ✅ Galaxy / Particles / Aurora 全部接入 observeRenderGate(视口外零 GPU 开销)
  • ✅ Galaxy 新增 dpr prop;Particles 用 pixelRatio + 粒子数缩放
  • ✅ ImmersiveHero / HeroBackground:不可用时渲染 StaticHeroFallback(纯 CSS:深色径向渐变+静态星点 / 浅色暖陶土渐变)
  • ✅ SkillsShowcase 卡片内 demo:降级为静态渐变块

3. Shader 渐变(新组件)

  • webgl/ShaderGradient.tsx:单三角形全屏 simplex 噪声域扭曲流体渐变,三色插值+呼吸高光,自带渲染门控
  • webgl/FluidBackground.tsx:主题感知包装(深色蓝紫/浅色暖陶土)+ 完整降级链
  • ✅ 接入 /blog 头部(低强度氛围背景)与 /showcase 演示区

4. 3D 卡片堆叠(新组件)

  • webgl/CardStack3D.tsx:透视堆叠(缩放/下移/变暗),顶层卡点击或拖拽飞出循环,reduced-motion 时简单切换
  • ✅ 接入 /showcase Card Interactions 区

5. 全局 reduced-motion 体系

  • ✅ globals.css:prefers-reduced-motion 时压缩所有过渡/动画时长、恢复默认光标
  • ✅ Lenis:reduced-motion 时不接管滚动(保留原生)
  • ✅ CustomCursor:reduced-motion 时禁用

6. 水合一致性重构

  • ✅ ImmersiveHero / SkillsShowcase / HeroBackground / FluidBackground 的 useEffect(setMounted) 水合门统一改用 useWebGLQuality() 返回值(null = 未挂载),消除 react-hooks/set-state-in-effect 告警

降级矩阵

条件 行为
WebGL context 创建失败 静态 CSS 背景,零 canvas
prefers-reduced-motion 静态背景 + 全局动画压缩 + 原生滚动/光标
低端设备(≤2GB 或 ≤2 核) 静态背景
中端设备(触控 / ≤4GB / ≤4 核) dpr=1,粒子 ×0.6,关闭鼠标交互
canvas 视口外 / 标签页隐藏 暂停 RAF,恢复时时间连续

验证

  • npm run build 通过(TypeScript 严格检查通过)
  • Phase 3 相关文件 ESLint 全部通过(存量 LiquidButton/MDXContent/ScrollProgress/ThemedGradientText/TransitionLink 的旧告警不在本次范围)
  • 生产构建运行时全路由 200(/ /blog /blog/[slug] /about /showcase),/showcase 已渲染 ShaderGradient 与 CardStack3D

下一步:Phase 4(待定)

候选:存量 lint 告警清理、移动端体验打磨、Lighthouse 性能基线、真机验收


遗留问题清理 ✅

已完成

1. ESLint 全部清零(npx eslint src 无任何告警/错误)

  • ✅ TransitionLink:[key: string]: any → 继承 ComponentProps<typeof Link>(document as any).startViewTransition → 直接调用(@types/dom-view-transitions 已提供类型)
  • ✅ LiquidButton:联合 ref + as any → 拆分为 anchorRef/buttonRef 两个独立 ref
  • ✅ MDXContent:(child: any) → 类型谓词收窄 child is { type: "text"; value: string }
  • ✅ ScrollProgress:移除未使用的 gsap 导入
  • ✅ ThemedGradientText:useEffect(setMounted)useSyncExternalStore 水合门(无 setState-in-effect)

2. 废弃依赖清理

  • ✅ 移除 @studio-freight/lenis(代码只导入新包名 lenis,package.json / package-lock.json 均已无引用)

验证

  • npx eslint src 全通过(0 error / 0 warning)
  • npm run build 通过
  • 生产构建运行时全路由 200(/ /blog /about /showcase)

仍未触及(需真实环境)

  • 真机低端设备降级路径实测
  • Lighthouse 性能基线
  • 移动端体验打磨

Phase 4: 极端微交互 ✅

详见 PHASE4-PLAN.md。核心交付:

  • 主题切换圆形扩散(View Transitions + clip-path,从 ThemeToggle 按钮中心,reduced-motion 降级直切)
  • RippleProvider 全局涟漪(事件委托 pointerdown,超大区域/data-no-ripple 跳过)+ 按压形变
  • TableOfContents 果冻高亮(motion layoutId)+ Lenis.scrollTo 平滑锚点
  • Navbar 弹性下划线(layoutId 跨链接滑动)
  • SpotlightCard useSpring 弹簧聚光灯
  • HorizontalArticles 触控关视差;ProjectsBento 触控 tap 高亮

Lighthouse 桌面首页基线(docs/lighthouse/desktop-home.json): Performance 97 / A11y 95 / BP 100 / SEO 100;LCP 0.9s / CLS 0.014 / TBT 120ms / TTI 1.0s

提交:71ce191,已推送并部署。


Phase 5: 实验性布局 ✅

详见 PHASE5-PLAN.md。核心交付:

1. 经历横向滚动叙事(ExperienceJourney)

  • 桌面端:sticky 钉住 + 竖向滚动驱动卡片横移(useScroll + useSpring 惯性)
  • SVG 波浪路径随滚动进度绘制(motion pathLength)
  • 顶部进度指示点(当前卡拉长高亮),背景大字年份装饰
  • 降级:移动端 / 触控 / reduced-motion → 传统竖向时间线(whileInView 淡入)
  • 接入 /about 替换原 Experience 区块

2. Hero 三层视差(FloatingShapes)

  • 前景浮动几何层(ring/dot/cross/triangle 六个 SVG 形状)
  • 滚动速度快于标题(-220~-340px vs 标题 -120px),制造纵深
  • idle 浮动动画错峰;低端设备 / 触控 / reduced-motion 不渲染(quality gate)

3. FlipCard 3D 翻转卡片

  • 点击翻转 rotateY 180°(preserve-3d + backface-visibility)
  • 键盘可达(button + aria-pressed),data-no-ripple 避免涟漪冲突
  • reduced-motion 时无旋转直切
  • 接入 /showcase Card Interactions 区(正面预览/背面代码片段)

未实现(主动裁则)

  • Blog 文章页分段钉住:与长文阅读体验冲突,放弃

验证

  • npx eslint src 全通过(0 error / 0 warning)
  • npm run build 通过
  • 生产构建运行时全路由 200;/showcase 渲染 FlipCard,/about 渲染时间线内容

下一步:Phase 6

数据可视化(D3.js、Sandpack、雷达图)


Phase 6: 数据可视化 ✅

详见 PHASE6-PLAN.md。核心决策:零新增依赖(评估后放弃 D3.js 与 Sandpack,SVG + motion 自绘)。

1. SkillRadar 技能雷达图(viz/SkillRadar.tsx)

  • 六维雷达(Frontend/Motion/AI/Engineering/Design/Performance)
  • 数据多边形从中心弹性展开(spring scale),顶点 stagger 淡入
  • hover 顶点显示 tooltip;颜色全走 CSS 变量自动适配双主题
  • reduced-motion 无动画直接显示;接入 /about

2. BlogStatsFilter tag 条形图 + 过滤(viz/BlogStatsFilter.tsx)

  • 按 tag 聚合文章数,横向条形弹性伸长入场(stagger)
  • 点击条形客户端过滤文章;AnimatePresence popLayout 平滑重排
  • 替换 /blog 原静态列表;传入前裁剪 content 字段(不把全文送到客户端)

3. ActivityHeatmap 活动热力图(viz/ActivityHeatmap.tsx)

  • GitHub 风格 26 周格子;文章发布日固定最高强度,其余确定性伪随机(同日同值,无水合问题)
  • 颜色用 color-mix + --accent 透明度阶梯,双主题自动适配
  • hover 显示日期与强度;接入 /about

4. i18n

  • 新增 about.radarTitle / about.activityTitle / blog.allTag(en/zh)
  • About 页改为 async server component(getTranslations + getAllPosts)

主动裁则

  • Showcase 代码演练场:FlipCard 模式(Phase 5)已覆盖此需求,不引入 Sandpack

验证

  • npx eslint src 全通过;npm run build 通过
  • 全路由 200;/about 英文渲染 Skill Radar / Writing Activity,中文渲染技能雷达/写作活跃度;/blog tag 聚合数据 SSR 正常

下一步:Phase 7

AI 增强(语义搜索、AI 摘要)


Phase 7: AI 增强 ✅

详见 PHASE7-PLAN.md。核心决策:新增唯一依赖 flexsearch(~8KB gzip),拒绝运行时 LLM API(静态零密钥架构)。

1. FlexSearch 全文搜索

  • lib/search.ts:MDX → 纯文本索引数据(去 frontmatter/import/markdown 标记,截 800 字符)
  • /api/search-index:force-static 双语索引端点(en+zh 共 ~11KB)
  • SearchModal:⌘K/Ctrl+K 唤起,懒加载 flexsearch + 索引 JSON, 标题/描述/标签/正文联合搜索,关键词高亮,↑↓+Enter 键盘导航, 最近搜索(localStorage ×5),无结果兼容热门 tag 兕底
  • 接入 Navbar(带 ⌘K 提示按钮)

2. 相关文章推荐

  • getRelatedPosts:tag 交集 ×10 + 日期接近度(同年+2/相邻年+1)打分,最多 3 篇
  • 文章页底部「相关阅读」区(至少 1 篇时显示)

3. i18n

  • 新增 search.*(6 条)与 blog.related(en/zh)

主动裁则

  • 构建时 AI 摘要:需在 CI 引入 LLM API key(与零密钥架构冲突), 且现有手写 description 质量已足,收益为负,裁掉
  • 向量语义搜索:需运行时 API,同理裁掉;FlexSearch fuzzy 前缀匹配已覆盖实际需求

验证

  • npx eslint src 全通过;npm run build 通过(/api/search-index 静态生成)
  • 全路由 200;索引端点 en/zh 各 3 篇、总 11KB(目标 <100KB)
  • 文章页渲染 Related Reading;Navbar 渲染 ⌘K 搜索按钮

下一步:Phase 8

性能优化与打磨(八阶段收官)


Phase 8: 性能优化与打磨 ✅(八阶段收官)

性能优化(移动端 74 → 90)

1. WebGL 懒加载(ogl 移出首屏主 chunk)

  • ImmersiveHero / HeroBackground / SkillsShowcase 中的 Galaxy/Aurora/Particles 全部改 next/dynamic + ssr: false(它们本就客户端挂载后才渲染)
  • 效果:TBT 390ms → 40ms,FCP 2.4s → 0.9s,bootup 主线程脉冲消失

2. LCP 修复(标题 SSR 可见渲染)

  • Hero 主标题水合前占位从 opacity-0 改为可见文本
  • 原问题:LCP 被推迟到 JS 挂载 + 逐字动画完成(移动端 4.5s)
  • 效果:LCP 4.5s → 3.6s(剩余成分是字体加载,已有 display:swap)

3. Lighthouse 最终基线(docs/lighthouse/)

Performance LCP TBT CLS
Desktop 100 0.7s 0ms ~0.01
Mobile 90 3.6s 40ms 0.022

打磨修缮

  • ✅ Footer 年份:硬编码 2024 → new Date().getFullYear()(5 处)
  • ✅ 文章页/横向画廊日期 locale:硬编码 en-US → 跟随 next-intl locale(zh → zh-CN,实测「2024年3月」)
  • ✅ README 重写:create-next-app 模板 → 项目实态(亮点/技术栈/性能表/开发指引)

验证

  • ESLint 0/0;build 通过;全路由 + /api/search-index 200
  • 动态年份渲染 2026;中文日期格式生效

八阶段全部完成 🎉

Phase 1 动效引擎 → 2 转场流体 → 3 WebGL → 4 微交互 → 5 实验布局 → 6 数据可视化 → 7 搜索/推荐 → 8 性能收官

待真机验收:移动端交互手感、WebGL 分级参数、主题扩散视觉效果


Phase 9: 视觉技术力升级 ✅(实现完成,真机验收未完)

已完成

  • ✅ Hero 粒子重组标题:WebGL 粒子采样、碎裂聚合、鼠标斥力、滚动散开、主题配色与完整降级链
  • /en/lab/zh/lab:6 个零依赖手写 Demo,双语 SSG 并进入 sitemap
  • ✅ Lab 首页引流带、WebGL context 门控与 reduced-motion 静态降级
  • ✅ 粒子采样、首帧白字闪现、FluidSim 黑屏等实现问题已修复并上线
  • ✅ 原计划的菲涅尔球和 WaveGrid 曾完成,后续按 Phase 10.1 视觉减法决策移除,不再是验收目标

仍待真机验收

  • 375px 中文/英文换行与 ParticleGate 首帧观感
  • Hero 聚合、Lab 六个 Demo 的交互手感与 WebGL context 上限
  • Safari 流体模拟、reduced-motion 全链路降级
  • Lighthouse 复测与真实设备帧率

详细实现与验收边界见 PHASE9-PLAN.md


Phase 10.1–10.9: 视觉减法、签名系统与性能打磨 ✅

  • ✅ 视觉减法与中文字体系统
  • ✅ accent 降频、卡片点阵、Pier 品牌字标/符号、代码块与阅读进度条
  • ✅ Lab 玻璃态最终采用 shader 内折射,移除导致软件光栅化的 SVG reference filter
  • ✅ 全站卡片玻璃表面、WebGL DPR/低端 blur 分级与 ambient 呼吸光晕
  • ✅ 生产部署完成;Phase 10.9 的真机观感已通过
  • ⏳ Phase 10.1 的 Hero、字体、背景强度、技能卡 hover 和分隔线仍与 Phase 9 合并做一次真机验收

Currents 集成状态(2026-08-11)

  • ✅ Phase 0–7、批次 2、事件基础、独立事件页、详情 hardening、24h 热度曲线与完整事件 sitemap 已上线
  • ✅ 阶段 A:资讯/事件详情页内容反馈入口(现名「报告内容问题」)+ POST /v1/feedback 已上线并完成生产验收
  • ✅ 阶段 B:五工具只读 MCP Server + Agent Skill 已实现、部署并完成生产验收(服务端;受邀凭据 tools/list 与五工具实调已于 2026-08-11 复验)
  • ✅ 阶段 C:Currents 统一产品外壳(常驻左侧导航 + 移动端抽屉)、/currents/agent Agent 接入页、/feedback 全局产品反馈页(后端 targetType=site + 迁移 011)、多类型全站搜索(博客/功能页/主题,功能页关键词优先)已上线并完成生产验收(PR #2、Vercel run 31449399427、commit 209cf97;后端 PR #1、镜像 currents-api:feedback-site-20260811-b8e67b7
  • ✅ SG2 运维事故已恢复;页面 200、API health 200、MCP 未授权 401 为当前复验基线(2026-08-11 阶段 C 部署后复验通过)
  • ⏳ 客户端真实接入仍待逐一核验:Codex、Claude Code、佳等具体客户端需核验配置持久化、工具发现与五工具调用(服务端已部署 ≠ 客户端已接入;受邀凭据发放后逐客户端验收)
  • 阶段 C 回滚点:后端镜像 currents-api:feedback-20260810-bd31fc5 + 数据库备份 /opt/currents/backups/pre-fb-site-20260811T013149Z.db;前端 Vercel 上一部署(run 31400949712,commit c511e23)

Currents 响应式与动效统一修复(2026-08-11,已部署 PR #3 基线)

  • ✅ 外壳统一为 1760px 自适应编辑工作台,Navbar/CurrentsShell/SiteFooter 同一轴线(--currents-shell-max
  • ✅ 侧栏仅 ≥1280px 显示(224px),1024–1279px 保持全宽正文,消除 1024px 临界断崖
  • ✅ 移动端以「潮汐 · 当前页」文字产品导航替换第二个汉堡;筛选器桌面滚动收缩单行工具栏、移动端吸顶极简栏 + 底部面板
  • ✅ 新增 --currents-surface-* 语义表面变量(浅色暖纸层级 / 深色同步);已读态改局部标记 + 左边框,不再整卡 opacity
  • ✅ 今日要闻重构为主故事 7/12 + 右侧 2×2 次要卡(容器查询驱动),消除主卡内部空白
  • ✅ 站内导航全面恢复 TransitionLink/View Transitions;GSAP/Lenis 单一驱动循环未动;删除遗留 currents-fade-in/currents-slide-in keyframes
  • ✅ 验收:test 91 过 / lint 0 error / build 通过;生产 9 视口(375–2560)无横向溢出、2560px 壳 1760px、移动端吸顶 56px、桌面收缩栏 52–60px
  • 交付:PR #3、merge commit 5361594、生产部署 pier-blog-9eixpss8u-jia-ethans-projects.vercel.app
  • 前端回滚点:合并前 main commit b9c5648 + 上一生产部署 pier-blog-e2tbza2sc-jia-ethans-projects.vercel.app
  • ➖ OpenAPI 与公共 REST API 产品化不在当前范围;反馈管理继续使用服务器 CLI;Agent 接入为受邀开放,不做自助 Token

PR #3 Review 后续修正(已部署,待浏览器验收)

  • ✅ 修复 query-only 导航等待超时、重复 destination 误启动转场,以及 reduced-motion 动效降级
  • ✅ 修复 1280–1535px 内容宽度断崖、1760px gutter 跳变,并让 Navbar、筛选器与侧栏统一消费实际导航高度
  • ✅ 修复移动端筛选面板的焦点圈、背景隔离、滚动锁、Esc、焦点恢复与跨断点关闭
  • ✅ 修复反馈页产品外壳复用、多信源计数缺失、已读卡表面变量循环与左边框覆盖
  • ✅ 日期标题取消白色渐变和吸顶层,改为透明内容流样式,直接融入页面背景
  • ✅ 本地验证:test 106/106、lint 0 error(2 个既有 warning)、TypeScript、build、git diff --check 均通过
  • 交付:commit ff5beef;Actions run 31459121708 成功,production deployment pier-blog-p9cmagbz4-jia-ethans-projects.vercel.app;未另建 PR
  • 验收边界:本地自动化验证与部署工作流通过;浏览器视觉验收已随 2026-08-11 排版工作补做(多视口双主题截图,无布局回归)

Agent 接入页与 AI 日报页排版优化(2026-08-11,已部署并完成技术验收)

  • ✅ Agent 页脱离旧 max-w-3xl 孤岛:xl 起「主文档栏 832px + 右侧粘性目录/快速接入栏 240px(2xl 864+256)」,<xl 转为正文顶部紧凑横滚目录
  • ✅ 首屏双入口:主按钮「通过邮件申请」(沿用现有 mailto),次按钮「查看配置步骤」锚至 #configure;正文按理解接入/配置/安装与验证/排障与申请四阶段组织(accent eyebrow + 锚点)
  • ✅ 新增 src/components/currents/AgentCopyBlock.tsx(代码块常驻复制按钮 + 示例提问复制卡片,含「已复制」反馈)与 AgentToc.tsx(滚动监听高亮当前章节,对 Lenis 缓动可靠);零新依赖
  • ✅ 日报页移除 mx-auto max-w-3xl 居中窄栏:1020px 左锚定宽版单栏,日期下分类锚点胶囊(移动端容器内横滚),条目统一 divide-y 编辑列表(来源·评分同一元数据行,评分不再悬浮右侧),栏目标题升为 serif + 分隔线,LEAD 中等强调(摘要限三行)
  • ✅ 复制交互 Review 修正:反馈链接不再重复 locale;Clipboard API 失败时依次尝试 legacy copy 与手动选择;复制成功/失败通过动态 accessible name 和 aria-live 通知;请求序号与计时器清理避免连续点击竞态
  • ✅ i18n:zh.json/en.json 各增 10 个 key(阶段标签、复制状态与目录标题)
  • ✅ 验证:18 个测试文件、112/112 tests、lint 0 error(2 个既有 warning)、TypeScript、production build、git diff --check 通过;独立 Review Agent 无部署阻断
  • ✅ 交付:commits 8319969 / 0fd04b5 已推送 main;Actions run 31468832109 success;production deployment pier-blog-e5gt0npjh-jia-ethans-projects.vercel.app Ready 并 alias 到 ethanpier.com
  • ✅ 线上技术验收:/zh/currents/agent/en/currents/agent/zh/currents/daily 均为 200;中英文反馈链接 locale 正确;复制按钮状态与剪贴板内容正常;日报 5/5 分类锚点存在;本地 Source Serif 字体加载成功且无新增浏览器错误
  • 回滚:代码基线 db970b0;上一 production deployment pier-blog-ea8cpgns8-jia-ethans-projects.vercel.app