diff --git a/src/components/Footer.astro b/src/components/Footer.astro
index ee27196..8e80bcf 100644
--- a/src/components/Footer.astro
+++ b/src/components/Footer.astro
@@ -3,11 +3,14 @@
import { t } from '../i18n/ui';
import type { Locale } from '../lib/locale';
-// /en/ 侧由 T4 薄页传 locale='en';zh 路由无人传参,默认 zh 零回归
+// locale 感知:显式 prop 优先;无 prop 时构建期按页面 URL 推断轨道
+// (BaseLayout 引用本组件不透传 locale,靠 Astro.url 静态解析补全 en 轨)
+import { localeOf } from '../lib/locale';
interface Props {
locale?: Locale;
}
-const { locale = 'zh' } = Astro.props;
+const { locale: propLocale } = Astro.props;
+const locale = propLocale ?? localeOf(Astro.url.pathname);
---
diff --git a/src/i18n/ui.ts b/src/i18n/ui.ts
index 9406124..3e34b4c 100644
--- a/src/i18n/ui.ts
+++ b/src/i18n/ui.ts
@@ -74,6 +74,10 @@ const dict = {
heatmap_more: { zh: '多', en: 'More' },
heatmap_note: { zh: '数据来自 gitea · 构建期生成', en: 'via gitea · generated at build time' },
+ // ===== B 车道:Footer 极客双页入口(stack/colophon 页内文案各自内联,不入本表) =====
+ footer_stack: { zh: '装备', en: 'stack' },
+ footer_colophon: { zh: '制作', en: 'colophon' },
+
// ===== 命令面板(Phase 4 T1 车道):动作/导航/分组与键位提示 =====
nav_home: { zh: '首页', en: 'Home' },
nav_moments: { zh: '瞬间', en: 'Moments' },
diff --git a/src/pages/colophon.astro b/src/pages/colophon.astro
new file mode 100644
index 0000000..c71a66a
--- /dev/null
+++ b/src/pages/colophon.astro
@@ -0,0 +1,117 @@
+---
+// /colophon 制作页:本站如何造出来——灰阶数据表叙事,不做营销页
+// 事实源:package.json 实版本、部署实录、docs/博客重设计调研报告.md 拍板项
+import BaseLayout from '../layouts/BaseLayout.astro';
+
+const SECTIONS = [
+ {
+ tag: 'build',
+ items: [
+ ['Astro 7.3.8', '静态生成(SSG),零运行时框架 JS;交互由原生 island 脚本承担'],
+ ['Pagefind', '搜索索引构建期生成,静态站零后端搜索'],
+ ['Shiki', '代码双主题高亮,构建期完成'],
+ ['构建产物', '约 30 页 / 数秒完成,homelab 上由 push 触发'],
+ ],
+ },
+ {
+ tag: 'visual',
+ items: [
+ ['丙路线', '灰阶骨架 × 分轨正文:结构用灰阶与留白说话,正文按内容轨道换字体'],
+ ['四字体族', '思源宋(书评正文)· 思源黑(UI/技术)· JetBrains Mono(代码)· 霞鹜文楷(金句,系统栈回退)'],
+ ['@fontsource', '字体自托管分片加载;思源黑/宋切换变字体后 CSS 345KB→106KB 全站提速'],
+ ['tokens', '颜色/间距/时长全部变量化,亮暗两套一套代码'],
+ ],
+ },
+ {
+ tag: 'writing flow',
+ items: [
+ ['gitea', '自托管 git 服务:本地编辑器与 gitea 网页写的是同一个仓库'],
+ ['webhook', 'push 触发,HMAC 签名验证,仅 main 分支'],
+ ['发布链', 'homelab 构建 → rsync → nginx 静态目录,全程无云厂商构建分钟'],
+ ['透明化', '页脚 built-from 一行链到本次构建对应的 commit'],
+ ],
+ },
+ {
+ tag: 'i18n',
+ items: [
+ ['预翻译', '腾讯 TMT 构建期机翻,.en.md 入仓版本化'],
+ ['双语轨', '/en/ 前缀预构建,切换是纯导航零等待'],
+ ['译注', '机翻文章带 AI 译注小标,欢迎指正'],
+ ],
+ },
+ {
+ tag: 'features',
+ items: [
+ ['评论', 'Artalk 2.10 自托管(sqlite),挂主域 /artalk 路径'],
+ ['图库', 'EXIF 构建期提取(exifr)+ sharp 宽高比驱动 masonry,零运行时 JS'],
+ ['边缘', 'ESA CDN + HTTPS 通配证书;页脚 ICP 备案法定保留'],
+ ],
+ },
+];
+---
+
+
+
+ 制作 / colophon
+
+ 一个静态博客能自己决定的事情,尽量自己决定:自己构建、自己托管、自己翻译、自己记版本。
+
+ {SECTIONS.map((s) => (
+
+ {s.tag}
+
+ {s.items.map(([term, desc]) => (
+
+
- {term}
+ - {desc}
+
+ ))}
+
+
+ ))}
+
+
+
+
diff --git a/src/pages/en/colophon.astro b/src/pages/en/colophon.astro
new file mode 100644
index 0000000..e609a12
--- /dev/null
+++ b/src/pages/en/colophon.astro
@@ -0,0 +1,115 @@
+---
+// en/colophon: English track of /colophon — same structure, condensed copy
+import BaseLayout from '../../layouts/BaseLayout.astro';
+
+const SECTIONS = [
+ {
+ tag: 'build',
+ items: [
+ ['Astro 7.3.8', 'static site generation, zero runtime framework JS; interactions are small native scripts'],
+ ['Pagefind', 'search index built at compile time — search on a static site, no backend'],
+ ['Shiki', 'dual-theme syntax highlighting, done at build'],
+ ['output', '~30 pages in seconds, triggered by every push'],
+ ],
+ },
+ {
+ tag: 'visual',
+ items: [
+ ['grayscale × tracks', 'a grayscale skeleton for structure; body typography switches per content track'],
+ ['four families', 'Noto Serif SC (books) · Noto Sans SC (UI/tech) · JetBrains Mono (code) · LXGW WenKai (quotes, system fallback)'],
+ ['@fontsource', 'self-hosted, subset fonts; switching to variable fonts cut font CSS 345KB → 106KB'],
+ ['tokens', 'colors, spacing and motion are all CSS variables — light/dark in one codebase'],
+ ],
+ },
+ {
+ tag: 'writing flow',
+ items: [
+ ['gitea', 'self-hosted git: my local editor and the web UI write to the same repository'],
+ ['webhook', 'push-triggered, HMAC-verified, main branch only'],
+ ['pipeline', 'homelab build → rsync → nginx; no cloud build minutes'],
+ ['transparency', 'the built-from line in the footer links to the exact commit'],
+ ],
+ },
+ {
+ tag: 'i18n',
+ items: [
+ ['pre-translation', 'machine-translated by Tencent TMT at build; .en.md files live in the repo'],
+ ['dual track', '/en/ pages are prebuilt — switching language is pure navigation'],
+ ['honesty', 'machine-translated posts carry a note; corrections welcome'],
+ ],
+ },
+ {
+ tag: 'features',
+ items: [
+ ['comments', 'self-hosted Artalk 2.10 (sqlite) at /artalk'],
+ ['gallery', 'EXIF extracted at build (exifr) + aspect-ratio-driven masonry via sharp, no runtime JS'],
+ ['edge', 'ESA CDN, wildcard HTTPS; ICP filing kept in the footer as required'],
+ ],
+ },
+];
+---
+
+
+
+ colophon / 制作
+
+ A static blog that decides for itself wherever it can: its own build, its own hosting, its own translations, its own version history.
+
+ {SECTIONS.map((s) => (
+
+ {s.tag}
+
+ {s.items.map(([term, desc]) => (
+
+
- {term}
+ - {desc}
+
+ ))}
+
+
+ ))}
+
+
+
+
diff --git a/src/pages/en/stack.astro b/src/pages/en/stack.astro
new file mode 100644
index 0000000..5f3ddca
--- /dev/null
+++ b/src/pages/en/stack.astro
@@ -0,0 +1,117 @@
+---
+// en/stack: English track of /stack — same structure, condensed copy
+import BaseLayout from '../../layouts/BaseLayout.astro';
+
+const SECTIONS = [
+ {
+ tag: 'homelab',
+ items: [
+ ['Debian 13', 'trixie, the host system'],
+ ['Docker', 'Engine + Compose; every service runs containerized'],
+ // TODO(next round): hardware details (machine/CPU/RAM/storage) pending
+ ],
+ },
+ {
+ tag: 'self-hosted',
+ items: [
+ ['gitea 28.2', 'git hosting — the source of the writing & build flow (git.wait4x.online)'],
+ ['nginx', 'static site serving and reverse proxy'],
+ ['Artalk 2.10', 'comments, sqlite storage'],
+ ['ddns-go', 'IPv6 dynamic DNS'],
+ ['clash', 'outbound traffic routing'],
+ ['new-api', 'LLM API gateway (build-time translation goes through it)'],
+ ['crawl4ai', 'headless-browser fetching service'],
+ ],
+ },
+ {
+ tag: 'site deps',
+ items: [
+ ['Astro 7.3.8', 'the SSG framework'],
+ ['sharp 0.35', 'image optimization pipeline'],
+ ['exifr 7.1', 'EXIF extraction at build'],
+ ['@fontsource 5.3', 'self-hosted subset fonts: Noto Sans/Serif SC, JetBrains Mono'],
+ ['Pagefind', 'static search index'],
+ ['Playwright 1.64', 'E2E self-checks (chromium screenshots & assertions)'],
+ ],
+ },
+ {
+ tag: 'daily',
+ items: [
+ // TODO(next round): daily software list pending
+ ],
+ },
+];
+---
+
+
+
+ stack / 装备
+ One small machine and a handful of open source. Self-host what can be self-hosted; version what can be versioned.
+ {SECTIONS.map((s) => (
+
+ {s.tag}
+ {s.items.length === 0 ? (
+ TODO(next round): list pending
+ ) : (
+
+ {s.items.map(([term, desc]) => (
+
+
- {term}
+ - {desc}
+
+ ))}
+
+ )}
+
+ ))}
+
+
+
+
diff --git a/src/pages/stack.astro b/src/pages/stack.astro
new file mode 100644
index 0000000..b157c2f
--- /dev/null
+++ b/src/pages/stack.astro
@@ -0,0 +1,117 @@
+---
+// /stack 装备页:跑着这个站与日常的一切——按实情条目化,硬件细节未定处宁缺留 TODO
+import BaseLayout from '../layouts/BaseLayout.astro';
+
+const SECTIONS = [
+ {
+ tag: 'homelab',
+ items: [
+ ['Debian 13', 'trixie,宿主系统'],
+ ['Docker', 'Engine + Compose,全部服务容器化部署'],
+ // TODO(下轮): 机型/CPU/内存/存储等硬件细节待用户补
+ ],
+ },
+ {
+ tag: 'self-hosted',
+ items: [
+ ['gitea 28.2', 'git 托管:写作流与构建触发源头(git.wait4x.online)'],
+ ['nginx', '静态站点服务与反代出口'],
+ ['Artalk 2.10', '评论系统,sqlite 存储'],
+ ['ddns-go', 'IPv6 动态解析'],
+ ['clash', '出网分流'],
+ ['new-api', 'LLM API 网关(构建期翻译走它)'],
+ ['crawl4ai', '无头浏览器抓取服务'],
+ ],
+ },
+ {
+ tag: 'site deps',
+ items: [
+ ['Astro 7.3.8', 'SSG 框架'],
+ ['sharp 0.35', '图像优化管线'],
+ ['exifr 7.1', 'EXIF 构建期提取'],
+ ['@fontsource 5.3', '思源黑/思源宋/JetBrains Mono 自托管分片'],
+ ['Pagefind', '静态搜索索引'],
+ ['Playwright 1.64', 'E2E 自验(chromium 截图与断言)'],
+ ],
+ },
+ {
+ tag: 'daily',
+ items: [
+ // TODO(下轮): 日常软件清单待用户补(编辑器/浏览器/终端等)
+ ],
+ },
+];
+---
+
+
+
+ 装备 / stack
+ 一台小机器 + 一把开源工具。能用自托管解决的不上云,能版本化的不靠记忆。
+ {SECTIONS.map((s) => (
+
+ {s.tag}
+ {s.items.length === 0 ? (
+ TODO(下轮):清单待补
+ ) : (
+
+ {s.items.map(([term, desc]) => (
+
+
- {term}
+ - {desc}
+
+ ))}
+
+ )}
+
+ ))}
+
+
+
+