初始化提交

This commit is contained in:
chenxin committed 2026-08-21 16:00:13 +08:00
commit 887c1f449e
963 files changed
+166869

No files matched your search

+412
View File
@@ -0,0 +1,412 @@
<!doctype html>
<html lang="zh-CN" data-theme="dark">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>魂镜 · 设计原型目录</title>
<link rel="stylesheet" href="tokens.css" />
<link rel="stylesheet" href="_base.css" />
<link rel="stylesheet" href="_chrome.css" />
<style>
/* ============================================================
* 铜镜鉴心 v2.1 — 设计原型目录(index)
* 全部原型的可点击入口;每张卡带 live iframe 缩略图(原型
* 改动即时反映,无需重新截图)。自身不注入 sidebar。
* ============================================================ */
.stage { max-width: 1180px; margin: 0 auto; padding: 56px 32px 80px; }
/* ── hero ── */
.hero { position: relative; margin-bottom: 48px; padding-bottom: 32px; border-bottom: 1px solid var(--rule); }
.hero h1 { font-family: "Songti SC", serif; font-size: 44px; font-weight: 700; letter-spacing: 0.06em; margin: 0 0 6px; color: var(--fg); }
.hero .lede { font-size: 14.5px; color: var(--fg-dim); line-height: 1.7; max-width: 660px; }
.hero .lede code { font-family: "JetBrains Mono", monospace; font-size: 13px; color: var(--gilt); }
/* ── 推荐阅读路径:3 步胶囊,首次访客的引导线 ── */
.reading-path { display: flex; align-items: stretch; gap: 10px; margin-top: 22px; flex-wrap: wrap; }
.path-label { font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.1em; color: var(--fg-faint); text-transform: uppercase; align-self: center; margin-right: 4px; }
.path-step { display: flex; align-items: center; gap: 10px; padding: 9px 16px 9px 12px; border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); text-decoration: none; transition: border-color var(--duration-normal), background var(--duration-normal), transform var(--duration-normal); }
.path-step:hover { border-color: var(--patina-dim); background: var(--surface-hi); transform: translateY(-1px); }
.path-step .step-num { font-family: "Songti SC", serif; font-size: 18px; font-weight: 700; color: var(--gilt); line-height: 1; flex-shrink: 0; }
.path-step .step-body { display: flex; flex-direction: column; gap: 1px; }
.path-step .step-title { font-family: "Songti SC", serif; font-size: 13.5px; font-weight: 600; color: var(--fg); }
.path-step .step-desc { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); letter-spacing: 0.02em; }
.path-arrow { align-self: center; color: var(--fg-faint); font-size: 14px; opacity: 0.6; }
.hero-bar { display: flex; align-items: center; gap: 16px; margin-top: 22px; flex-wrap: wrap; }
.stats { display: flex; gap: 18px; flex-wrap: wrap; }
.stat { display: flex; align-items: baseline; gap: 6px; }
.stat b { font-family: "Songti SC", serif; font-size: 22px; font-weight: 700; color: var(--patina); }
.stat span { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-faint); letter-spacing: 0.06em; }
.hero-bar .spacer { flex: 1; }
/* ── 分组 ── */
.group { margin-top: 42px; }
.group-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 16px; }
.group-title { font-family: "Songti SC", serif; font-size: 17px; font-weight: 700; letter-spacing: 0.06em; color: var(--fg); }
.group-sub { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-faint); letter-spacing: 0.06em; }
/* ── 共享层文件卡网格(无缩略图) ── */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(252px, 1fr)); gap: 12px; }
/* ── 页面原型网格(固定列宽对齐 live 缩略图) ── */
.grid-thumb { display: grid; grid-template-columns: repeat(auto-fill, 268px); gap: 14px; }
.proto { display: flex; flex-direction: column; padding: 14px 16px; border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); text-decoration: none; transition: border-color 0.15s, transform 0.15s, background 0.15s; position: relative; overflow: hidden; }
.proto::after { content: ""; position: absolute; inset: 0; background-image: var(--sweep-gradient); background-size: 220% 100%; background-position: -40% 0; opacity: 0; transition: opacity 0.4s; pointer-events: none; }
.proto:hover { border-color: var(--patina-dim); transform: translateY(-2px); background: var(--surface-hi); }
.proto:hover::after { opacity: 0.5; }
.proto-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.proto-title { font-family: "Songti SC", serif; font-size: 15.5px; font-weight: 600; color: var(--fg); }
.proto-route { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--patina); letter-spacing: 0.02em; margin-top: 2px; }
.proto-route.none { color: var(--fg-faint); }
.proto-route .draft { color: var(--gilt); font-size: 9.5px; margin-left: 5px; opacity: 0.85; }
.proto-desc { font-size: 12px; color: var(--fg-dim); line-height: 1.5; margin-top: 6px; }
/* ── live 缩略图 ──
iframe 固定 960×602,scale 0.2792 缩到 268×168 正好填满一列;
pointer-events:none 让点击穿透到卡片 <a>;lazy 仅加载视口内。 */
.thumb { position: relative; width: 100%; height: 168px; border-radius: 10px; overflow: hidden; margin-bottom: 10px; border: 1px solid var(--rule); background: var(--ink); transition: border-color 0.15s; }
.thumb iframe { position: absolute; top: 0; left: 0; width: 960px; height: 602px; border: 0; transform: scale(0.2792); transform-origin: 0 0; pointer-events: none; background: var(--ink); }
.thumb::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 62%, var(--surface) 100%); pointer-events: none; }
.proto:hover .thumb { border-color: var(--patina-dim); }
/* 文件卡(共享层) */
.proto.file .proto-title { color: var(--gilt); font-family: "JetBrains Mono", monospace; font-size: 13px; }
/* 状态点 */
.status { display: inline-flex; align-items: center; gap: 5px; font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.04em; white-space: nowrap; }
.status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.status-ok { color: var(--patina); } .status-ok::before { background: var(--patina); }
.status-maybe { color: var(--gilt); } .status-maybe::before { background: var(--gilt); }
.status-todo { color: var(--fg-faint); } .status-todo::before { background: var(--fg-faint); }
.status-bench { color: var(--gilt); } .status-bench::before { background: var(--gilt); box-shadow: 0 0 8px var(--gilt); }
/* ── 预览提示 ── */
.preview-hint { margin-top: 56px; padding: 18px 22px; border: 1px solid var(--gilt-dim); border-radius: 12px; background: var(--face-sheen), var(--surface); }
.preview-hint .t { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin-bottom: 8px; }
.preview-hint code { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--patina); background: var(--surface-hi); padding: 2px 7px; border-radius: 4px; }
.preview-hint p { font-size: 12.5px; color: var(--fg-dim); line-height: 1.7; margin: 0; }
/* ── 响应式:窄屏隐藏缩略图、网格自适应 ── */
@media (max-width: 720px) {
.grid-thumb { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.thumb { display: none; }
}
</style>
</head>
<body>
<main class="stage">
<!-- ════════ hero ════════ -->
<header class="hero">
<h1>魂鏡 · 設計原型</h1>
<p class="lede">铜镜鉴心视觉参考稿集合。每个原型是自包含的 HTML,共享 <code>tokens.css</code> / <code>_base.css</code> / <code>_chrome.css</code> 三层与 <code>_nav.html</code> 统一侧栏。每张卡片的缩略图为 live iframe——原型改动即时反映,无需重新截图。</p>
<!-- 推荐阅读路径:首次访客的引导线 -->
<nav class="reading-path" aria-label="推荐阅读顺序">
<span class="path-label">推荐阅读</span>
<a class="path-step" href="copper-mirror-redesign-v2.html">
<span class="step-num">壹</span>
<span class="step-body">
<span class="step-title">铜镜鉴心 North Star</span>
<span class="step-desc">设计 DNA · 色谱 / 字阶 / 组件</span>
</span>
</a>
<span class="path-arrow" aria-hidden="true">→</span>
<a class="path-step" href="cosmos-preview.html">
<span class="step-num">贰</span>
<span class="step-body">
<span class="step-title">灵枢</span>
<span class="step-desc">签名元素 · 九枢星盘</span>
</span>
</a>
<span class="path-arrow" aria-hidden="true">→</span>
<a class="path-step" href="admin-preview.html">
<span class="step-num">叁</span>
<span class="step-body">
<span class="step-title">司命台</span>
<span class="step-desc">控制台 dashboard</span>
</span>
</a>
</nav>
<div class="hero-bar">
<div class="stats">
<div class="stat"><b id="stat-total">—</b><span>原型</span></div>
<div class="stat"><b id="stat-done">—</b><span>已落地</span></div>
<div class="stat"><b id="stat-planned">—</b><span>待实现</span></div>
</div>
<div class="spacer"></div>
<a class="btn btn-outline btn-sm" href="../README.md">README</a>
<button class="btn btn-outline btn-sm" id="theme-toggle" type="button"><span id="theme-label">夜铜</span></button>
</div>
</header>
<!-- ════════ 共享层 ════════ -->
<section class="group">
<div class="group-head">
<span class="group-title">共享层</span>
<span class="group-sub">— 改一处,全站生效</span>
</div>
<div class="grid">
<a class="proto file" href="tokens.css">
<div class="proto-head"><span class="proto-title">tokens.css</span><span class="tag tag-gilt">变量</span></div>
<div class="proto-desc">铜镜鉴心暗+亮全套 CSS 变量,设计 token 单一事实源</div>
</a>
<a class="proto file" href="_base.css">
<div class="proto-head"><span class="proto-title">_base.css</span><span class="tag tag-gilt">基底</span></div>
<div class="proto-desc">reset / body / 极光铜晕 / 字体类 / reduced-motion</div>
</a>
<a class="proto file" href="_chrome.css">
<div class="proto-head"><span class="proto-title">_chrome.css</span><span class="tag tag-gilt">组件</span></div>
<div class="proto-desc">sidebar / 导航 / 卡片 / 按钮 / 标签 / 页头共享样式</div>
</a>
<a class="proto file" href="_nav.html">
<div class="proto-head"><span class="proto-title">nav.html</span><span class="tag tag-gilt">片段</span></div>
<div class="proto-desc">统一 7 组侧栏导航,由 _theme.js fetch 注入各页</div>
</a>
<a class="proto file" href="_theme.js">
<div class="proto-head"><span class="proto-title">_theme.js</span><span class="tag tag-gilt">脚本</span></div>
<div class="proto-desc">nav 注入 + 当前页高亮 + 主题切换 + localStorage</div>
</a>
</div>
</section>
<!-- ════════ 设计系统 · 北极星 ════════ -->
<section class="group">
<div class="group-head">
<span class="group-title">设计系统 · 北极星</span>
<span class="group-sub">— 色谱 / 字阶 / 组件 / 签名元素</span>
</div>
<div class="grid-thumb">
<a class="proto" href="copper-mirror-redesign-v2.html">
<div class="thumb"><iframe src="copper-mirror-redesign-v2.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="铜镜鉴心 North Star 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">铜镜鉴心 North Star</span><span class="status status-bench">基准</span></div>
<div class="proto-route none">设计系统页</div>
<div class="proto-desc">色谱 / 字阶 / 组件库 / 九枢星盘签名元素</div>
</a>
<a class="proto" href="copper-mirror-login.html">
<div class="thumb"><iframe src="copper-mirror-login.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="登入灵台 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">登入灵台</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/login</div>
<div class="proto-desc">铜镜鉴心登录页</div>
</a>
</div>
</section>
<!-- ════════ 灵台 · 对话 ════════ -->
<section class="group">
<div class="group-head"><span class="group-title">灵台 · 对话</span></div>
<div class="grid-thumb">
<a class="proto" href="chat-redesign-preview.html">
<div class="thumb"><iframe src="chat-redesign-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="对话 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">对话</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/chat</div>
<div class="proto-desc">app-shell + 可折叠侧栏 + 镜面 v6</div>
</a>
<a class="proto" href="run-trace-preview.html">
<div class="thumb"><iframe src="run-trace-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="运行轨迹 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">运行轨迹</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/runs/[id]</div>
<div class="proto-desc">运行链路追踪与回放</div>
</a>
</div>
</section>
<!-- ════════ 魂册 ════════ -->
<section class="group">
<div class="group-head"><span class="group-title">魂册</span><span class="group-sub">— 人物的载体与档案</span></div>
<div class="grid-thumb">
<a class="proto" href="characters-preview.html">
<div class="thumb"><iframe src="characters-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="人物列表 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">人物列表</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/characters</div>
<div class="proto-desc">魂册人物总览</div>
</a>
<a class="proto" href="character-detail-preview.html">
<div class="thumb"><iframe src="character-detail-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="人物详情 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">人物详情</span><span class="status status-maybe">部分</span></div>
<div class="proto-route">/characters/[id]</div>
<div class="proto-desc">单人物档案与状态</div>
</a>
<a class="proto" href="character-materials-preview.html">
<div class="thumb"><iframe src="character-materials-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="人物资料 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">人物资料</span><span class="status status-maybe">部分</span></div>
<div class="proto-route">/characters/[id]/*</div>
<div class="proto-desc">资料沉淀与衍生</div>
</a>
</div>
</section>
<!-- ════════ 心智 ════════ -->
<section class="group">
<div class="group-head"><span class="group-title">心智</span><span class="group-sub">— 人物的内世界模型</span></div>
<div class="grid-thumb">
<a class="proto" href="cosmos-preview.html">
<div class="thumb"><iframe src="cosmos-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="灵枢 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">灵枢</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/cosmos</div>
<div class="proto-desc">九枢系统视图 · 太极阴阳平衡心智解剖</div>
</a>
<a class="proto" href="wuxing-preview.html">
<div class="thumb"><iframe src="wuxing-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="五行 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">五行</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/wuxing</div>
<div class="proto-desc">五行生克可视化</div>
</a>
<a class="proto" href="personality-preview.html">
<div class="thumb"><iframe src="personality-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="人格 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">人格</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/personality</div>
<div class="proto-desc">人格定义与维度</div>
</a>
<a class="proto" href="drive-preview.html">
<div class="thumb"><iframe src="drive-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="内驱力 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">内驱力</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/drive</div>
<div class="proto-desc">动机与目标驱动</div>
</a>
<a class="proto" href="evolution-preview.html">
<div class="thumb"><iframe src="evolution-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="演化 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">演化</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/evolution</div>
<div class="proto-desc">大周天人格演化轨迹</div>
</a>
</div>
</section>
<!-- ════════ 编排 ════════ -->
<section class="group">
<div class="group-head"><span class="group-title">编排</span><span class="group-sub">— 角色卡 · 世界设定 · 符文 · 眉批</span></div>
<div class="grid-thumb">
<a class="proto" href="card-import-preview.html">
<div class="thumb"><iframe src="card-import-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="魂册降生 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">魂册降生 · 角色卡</span><span class="status status-todo">待实现</span></div>
<div class="proto-route">/characters/import</div>
<div class="proto-desc">V1/V2/V3 角色卡导入建立人物 · 静态快照导出</div>
</a>
<a class="proto" href="lorebook-preview.html">
<div class="thumb"><iframe src="lorebook-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="世谱 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">世谱 · Lorebook</span><span class="status status-todo">待实现</span></div>
<div class="proto-route">/lorebooks</div>
<div class="proto-desc">关键词触发的世界设定按需注入</div>
</a>
<a class="proto" href="rune-engine-preview.html">
<div class="thumb"><iframe src="rune-engine-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="符文引擎 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">符文引擎 · Macros</span><span class="status status-todo">待实现</span></div>
<div class="proto-route">/macros</div>
<div class="proto-desc">组装管线末端 {{char}} 占位符替换引擎</div>
</a>
<a class="proto" href="margin-notes-preview.html">
<div class="thumb"><iframe src="margin-notes-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="眉批 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">眉批 · Author's Note</span><span class="status status-todo">待实现</span></div>
<div class="proto-route">/author-notes</div>
<div class="proto-desc">作为 context_transformer 按深度注入对话流</div>
</a>
</div>
</section>
<!-- ════════ 内景 ════════ -->
<section class="group">
<div class="group-head"><span class="group-title">内景</span><span class="group-sub">— 外部世界与时序</span></div>
<div class="grid-thumb">
<a class="proto" href="world-preview.html">
<div class="thumb"><iframe src="world-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="世界 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">世界 · 河图绘形</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/world</div>
<div class="proto-desc">世界实体图谱</div>
</a>
<a class="proto" href="time-preview.html">
<div class="thumb"><iframe src="time-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="时态 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">时态</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/time</div>
<div class="proto-desc">时间线与叙事时序</div>
</a>
</div>
</section>
<!-- ════════ 藏识 ════════ -->
<section class="group">
<div class="group-head"><span class="group-title">藏识</span></div>
<div class="grid-thumb">
<a class="proto" href="memory-preview.html">
<div class="thumb"><iframe src="memory-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="记忆 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">记忆</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/memory</div>
<div class="proto-desc">息壤记忆管理</div>
</a>
<a class="proto" href="archive-preview.html">
<div class="thumb"><iframe src="archive-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="归档 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">归档 · 记忆时间河</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/archive</div>
<div class="proto-desc">时间河回溯</div>
</a>
</div>
</section>
<!-- ════════ 百工 · 系统 ════════ -->
<section class="group">
<div class="group-head"><span class="group-title">百工 · 系统</span></div>
<div class="grid-thumb">
<a class="proto" href="tools-preview.html">
<div class="thumb"><iframe src="tools-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="工具 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">工具</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/tools</div>
<div class="proto-desc">工具调用管理</div>
</a>
<a class="proto" href="model-gateway-preview.html">
<div class="thumb"><iframe src="model-gateway-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="模型网关 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">模型网关</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/models</div>
<div class="proto-desc">多模型路由与调度</div>
</a>
<a class="proto" href="settings-preview.html">
<div class="thumb"><iframe src="settings-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="设置 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">设置</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/settings</div>
<div class="proto-desc">全局配置</div>
</a>
</div>
</section>
<!-- ════════ 司命台 · admin ════════ -->
<section class="group">
<div class="group-head"><span class="group-title">司命台 · admin</span></div>
<div class="grid-thumb">
<a class="proto" href="admin-preview.html">
<div class="thumb"><iframe src="admin-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="司命台 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">司命台融合稿</span><span class="status status-ok">已落地</span></div>
<div class="proto-route">/admin</div>
<div class="proto-desc">控制台 dashboard 网格</div>
</a>
<a class="proto" href="admin-characters-preview.html">
<div class="thumb"><iframe src="admin-characters-preview.html" loading="lazy" scrolling="no" tabindex="-1" aria-hidden="true" title="人物模板管理 预览"></iframe></div>
<div class="proto-head"><span class="proto-title">人物模板管理</span><span class="status status-maybe">部分</span></div>
<div class="proto-route">/admin/*</div>
<div class="proto-desc">人物模板配置</div>
</a>
</div>
</section>
<!-- ════════ 预览提示 ════════ -->
<div class="preview-hint">
<div class="t">如何预览</div>
<p>原型侧栏由 <code>_theme.js</code> 通过 <code>fetch</code> 注入,<strong>需启动本地服务器</strong>(<code>file://</code> 双击打开时侧栏与缩略图均会失效)。在 <code>frontend/</code> 下运行 <code>pnpm design</code>,然后访问 <code>http://localhost:3001</code>。卡片缩略图为 live iframe,原型页改动后刷新本页即同步。</p>
</div>
</main>
<script src="_theme.js" defer></script>
<script>
/* 自动统计原型数量(新增页面无需手改 hero 数字) */
(function () {
var protos = document.querySelectorAll(".proto:not(.file)");
var done = document.querySelectorAll(".proto:not(.file) .status-ok").length;
var planned = document.querySelectorAll(".proto:not(.file) .status-maybe, .proto:not(.file) .status-todo").length;
var el;
if ((el = document.getElementById("stat-total"))) el.textContent = protos.length;
if ((el = document.getElementById("stat-done"))) el.textContent = done;
if ((el = document.getElementById("stat-planned"))) el.textContent = planned;
})();
</script>
</body>
</html>