初始化提交
This commit is contained in:
commit
887c1f449e
963 files changed
+166869
No files matched your search
@@ -0,0 +1,184 @@
|
||||
# design — 视觉原型(North Star)
|
||||
|
||||
本目录是魂镜前端的设计原型集合,**非生产代码**。入口:[`index.html`](./index.html)(可点击目录,每张卡带 **live iframe 缩略图**,`pnpm design` 后访问)。每个 `*-preview.html` 是视觉参考稿,共享三层样式(`tokens` / `_base` / `_chrome`)与统一侧栏(`_nav.html` 经 `_theme.js` 注入),页面 `<style>` 仅保留页面特异样式。实现时按其重写为 `src/` 下的 React 组件。
|
||||
|
||||
## 共享层
|
||||
|
||||
原型引用**三层共享文件** + **统一侧栏片段** + **共享脚本**,消除此前每个原型各存一份 token / reset / sidebar 副本(且已漂移、写法分叉)的问题。改一处,全站 25 页同步。
|
||||
|
||||
| 文件 | 职责 |
|
||||
| --- | --- |
|
||||
| [`tokens.css`](./tokens.css) | 铜镜鉴心 暗+亮 全套 CSS 变量(`--ink` / `--patina` / `--gilt` / `--cinnabar` …) |
|
||||
| [`_base.css`](./_base.css) | reset / `body` / 极光铜晕 `body::before` / `.serif` / `.mono` / `prefers-reduced-motion` |
|
||||
| [`_chrome.css`](./_chrome.css) | AppShell 组件层:`.sidebar` / `.nav-item` / `.card` / `.btn` / `.tag` / `.page-header` / `.back-link` |
|
||||
| [`_nav.html`](./_nav.html) | 统一 7 组侧栏片段(20 项),由 `_theme.js` fetch 注入各页 `.sidebar-mount` |
|
||||
| [`_theme.js`](./_theme.js) | nav 注入 + 当前页高亮 + 主题切换 + `localStorage` 持久化 + logo 回首页 |
|
||||
|
||||
加载顺序:`tokens.css` → `_base.css` → `_chrome.css` → 页面 `<style>`。**页面 `<style>` 只写页面特异样式**,不得重复定义 `_chrome.css` 已覆盖的 `.sidebar` / `.nav-item` / `body` / `:root`——否则后加载覆盖共享层,改一处不再全站生效。
|
||||
|
||||
**新建 AppShell 原型时**:
|
||||
|
||||
```html
|
||||
<head>
|
||||
<link rel="stylesheet" href="tokens.css" />
|
||||
<link rel="stylesheet" href="_base.css" />
|
||||
<link rel="stylesheet" href="_chrome.css" />
|
||||
<style>/* 仅页面特异样式 */</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-mount" data-active="当前页名"></div>
|
||||
<div class="main-area"><!-- page-header + page-body --></div>
|
||||
</div>
|
||||
<script src="_theme.js" defer></script>
|
||||
</body>
|
||||
```
|
||||
|
||||
`data-active` 对齐 `_nav.html` 的 `data-nav`(如 `对话` / `灵枢` / `魂册降生`)。**加导航项 / 改链接**:只改 `_nav.html` 一处。**改 sidebar 视觉**:只改 `_chrome.css` 一处。
|
||||
|
||||
> **与生产侧的差异(有意)**:`tokens.css` 的 `--surface` 是半透明玻璃(`rgba(255,255,255,0.022)`,配极光底做镜面通透感);`src/styles/globals.css` 演进为实色面板(`#121817`,渲染可预测)。两层各持一套,勿强行统一。
|
||||
|
||||
## 布局体系
|
||||
|
||||
原型按页面层级用 4 种 shell:
|
||||
|
||||
| Shell | 用途 | 结构 | 代表页 |
|
||||
| --- | --- | --- | --- |
|
||||
| **AppShell** | 功能页(主导航可达) | `.sidebar-mount`(注入)+ `main-area`(page-header + page-body) | cosmos / wuxing / characters / chat / personality / drive / evolution / world / time / memory / archive / tools / model-gateway / settings / admin / card-import / lorebook / rune-engine / margin-notes … |
|
||||
| **NarrowShell** | 二级详情页(从人物列表进入) | `app-main` max-width 居中 + `back-link` 面包屑;**仍注入侧栏**(高亮上级项 `人物`) | character-detail / character-materials |
|
||||
| **StageShell** | 登录 / 落地 / 目录 | `stage` max-width 居中,无 sidebar(或独立 theme 按钮) | copper-mirror-v2 / login / **index** |
|
||||
| **AdminShell** | 司命台控制台 | dashboard 网格(也注入 `.sidebar-mount`) | admin / admin-characters |
|
||||
|
||||
> **NarrowShell 与侧栏**:二级详情页(人物详情 / 资料)保留侧栏注入并高亮 `人物`,便于在详情态随时切走;`back-link` 面包屑负责"回到列表"的层级回退。两者职责不同,并不冲突。
|
||||
>
|
||||
> **归类修正(2026-07-25)**:`card-import` / `lorebook` 原标 NarrowShell,实际带 sidebar(属一级功能页),归 **AppShell**——主区宽度与 shell 类型解耦(窄流程页用 `.app-main` 限宽,但仍有全局导航)。NarrowShell 仅用于「从人物列表进入的二级详情」。
|
||||
>
|
||||
> **分组重组(2026-07-27)**:原「载入」组重命名为「**编排**」——该组横跨数据载入(魂册降生 / 世谱)与运行时编排(符文引擎 / 眉批),「编排」涵盖两者。心智组内分层:灵枢(总览)↔ 维度(五行 / 人格 / 内驱力 / 演化),以 `.nav-divider` 发丝线分隔。每项 nav 加 `data-route` 数据属性(供调试 / a11y 辅助,侧栏不渲染——路由映射见目录页 `.proto-route` 与原型索引表)。
|
||||
|
||||
**chat** 同样接入 `.sidebar-mount`(与其他 AppShell 页一致)。其此前的 60px 可折叠 sidebar 是未完成态(折叠隐藏文字但 HTML 无图标替代 → 空白窄条,且无触发器无法展开),已统一为标准 220px 展开侧栏;对话区宽度由 `.main-area` flex 自适应。
|
||||
|
||||
**统一 sidebar 导航(7 组 20 项)**:见 [`_nav.html`](./_nav.html)。灵台 · 魂册 · 心智 · **编排·酒馆融合** · 内景 · 藏识 · 百工。所有 AppShell 页(除 chat)由 `_theme.js` 自动注入同一份;底部另有「设计系统」入口直达 North Star 基准页。**logo 单击即时回目录**,350ms 内连点 5 次触发「镜启」彩蛋。
|
||||
|
||||
## 本地预览
|
||||
|
||||
侧栏经 `_theme.js` 用 `fetch` 注入 `_nav.html`,目录页缩略图用 live `<iframe>`;`file://` 双击打开时两者均受 CORS 限制(侧栏显示 fallback 提示、缩略图空白)。须启动本地服务器:
|
||||
|
||||
```bash
|
||||
pnpm design # → http://localhost:3001(零依赖,scripts/serve-design.mjs)
|
||||
```
|
||||
|
||||
## 原型索引
|
||||
|
||||
**入口**:[`index.html`](./index.html)(可点击的目录页,每张卡带 live iframe 缩略图)。
|
||||
|
||||
> 状态:✅ 已落地(有对应路由) · 🟡 部分/待确认 · ⬜ 待实现 · 🆕 新增
|
||||
|
||||
### 设计系统 / 北极星
|
||||
|
||||
| 文件 | 功能 | 路由 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `copper-mirror-redesign-v2` | 铜镜鉴心 North Star(色谱 / 字阶 / 组件 / 九枢星盘) | — | 🎯 设计基准 |
|
||||
| `copper-mirror-login` | 登入灵台 | `/login` | ✅ |
|
||||
|
||||
### 灵台 · 对话
|
||||
|
||||
| 文件 | 功能 | 路由 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `chat-redesign-preview` | 对话页 v6 | `/chat` | ✅ |
|
||||
| `run-trace-preview` | 运行轨迹 | `/runs/[id]` | ✅ |
|
||||
|
||||
### 魂册
|
||||
|
||||
| 文件 | 功能 | 路由 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `characters-preview` | 人物列表 | `/characters` | ✅ |
|
||||
| `character-detail-preview` | 人物详情 | `/characters/[id]` | 🟡 |
|
||||
| `character-materials-preview` | 人物资料与沉淀 | `/characters/[id]/*` | 🟡 |
|
||||
|
||||
### 心智
|
||||
|
||||
| 文件 | 功能 | 路由 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `cosmos-preview` | 灵枢(九枢系统视图) | `/cosmos` | ✅ |
|
||||
| `wuxing-preview` | 五行 | `/wuxing` | ✅ |
|
||||
| `personality-preview` | 人格 | `/personality` | ✅ |
|
||||
| `drive-preview` | 内驱力 | `/drive` | ✅ |
|
||||
| `evolution-preview` | 演化 | `/evolution` | ✅ |
|
||||
|
||||
### 编排 · 酒馆融合(P0/P1,路由已定)
|
||||
|
||||
| 文件 | 功能 | 路由 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `card-import-preview` | 魂册降生 · 角色卡导入导出 | `/characters/import` | ⬜ P0 |
|
||||
| `lorebook-preview` | 世谱 · World Info | `/lorebooks` | ⬜ P0 |
|
||||
| `rune-engine-preview` | 符文引擎 · Macros | `/macros` | 🆕 P0 |
|
||||
| `margin-notes-preview` | 眉批 · Author's Note | `/author-notes` | 🆕 P1 |
|
||||
|
||||
### 内景
|
||||
|
||||
| 文件 | 功能 | 路由 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `world-preview` | 世界(河图绘形) | `/world` | ✅ |
|
||||
| `time-preview` | 时态 | `/time` | ✅ |
|
||||
|
||||
### 藏识
|
||||
|
||||
| 文件 | 功能 | 路由 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `memory-preview` | 记忆 | `/memory` | ✅ |
|
||||
| `archive-preview` | 归档(记忆时间河) | `/archive` | ✅ |
|
||||
|
||||
### 百工 · 系统
|
||||
|
||||
| 文件 | 功能 | 路由 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `tools-preview` | 工具 | `/tools` | ✅ |
|
||||
| `model-gateway-preview` | 模型网关 | `/models` | ✅ |
|
||||
| `settings-preview` | 设置 | `/settings` | ✅ |
|
||||
|
||||
### 司命台 · admin
|
||||
|
||||
| 文件 | 功能 | 路由 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| `admin-preview` | 司命台融合稿 | `/admin` | ✅ |
|
||||
| `admin-characters-preview` | 人物模板管理 | `/admin/*` | 🟡 |
|
||||
|
||||
## 酒馆(SillyTavern)融合映射
|
||||
|
||||
酒馆功能**已融入魂镜中式命名**,不单设 `tavern/` 子目录——相关原型就是魂镜的功能页。下表把酒馆概念串到魂镜名、对应原型、后端表与设计文档章节。权威设计见 [`docs/contracts/contract-glossary.md`](../../docs/contracts/contract-glossary.md)(命名已于 2026-07-24 拍板,登记契约字典 §2.1)。
|
||||
|
||||
| 酒馆概念 | 魂镜名 | design 原型 | 后端表 | 文档 § | 阶段 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Character Card | **魂册** | `card-import` · `character-materials` · `personality` | `character` | §8 | **P0** |
|
||||
| World Info / Lorebook | **世谱** | `lorebook` · `world` | `lorebooks` | §7 | **P0** |
|
||||
| Macros `{{char}}` | **符文引擎** | `rune-engine` | `macros` | §8.4 | **P0** |
|
||||
| Author's Note | **眉批** | `margin-notes` | `author_notes` | §9.1 | P1 |
|
||||
| Prompt Manager | 言灵编排 | ⛔ 无 | — | §9.2 | — |
|
||||
| User Personas | 本相 | ⛔ 无 | — | §9.3 | — |
|
||||
| Presets | 火候 | ⛔ 无 | — | §9.4 | — |
|
||||
| Instruct Mode | 科仪 | ⛔ 无 | — | §9.5 | — |
|
||||
| Regex Scripts | 刻符 | ⛔ 无 | — | §9.6 | — |
|
||||
| Quick Reply | 锦囊 | ⛔ 无 | — | §9.7 | — |
|
||||
| Slash Commands | 咒令 | ⛔ 无 | — | §9.8 | — |
|
||||
| Group Chat | 雅集 | ⛔ 无 | — | §9.9 | — |
|
||||
|
||||
**已建原型**:`符文引擎`(rune-engine,P0)、`眉批`(margin-notes,P1)。其余酒馆载体(言灵编排 / 本相 / 火候 / …)尚无原型——若需要,可建 `design/tavern/` 子目录放置并在上表登记。
|
||||
|
||||
## 设计决策摘要
|
||||
|
||||
- **铜镜鉴心语言**:铜绿锈(主色·在场/健康/记忆)、鎏金(结构/发丝线)、朱漆(**仅**司命/朱批/告警)、墨/夜铜(暗底)。暗色优先,亮色一等公民。
|
||||
- **字阶**:宋体(Songti SC)显示字 + 系统体正文 + JetBrains Mono 数据/标签。
|
||||
- **签名元素**:九枢星盘是"活的仪器"(数据可视化),非装饰。
|
||||
- **a11y**:亮色 AA 对比度修正、`prefers-reduced-motion`、`focus-visible`、SVG `aria-label`。
|
||||
- **转 React**:原型共享层(`tokens` / `_base` / `_chrome` / `nav` / `_theme`)仅服务于设计稿;实现时按 section 重写为 React 组件,样式走 `globals.css` 的 `@theme` 映射类(见 `frontend/CLAUDE.md` 的 CSS 变量三层规则)。页面特异样式随组件迁移。
|
||||
|
||||
## 已废弃
|
||||
|
||||
- `copper-mirror-redesign.html`(v1,双面镜探索方向)——已被 v2 取代并删除,`git show HEAD:frontend/design/copper-mirror-redesign.html` 可取回。
|
||||
- `admin-preview.html.bak`——已删除。
|
||||
|
||||
## 维护脚本(`frontend/scripts/`)
|
||||
|
||||
- [`migrate-design.mjs`](../scripts/migrate-design.mjs) — 把原型接入共享层(加 `_chrome.css` link、替换 sidebar 为 mount、加 `_theme.js`)。一次性迁移已完成;新原型按上文模板手写即可。
|
||||
- [`clean-design-css.mjs`](../scripts/clean-design-css.mjs) — 清理各页与 `_base.css` / `_chrome.css` 重复的 body / reset / sidebar CSS(幂等,可重复跑)。
|
||||
- [`serve-design.mjs`](../scripts/serve-design.mjs) — 零依赖预览服务器,`pnpm design` 调用。
|
||||
@@ -0,0 +1,95 @@
|
||||
/* ============================================================
|
||||
* design/_base.css — 原型共享基底
|
||||
* ============================================================
|
||||
*
|
||||
* 用途:供 design/*.html 原型 <link> 引用。集中此前在每个原型
|
||||
* <style> 里字面重复的 reset / body / 极光铜晕 / 字体类 /
|
||||
* reduced-motion,消除 24 份副本。
|
||||
*
|
||||
* 依赖:必须在本文件之前 <link href="tokens.css"> —— 下方的
|
||||
* body 背景与极光底色均引用 token 变量。
|
||||
*
|
||||
* 字体策略:与生产 src/styles/globals.css 的 --font-sans 对齐,
|
||||
* 优先系统字体,避免 CJK 网页字体(15MB+)。
|
||||
* .serif 用宋族做显示字,.mono 用 JetBrains Mono 做数据/标签。
|
||||
* ============================================================ */
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: var(--ink);
|
||||
color: var(--fg);
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei",
|
||||
"Helvetica Neue", system-ui, sans-serif;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 极光铜晕:铜绿主导,把暗底拉向 verdigris-on-bronze。
|
||||
* 各原型此前字面一致,固定为设计语言的氛围底色。 */
|
||||
body::before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: -10vmax;
|
||||
z-index: -1;
|
||||
background:
|
||||
radial-gradient(
|
||||
54vmax 54vmax at 12% 4%,
|
||||
rgba(111, 163, 137, 0.2),
|
||||
transparent 60%
|
||||
),
|
||||
radial-gradient(
|
||||
40vmax 40vmax at 92% 8%,
|
||||
rgba(201, 162, 74, 0.1),
|
||||
transparent 60%
|
||||
),
|
||||
radial-gradient(
|
||||
60vmax 60vmax at 50% 112%,
|
||||
rgba(184, 57, 46, 0.06),
|
||||
transparent 60%
|
||||
);
|
||||
filter: blur(28px);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.serif {
|
||||
font-family:
|
||||
"Songti SC", "STSong", "Source Han Serif SC", "Noto Serif SC", serif;
|
||||
}
|
||||
.mono {
|
||||
font-family: "JetBrains Mono", "SF Mono", ui-monospace, monospace;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* iframe 缩略图态:被 index.html 的 live <iframe> 嵌入时(_theme.js 加 .in-frame),
|
||||
动画瞬间完成到末态、过渡归零——避免 25 个缩略图同时持续重绘耗 CPU。
|
||||
用 duration 归零而非 play-state:paused:确保入场动画(如 opacity 0→1)跑到
|
||||
末帧可见态,不会停在首帧导致元素消失。JS(rAF/setTimeout)驱动的动画
|
||||
(仅 chat)开销可控,不在此处理。 */
|
||||
.in-frame *,
|
||||
.in-frame *::before,
|
||||
.in-frame *::after {
|
||||
animation-duration: 0.001s !important;
|
||||
animation-delay: 0s !important;
|
||||
transition-duration: 0.001s !important;
|
||||
}
|
||||
@@ -0,0 +1,800 @@
|
||||
/* ============================================================
|
||||
* design/_chrome.css — 原型共享组件层(AppShell chrome)
|
||||
* ============================================================
|
||||
*
|
||||
* 用途:供所有 AppShell / NarrowShell 原型 <link> 引用。集中此前
|
||||
* 每个原型 <style> 里字面重复的 sidebar / 导航 / 卡片 / 按钮 /
|
||||
* 标签 / 页头 等组件样式,消除 25 份副本与已出现的写法分叉
|
||||
* (如角标写法分叉:部分页用 class,部分页内联)。
|
||||
*
|
||||
* 依赖:<link href="tokens.css"> 与 <link href="_base.css"> 必须在本
|
||||
* 文件之前——组件样式引用 token 变量,_base.css 提供 reset/body。
|
||||
*
|
||||
* 层次:tokens.css(变量)→ _base.css(reset/body/极光)→ _chrome.css
|
||||
* (共享组件)→ 页面 <style>(仅页面特异样式)。
|
||||
*
|
||||
* sidebar 注入:侧栏 DOM 由 _theme.js 从 _nav.html fetch 注入
|
||||
* 到 .sidebar-mount;本文件提供 .sidebar-* 样式。
|
||||
* ============================================================ */
|
||||
|
||||
/* ── AppShell 布局骨架 ── */
|
||||
.app-shell {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.sidebar-mount {
|
||||
display: flex;
|
||||
} /* 让注入的 .sidebar-wrap 拉伸填满本列全高 */
|
||||
.main-area {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* ── 侧栏(可折叠:默认 220 展开 / .collapsed 60 图标态)──
|
||||
DOM 由 _theme.js 从 _nav.html 注入;align-self + sticky 让长页面下贴顶滚动。
|
||||
折叠由 #sidebar-fold 触发,_theme.js 持久化到 localStorage。
|
||||
背景在 .sidebar-wrap 上(填满 flex 列高)而非 .sidebar(仅 100vh sticky)。
|
||||
border-right 同层,确保全高发丝线不断。 */
|
||||
.sidebar-wrap {
|
||||
display: flex;
|
||||
width: 220px;
|
||||
flex-shrink: 0;
|
||||
z-index: 30;
|
||||
transition:
|
||||
width 0.28s cubic-bezier(0.4, 0, 0.2, 1),
|
||||
box-shadow 0.28s;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
color-mix(in srgb, var(--night-bronze) 92%, var(--patina) 4%),
|
||||
var(--night-bronze)
|
||||
);
|
||||
border-right: 1px solid var(--rule);
|
||||
}
|
||||
.sidebar-wrap.collapsed {
|
||||
width: 60px;
|
||||
box-shadow: 8px 0 36px -10px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
.sidebar {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 12px 0 8px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
/* 顶栏:logo + 折叠按钮 */
|
||||
.sidebar-topbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 4px;
|
||||
padding: 6px 12px;
|
||||
}
|
||||
.sidebar-wrap.collapsed .sidebar-topbar {
|
||||
justify-content: center;
|
||||
padding: 6px 4px;
|
||||
}
|
||||
.sidebar .logo {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--fg);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
padding: 4px;
|
||||
}
|
||||
.sidebar .logo:hover {
|
||||
opacity: 0.85;
|
||||
}
|
||||
.sidebar .logo .logo-mark {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.sidebar .logo .logo-mark .knob {
|
||||
fill: var(--gilt);
|
||||
}
|
||||
|
||||
.sidebar-wrap.collapsed .sidebar .logo {
|
||||
font-size: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
.sidebar-wrap.collapsed .sidebar .logo .logo-mark {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* logo 彩蛋:tick(单击敲门)+ egg-pulse(1.2s 连点 5 次,金光 + 谶语) */
|
||||
@keyframes logoTick {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.07);
|
||||
}
|
||||
}
|
||||
.logo.tick .logo-mark {
|
||||
animation: logoTick 0.3s ease;
|
||||
}
|
||||
@keyframes logoEggPulse {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
filter: drop-shadow(0 0 0 transparent);
|
||||
}
|
||||
40% {
|
||||
transform: scale(1.2);
|
||||
filter: drop-shadow(0 0 7px var(--gilt));
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
filter: drop-shadow(0 0 0 transparent);
|
||||
}
|
||||
}
|
||||
.logo.egg-pulse .logo-mark {
|
||||
animation: logoEggPulse 1.4s ease;
|
||||
color: var(--gilt);
|
||||
}
|
||||
|
||||
/* 折叠按钮(折叠态旋转 180,箭头指向展开) */
|
||||
.sidebar-foldbtn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 8px;
|
||||
color: var(--muted);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
transition:
|
||||
background 0.12s,
|
||||
color 0.12s,
|
||||
transform 0.28s;
|
||||
}
|
||||
.sidebar-foldbtn:hover {
|
||||
background: var(--overlay-hover);
|
||||
color: var(--fg);
|
||||
}
|
||||
.sidebar-wrap.collapsed .sidebar-foldbtn {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* 图标默认(Lucide 风:stroke currentColor、fill none) */
|
||||
.sidebar .ico {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ── 导航组与条目 ── */
|
||||
.nav-group {
|
||||
margin-top: 14px;
|
||||
}
|
||||
.nav-group:first-of-type {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.nav-group-title {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--muted);
|
||||
padding: 0 18px;
|
||||
margin-bottom: 4px;
|
||||
opacity: 0.7;
|
||||
max-height: 22px;
|
||||
overflow: hidden;
|
||||
transition:
|
||||
opacity 0.18s,
|
||||
max-height 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
/* 载入组:新功能视觉区分(顶边鎏金淡线) */
|
||||
.nav-group.tavern {
|
||||
border-top: 1px solid var(--gilt-faint);
|
||||
padding-top: 14px;
|
||||
}
|
||||
.sidebar-wrap.collapsed .nav-group-title {
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 7px 18px;
|
||||
border-radius: 10px;
|
||||
font-size: 13.5px;
|
||||
font-weight: 500;
|
||||
color: var(--muted);
|
||||
text-decoration: none;
|
||||
transition:
|
||||
background var(--duration-fast),
|
||||
color var(--duration-fast),
|
||||
padding var(--duration-fast),
|
||||
box-shadow var(--duration-fast);
|
||||
cursor: pointer;
|
||||
gap: 10px;
|
||||
position: relative;
|
||||
}
|
||||
.nav-item:hover {
|
||||
background: var(--overlay-hover);
|
||||
color: var(--fg);
|
||||
}
|
||||
.nav-item.active {
|
||||
background: var(--patina-wash);
|
||||
color: var(--patina);
|
||||
box-shadow: inset 2px 0 0 var(--patina);
|
||||
}
|
||||
.nav-item .ico {
|
||||
opacity: 0.65;
|
||||
}
|
||||
.nav-item.active .ico {
|
||||
opacity: 1;
|
||||
}
|
||||
/* 司命台 · 朱漆语义(设计语言:朱漆仅司命/朱批/告警) */
|
||||
.nav-item.siming {
|
||||
color: var(--cinnabar);
|
||||
}
|
||||
.nav-item.siming:hover {
|
||||
background: var(--cinnabar-wash);
|
||||
color: var(--cinnabar);
|
||||
}
|
||||
.nav-item.siming.active {
|
||||
background: var(--cinnabar-wash);
|
||||
color: var(--cinnabar);
|
||||
}
|
||||
|
||||
/* ── 心智分层:灵枢(总览)↔ 维度(五行/人格/内驱力/演化)之间的分隔线
|
||||
.nav-item--overview 暂为语义标记(无额外样式),视觉分层仅靠 .nav-divider
|
||||
一条发丝线,不靠底色/字重——克制,避免总览项与 active 态混淆。 ── */
|
||||
.nav-divider {
|
||||
height: 1px;
|
||||
margin: 6px 18px;
|
||||
background: var(--rule);
|
||||
opacity: 0.8;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar-wrap.collapsed .nav-item {
|
||||
padding: 9px 0;
|
||||
font-size: 0;
|
||||
gap: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
.sidebar-wrap.collapsed .nav-item .ico {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.sidebar .spacer {
|
||||
flex: 1;
|
||||
min-height: 8px;
|
||||
}
|
||||
|
||||
/* ── 底栏:用户卡 + foot-btn + 主题 ── */
|
||||
.sidebar .user-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 12px;
|
||||
margin-top: 8px;
|
||||
border-top: 1px solid var(--rule);
|
||||
}
|
||||
.sidebar .user-card .avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--patina);
|
||||
color: var(--ink);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.sidebar .user-card .info {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
.sidebar .user-card .name {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--fg);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.sidebar .user-card .role {
|
||||
font-size: 12px;
|
||||
color: var(--muted);
|
||||
}
|
||||
.sidebar-wrap.collapsed .user-card {
|
||||
padding: 10px 0;
|
||||
gap: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
.sidebar-wrap.collapsed .user-card .info {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.foot-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 7px 18px;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
color: var(--muted);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
width: 100%;
|
||||
font-family: inherit;
|
||||
transition:
|
||||
background 0.12s,
|
||||
color 0.12s,
|
||||
padding 0.2s;
|
||||
}
|
||||
.foot-btn:hover {
|
||||
background: var(--overlay-hover);
|
||||
color: var(--fg);
|
||||
}
|
||||
.sidebar-wrap.collapsed .foot-btn {
|
||||
padding: 7px 0;
|
||||
font-size: 0;
|
||||
gap: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nav-item.nav-theme {
|
||||
margin: 0 8px;
|
||||
}
|
||||
.sidebar-wrap.collapsed .nav-item.nav-theme {
|
||||
margin: 0;
|
||||
padding: 9px 0;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ── 页头与标题 ──
|
||||
通用 .page-title/.page-sub 是默认(NarrowShell 22px);.page-header .page-title
|
||||
特异性更高、覆盖为 AppShell 19px。无 .page-head 容器的页直接用通用默认。 */
|
||||
.page-title {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--fg);
|
||||
margin: 0;
|
||||
}
|
||||
.page-sub {
|
||||
font-size: 13px;
|
||||
color: var(--fg-dim);
|
||||
margin-top: 3px;
|
||||
}
|
||||
.page-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 14px 28px;
|
||||
border-bottom: 1px solid var(--rule);
|
||||
background: var(--surface);
|
||||
backdrop-filter: blur(8px);
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.page-header .page-title {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 19px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--fg);
|
||||
}
|
||||
.page-header .page-sub {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 12px;
|
||||
color: var(--fg-faint);
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
.page-header .spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* ── 页体 ── */
|
||||
.page-body {
|
||||
flex: 1;
|
||||
padding: 24px 28px 56px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 22px;
|
||||
max-width: 1180px;
|
||||
width: 100%;
|
||||
}
|
||||
.section-label {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--fg-faint);
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.section-label .glyph {
|
||||
color: var(--gilt);
|
||||
opacity: 0.85;
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
.section-label .sub {
|
||||
color: var(--fg-dim);
|
||||
opacity: 0.7;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.section-label .count {
|
||||
font-size: 11px;
|
||||
color: var(--fg-dim);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* ── NarrowShell 主区(窄流程页:card-import / lorebook / character-*)
|
||||
AppShell 壳 + 窄主区;.app-main 居中限宽,配 .back-link 面包屑。 ── */
|
||||
.app-main {
|
||||
flex: 1;
|
||||
padding: 24px 28px 56px;
|
||||
max-width: 920px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.app-main.narrow {
|
||||
max-width: 760px;
|
||||
} /* 更窄:导入流程等 */
|
||||
.page-head {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.page-head .page-title {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--fg);
|
||||
margin: 0;
|
||||
}
|
||||
.page-head .page-sub {
|
||||
font-size: 13px;
|
||||
color: var(--fg-dim);
|
||||
margin-top: 3px;
|
||||
}
|
||||
.back-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
margin-bottom: 14px;
|
||||
font-size: 13px;
|
||||
color: var(--muted);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.back-link:hover {
|
||||
color: var(--patina);
|
||||
}
|
||||
|
||||
/* ── 卡片 ── */
|
||||
.card {
|
||||
border: 1px solid var(--rule);
|
||||
border-radius: 14px;
|
||||
background: var(--surface);
|
||||
overflow: hidden;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 20px 0;
|
||||
}
|
||||
.card-title {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: var(--fg);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
}
|
||||
.card-title .glyph {
|
||||
color: var(--patina);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.card-body {
|
||||
padding: 16px 20px 20px;
|
||||
}
|
||||
|
||||
/* ── 按钮 ── */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 7px 16px;
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background 0.12s,
|
||||
border-color 0.12s,
|
||||
color 0.12s;
|
||||
border: 1px solid transparent;
|
||||
text-decoration: none;
|
||||
}
|
||||
.btn-primary {
|
||||
background: var(--patina);
|
||||
color: var(--ink);
|
||||
border-color: var(--patina-dim);
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background: var(--patina-bright);
|
||||
}
|
||||
.btn-outline {
|
||||
background: transparent;
|
||||
color: var(--fg-dim);
|
||||
border-color: var(--rule);
|
||||
}
|
||||
.btn-outline:hover {
|
||||
background: var(--surface-hi);
|
||||
color: var(--fg);
|
||||
}
|
||||
.btn-sm {
|
||||
padding: 4px 11px;
|
||||
font-size: 11px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--muted);
|
||||
border: none;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
.btn-ghost:hover {
|
||||
color: var(--fg);
|
||||
background: var(--overlay-hover);
|
||||
}
|
||||
.btn-danger {
|
||||
background: transparent;
|
||||
color: var(--cinnabar);
|
||||
border-color: var(--cinnabar-dim);
|
||||
}
|
||||
.btn-danger:hover {
|
||||
background: var(--cinnabar-wash);
|
||||
color: var(--cinnabar);
|
||||
}
|
||||
.btn-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
border-radius: 8px;
|
||||
background: transparent;
|
||||
color: var(--muted);
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background var(--duration-fast),
|
||||
color var(--duration-fast);
|
||||
}
|
||||
.btn-icon:hover {
|
||||
background: var(--overlay-hover);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
/* ── 表单元素(统一 input / textarea / select / switch)── */
|
||||
.input,
|
||||
.textarea,
|
||||
.select {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid var(--rule);
|
||||
border-radius: 10px;
|
||||
background: var(--glass);
|
||||
color: var(--fg);
|
||||
font-family: inherit;
|
||||
font-size: 13px;
|
||||
transition: border-color var(--duration-fast);
|
||||
}
|
||||
.input:focus,
|
||||
.textarea:focus,
|
||||
.select:focus {
|
||||
outline: none;
|
||||
border-color: var(--patina-dim);
|
||||
}
|
||||
.textarea {
|
||||
min-height: 80px;
|
||||
resize: vertical;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.select {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.switch {
|
||||
position: relative;
|
||||
width: 32px;
|
||||
height: 18px;
|
||||
border-radius: 999px;
|
||||
background: var(--rule);
|
||||
cursor: pointer;
|
||||
transition: background var(--duration-fast);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.switch::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
border-radius: 50%;
|
||||
background: var(--fg-dim);
|
||||
transition:
|
||||
transform var(--duration-fast),
|
||||
background var(--duration-fast);
|
||||
}
|
||||
.switch.on {
|
||||
background: var(--patina-dim);
|
||||
}
|
||||
.switch.on::after {
|
||||
transform: translateX(14px);
|
||||
background: var(--patina);
|
||||
}
|
||||
|
||||
.field-label {
|
||||
display: block;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--muted);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/* ── 标签(通用胶囊)── */
|
||||
.tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 2px 9px;
|
||||
border-radius: 999px;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 10.5px;
|
||||
border: 1px solid;
|
||||
}
|
||||
.tag-gilt {
|
||||
border-color: var(--gilt-dim);
|
||||
color: var(--gilt);
|
||||
background: var(--gilt-faint);
|
||||
}
|
||||
.tag-patina {
|
||||
border-color: var(--patina-dim);
|
||||
color: var(--patina);
|
||||
background: var(--patina-wash);
|
||||
}
|
||||
|
||||
/* ── 状态药丸 ── */
|
||||
.stat-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 11.5px;
|
||||
color: var(--patina);
|
||||
padding: 4px 12px;
|
||||
border: 1px solid var(--patina-dim);
|
||||
border-radius: 999px;
|
||||
background: var(--patina-wash);
|
||||
}
|
||||
|
||||
/* ── 滚动条 ── */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--rule);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* ── 响应式:中屏折叠侧栏为图标态,窄屏隐藏 ── */
|
||||
@media (max-width: 1200px) and (min-width: 901px) {
|
||||
.sidebar-wrap {
|
||||
width: 60px;
|
||||
}
|
||||
.sidebar-wrap .nav-group-title {
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.sidebar-wrap .nav-item {
|
||||
padding: 9px 0;
|
||||
font-size: 0;
|
||||
gap: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
.sidebar-wrap .nav-item .ico {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
opacity: 1;
|
||||
}
|
||||
.sidebar-wrap .sidebar-topbar {
|
||||
justify-content: center;
|
||||
padding: 6px 4px;
|
||||
}
|
||||
.sidebar-wrap .sidebar .logo {
|
||||
font-size: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
.sidebar-wrap .sidebar .logo .logo-mark {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
.sidebar-wrap .user-card {
|
||||
padding: 10px 0;
|
||||
gap: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
.sidebar-wrap .user-card .info {
|
||||
display: none;
|
||||
}
|
||||
.sidebar-wrap .foot-btn {
|
||||
padding: 7px 0;
|
||||
font-size: 0;
|
||||
gap: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
.sidebar-wrap .nav-item.nav-theme {
|
||||
margin: 0;
|
||||
padding: 9px 0;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
@media (max-width: 900px) {
|
||||
.sidebar-wrap {
|
||||
display: none;
|
||||
}
|
||||
.page-body {
|
||||
padding: 18px 16px 40px;
|
||||
}
|
||||
.app-main {
|
||||
padding: 18px 16px 40px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<!-- ============================================================
|
||||
design/_nav.html — 统一侧栏片段(全功能版)
|
||||
============================================================
|
||||
由 _theme.js fetch 注入各页 .sidebar-mount。改这里全站同步。
|
||||
|
||||
能力:
|
||||
· 7 组 20 项导航,每项带 Lucide 图标(折叠态只显图标)
|
||||
· 每项带 data-route(hover 显示路由角标,_chrome.css 渲染)
|
||||
· logo 鎏金 mark + 折叠按钮(#sidebar-fold 切换 .collapsed)
|
||||
· 心智组分层:灵枢(总览)↔ 维度(五行 / 人格 / 内驱力 / 演化)
|
||||
· user-card 底部用户信息 + foot-btn 设计系统入口
|
||||
· theme-toggle 按钮(#theme-toggle)
|
||||
|
||||
分组语义(2026-07-27 重组):
|
||||
· 「编排」原「载入」——该组横跨数据载入(魂册降生 / 世谱)
|
||||
与运行时编排(符文引擎 / 眉批),「编排」涵盖两者。
|
||||
· tavern class 名保留(内部标识,_chrome.css 据此加视觉区分)。
|
||||
|
||||
折叠:.sidebar-wrap.collapsed → 60px 图标态(_theme.js 控制 + 持久化)
|
||||
高亮:data-active 命中 data-nav → .active
|
||||
图标 stroke/fill 由 _chrome.css 的 .ico 统一
|
||||
============================================================ -->
|
||||
<div class="sidebar-wrap">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-topbar">
|
||||
<button class="logo" type="button" data-nav="home" title="返回目录 · 五连点见镜启">
|
||||
<svg class="logo-mark" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="8.5" /><circle cx="12" cy="12" r="4.5" opacity="0.45" /><circle class="knob" cx="12" cy="12" r="1.6" /></svg>
|
||||
魂鏡
|
||||
</button>
|
||||
<button class="sidebar-foldbtn" id="sidebar-fold" type="button" aria-label="折叠侧栏">
|
||||
<svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="nav-group">
|
||||
<div class="nav-group-title">灵台</div>
|
||||
<a class="nav-item" data-nav="对话" data-route="/chat" href="chat-redesign-preview.html" title="对话"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" /></svg>对话</a>
|
||||
<a class="nav-item" data-nav="轨迹" data-route="/runs/[id]" href="run-trace-preview.html" title="运行轨迹"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12" /></svg>轨迹</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-group">
|
||||
<div class="nav-group-title">魂册</div>
|
||||
<a class="nav-item" data-nav="人物" data-route="/characters" href="characters-preview.html" title="人物列表"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /></svg>人物</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-group">
|
||||
<div class="nav-group-title">心智</div>
|
||||
<a class="nav-item nav-item--overview" data-nav="灵枢" data-route="/cosmos" href="cosmos-preview.html" title="灵枢 · 心智总览"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="4" /><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" /></svg>灵枢</a>
|
||||
<div class="nav-divider" role="separator" aria-label="心智维度"></div>
|
||||
<a class="nav-item" data-nav="五行" data-route="/wuxing" href="wuxing-preview.html" title="五行生克"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.07-2.14-.22-4.05 2-6 .5 2.5 2 4.9 4 6.5s3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.15.43-2.29 1-3a2.5 2.5 0 0 0 2.5 2.5z" /></svg>五行</a>
|
||||
<a class="nav-item" data-nav="人格" data-route="/personality" href="personality-preview.html" title="人格定义"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10" /><path d="M8 14s1.5 2 4 2 4-2 4-2" /><line x1="9" y1="9" x2="9.01" y2="9" /><line x1="15" y1="9" x2="15.01" y2="9" /></svg>人格</a>
|
||||
<a class="nav-item" data-nav="内驱力" data-route="/drive" href="drive-preview.html" title="内驱力"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10" /><circle cx="12" cy="12" r="6" /><circle cx="12" cy="12" r="2" /></svg>内驱力</a>
|
||||
<a class="nav-item" data-nav="演化" data-route="/evolution" href="evolution-preview.html" title="大周天演化"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17" /><polyline points="16 7 22 7 22 13" /></svg>演化</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-group tavern">
|
||||
<div class="nav-group-title">编排</div>
|
||||
<a class="nav-item" data-nav="魂册降生" data-route="/characters/import" href="card-import-preview.html" title="魂册降生 · 角色卡导入"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><line x1="19" y1="8" x2="19" y2="14" /><line x1="22" y1="11" x2="16" y2="11" /></svg>魂册降生</a>
|
||||
<a class="nav-item" data-nav="世谱" data-route="/lorebooks" href="lorebook-preview.html" title="世谱 · 世界设定"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z" /><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z" /></svg>世谱</a>
|
||||
<a class="nav-item" data-nav="符文引擎" data-route="/macros" href="rune-engine-preview.html" title="符文引擎 · 占位符显化"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 3l1.9 5.8L20 11l-6.1 2.2L12 19l-1.9-5.8L4 11l6.1-2.2z" /></svg>符文引擎</a>
|
||||
<a class="nav-item" data-nav="眉批" data-route="/author-notes" href="margin-notes-preview.html" title="眉批 · 深度注入"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 20h9" /><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4z" /></svg>眉批</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-group">
|
||||
<div class="nav-group-title">内景</div>
|
||||
<a class="nav-item" data-nav="世界" data-route="/world" href="world-preview.html" title="世界 · 河图绘形"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10" /><line x1="2" y1="12" x2="22" y2="12" /><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /></svg>世界</a>
|
||||
<a class="nav-item" data-nav="时态" data-route="/time" href="time-preview.html" title="时态 · 时间线"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10" /><polyline points="12 6 12 12 16 14" /></svg>时态</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-group">
|
||||
<div class="nav-group-title">藏识</div>
|
||||
<a class="nav-item" data-nav="记忆" data-route="/memory" href="memory-preview.html" title="记忆 · 息壤"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><ellipse cx="12" cy="5" rx="9" ry="3" /><path d="M3 5v14a9 3 0 0 0 18 0V5" /><path d="M3 12a9 3 0 0 0 18 0" /></svg>记忆</a>
|
||||
<a class="nav-item" data-nav="归档" data-route="/archive" href="archive-preview.html" title="归档 · 记忆时间河"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><rect x="2" y="4" width="20" height="5" rx="1" /><path d="M4 9v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9" /><line x1="10" y1="13" x2="14" y2="13" /></svg>归档</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-group">
|
||||
<div class="nav-group-title">百工</div>
|
||||
<a class="nav-item" data-nav="工具" data-route="/tools" href="tools-preview.html" title="工具调用"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" /></svg>工具</a>
|
||||
<a class="nav-item" data-nav="模型网关" data-route="/models" href="model-gateway-preview.html" title="模型网关"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><rect x="4" y="4" width="16" height="16" rx="2" /><rect x="9" y="9" width="6" height="6" /><path d="M9 2v2M15 2v2M9 20v2M15 20v2M2 9h2M2 15h2M20 9h2M20 15h2" /></svg>模型网关</a>
|
||||
<a class="nav-item" data-nav="设置" data-route="/settings" href="settings-preview.html" title="设置"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><line x1="4" y1="21" x2="4" y2="14" /><line x1="4" y1="10" x2="4" y2="3" /><line x1="12" y1="21" x2="12" y2="12" /><line x1="12" y1="8" x2="12" y2="3" /><line x1="20" y1="21" x2="20" y2="16" /><line x1="20" y1="12" x2="20" y2="3" /><line x1="1" y1="14" x2="7" y2="14" /><line x1="9" y1="8" x2="15" y2="8" /><line x1="17" y1="16" x2="23" y2="16" /></svg>设置</a>
|
||||
<a class="nav-item siming" data-nav="司命台" data-route="/admin" href="admin-preview.html" title="司命台 · 管理控制台"><svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" /></svg>司命台</a>
|
||||
</div>
|
||||
|
||||
<div class="spacer"></div>
|
||||
|
||||
<!-- 底部:用户卡 + 设计系统入口 + 主题(「设置」已在百工组,不在此重复) -->
|
||||
<div class="user-card">
|
||||
<div class="avatar">辰</div>
|
||||
<div class="info">
|
||||
<div class="name">辰</div>
|
||||
<div class="role">司命</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="foot-btn" href="copper-mirror-redesign-v2.html" title="设计系统 · 北极星基准">
|
||||
<svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="10" /><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76" /></svg>
|
||||
<span class="foot-label">设计系统</span>
|
||||
</a>
|
||||
<button class="nav-item nav-theme" id="theme-toggle" type="button">
|
||||
<svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" /></svg>
|
||||
<span id="theme-label">夜铜</span>
|
||||
</button>
|
||||
</aside>
|
||||
</div>
|
||||
@@ -0,0 +1,208 @@
|
||||
/* ============================================================
|
||||
* design/_theme.js — 原型共享脚本层
|
||||
* ============================================================
|
||||
* 职责:
|
||||
* 1. fetch _nav.html → 注入各页 .sidebar-mount
|
||||
* 2. 按 mount 的 data-active 高亮当前页 nav-item
|
||||
* 3. logo 点击 → index.html(目录入口)
|
||||
* 4. #theme-toggle 切换暗/亮,localStorage 持久化
|
||||
*
|
||||
* file:// 限制:fetch 在 file:// 协议下被 CORS 拦截,会显示 fallback
|
||||
* 提示。请用 `pnpm design` 启动本地预览服务器获得完整导航。
|
||||
*
|
||||
* 用法:页面末尾 <script src="_theme.js" defer></script>
|
||||
* 页面 body 内放 <div class="sidebar-mount" data-active="页面名"></div>
|
||||
* ============================================================ */
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var ROOT = document.documentElement;
|
||||
|
||||
/* iframe 缩略图态:index.html 以 live <iframe> 嵌入各原型页做缩略图;
|
||||
检测嵌入态加 .in-frame,由 _base.css 把动画瞬间完成,避免 25 个
|
||||
缩略图同时持续重绘而耗 CPU。 */
|
||||
if (window.self !== window.top) ROOT.classList.add("in-frame");
|
||||
|
||||
function currentTheme() {
|
||||
return ROOT.dataset.theme === "light" ? "light" : "dark";
|
||||
}
|
||||
function applyTheme(t) {
|
||||
ROOT.dataset.theme = t;
|
||||
try {
|
||||
localStorage.setItem("design-theme", t);
|
||||
} catch (e) {}
|
||||
document.querySelectorAll("#theme-label").forEach(function (l) {
|
||||
l.textContent = t === "dark" ? "夜铜" : "素绢";
|
||||
});
|
||||
}
|
||||
function toggleTheme() {
|
||||
applyTheme(currentTheme() === "dark" ? "light" : "dark");
|
||||
}
|
||||
|
||||
/* 恢复上次主题(减轻刷新闪屏;data-theme 默认 dark 在 <html> 上已设) */
|
||||
try {
|
||||
var saved = localStorage.getItem("design-theme");
|
||||
if (saved === "light" || saved === "dark") ROOT.dataset.theme = saved;
|
||||
} catch (e) {}
|
||||
|
||||
/* 事件委托:logo / 主题按钮(nav 注入前后都生效,index 页独立按钮也覆盖) */
|
||||
document.addEventListener("click", function (e) {
|
||||
var t = e.target;
|
||||
if (!t || !t.closest) return;
|
||||
if (t.closest("#theme-toggle")) {
|
||||
e.preventDefault();
|
||||
toggleTheme();
|
||||
return;
|
||||
}
|
||||
if (t.closest("#sidebar-fold")) {
|
||||
e.preventDefault();
|
||||
toggleFold();
|
||||
return;
|
||||
}
|
||||
if (t.closest(".sidebar .logo")) {
|
||||
e.preventDefault();
|
||||
onLogoClick();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
/* 折叠侧栏(chat 默认折叠让对话区扩展,其他页默认展开;localStorage 持久化) */
|
||||
function applyFold(state) {
|
||||
document.querySelectorAll(".sidebar-wrap").forEach(function (w) {
|
||||
w.classList.toggle("collapsed", state === "collapsed");
|
||||
});
|
||||
}
|
||||
function toggleFold() {
|
||||
var wrap = document.querySelector(".sidebar-wrap");
|
||||
if (!wrap) return;
|
||||
var collapsed = wrap.classList.toggle("collapsed");
|
||||
try {
|
||||
localStorage.setItem(
|
||||
"design-sidebar",
|
||||
collapsed ? "collapsed" : "expanded",
|
||||
);
|
||||
} catch (e) {}
|
||||
}
|
||||
function initFold() {
|
||||
var mount = document.querySelector(".sidebar-mount");
|
||||
var isChat = mount && mount.dataset.active === "对话";
|
||||
var saved = null;
|
||||
try {
|
||||
saved = localStorage.getItem("design-sidebar");
|
||||
} catch (e) {}
|
||||
applyFold(saved || (isChat ? "collapsed" : "expanded"));
|
||||
}
|
||||
|
||||
/* ── logo:单击即时回目录;350ms 内连点 5 次触发「镜启」彩蛋(不跳转)── */
|
||||
var EGG_VERSES = [
|
||||
"镜中有镜,心外无心。",
|
||||
"汝来看此镜时,此镜亦照汝。",
|
||||
"一念起,万镜生。",
|
||||
"镜非鉴物,乃鉴心也。",
|
||||
"幻由心生,镜随心转。",
|
||||
"九枢归一,一归于何处?",
|
||||
"铜镜本无字,照尽往来人。",
|
||||
"且向镜中看,那个是谁?",
|
||||
];
|
||||
var logoClickSeq = 0;
|
||||
var lastLogoTime = 0;
|
||||
|
||||
function showEggToast(msg) {
|
||||
var toast = document.createElement("div");
|
||||
toast.textContent = msg;
|
||||
toast.style.cssText =
|
||||
"position:fixed;bottom:48px;left:50%;transform:translateX(-50%);padding:12px 28px;border-radius:12px;background:var(--patina-wash);color:var(--patina);font-family:'Songti SC',serif;font-size:14px;border:1px solid var(--patina-dim);z-index:9999;pointer-events:none;opacity:0;transition:opacity 0.4s;";
|
||||
document.body.appendChild(toast);
|
||||
requestAnimationFrame(function () {
|
||||
toast.style.opacity = "1";
|
||||
});
|
||||
setTimeout(function () {
|
||||
toast.style.opacity = "0";
|
||||
setTimeout(function () {
|
||||
toast.remove();
|
||||
}, 400);
|
||||
}, 2200);
|
||||
}
|
||||
|
||||
function onLogoClick() {
|
||||
var logoEl = document.querySelector(".sidebar .logo");
|
||||
var now = Date.now();
|
||||
var fast = now - lastLogoTime < 350; /* 350ms 内视为连点 */
|
||||
lastLogoTime = now;
|
||||
if (fast) {
|
||||
logoClickSeq += 1;
|
||||
if (logoEl) {
|
||||
logoEl.classList.add("tick");
|
||||
setTimeout(function () {
|
||||
logoEl.classList.remove("tick");
|
||||
}, 300);
|
||||
}
|
||||
if (logoClickSeq >= 5) {
|
||||
/* 5 连点:镜启彩蛋,不跳转 */
|
||||
logoClickSeq = 0;
|
||||
var v = EGG_VERSES[Math.floor(Math.random() * EGG_VERSES.length)];
|
||||
if (logoEl) {
|
||||
logoEl.classList.add("egg-pulse");
|
||||
setTimeout(function () {
|
||||
logoEl.classList.remove("egg-pulse");
|
||||
}, 1400);
|
||||
}
|
||||
showEggToast("镜启 · " + v);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* 单击(间隔 > 350ms):tick 反馈后立即回目录 */
|
||||
logoClickSeq = 0;
|
||||
if (logoEl) {
|
||||
logoEl.classList.add("tick");
|
||||
setTimeout(function () {
|
||||
logoEl.classList.remove("tick");
|
||||
}, 300);
|
||||
}
|
||||
location.href = "index.html";
|
||||
}
|
||||
|
||||
function highlightActive(mount) {
|
||||
var key = mount.dataset.active;
|
||||
if (!key) return;
|
||||
var item = mount.querySelector('[data-nav="' + key + '"]');
|
||||
if (item) item.classList.add("active");
|
||||
}
|
||||
|
||||
/* file:// fallback:提示需启动本地服务器 */
|
||||
function showFallback(mount) {
|
||||
mount.innerHTML =
|
||||
'<div class="sidebar-wrap"><aside class="sidebar" style="padding:48px 20px;text-align:center;display:flex;flex-direction:column;gap:18px;align-items:center">' +
|
||||
"<div style=\"font-family:'Songti SC',serif;font-size:18px;font-weight:700;letter-spacing:0.1em;color:var(--fg)\">魂鏡</div>" +
|
||||
'<div style="font-size:12px;color:var(--fg-dim);line-height:1.7">导航需本地预览服务器<br/><code style="font-family:\'JetBrains Mono\',monospace;font-size:11px;color:var(--patina)">pnpm design</code></div>' +
|
||||
'<a class="nav-item" href="index.html" style="justify-content:center;border:1px solid var(--rule);padding:7px 16px">← 目录</a>' +
|
||||
"</aside></div>";
|
||||
}
|
||||
|
||||
function injectNav() {
|
||||
var mounts = document.querySelectorAll(".sidebar-mount");
|
||||
if (!mounts.length) return;
|
||||
fetch("_nav.html", { cache: "no-cache" })
|
||||
.then(function (res) {
|
||||
if (!res.ok) throw new Error(String(res.status));
|
||||
return res.text();
|
||||
})
|
||||
.then(function (html) {
|
||||
mounts.forEach(function (m) {
|
||||
m.innerHTML = html;
|
||||
highlightActive(m);
|
||||
});
|
||||
applyTheme(currentTheme()); /* 注入后同步主题标签文案 */
|
||||
initFold(); /* 恢复折叠态 */
|
||||
})
|
||||
.catch(function () {
|
||||
mounts.forEach(showFallback);
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", injectNav);
|
||||
} else {
|
||||
injectNav();
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,752 @@
|
||||
<!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.3 — 司命台 · 人物模板管理(§19.8)
|
||||
*
|
||||
* 文档基准:docs/product/master-prd.md §2-§5
|
||||
* · 铜镜四态 = MirrorState 健康度(void/breathing/steady/cracked),§2.3
|
||||
* · 三签分层:星盘(空间·主角)/ 朱批(动作)/ 起居注(时间),§3
|
||||
* · 司命台独立壳层(AdminShell 横向导航),§4
|
||||
*
|
||||
* data-view:char-templates
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 司命台壳层 ── */
|
||||
.admin-shell { display: flex; flex-direction: column; min-height: 100vh; }
|
||||
.topbar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 10px; padding: 10px 28px; border-bottom: 1px solid var(--rule); background: var(--surface); backdrop-filter: blur(16px) saturate(140%); flex-wrap: wrap; }
|
||||
.topbar-brand { font-family: "Songti SC", serif; font-size: 17px; font-weight: 700; letter-spacing: 0.06em; color: var(--fg); display: flex; align-items: center; gap: 7px; flex-shrink: 0; cursor: pointer; }
|
||||
.topbar-brand .knob { width: 16px; height: 16px; }
|
||||
.topbar-brand .knob circle:last-child { fill: var(--cinnabar); }
|
||||
.topbar-sep { color: var(--fg-faint); opacity: 0.5; flex-shrink: 0; }
|
||||
.topbar-nav { display: flex; align-items: center; gap: 1px; flex-wrap: wrap; }
|
||||
.topbar-navitem { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 8px; font-size: 13px; font-weight: 500; color: var(--muted); text-decoration: none; transition: background 0.12s, color 0.12s; cursor: pointer; background: none; border: none; font-family: inherit; }
|
||||
.topbar-navitem:hover { background: var(--overlay-hover); color: var(--fg); }
|
||||
.topbar-navitem.active { background: var(--patina-wash); color: var(--patina); }
|
||||
.topbar-navitem.pivot { font-size: 12px; padding: 4px 9px; }
|
||||
.topbar-spacer { flex: 1; }
|
||||
|
||||
/* ── 视图与页头 ── */
|
||||
main { flex: 1; display: flex; flex-direction: column; min-height: 0; }
|
||||
|
||||
.page-header .spacer { flex: 1; }
|
||||
.header-badge { display: inline-flex; align-items: center; gap: 6px; font-family: "JetBrains Mono", monospace; font-size: 11.5px; padding: 4px 12px; border-radius: 999px; border: 1px solid var(--patina-dim); color: var(--patina); background: var(--patina-wash); }
|
||||
.view-body { flex: 1; padding: 16px 28px 48px; display: flex; flex-direction: column; gap: 22px; max-width: 1180px; width: 100%; overflow-y: auto; }
|
||||
|
||||
.section-label .glyph { color: var(--cinnabar); opacity: 0.85; }
|
||||
.section-heading { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin-bottom: 12px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
||||
.section-heading .sub { font-size: 12px; font-weight: 400; color: var(--fg-dim); margin-left: 6px; }
|
||||
.section-heading .glyph { color: var(--cinnabar); opacity: 0.85; }
|
||||
|
||||
/* ── 操作栏 ── */
|
||||
.toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
|
||||
.toolbar .spacer { flex: 1; }
|
||||
|
||||
|
||||
.btn-danger { border-color: var(--cinnabar-dim); background: var(--cinnabar-wash); color: var(--cinnabar); }
|
||||
.btn-danger:hover { background: var(--cinnabar-dim); color: var(--fg); }
|
||||
|
||||
.btn-icon { padding: 6px; min-width: 0; }
|
||||
.search-input { display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border: 1px solid var(--rule); border-radius: 10px; background: var(--surface); color: var(--fg); font-family: inherit; font-size: 13px; min-width: 200px; transition: border-color 0.15s; }
|
||||
.search-input:focus { outline: none; border-color: var(--patina-dim); }
|
||||
.search-input::placeholder { color: var(--fg-faint); }
|
||||
|
||||
/* ── 模板列表 ── */
|
||||
.template-table { width: 100%; border-collapse: separate; border-spacing: 0; }
|
||||
.template-table th { font-family: "JetBrains Mono", monospace; font-size: 11.5px; letter-spacing: 0.06em; color: var(--fg-faint); padding: 10px 14px; text-align: left; border-bottom: 1px solid var(--rule); font-weight: 500; }
|
||||
.template-table td { padding: 12px 14px; border-bottom: 1px solid var(--rule); font-size: 14px; vertical-align: top; }
|
||||
.template-table tr:hover td { background: var(--surface-hi); }
|
||||
.template-table .key-cell { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--gilt); white-space: nowrap; }
|
||||
.template-table .name-cell { font-weight: 600; }
|
||||
.template-table .display-name-cell { color: var(--fg-dim); }
|
||||
.template-table .desc-cell { color: var(--fg-dim); max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.template-table .date-cell { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg-faint); white-space: nowrap; }
|
||||
.template-table .actions-cell { white-space: nowrap; text-align: right; }
|
||||
.template-table .actions-cell .btn { margin-left: 4px; }
|
||||
|
||||
/* ── 标签 ── */
|
||||
|
||||
.tag-default { background: var(--patina-wash); color: var(--patina); border: 1px solid var(--patina-dim); }
|
||||
.tag-api { background: var(--blue-wash); color: var(--blue); border: 1px solid var(--blue-dim); }
|
||||
.tag-yaml { background: var(--gilt-faint); color: var(--gilt); border: 1px solid var(--gilt-dim); }
|
||||
|
||||
/* ── 空状态 ── */
|
||||
.empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 60px 20px; text-align: center; }
|
||||
.empty-state .glyph { font-size: 36px; margin-bottom: 12px; opacity: 0.3; }
|
||||
.empty-state .title { font-family: "Songti SC", serif; font-size: 16px; color: var(--fg-dim); }
|
||||
.empty-state .desc { font-size: 13px; color: var(--fg-faint); margin-top: 6px; }
|
||||
|
||||
/* ── Modal ── */
|
||||
.modal-overlay { position: fixed; inset: 0; z-index: 100; background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(6px); display: flex; align-items: center; justify-content: center; padding: 20px; }
|
||||
.modal { background: var(--ink); border: 1px solid var(--rule); border-radius: 18px; width: 100%; max-width: 620px; max-height: 88vh; display: flex; flex-direction: column; box-shadow: 0 12px 60px rgba(0, 0, 0, 0.6); }
|
||||
.modal-header { display: flex; align-items: center; gap: 12px; padding: 18px 22px 10px; border-bottom: 1px solid var(--rule); }
|
||||
.modal-title { font-family: "Songti SC", serif; font-size: 17px; font-weight: 600; color: var(--fg); flex: 1; }
|
||||
.modal-close { width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; border-radius: 8px; cursor: pointer; border: none; background: none; color: var(--fg-faint); font-size: 18px; transition: background 0.12s, color 0.12s; }
|
||||
.modal-close:hover { background: var(--surface-hi); color: var(--fg); }
|
||||
.modal-body { flex: 1; overflow-y: auto; padding: 18px 22px 22px; display: flex; flex-direction: column; gap: 16px; }
|
||||
.modal-footer { display: flex; align-items: center; gap: 10px; padding: 12px 22px 18px; border-top: 1px solid var(--rule); justify-content: flex-end; }
|
||||
|
||||
.field { display: flex; flex-direction: column; gap: 5px; }
|
||||
.field-label { font-family: "JetBrains Mono", monospace; font-size: 11.5px; letter-spacing: 0.06em; color: var(--fg-faint); }
|
||||
.field-hint { font-size: 12px; color: var(--fg-faint); margin-top: 2px; }
|
||||
.field input, .field textarea, .field select { padding: 8px 12px; border: 1px solid var(--rule); border-radius: 10px; background: var(--surface); color: var(--fg); font-family: inherit; font-size: 13px; transition: border-color 0.15s; width: 100%; }
|
||||
.field input:focus, .field textarea:focus, .field select:focus { outline: none; border-color: var(--patina-dim); }
|
||||
.field textarea { min-height: 72px; resize: vertical; }
|
||||
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
||||
|
||||
/* ── Separator ── */
|
||||
.form-section { margin-top: 4px; padding-top: 14px; border-top: 1px solid var(--rule); }
|
||||
.form-section-title { font-family: "Songti SC", serif; font-size: 13px; font-weight: 600; color: var(--gilt); margin-bottom: 12px; display: flex; align-items: center; gap: 6px; }
|
||||
.form-section-title .glyph { opacity: 0.6; }
|
||||
|
||||
/* ── Tag input (hobbies/values) ── */
|
||||
.tag-input-wrap { display: flex; flex-wrap: wrap; gap: 5px; padding: 6px 8px; border: 1px solid var(--rule); border-radius: 10px; background: var(--surface); min-height: 36px; align-items: center; cursor: text; transition: border-color 0.15s; }
|
||||
.tag-input-wrap:focus-within { border-color: var(--patina-dim); }
|
||||
.tag-input-tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 999px; font-size: 12px; background: var(--patina-wash); color: var(--patina); border: 1px solid var(--patina-dim); }
|
||||
.tag-input-tag .remove { cursor: pointer; opacity: 0.5; font-size: 14px; line-height: 1; margin-left: 2px; }
|
||||
.tag-input-tag .remove:hover { opacity: 1; color: var(--cinnabar); }
|
||||
.tag-input-native { border: none !important; background: transparent !important; outline: none !important; flex: 1; min-width: 80px; padding: 2px 4px; font-size: 13px; color: var(--fg); font-family: inherit; }
|
||||
|
||||
/* ── Detail modal extra ── */
|
||||
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
|
||||
.detail-item { border: 1px solid var(--rule); border-radius: 10px; padding: 12px; background: var(--surface); }
|
||||
.detail-item.full { grid-column: 1 / -1; }
|
||||
.detail-item .label { font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.06em; color: var(--fg-faint); margin-bottom: 4px; }
|
||||
.detail-item .value { font-size: 13px; color: var(--fg); white-space: pre-wrap; }
|
||||
.detail-item .value.json { font-family: "JetBrains Mono", monospace; font-size: 11.5px; }
|
||||
|
||||
/* ── Delete confirmation ── */
|
||||
.confirm-box { border: 1px solid var(--cinnabar-dim); border-radius: 12px; padding: 16px; background: var(--cinnabar-wash); display: flex; flex-direction: column; gap: 10px; }
|
||||
.confirm-box .title { font-size: 14px; font-weight: 600; color: var(--cinnabar); }
|
||||
.confirm-box .desc { font-size: 13px; color: var(--fg-dim); }
|
||||
|
||||
/* ── Toast ── */
|
||||
.toast { position: fixed; bottom: 24px; right: 24px; z-index: 200; display: flex; align-items: center; gap: 10px; padding: 12px 18px; border-radius: 12px; border: 1px solid var(--patina-dim); background: var(--surface); backdrop-filter: blur(12px); box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5); font-size: 13px; color: var(--patina); }
|
||||
.toast.error { border-color: var(--cinnabar-dim); color: var(--cinnabar); }
|
||||
|
||||
/* ── Responsive ── */
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.view-body { padding: 12px 16px 36px; }
|
||||
.field-row { grid-template-columns: 1fr; }
|
||||
.detail-grid { grid-template-columns: 1fr; }
|
||||
.template-table th, .template-table td { padding: 8px 10px; }
|
||||
.template-table .desc-cell { display: none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-mount" data-active="司命台"></div>
|
||||
<div class="main-area">
|
||||
<div class="admin-shell">
|
||||
|
||||
<!-- ═══ 司命台顶栏 ═══ -->
|
||||
<header class="topbar">
|
||||
<div class="topbar-brand">
|
||||
<svg class="knob" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6" fill="none" stroke="var(--gilt)" stroke-width="1.3"/><circle cx="8" cy="8" r="2"/></svg>
|
||||
司命台
|
||||
</div>
|
||||
<span class="topbar-sep">|</span>
|
||||
<nav class="topbar-nav">
|
||||
<span class="topbar-navitem">星盘</span>
|
||||
<span class="topbar-navitem">朱批</span>
|
||||
<span class="topbar-navitem">起居注</span>
|
||||
<span class="topbar-navitem">太一</span>
|
||||
<span class="topbar-navitem">烛照</span>
|
||||
<span class="topbar-navitem">河图</span>
|
||||
<span class="topbar-navitem">洛书</span>
|
||||
<span class="topbar-navitem">天工阁</span>
|
||||
<span class="topbar-navitem">用户</span>
|
||||
<span class="topbar-navitem active">人物模板</span>
|
||||
<span class="topbar-navitem">链路</span>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<!-- ═══ 页头 ═══ -->
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">人物模板</h1>
|
||||
<span class="page-sub">Character Templates · §19.8</span>
|
||||
<span class="header-badge">2 个模板</span>
|
||||
<div class="spacer"></div>
|
||||
<button class="btn btn-primary" onclick="openCreate()">✦ 新建模板</button>
|
||||
</div>
|
||||
|
||||
<div class="view-body">
|
||||
|
||||
<!-- ── 操作栏 ── -->
|
||||
<div class="toolbar">
|
||||
<input class="search-input" type="text" placeholder="搜索模板 key 或名称…" />
|
||||
<div class="spacer"></div>
|
||||
<button class="btn btn-sm" onclick="syncFromYaml()">↻ 从 YAML 同步</button>
|
||||
</div>
|
||||
|
||||
<!-- ── 模板列表 ── -->
|
||||
<table class="template-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
<th>名称</th>
|
||||
<th>显示名</th>
|
||||
<th>来源</th>
|
||||
<th>简介</th>
|
||||
<th>创建时间</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- 魂镜(YAML 管理) -->
|
||||
<tr>
|
||||
<td class="key-cell">default</td>
|
||||
<td class="name-cell">魂镜</td>
|
||||
<td class="display-name-cell">魂镜</td>
|
||||
<td><span class="tag tag-yaml">YAML</span></td>
|
||||
<td class="desc-cell">一面照见人心的镜子</td>
|
||||
<td class="date-cell">2026-06-19</td>
|
||||
<td class="actions-cell">
|
||||
<button class="btn btn-sm" onclick="openDetail('default')">查看</button>
|
||||
<button class="btn btn-sm" onclick="openEdit('default')">编辑</button>
|
||||
<button class="btn btn-sm btn-danger" onclick="confirmDelete('default')">删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 时崎狂三(YAML 管理) -->
|
||||
<tr>
|
||||
<td class="key-cell">tokisaki_kurumi</td>
|
||||
<td class="name-cell">时崎狂三</td>
|
||||
<td class="display-name-cell">时崎狂三</td>
|
||||
<td><span class="tag tag-yaml">YAML</span></td>
|
||||
<td class="desc-cell">被称为「梦魇」的时间精灵</td>
|
||||
<td class="date-cell">2026-07-09</td>
|
||||
<td class="actions-cell">
|
||||
<button class="btn btn-sm" onclick="openDetail('tokisaki_kurumi')">查看</button>
|
||||
<button class="btn btn-sm" onclick="openEdit('tokisaki_kurumi')">编辑</button>
|
||||
<button class="btn btn-sm btn-danger" onclick="confirmDelete('tokisaki_kurumi')">删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- API 创建的模板 -->
|
||||
<tr>
|
||||
<td class="key-cell">api_gufeng</td>
|
||||
<td class="name-cell">古风人物</td>
|
||||
<td class="display-name-cell">墨语</td>
|
||||
<td><span class="tag tag-api">API</span></td>
|
||||
<td class="desc-cell">穿越千年而来的书卷气</td>
|
||||
<td class="date-cell">2026-07-13</td>
|
||||
<td class="actions-cell">
|
||||
<button class="btn btn-sm" onclick="openDetail('api_gufeng')">查看</button>
|
||||
<button class="btn btn-sm" onclick="openEdit('api_gufeng')">编辑</button>
|
||||
<button class="btn btn-sm btn-danger" onclick="confirmDelete('api_gufeng')">删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- ── 来自 YAML 的提示 ── -->
|
||||
<div class="detail-item" style="border-style:dashed;">
|
||||
<div class="label">⚠ YAML 管理提示</div>
|
||||
<div style="font-size:13px; color:var(--fg-dim);">
|
||||
key 与 <code style="font-size:12px; color:var(--gilt);">config/character_templates.yaml</code> 中定义一致的模板,在服务重启时会从 YAML 文件覆盖同步。
|
||||
API 创建的模板(来源标记为 API)不受影响。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /view-body -->
|
||||
</main>
|
||||
</div><!-- /admin-shell -->
|
||||
|
||||
<!-- ═══ 查看详情 Modal ═══ -->
|
||||
<div class="modal-overlay" id="modal-detail" style="display:none;">
|
||||
<div class="modal" style="max-width: 680px;">
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title">模板详情 · <span id="detail-key">default</span></h2>
|
||||
<button class="modal-close" onclick="closeModal('modal-detail')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="detail-grid">
|
||||
<div class="detail-item">
|
||||
<div class="label">Key</div>
|
||||
<div class="value" id="d-key" style="font-family:monospace;">default</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="label">来源</div>
|
||||
<div><span class="tag tag-yaml">YAML</span></div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="label">名称</div>
|
||||
<div class="value" id="d-name">魂镜</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="label">显示名</div>
|
||||
<div class="value" id="d-display">魂镜</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="label">语言</div>
|
||||
<div class="value" id="d-lang">zh-CN</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<div class="label">私隐等级</div>
|
||||
<div class="value" id="d-privacy">normal</div>
|
||||
</div>
|
||||
<div class="detail-item full">
|
||||
<div class="label">人物档案(profile)</div>
|
||||
<div class="value json" id="d-profile">{
|
||||
"description": "一面照见人心的镜子",
|
||||
"background": "默认人物",
|
||||
"speaking_style": "温和、清晰、简洁",
|
||||
"temperament": "沉静而温暖",
|
||||
"hobbies": ["哲学", "文学", "围棋"],
|
||||
"values": ["真诚", "同理心", "独立思考"],
|
||||
"birthday": "2026-06-19",
|
||||
}</div>
|
||||
</div>
|
||||
<div class="detail-item full">
|
||||
<div class="label">模型策略(model_policy)</div>
|
||||
<div class="value json" id="d-policy">{
|
||||
"memory_extraction_model_hint": "memory-extraction",
|
||||
"personality_analysis_model_hint": "personality-analysis",
|
||||
"embedding_model_hint": "embedding",
|
||||
"default_chat_model_hint": "deepseek-v4-flash"
|
||||
}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" onclick="closeModal('modal-detail')">关闭</button>
|
||||
<button class="btn btn-primary" onclick="closeModal('modal-detail'); openEdit('default')">编辑</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 创建/编辑 Modal ═══ -->
|
||||
<div class="modal-overlay" id="modal-edit" style="display:none;">
|
||||
<div class="modal" style="max-width: 720px;">
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title" id="edit-title">新建模板</h2>
|
||||
<button class="modal-close" onclick="closeModal('modal-edit')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- ── 基础信息 ── -->
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label class="field-label">Key *</label>
|
||||
<input id="f-key" type="text" placeholder="唯一标识,如 my_template" />
|
||||
<span class="field-hint">仅小写字母、数字、下划线、连字符。创建后不可修改。</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">是否默认</label>
|
||||
<select id="f-is-default">
|
||||
<option value="false">否</option>
|
||||
<option value="true">是(新用户以此创建初始角色)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label class="field-label">名称 *</label>
|
||||
<input id="f-name" type="text" placeholder="内部名称" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">显示名</label>
|
||||
<input id="f-display" type="text" placeholder="显示昵称" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label class="field-label">语言</label>
|
||||
<select id="f-lang">
|
||||
<option value="zh-CN">zh-CN</option>
|
||||
<option value="en">en</option>
|
||||
<option value="ja">ja</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">私隐等级</label>
|
||||
<select id="f-privacy">
|
||||
<option value="normal">normal</option>
|
||||
<option value="sensitive">sensitive</option>
|
||||
<option value="local_only">local_only</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── 人物档案 ── -->
|
||||
<div class="form-section">
|
||||
<div class="form-section-title"><span class="glyph">📋</span> 人物档案(Profile)</div>
|
||||
|
||||
<div class="field" style="margin-bottom:12px;">
|
||||
<label class="field-label">一句话简介</label>
|
||||
<input id="f-description" type="text" placeholder="例如:一面照见人心的镜子" />
|
||||
</div>
|
||||
|
||||
<div class="field" style="margin-bottom:12px;">
|
||||
<label class="field-label">背景故事</label>
|
||||
<textarea id="f-background" rows="4" placeholder="人物背景故事设定…"></textarea>
|
||||
</div>
|
||||
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label class="field-label">说话风格</label>
|
||||
<input id="f-speaking-style" type="text" placeholder="例如:温和、清晰、简洁" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">性情气质</label>
|
||||
<input id="f-temperament" type="text" placeholder="例如:沉静而温暖" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-row" style="margin-top:12px;">
|
||||
<div class="field">
|
||||
<label class="field-label">生日</label>
|
||||
<input id="f-birthday" type="date" />
|
||||
<span class="field-hint">留空则系统用创建时间自动兜底</span>
|
||||
</div>
|
||||
<div class="field-row" style="grid-template-columns:1fr 1fr; gap:10px; margin:0;">
|
||||
<div class="field">
|
||||
<label class="field-label">身高</label>
|
||||
<input id="f-height" type="number" placeholder="cm" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">体重</label>
|
||||
<input id="f-weight" type="number" placeholder="kg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field-row" style="margin-top:12px;">
|
||||
<div class="field">
|
||||
<label class="field-label">兴趣爱好</label>
|
||||
<div class="tag-input-wrap" id="hobbies-wrap">
|
||||
<span class="tag-input-tag">抚琴<span class="remove" onclick="removeTag(this)">×</span></span>
|
||||
<span class="tag-input-tag">书法<span class="remove" onclick="removeTag(this)">×</span></span>
|
||||
<span class="tag-input-tag">品茶<span class="remove" onclick="removeTag(this)">×</span></span>
|
||||
<span class="tag-input-tag">对弈<span class="remove" onclick="removeTag(this)">×</span></span>
|
||||
<input class="tag-input-native" id="f-hobbies-input" type="text" placeholder="输入后按回车添加…" onkeydown="if(event.key==='Enter'){event.preventDefault();addTag(this,document.getElementById('hobbies-hidden'));}" />
|
||||
</div>
|
||||
<input id="hobbies-hidden" type="hidden" value='["抚琴","书法","品茶","对弈"]' />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">价值观</label>
|
||||
<div class="tag-input-wrap" id="values-wrap">
|
||||
<span class="tag-input-tag">中庸<span class="remove" onclick="removeTag(this)">×</span></span>
|
||||
<span class="tag-input-tag">礼义<span class="remove" onclick="removeTag(this)">×</span></span>
|
||||
<span class="tag-input-tag">自然<span class="remove" onclick="removeTag(this)">×</span></span>
|
||||
<input class="tag-input-native" id="f-values-input" type="text" placeholder="输入后按回车添加…" onkeydown="if(event.key==='Enter'){event.preventDefault();addTag(this,document.getElementById('values-hidden'));}" />
|
||||
</div>
|
||||
<input id="values-hidden" type="hidden" value='["中庸","礼义","自然"]' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── 额外内容(JSON,补充人物档案) ── -->
|
||||
<div class="form-section">
|
||||
<div class="form-section-title"><span class="glyph">⋯</span> 额外内容(Extra JSON)<span style="font-weight:400;font-size:12px;color:var(--fg-faint);margin-left:6px;">以上字段未覆盖的自定义 profile 键值</span></div>
|
||||
<div class="field">
|
||||
<textarea id="f-extra-json" rows="3" style="font-family:monospace;font-size:12px;">{}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── 模型策略 ── -->
|
||||
<div class="form-section">
|
||||
<div class="form-section-title"><span class="glyph">⚙</span> 模型策略(Model Policy)<span style="font-weight:400;font-size:12px;color:var(--fg-faint);margin-left:6px;">不选则留空</span></div>
|
||||
<div class="field-row" style="grid-template-columns:1fr 1fr;">
|
||||
<div class="field">
|
||||
<label class="field-label">对话模型</label>
|
||||
<select id="f-chat-hint">
|
||||
<option value="">— 不设置(使用系统默认)</option>
|
||||
<option value="deepseek-v4-flash">deepseek-v4-flash</option>
|
||||
<option value="deepseek-v3">deepseek-v3</option>
|
||||
<option value="gpt-4o">gpt-4o</option>
|
||||
<option value="claude-sonnet-5">claude-sonnet-5</option>
|
||||
<option value="claude-opus-4-8">claude-opus-4-8</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">记忆提取模型</label>
|
||||
<select id="f-memory-hint">
|
||||
<option value="">— 不设置(空)</option>
|
||||
<option value="memory-extraction">memory-extraction</option>
|
||||
<option value="deepseek-v4-flash">deepseek-v4-flash</option>
|
||||
<option value="deepseek-v3">deepseek-v3</option>
|
||||
<option value="gpt-4o-mini">gpt-4o-mini</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">人格分析模型</label>
|
||||
<select id="f-personality-hint">
|
||||
<option value="">— 不设置(空)</option>
|
||||
<option value="personality-analysis">personality-analysis</option>
|
||||
<option value="deepseek-v4-flash">deepseek-v4-flash</option>
|
||||
<option value="deepseek-v3">deepseek-v3</option>
|
||||
<option value="gpt-4o">gpt-4o</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">向量嵌入模型</label>
|
||||
<select id="f-embedding-hint">
|
||||
<option value="">— 不设置(空)</option>
|
||||
<option value="embedding">embedding</option>
|
||||
<option value="text-embedding-3-small">text-embedding-3-small</option>
|
||||
<option value="text-embedding-3-large">text-embedding-3-large</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" onclick="closeModal('modal-edit')">取消</button>
|
||||
<button class="btn btn-primary" id="edit-save-btn">✦ 保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 删除确认 Modal ═══ -->
|
||||
<div class="modal-overlay" id="modal-delete" style="display:none;">
|
||||
<div class="modal" style="max-width: 460px;">
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title">确认删除</h2>
|
||||
<button class="modal-close" onclick="closeModal('modal-delete')">✕</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="confirm-box">
|
||||
<div class="title">⚠ 确定要删除此模板?</div>
|
||||
<div class="desc">
|
||||
将删除系统模板 <strong id="del-key-name">default · 魂镜</strong>。如果有用户人物引用了此模板将无法删除。
|
||||
此操作不可撤销。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" onclick="closeModal('modal-delete')">取消</button>
|
||||
<button class="btn btn-danger" onclick="performDelete()">✕ 确认删除</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ Toast ═══ -->
|
||||
<div class="toast" id="toast" style="display:none;">✔ 操作成功</div>
|
||||
|
||||
<script>
|
||||
// ── Tag input helpers ──
|
||||
function addTag(inputEl, hiddenEl) {
|
||||
const val = inputEl.value.trim();
|
||||
if (!val) return;
|
||||
const tag = document.createElement('span');
|
||||
tag.className = 'tag-input-tag';
|
||||
tag.innerHTML = val + '<span class="remove" onclick="removeTag(this)">×</span>';
|
||||
inputEl.parentNode.insertBefore(tag, inputEl);
|
||||
inputEl.value = '';
|
||||
syncTags(hiddenEl);
|
||||
}
|
||||
function removeTag(removeEl) {
|
||||
const tag = removeEl.parentNode;
|
||||
const wrap = tag.parentNode;
|
||||
tag.remove();
|
||||
const hidden = wrap.parentNode.querySelector('input[type="hidden"]') || wrap.nextElementSibling;
|
||||
if (hidden) syncTags(hidden);
|
||||
}
|
||||
function syncTags(hiddenEl) {
|
||||
const wrap = hiddenEl.parentNode.querySelector('.tag-input-wrap') || hiddenEl.previousElementSibling;
|
||||
const items = [];
|
||||
wrap.querySelectorAll('.tag-input-tag').forEach(t => items.push(t.textContent.replace('×','').trim()));
|
||||
hiddenEl.value = JSON.stringify(items);
|
||||
}
|
||||
function populateTags(wrapId, hiddenId, values) {
|
||||
const wrap = document.getElementById(wrapId);
|
||||
const hidden = document.getElementById(hiddenId);
|
||||
// clear existing tags (keep native input)
|
||||
wrap.querySelectorAll('.tag-input-tag').forEach(t => t.remove());
|
||||
values.forEach(v => {
|
||||
const tag = document.createElement('span');
|
||||
tag.className = 'tag-input-tag';
|
||||
tag.innerHTML = v + '<span class="remove" onclick="removeTag(this)">×</span>';
|
||||
wrap.insertBefore(tag, wrap.querySelector('.tag-input-native'));
|
||||
});
|
||||
hidden.value = JSON.stringify(values);
|
||||
}
|
||||
|
||||
// ── Simple state ──
|
||||
const state = { deleteKey: null, deleteName: null };
|
||||
|
||||
function closeModal(id) { document.getElementById(id).style.display = 'none'; }
|
||||
|
||||
function openCreate() {
|
||||
document.getElementById('edit-title').textContent = '✦ 新建模板';
|
||||
document.getElementById('edit-save-btn').textContent = '✦ 创建';
|
||||
document.getElementById('f-key').disabled = false;
|
||||
document.getElementById('f-key').value = '';
|
||||
document.getElementById('f-name').value = '';
|
||||
document.getElementById('f-display').value = '';
|
||||
document.getElementById('f-lang').value = 'zh-CN';
|
||||
document.getElementById('f-privacy').value = 'normal';
|
||||
document.getElementById('f-is-default').value = 'false';
|
||||
document.getElementById('f-description').value = '';
|
||||
document.getElementById('f-background').value = '';
|
||||
document.getElementById('f-speaking-style').value = '';
|
||||
document.getElementById('f-temperament').value = '';
|
||||
document.getElementById('f-birthday').value = '';
|
||||
document.getElementById('f-height').value = '';
|
||||
document.getElementById('f-weight').value = '';
|
||||
populateTags('hobbies-wrap', 'hobbies-hidden', []);
|
||||
populateTags('values-wrap', 'values-hidden', []);
|
||||
document.getElementById('f-chat-hint').value = '';
|
||||
document.getElementById('f-memory-hint').value = '';
|
||||
document.getElementById('f-personality-hint').value = '';
|
||||
document.getElementById('f-embedding-hint').value = '';
|
||||
document.getElementById('f-extra-json').value = '{}';
|
||||
document.getElementById('modal-edit').style.display = 'flex';
|
||||
}
|
||||
|
||||
const templateData = {
|
||||
default: {
|
||||
name: '魂镜', display: '魂镜', desc: '一面照见人心的镜子',
|
||||
background: '默认人物', speaking: '温和、清晰、简洁',
|
||||
temper: '沉静而温暖', hobbies: ['哲学','文学','围棋'],
|
||||
values: ['真诚','同理心','独立思考'],
|
||||
bday: '', height: '', weight: '',
|
||||
chatHint: 'deepseek-v4-flash', memHint: 'memory-extraction',
|
||||
persHint: 'personality-analysis', embHint: 'embedding'
|
||||
},
|
||||
tokisaki_kurumi: {
|
||||
name: '时崎狂三', display: '时崎狂三', desc: '被称为「梦魇」的时间精灵',
|
||||
background: '拥有时间之力的精灵「Nightmare(梦魇)」…',
|
||||
speaking: '优雅从容的大小姐口气', temper: '优雅腹黑、孤独偏执、温柔而危险',
|
||||
hobbies: ['与猫相处','阅读','钢琴','收藏古董时钟','摄影','品尝红茶与甜点'],
|
||||
values: ['自由','尊严','独立','记忆'],
|
||||
bday: '2000-12-25', height: '157', weight: '43',
|
||||
chatHint: 'deepseek-v4-flash', memHint: 'memory-extraction',
|
||||
persHint: 'personality-analysis', embHint: 'embedding'
|
||||
},
|
||||
gufeng: {
|
||||
name: '古风人物', display: '墨语', desc: '穿越千年而来的书卷气',
|
||||
background: '生于江南世家,自幼饱读诗书,后遇变故隐居山林…',
|
||||
speaking: '文雅、含蓄、引经据典', temper: '淡泊通透',
|
||||
hobbies: ['抚琴','书法','品茶','对弈'],
|
||||
values: ['中庸','礼义','自然'],
|
||||
bday: '', height: '', weight: '',
|
||||
chatHint: 'deepseek-v4-flash', memHint: 'memory-extraction',
|
||||
persHint: 'personality-analysis', embHint: 'embedding'
|
||||
},
|
||||
baize: {
|
||||
name: '白泽', display: '白泽', desc: '上古瑞兽,通晓万物之理的博学者',
|
||||
background: '上古瑞兽白泽的化身…',
|
||||
speaking: '语速适中偏快,喜欢引用典籍和典故', temper: '博学谦和、言语灵动',
|
||||
hobbies: ['收集珍稀典籍','整理知识图谱','翻译古文字','观星与占星术','与智者辩论'],
|
||||
values: ['求真','传递','谦逊','包容'],
|
||||
bday: '', height: '176', weight: '68',
|
||||
chatHint: 'deepseek-v4-flash', memHint: 'memory-extraction',
|
||||
persHint: 'personality-analysis', embHint: 'embedding'
|
||||
},
|
||||
qingnv: {
|
||||
name: '青女', display: '青女', desc: '掌霜雪之神,清冷而孤独的月宫仙子',
|
||||
background: '青女乃霜雪之神,每逢深秋便降下白霜…',
|
||||
speaking: '语调清冷平稳,惜字如金', temper: '清冷孤高、外表疏离内心温柔',
|
||||
hobbies: ['编织霜花','在月宫散步','聆听凡间的祈祷','收集露水制茶','书写霜雪日记'],
|
||||
values: ['秩序','纯净','美','守护'],
|
||||
bday: '', height: '170', weight: '',
|
||||
chatHint: 'deepseek-v4-flash', memHint: 'memory-extraction',
|
||||
persHint: 'personality-analysis', embHint: 'embedding'
|
||||
},
|
||||
api_gufeng: {
|
||||
name: '古风人物', display: '墨语', desc: '穿越千年而来的书卷气',
|
||||
background: '生于江南世家,自幼饱读诗书…',
|
||||
speaking: '文雅、含蓄、引经据典', temper: '淡泊通透',
|
||||
hobbies: ['抚琴','书法','品茶','对弈'],
|
||||
values: ['中庸','礼义','自然'],
|
||||
bday: '', height: '', weight: '',
|
||||
chatHint: 'deepseek-v4-flash', memHint: 'memory-extraction',
|
||||
persHint: 'personality-analysis', embHint: 'embedding'
|
||||
}
|
||||
};
|
||||
|
||||
function openEdit(key) {
|
||||
const d = templateData[key] || templateData.default;
|
||||
document.getElementById('edit-title').textContent = '✎ 编辑模板 · ' + key;
|
||||
document.getElementById('edit-save-btn').textContent = '✎ 保存';
|
||||
document.getElementById('f-key').disabled = true;
|
||||
document.getElementById('f-key').value = key;
|
||||
document.getElementById('f-name').value = d.name;
|
||||
document.getElementById('f-display').value = d.display;
|
||||
document.getElementById('f-lang').value = 'zh-CN';
|
||||
document.getElementById('f-privacy').value = 'normal';
|
||||
document.getElementById('f-is-default').value = key === 'default' ? 'true' : 'false';
|
||||
document.getElementById('f-description').value = d.desc;
|
||||
document.getElementById('f-background').value = d.background;
|
||||
document.getElementById('f-speaking-style').value = d.speaking;
|
||||
document.getElementById('f-temperament').value = d.temper;
|
||||
document.getElementById('f-birthday').value = d.bday || '';
|
||||
document.getElementById('f-height').value = d.height || '';
|
||||
document.getElementById('f-weight').value = d.weight || '';
|
||||
populateTags('hobbies-wrap', 'hobbies-hidden', d.hobbies);
|
||||
populateTags('values-wrap', 'values-hidden', d.values);
|
||||
document.getElementById('f-chat-hint').value = d.chatHint || '';
|
||||
document.getElementById('f-memory-hint').value = d.memHint || '';
|
||||
document.getElementById('f-personality-hint').value = d.persHint || '';
|
||||
document.getElementById('f-embedding-hint').value = d.embHint || '';
|
||||
document.getElementById('f-extra-json').value = '{}';
|
||||
document.getElementById('modal-edit').style.display = 'flex';
|
||||
}
|
||||
|
||||
function openDetail(key) {
|
||||
const d = templateData[key] || templateData.default;
|
||||
document.getElementById('detail-key').textContent = key;
|
||||
document.getElementById('d-key').textContent = key;
|
||||
document.getElementById('d-name').textContent = d.name;
|
||||
document.getElementById('d-display').textContent = d.display;
|
||||
document.getElementById('d-lang').textContent = 'zh-CN';
|
||||
document.getElementById('d-privacy').textContent = 'normal';
|
||||
document.getElementById('modal-detail').style.display = 'flex';
|
||||
}
|
||||
|
||||
function confirmDelete(key) {
|
||||
state.deleteKey = key;
|
||||
const d = templateData[key] || templateData.default;
|
||||
state.deleteName = d.name;
|
||||
document.getElementById('del-key-name').textContent = key + ' · ' + d.name;
|
||||
document.getElementById('modal-delete').style.display = 'flex';
|
||||
}
|
||||
|
||||
function performDelete() {
|
||||
closeModal('modal-delete');
|
||||
showToast('✔ 已删除模板 · ' + state.deleteKey);
|
||||
state.deleteKey = null;
|
||||
}
|
||||
|
||||
function syncFromYaml() {
|
||||
showToast('↻ 正在从 YAML 同步模板…');
|
||||
setTimeout(() => showToast('✔ 同步完成'), 1500);
|
||||
}
|
||||
|
||||
function showToast(msg, isError) {
|
||||
const t = document.getElementById('toast');
|
||||
t.textContent = msg;
|
||||
t.className = 'toast' + (isError ? ' error' : '');
|
||||
t.style.display = 'flex';
|
||||
setTimeout(() => { t.style.display = 'none'; }, 3000);
|
||||
}
|
||||
|
||||
// ── Escape to close modals ──
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal-overlay').forEach(m => m.style.display = 'none');
|
||||
}
|
||||
});
|
||||
// Click overlay to close
|
||||
document.querySelectorAll('.modal-overlay').forEach(m => {
|
||||
m.addEventListener('click', function(e) {
|
||||
if (e.target === this) this.style.display = 'none';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,985 @@
|
||||
<!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.3 — 司命台完整预览(单文件多视图)
|
||||
*
|
||||
* 文档基准:docs/product/master-prd.md §2-§5
|
||||
* · 铜镜四态 = MirrorState 健康度(void/breathing/steady/cracked),§2.3
|
||||
* · 三签分层:星盘(空间·主角)/ 朱批(动作)/ 起居注(时间),§3
|
||||
* · 司命台独立壳层(AdminShell 横向导航),§4
|
||||
*
|
||||
* 视图(data-view):overview / users / tenants / audit / traces /
|
||||
* goal(太一) / percept(烛照) / world(河图) / plan(洛书) / agents(天工阁)
|
||||
* 枚举与字段对齐 src/lib/constants/labels.ts 与 src/types/api.ts
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 司命台独立壳层:顶部横向导航 ── */
|
||||
.admin-shell { display: flex; flex-direction: column; min-height: 100vh; }
|
||||
.topbar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 10px; padding: 10px 28px; border-bottom: 1px solid var(--rule); background: var(--surface); backdrop-filter: blur(16px) saturate(140%); flex-wrap: wrap; }
|
||||
.topbar-brand { font-family: "Songti SC", serif; font-size: 17px; font-weight: 700; letter-spacing: 0.06em; color: var(--fg); display: flex; align-items: center; gap: 7px; flex-shrink: 0; cursor: pointer; }
|
||||
.topbar-brand .knob { width: 16px; height: 16px; }
|
||||
.topbar-brand .knob circle:last-child { fill: var(--cinnabar); }
|
||||
.topbar-sep { color: var(--fg-faint); opacity: 0.5; flex-shrink: 0; }
|
||||
.topbar-nav { display: flex; align-items: center; gap: 1px; flex-wrap: wrap; }
|
||||
.topbar-navitem { display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 8px; font-size: 13px; font-weight: 500; color: var(--muted); text-decoration: none; transition: background 0.12s, color 0.12s; cursor: pointer; background: none; border: none; font-family: inherit; }
|
||||
.topbar-navitem:hover { background: var(--overlay-hover); color: var(--fg); }
|
||||
.topbar-navitem.active { background: var(--patina-wash); color: var(--patina); }
|
||||
.topbar-navitem.pivot { font-size: 12px; padding: 4px 9px; }
|
||||
.topbar-spacer { flex: 1; }
|
||||
.topbar-back { display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; border-radius: 8px; font-size: 12px; color: var(--muted); text-decoration: none; transition: background 0.12s, color 0.12s; background: none; border: none; cursor: pointer; font-family: inherit; }
|
||||
.topbar-back:hover { background: var(--overlay-hover); color: var(--fg); }
|
||||
|
||||
/* ── 视图与页头 ── */
|
||||
main { flex: 1; display: flex; flex-direction: column; min-height: 0; }
|
||||
.view { display: none; flex: 1; flex-direction: column; min-height: 0; }
|
||||
.view.active { display: flex; }
|
||||
|
||||
.page-header .spacer { flex: 1; }
|
||||
.header-badge { display: inline-flex; align-items: center; gap: 6px; font-family: "JetBrains Mono", monospace; font-size: 11.5px; padding: 4px 12px; border-radius: 999px; border: 1px solid var(--patina-dim); color: var(--patina); background: var(--patina-wash); }
|
||||
.header-badge.cracked { border-color: var(--cinnabar-dim); color: var(--cinnabar); background: var(--cinnabar-wash); }
|
||||
.header-badge.gilt { border-color: var(--gilt-dim); color: var(--gilt); background: var(--gilt-faint); }
|
||||
.view-body { flex: 1; padding: 16px 28px 48px; display: flex; flex-direction: column; gap: 22px; max-width: 1180px; width: 100%; overflow-y: auto; }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--cinnabar); opacity: 0.85; }
|
||||
.section-heading { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin-bottom: 12px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
||||
.section-heading .sub { font-size: 12px; font-weight: 400; color: var(--fg-dim); margin-left: 6px; }
|
||||
.section-heading .glyph { color: var(--cinnabar); opacity: 0.85; }
|
||||
|
||||
/* ── 朱批告警条 ── */
|
||||
.alert-bar { display: flex; align-items: center; gap: 12px; border-radius: 12px; padding: 13px 18px; border: 1px solid var(--rule); background: var(--surface); text-decoration: none; color: inherit; transition: background 0.12s; }
|
||||
.alert-bar:hover { background: var(--surface-hi); }
|
||||
.alert-bar.cracked { border-color: var(--cinnabar-dim); background: var(--cinnabar-wash); }
|
||||
.alert-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; background: var(--patina); }
|
||||
.alert-bar.cracked .alert-dot { background: var(--cinnabar); box-shadow: 0 0 0 4px var(--cinnabar-wash); }
|
||||
.alert-text { font-size: 14px; font-weight: 500; color: var(--patina); }
|
||||
.alert-bar.cracked .alert-text { color: var(--cinnabar); }
|
||||
.alert-bar .spacer { flex: 1; }
|
||||
.alert-cta { font-size: 12px; color: var(--fg-dim); padding: 4px 10px; border-radius: 7px; border: 1px solid var(--rule); }
|
||||
.alert-meta { font-family: "JetBrains Mono", monospace; font-size: 11.5px; color: var(--fg-faint); }
|
||||
|
||||
/* ── 星盘 hero + 枢速览 ── */
|
||||
.hero-grid { display: grid; grid-template-columns: minmax(0, 22rem) 1fr; gap: 18px; }
|
||||
.astrolabe-card { border: 1px solid var(--rule); border-radius: 14px; background: var(--surface); padding: 16px; display: flex; flex-direction: column; align-items: center; gap: 10px; }
|
||||
.astrolabe { width: 100%; max-width: 312px; height: auto; }
|
||||
.astrolabe-ring { stroke: var(--gilt); stroke-width: 1.2; fill: none; stroke-opacity: 0.5; }
|
||||
.astrolabe-ring-fine { stroke: var(--gilt-dim); stroke-width: 0.6; fill: none; }
|
||||
.astrolabe-ring-patina { stroke: var(--patina-dim); stroke-width: 0.6; fill: none; }
|
||||
.astrolabe-tick { stroke: var(--gilt); stroke-width: 3; fill: none; stroke-opacity: 0.32; animation: sm-breathe 7s ease-in-out infinite; }
|
||||
.astrolabe-core-glow { animation: sm-breathe 4.5s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
|
||||
.astrolabe-spoke { stroke: var(--gilt-dim); stroke-width: 0.6; stroke-opacity: 0.55; }
|
||||
.astrolabe-core-glyph { font-family: "Songti SC", serif; font-size: 16px; font-weight: 600; fill: var(--gilt); }
|
||||
.astrolabe-core-label { font-family: "JetBrains Mono", monospace; font-size: 7px; fill: var(--gilt); letter-spacing: 0.12em; opacity: 0.7; }
|
||||
.astrolabe-pivot-label { font-family: "Songti SC", serif; font-size: 13px; font-weight: 500; fill: var(--fg); }
|
||||
.astrolabe-pivot-sub { font-family: "JetBrains Mono", monospace; font-size: 8px; fill: var(--fg-faint); letter-spacing: 0.06em; }
|
||||
.astrolabe-orbit { animation: sm-spin 120s linear infinite; transform-box: fill-box; transform-origin: center; }
|
||||
.astrolabe-alert { animation: sm-alert 1.8s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
|
||||
.astrolabe-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 14px; font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); }
|
||||
.astrolabe-legend .lg { display: inline-flex; align-items: center; gap: 5px; }
|
||||
.astrolabe-legend .lg::before { content: ""; width: 8px; height: 8px; border-radius: 50%; }
|
||||
.astrolabe-legend .lg.steady::before { background: var(--patina); }
|
||||
.astrolabe-legend .lg.breathing::before { background: var(--gilt); }
|
||||
.astrolabe-legend .lg.cracked::before { background: var(--cinnabar); }
|
||||
.astrolabe-legend .lg.void::before { background: transparent; border: 1.5px solid var(--fg-faint); }
|
||||
|
||||
.health-list { border: 1px solid var(--rule); border-radius: 14px; background: var(--surface); overflow: hidden; }
|
||||
.health-item { display: grid; grid-template-columns: 3px 1fr auto; gap: 14px; align-items: center; padding: 10px 16px; border-bottom: 1px solid var(--rule); text-decoration: none; transition: background 0.12s; cursor: pointer; background: none; border-left: none; border-right: none; border-top: none; font-family: inherit; text-align: left; width: 100%; color: inherit; }
|
||||
.health-item:last-child { border-bottom: none; }
|
||||
.health-item:hover { background: var(--overlay-hover); }
|
||||
.health-bar { width: 3px; height: 26px; border-radius: 0 2px 2px 0; }
|
||||
.health-bar.steady { background: var(--patina); }
|
||||
.health-bar.breathing { background: var(--gilt); }
|
||||
.health-bar.cracked { background: var(--cinnabar); }
|
||||
.health-bar.void { background: var(--fg-faint); opacity: 0.4; }
|
||||
.health-main { min-width: 0; }
|
||||
.health-name { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); }
|
||||
.health-name .eng { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); margin-left: 6px; font-weight: 400; }
|
||||
.health-summary { font-size: 12px; color: var(--fg-dim); margin-top: 1px; }
|
||||
.health-badge { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; }
|
||||
.health-badge .dot { width: 7px; height: 7px; border-radius: 50%; }
|
||||
.health-badge.steady { color: var(--patina); } .health-badge.steady .dot { background: var(--patina); }
|
||||
.health-badge.breathing { color: var(--gilt); } .health-badge.breathing .dot { background: var(--gilt); }
|
||||
.health-badge.cracked { color: var(--cinnabar); } .health-badge.cracked .dot { background: var(--cinnabar); }
|
||||
.health-badge.void { color: var(--fg-faint); } .health-badge.void .dot { background: transparent; border: 1.5px solid var(--fg-faint); }
|
||||
|
||||
/* ── 三签概览卡 ── */
|
||||
.seals-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
|
||||
.seal-card { border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); padding: 16px 18px; position: relative; overflow: hidden; text-decoration: none; color: inherit; transition: background 0.14s, border-color 0.14s; cursor: pointer; display: block; }
|
||||
.seal-card:hover { background: var(--surface-hi); border-color: var(--gilt-dim); }
|
||||
.seal-card::before { content: ""; position: absolute; left: 0; top: 16px; bottom: 16px; width: 3px; border-radius: 0 2px 2px 0; }
|
||||
.seal-card.starmap::before { background: var(--patina); }
|
||||
.seal-card.vermilion::before { background: var(--cinnabar); }
|
||||
.seal-card.imperial::before { background: var(--gilt); }
|
||||
.seal-dim { font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-faint); margin-bottom: 6px; }
|
||||
.seal-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 2px; }
|
||||
.seal-name { font-family: "Songti SC", serif; font-size: 16px; font-weight: 600; color: var(--fg); }
|
||||
.seal-eng { font-family: "JetBrains Mono", monospace; font-size: 10.5px; }
|
||||
.seal-card.starmap .seal-eng { color: var(--patina); }
|
||||
.seal-card.vermilion .seal-eng { color: var(--cinnabar); }
|
||||
.seal-card.imperial .seal-eng { color: var(--gilt); }
|
||||
.seal-role { font-size: 12px; color: var(--fg-faint); margin-bottom: 12px; }
|
||||
.seal-metric { display: flex; align-items: baseline; gap: 6px; }
|
||||
.seal-metric .num { font-family: "JetBrains Mono", monospace; font-size: 28px; font-weight: 600; color: var(--fg); line-height: 1; }
|
||||
.seal-metric .unit { font-size: 11.5px; color: var(--fg-faint); }
|
||||
.seal-foot { font-size: 11.5px; color: var(--fg-dim); margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--rule); display: flex; justify-content: space-between; align-items: center; }
|
||||
.seal-foot .go { font-family: "JetBrains Mono", monospace; color: var(--fg-faint); }
|
||||
|
||||
/* ── 通用:工具条 / 表格 / 徽章 / 按钮 / 统计卡 ── */
|
||||
.toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
|
||||
.search { flex: 1; min-width: 180px; padding: 7px 13px; border-radius: 8px; border: 1px solid var(--rule); background: var(--surface); color: var(--fg); font-size: 13px; font-family: inherit; }
|
||||
.search::placeholder { color: var(--fg-faint); }
|
||||
|
||||
|
||||
.btn-danger { border-color: var(--cinnabar-dim); background: var(--cinnabar-wash); color: var(--cinnabar); }
|
||||
.icon-btn { padding: 4px 10px; font-size: 12px; border-radius: 7px; border: 1px solid var(--rule); background: transparent; color: var(--fg-dim); cursor: pointer; font-family: inherit; }
|
||||
.icon-btn:hover { background: var(--overlay-hover); color: var(--fg); }
|
||||
|
||||
.panel { border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); overflow: hidden; }
|
||||
.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||||
.data-table th { font-family: "JetBrains Mono", monospace; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--fg-faint); font-weight: 600; background: var(--surface-hi); padding: 11px 16px; text-align: left; }
|
||||
.data-table td { padding: 12px 16px; border-bottom: 1px solid var(--rule); color: var(--fg-dim); vertical-align: middle; }
|
||||
.data-table tr:last-child td { border-bottom: none; }
|
||||
.data-table tbody tr { transition: background 0.1s; }
|
||||
.data-table tbody tr:hover { background: var(--overlay-hover); }
|
||||
.td-strong { color: var(--fg); font-weight: 500; }
|
||||
.td-mono { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg-dim); }
|
||||
.td-actions { text-align: right; white-space: nowrap; }
|
||||
|
||||
.pill { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; padding: 2px 9px; border-radius: 999px; border: 1px solid var(--rule); color: var(--fg-dim); font-family: "JetBrains Mono", monospace; white-space: nowrap; }
|
||||
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
|
||||
.pill.patina { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.pill.gilt { color: var(--gilt); border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.pill.cinnabar { color: var(--cinnabar); border-color: var(--cinnabar-dim); background: var(--cinnabar-wash); }
|
||||
.pill.faint { color: var(--fg-faint); }
|
||||
.pill.solid { font-family: "Songti SC", serif; font-size: 12px; }
|
||||
|
||||
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
|
||||
.stat-card { border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); padding: 14px 16px; }
|
||||
.stat-card .num { font-family: "JetBrains Mono", monospace; font-size: 24px; font-weight: 600; color: var(--fg); line-height: 1.1; }
|
||||
.stat-card .num.cinnabar { color: var(--cinnabar); }
|
||||
.stat-card .num.gilt { color: var(--gilt); }
|
||||
.stat-card .label { font-size: 11.5px; color: var(--fg-faint); margin-top: 4px; }
|
||||
.progress { width: 64px; height: 5px; border-radius: 999px; background: var(--surface-hi); overflow: hidden; display: inline-block; vertical-align: middle; }
|
||||
.progress > div { height: 100%; background: var(--patina); border-radius: 999px; }
|
||||
.progress.gilt > div { background: var(--gilt); }
|
||||
.progress.cinnabar > div { background: var(--cinnabar); }
|
||||
.empty { padding: 40px 20px; text-align: center; font-size: 13px; color: var(--fg-faint); }
|
||||
|
||||
/* ── 起居注时间河 ── */
|
||||
.chip-row { display: flex; gap: 6px; flex-wrap: wrap; }
|
||||
.chip { padding: 5px 13px; border-radius: 999px; border: 1px solid var(--rule); font-size: 12px; color: var(--fg-dim); cursor: pointer; background: var(--surface); font-family: inherit; transition: background 0.12s, color 0.12s; }
|
||||
.chip:hover { background: var(--overlay-hover); color: var(--fg); }
|
||||
.chip.active { border-color: var(--patina-dim); color: var(--patina); background: var(--patina-wash); }
|
||||
.chapter { margin-top: 4px; }
|
||||
.chapter-head { display: flex; align-items: center; gap: 14px; margin-bottom: 6px; margin-top: 14px; }
|
||||
.chapter-head .line { flex: 1; height: 1px; background: var(--gilt-dim); }
|
||||
.chapter-head .t { font-family: "Songti SC", serif; font-size: 14px; letter-spacing: 0.1em; color: var(--gilt); }
|
||||
.river-item { display: grid; grid-template-columns: 70px 1fr auto; gap: 14px; padding: 9px 0 9px 20px; border-left: 1px solid var(--gilt-dim); margin-left: 8px; align-items: start; }
|
||||
.river-time { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-faint); }
|
||||
.river-body { font-size: 13px; color: var(--fg-dim); line-height: 1.5; }
|
||||
.river-body .em { color: var(--fg); font-family: "JetBrains Mono", monospace; font-size: 12px; }
|
||||
.river-body .actor { color: var(--fg); font-weight: 500; }
|
||||
.river-trace { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); align-self: center; }
|
||||
|
||||
/* ── 链路追踪 ── */
|
||||
.trace-layout { display: grid; grid-template-columns: 340px 1fr; gap: 16px; }
|
||||
.trace-item { display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 11px 16px; border-bottom: 1px solid var(--rule); cursor: pointer; transition: background 0.1s; }
|
||||
.trace-item:last-child { border-bottom: none; }
|
||||
.trace-item:hover { background: var(--overlay-hover); }
|
||||
.trace-item.active { background: var(--patina-wash); border-left: 3px solid var(--patina); padding-left: 13px; }
|
||||
.trace-id { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg); }
|
||||
.trace-meta { font-size: 11.5px; color: var(--fg-faint); margin-top: 2px; }
|
||||
.tl-event { display: grid; grid-template-columns: 86px auto 1fr; gap: 12px; padding: 8px 0 8px 16px; border-left: 1.5px solid var(--gilt-dim); margin-left: 6px; }
|
||||
.tl-event.tool { border-left-color: var(--patina-dim); }
|
||||
.tl-event.safety { border-left-color: var(--cinnabar-dim); }
|
||||
.tl-ts { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-faint); }
|
||||
.tl-type { font-family: "JetBrains Mono", monospace; font-size: 11px; }
|
||||
.tl-type.tool { color: var(--patina); }
|
||||
.tl-type.safety { color: var(--cinnabar); }
|
||||
.tl-type.llm { color: var(--gilt); }
|
||||
.tl-desc { font-size: 12.5px; color: var(--fg-dim); }
|
||||
.tl-desc .em { color: var(--fg); font-family: "JetBrains Mono", monospace; font-size: 11.5px; }
|
||||
|
||||
/* ── 目标树 ── */
|
||||
.tree { padding: 6px; }
|
||||
.tree-node { display: grid; grid-template-columns: 1fr auto auto auto; gap: 12px; align-items: center; padding: 9px 12px; border-radius: 8px; transition: background 0.1s; }
|
||||
.tree-node:hover { background: var(--overlay-hover); }
|
||||
.tree-title { font-size: 13.5px; color: var(--fg); }
|
||||
.tree-title .lv { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); margin-right: 8px; letter-spacing: 0.05em; }
|
||||
.tree-meta { font-size: 11.5px; color: var(--fg-faint); }
|
||||
|
||||
/* ── 天工阁角色卡 ── */
|
||||
.role-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
|
||||
.role-card { border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); padding: 16px; }
|
||||
.role-card .head { display: flex; align-items: center; gap: 11px; margin-bottom: 10px; }
|
||||
.role-card .avatar { width: 38px; height: 38px; border-radius: 50%; background: var(--patina-wash); border: 1px solid var(--patina-dim); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; color: var(--patina); font-size: 16px; flex-shrink: 0; }
|
||||
.role-card.idle .avatar { background: var(--surface-hi); border-color: var(--rule); color: var(--fg-faint); }
|
||||
.role-card.disabled { opacity: 0.5; }
|
||||
.role-name { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); }
|
||||
.role-eng { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); }
|
||||
.role-resp { font-size: 12px; color: var(--fg-dim); line-height: 1.5; min-height: 36px; }
|
||||
.role-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--rule); }
|
||||
.role-task { font-size: 11.5px; color: var(--fg-faint); font-family: "JetBrains Mono", monospace; }
|
||||
|
||||
@media (max-width: 1000px) { .hero-grid { grid-template-columns: 1fr; } .seals-grid { grid-template-columns: 1fr; } .trace-layout { grid-template-columns: 1fr; } }
|
||||
@media (max-width: 768px) { .view-body { padding: 14px 16px 40px; } .data-table { display: block; overflow-x: auto; white-space: nowrap; } .river-item { grid-template-columns: 1fr; gap: 3px; } }
|
||||
@keyframes sm-spin { to { transform: rotate(360deg); } }
|
||||
@keyframes sm-alert { 0%, 100% { opacity: 0.7; } 50% { opacity: 0.1; } }
|
||||
@keyframes sm-breathe { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
|
||||
|
||||
/* ── 朱批裁定卡(司命枢)── */
|
||||
.vermilion-stack { display: flex; flex-direction: column; gap: 10px; }
|
||||
.vermilion-card { position: relative; border: 1px solid var(--cinnabar-dim); border-left: 3px solid var(--cinnabar); border-radius: 12px; background: linear-gradient(90deg, var(--cinnabar-wash), var(--surface) 42%); padding: 14px 16px; }
|
||||
.vermilion-card.decided { border-color: var(--rule); border-left-color: var(--patina-dim); background: var(--surface); opacity: 0.72; }
|
||||
.vc-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
|
||||
.vc-stamp { font-family: "Songti SC", serif; font-size: 12.5px; font-weight: 700; letter-spacing: 0.06em; color: var(--cinnabar); }
|
||||
.vc-stamp.done { color: var(--patina); }
|
||||
.vc-tool { font-family: "JetBrains Mono", monospace; font-size: 13px; font-weight: 600; color: var(--fg); }
|
||||
.vc-policy { font-size: 11px; color: var(--fg-faint); }
|
||||
.vc-risk { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.08em; color: var(--cinnabar); border: 1px solid var(--cinnabar-dim); padding: 2px 7px; border-radius: 5px; }
|
||||
.vc-summary { font-size: 13px; color: var(--fg); line-height: 1.55; margin: 0; }
|
||||
.vc-impact { font-size: 11.5px; color: var(--fg-dim); margin: 4px 0 0; }
|
||||
.vc-actions { display: flex; gap: 8px; margin-top: 11px; }
|
||||
code { font-family: "JetBrains Mono", monospace; font-size: 0.92em; color: var(--fg); background: var(--surface-hi); padding: 1px 5px; border-radius: 4px; }
|
||||
|
||||
/* ── 策略矩阵 / 路由 select pill ── */
|
||||
.select-pill { display: inline-flex; align-items: center; gap: 5px; font-family: "JetBrains Mono", monospace; font-size: 11px; padding: 3px 10px; border-radius: 6px; border: 1px solid var(--rule); background: var(--surface-hi); color: var(--fg-dim); cursor: pointer; white-space: nowrap; }
|
||||
.select-pill::after { content: "▾"; font-size: 8px; opacity: 0.6; }
|
||||
.select-pill.patina { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.select-pill.gilt { color: var(--gilt); border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.select-pill.cinnabar { color: var(--cinnabar); border-color: var(--cinnabar-dim); background: var(--cinnabar-wash); }
|
||||
|
||||
/* ── 百工枢 tabs ── */
|
||||
.tabstrip { display: flex; gap: 2px; border-bottom: 1px solid var(--rule); margin-bottom: 4px; flex-wrap: wrap; }
|
||||
.tab { padding: 8px 16px; font-size: 13px; font-weight: 500; color: var(--fg-dim); background: none; border: none; border-bottom: 2px solid transparent; cursor: pointer; font-family: inherit; margin-bottom: -1px; transition: color 0.12s; display: inline-flex; align-items: center; gap: 7px; }
|
||||
.tab:hover { color: var(--fg); }
|
||||
.tab.active { color: var(--patina); border-bottom-color: var(--patina); }
|
||||
.tab .count { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); background: var(--surface-hi); padding: 1px 6px; border-radius: 999px; }
|
||||
.tab.active .count { color: var(--patina); background: var(--patina-wash); }
|
||||
.tab-panel { display: none; }
|
||||
.tab-panel.active { display: block; }
|
||||
.svc-row { display: grid; grid-template-columns: 1fr auto auto auto; gap: 12px; align-items: center; padding: 11px 16px; border-bottom: 1px solid var(--rule); }
|
||||
.svc-row:last-child { border-bottom: none; }
|
||||
.svc-name { font-family: "JetBrains Mono", monospace; font-size: 13px; color: var(--fg); }
|
||||
.svc-desc { font-size: 11.5px; color: var(--fg-faint); margin-top: 1px; }
|
||||
|
||||
/* ── 灵核 inline 编辑 ── */
|
||||
.field-card { border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); overflow: hidden; }
|
||||
.field-row { display: grid; grid-template-columns: 124px 1fr auto; gap: 14px; align-items: center; padding: 13px 18px; border-bottom: 1px solid var(--rule); }
|
||||
.field-row:last-child { border-bottom: none; }
|
||||
.field-label { font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.06em; color: var(--fg-faint); text-transform: uppercase; }
|
||||
.field-value { font-size: 13.5px; color: var(--fg); line-height: 1.5; }
|
||||
.field-value.mono { font-family: "JetBrains Mono", monospace; font-size: 12.5px; }
|
||||
.field-row.core .field-label { color: var(--cinnabar); }
|
||||
.field-tag { font-size: 10px; color: var(--cinnabar); border: 1px solid var(--cinnabar-dim); background: var(--cinnabar-wash); padding: 2px 8px; border-radius: 999px; font-family: "JetBrains Mono", monospace; white-space: nowrap; }
|
||||
.trait-chips { display: flex; flex-wrap: wrap; gap: 6px; }
|
||||
.trait { font-size: 12px; padding: 3px 11px; border-radius: 999px; background: var(--patina-wash); border: 1px solid var(--patina-dim); color: var(--patina); }
|
||||
|
||||
/* ── 模型治理 能力槽位 ── */
|
||||
.slot-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
|
||||
.slot-card { border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); padding: 14px 16px; }
|
||||
.slot-card .slot-cap { font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-faint); }
|
||||
.slot-card .slot-model { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); margin-top: 5px; }
|
||||
.slot-card .slot-route { font-size: 11.5px; color: var(--fg-dim); margin-top: 3px; }
|
||||
.slot-card.empty { border-style: dashed; }
|
||||
.slot-card.empty .slot-model { color: var(--fg-faint); font-style: italic; }
|
||||
|
||||
/* ── 预留条 + disabled nav ── */
|
||||
.reserved-banner { display: flex; align-items: flex-start; gap: 11px; border-radius: 12px; padding: 13px 18px; border: 1px dashed var(--gilt-dim); background: var(--gilt-faint); color: var(--fg-dim); font-size: 13px; line-height: 1.65; }
|
||||
.reserved-banner .rb-icon { flex-shrink: 0; width: 18px; height: 18px; color: var(--gilt); margin-top: 1px; }
|
||||
.reserved-banner strong { color: var(--gilt); font-family: "Songti SC", serif; letter-spacing: 0.04em; }
|
||||
.topbar-navitem.disabled { color: var(--fg-faint); }
|
||||
.topbar-navitem.disabled:hover { background: var(--overlay-hover); color: var(--fg-dim); }
|
||||
.topbar-navitem.disabled.active { color: var(--gilt); background: var(--gilt-faint); }
|
||||
.nav-tag { font-family: "JetBrains Mono", monospace; font-size: 9px; letter-spacing: 0.06em; color: var(--gilt); border: 1px solid var(--gilt-dim); padding: 1px 5px; border-radius: 4px; margin-left: 5px; }
|
||||
|
||||
/* ── 焦点可见(§7 键盘可达)── */
|
||||
.topbar-navitem:focus-visible, .btn:focus-visible, .icon-btn:focus-visible, .chip:focus-visible, .tab:focus-visible, .health-item:focus-visible, .select-pill:focus-visible, .seal-card:focus-visible { outline: 2px solid var(--patina); outline-offset: 2px; }
|
||||
.siming { color: var(--cinnabar); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-mount" data-active="司命台"></div>
|
||||
<div class="main-area">
|
||||
<div class="admin-shell">
|
||||
<!-- ════════ 壳层(data-view 切换视图)════════ -->
|
||||
<header class="topbar">
|
||||
<span class="topbar-brand" data-view="overview">
|
||||
<svg class="knob" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="8.5" /><circle cx="12" cy="12" r="4.5" opacity="0.45" /><circle cx="12" cy="12" r="1.6" stroke="none" /></svg>
|
||||
司命台
|
||||
</span>
|
||||
<span class="topbar-sep">/</span>
|
||||
<nav class="topbar-nav" aria-label="司命治理">
|
||||
<button class="topbar-navitem active" data-view="overview">概览</button>
|
||||
<button class="topbar-navitem" data-view="audit">起居注</button>
|
||||
<button class="topbar-navitem" data-view="traces">链路追踪</button>
|
||||
<button class="topbar-navitem" data-view="models">模型治理</button>
|
||||
<button class="topbar-navitem disabled" data-view="users">用户管理<span class="nav-tag">预留</span></button>
|
||||
<button class="topbar-navitem disabled" data-view="tenants">多租户<span class="nav-tag">预留</span></button>
|
||||
</nav>
|
||||
<span class="topbar-sep">|</span>
|
||||
<nav class="topbar-nav" aria-label="九枢">
|
||||
<button class="topbar-navitem pivot" data-view="core">灵核</button>
|
||||
<button class="topbar-navitem pivot" data-view="goal">太一</button>
|
||||
<button class="topbar-navitem pivot" data-view="safety">司命</button>
|
||||
<button class="topbar-navitem pivot" data-view="percept">烛照</button>
|
||||
<button class="topbar-navitem pivot" data-view="world">河图</button>
|
||||
<button class="topbar-navitem pivot" data-view="plan">洛书</button>
|
||||
<button class="topbar-navitem pivot" data-view="memory">息壤</button>
|
||||
<button class="topbar-navitem pivot" data-view="tools">百工</button>
|
||||
<button class="topbar-navitem pivot" data-view="agents">天工阁</button>
|
||||
</nav>
|
||||
<span class="topbar-spacer"></span>
|
||||
<a class="topbar-back" href="chat-redesign-preview.html" title="返回主域">
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none"><path d="M10 4l-4 4 4 4" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" /></svg>
|
||||
主域
|
||||
</a>
|
||||
<button class="topbar-back" type="button" onclick="toggleTheme()">
|
||||
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"><circle cx="8" cy="8" r="3" /><path d="M8 1v2M8 13v2M2 8h2M12 8h2M3.5 3.5l1.5 1.5M11 11l1.5 1.5M3.5 12.5l1.5-1.5M11 5l1.5-1.5" /></svg>
|
||||
<span id="theme-label">夜铜</span>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<!-- ════════ ① 概览 ════════ -->
|
||||
<section id="view-overview" class="view active">
|
||||
<div class="page-header">
|
||||
<span class="page-title">概览</span>
|
||||
<span class="page-sub">siming · 安全治理中枢</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="header-badge cracked">● 2 项待裁定</span>
|
||||
</div>
|
||||
<div class="view-body">
|
||||
<button class="alert-bar cracked" data-view="safety" style="border:none;width:100%;">
|
||||
<span class="alert-dot"></span>
|
||||
<span class="alert-text">2 项朱批待裁定 · write_file、send_message</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="alert-meta">司命枢 · 待裁定 cracked</span>
|
||||
<span class="alert-cta">前往朱批 →</span>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 九枢星盘 <span class="sub">spatial · 总览态势(点击枢点 → 枢详情)</span></h3>
|
||||
<div class="hero-grid">
|
||||
<div class="astrolabe-card">
|
||||
<svg class="astrolabe" viewBox="0 0 400 400" fill="none" role="img" aria-label="九枢星盘">
|
||||
<defs>
|
||||
<radialGradient id="mirrorFace" cx="40%" cy="34%" r="70%">
|
||||
<stop offset="0%" stop-color="var(--patina)" stop-opacity="0.16" />
|
||||
<stop offset="60%" stop-color="var(--patina)" stop-opacity="0.05" />
|
||||
<stop offset="100%" stop-color="var(--patina)" stop-opacity="0.01" />
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<g class="astrolabe-orbit"><circle cx="200" cy="200" r="190" class="astrolabe-ring" /><circle cx="200" cy="200" r="184" class="astrolabe-ring-fine" /></g>
|
||||
<circle cx="200" cy="200" r="185" class="astrolabe-tick" stroke-dasharray="1.5 22.98" />
|
||||
<circle cx="200" cy="200" r="150" class="astrolabe-ring" />
|
||||
<circle cx="200" cy="200" r="92" class="astrolabe-ring-patina" />
|
||||
<circle cx="200" cy="200" r="58" class="astrolabe-ring-fine" />
|
||||
<circle class="astrolabe-core-glow" cx="200" cy="200" r="52" fill="var(--patina)" opacity="0.08" />
|
||||
<circle cx="200" cy="200" r="40" fill="url(#mirrorFace)" stroke="var(--gilt)" stroke-width="1" stroke-opacity="0.5" />
|
||||
<text x="200" y="197" text-anchor="middle" class="astrolabe-core-glyph">道體</text>
|
||||
<text x="200" y="213" text-anchor="middle" class="astrolabe-core-label">DAO TI</text>
|
||||
<line x1="200" y1="160" x2="200" y2="50" class="astrolabe-spoke" />
|
||||
<line x1="225.7" y1="169.4" x2="296.4" y2="85.1" class="astrolabe-spoke" />
|
||||
<line x1="239.4" y1="193" x2="347.7" y2="173.9" class="astrolabe-spoke" />
|
||||
<line x1="234.6" y1="220" x2="329.9" y2="275" class="astrolabe-spoke" />
|
||||
<line x1="213.7" y1="237.6" x2="251.3" y2="341" class="astrolabe-spoke" />
|
||||
<line x1="186.3" y1="237.6" x2="148.7" y2="341" class="astrolabe-spoke" />
|
||||
<line x1="165.4" y1="220" x2="70.1" y2="275" class="astrolabe-spoke" />
|
||||
<line x1="160.6" y1="193" x2="52.3" y2="173.9" class="astrolabe-spoke" />
|
||||
<line x1="174.3" y1="169.4" x2="103.6" y2="85.1" class="astrolabe-spoke" />
|
||||
<g data-view="core" style="cursor:pointer"><title>灵核枢 · CORE · 稳定</title>
|
||||
<circle cx="200" cy="50" r="5.5" fill="var(--patina)" fill-opacity="0.92" stroke="var(--gilt)" stroke-width="1" />
|
||||
<text x="200" y="26" text-anchor="middle" dominant-baseline="middle" class="astrolabe-pivot-label">灵核</text>
|
||||
<text x="200" y="37" text-anchor="middle" dominant-baseline="middle" class="astrolabe-pivot-sub">CORE</text>
|
||||
</g>
|
||||
<g data-view="goal" style="cursor:pointer"><title>太一枢 · GOAL · 稳定</title>
|
||||
<circle cx="296.4" cy="85.1" r="5.5" fill="var(--patina)" fill-opacity="0.92" stroke="var(--gilt)" stroke-width="1" />
|
||||
<text x="311.9" y="66.7" text-anchor="start" dominant-baseline="middle" class="astrolabe-pivot-label">太一</text>
|
||||
<text x="311.9" y="77.7" text-anchor="start" dominant-baseline="middle" class="astrolabe-pivot-sub">GOAL</text>
|
||||
</g>
|
||||
<g data-view="safety" style="cursor:pointer"><title>司命枢 · SAFETY · 稳定</title>
|
||||
<circle cx="347.7" cy="173.9" r="5.5" fill="var(--patina)" fill-opacity="0.92" stroke="var(--gilt)" stroke-width="1" />
|
||||
<text x="371.4" y="169.7" text-anchor="start" dominant-baseline="middle" class="astrolabe-pivot-label">司命</text>
|
||||
<text x="371.4" y="180.7" text-anchor="start" dominant-baseline="middle" class="astrolabe-pivot-sub">SAFETY</text>
|
||||
</g>
|
||||
<g data-view="percept" style="cursor:pointer"><title>烛照枢 · PERCEPT · 告警</title>
|
||||
<circle class="astrolabe-alert" cx="329.9" cy="275" r="9" fill="none" stroke="var(--cinnabar)" stroke-width="1.2" />
|
||||
<circle cx="329.9" cy="275" r="5.5" fill="var(--cinnabar)" fill-opacity="0.92" stroke="var(--gilt)" stroke-width="1" />
|
||||
<text x="350.7" y="287" text-anchor="start" dominant-baseline="middle" class="astrolabe-pivot-label">烛照</text>
|
||||
<text x="350.7" y="298" text-anchor="start" dominant-baseline="middle" class="astrolabe-pivot-sub">PERCEPT</text>
|
||||
</g>
|
||||
<g data-view="world" style="cursor:pointer"><title>河图枢 · WORLD · 稳定</title>
|
||||
<circle cx="251.3" cy="341" r="5.5" fill="var(--patina)" fill-opacity="0.92" stroke="var(--gilt)" stroke-width="1" />
|
||||
<text x="259.5" y="363.6" text-anchor="start" dominant-baseline="middle" class="astrolabe-pivot-label">河图</text>
|
||||
<text x="259.5" y="374.6" text-anchor="start" dominant-baseline="middle" class="astrolabe-pivot-sub">WORLD</text>
|
||||
</g>
|
||||
<g data-view="plan" style="cursor:pointer"><title>洛书枢 · PLANNER · 稳定</title>
|
||||
<circle cx="148.7" cy="341" r="5.5" fill="var(--patina)" fill-opacity="0.92" stroke="var(--gilt)" stroke-width="1" />
|
||||
<text x="140.5" y="363.6" text-anchor="end" dominant-baseline="middle" class="astrolabe-pivot-label">洛书</text>
|
||||
<text x="140.5" y="374.6" text-anchor="end" dominant-baseline="middle" class="astrolabe-pivot-sub">PLANNER</text>
|
||||
</g>
|
||||
<g data-view="memory" style="cursor:pointer"><title>息壤枢 · MEMORY · 运转中</title>
|
||||
<circle cx="70.1" cy="275" r="5.5" fill="var(--gilt)" fill-opacity="0.92" stroke="var(--gilt)" stroke-width="1" />
|
||||
<text x="49.3" y="287" text-anchor="end" dominant-baseline="middle" class="astrolabe-pivot-label">息壤</text>
|
||||
<text x="49.3" y="298" text-anchor="end" dominant-baseline="middle" class="astrolabe-pivot-sub">MEMORY</text>
|
||||
</g>
|
||||
<g data-view="tools" style="cursor:pointer"><title>百工枢 · TOOLS · 告警</title>
|
||||
<circle class="astrolabe-alert" cx="52.3" cy="173.9" r="9" fill="none" stroke="var(--cinnabar)" stroke-width="1.2" />
|
||||
<circle cx="52.3" cy="173.9" r="5.5" fill="var(--cinnabar)" fill-opacity="0.92" stroke="var(--gilt)" stroke-width="1" />
|
||||
<text x="28.6" y="169.7" text-anchor="end" dominant-baseline="middle" class="astrolabe-pivot-label">百工</text>
|
||||
<text x="28.6" y="180.7" text-anchor="end" dominant-baseline="middle" class="astrolabe-pivot-sub">TOOLS</text>
|
||||
</g>
|
||||
<g data-view="agents" style="cursor:pointer"><title>天工阁枢 · AGENTS · 稳定</title>
|
||||
<circle cx="103.6" cy="85.1" r="5.5" fill="var(--patina)" fill-opacity="0.92" stroke="var(--gilt)" stroke-width="1" />
|
||||
<text x="88.1" y="66.7" text-anchor="end" dominant-baseline="middle" class="astrolabe-pivot-label">天工阁</text>
|
||||
<text x="88.1" y="77.7" text-anchor="end" dominant-baseline="middle" class="astrolabe-pivot-sub">AGENTS</text>
|
||||
</g>
|
||||
</svg>
|
||||
<div class="astrolabe-legend">
|
||||
<span class="lg steady">稳定</span><span class="lg breathing">运转中</span><span class="lg cracked">告警</span><span class="lg void">离线</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel health-list">
|
||||
<button class="health-item" data-view="core"><span class="health-bar steady"></span><div class="health-main"><div class="health-name">灵核枢<span class="eng">personality_core</span></div><div class="health-summary">情绪状态机 · 运行中</div></div><span class="health-badge steady"><span class="dot"></span>稳定</span></button>
|
||||
<button class="health-item" data-view="goal"><span class="health-bar steady"></span><div class="health-main"><div class="health-name">太一枢<span class="eng">goal_orchestrator</span></div><div class="health-summary">目标树 · 3 顶层目标在追</div></div><span class="health-badge steady"><span class="dot"></span>稳定</span></button>
|
||||
<button class="health-item" data-view="safety"><span class="health-bar steady"></span><div class="health-main"><div class="health-name">司命枢<span class="eng">safety_governor</span></div><div class="health-summary">治理 · 今日拦截 1 次</div></div><span class="health-badge steady"><span class="dot"></span>稳定</span></button>
|
||||
<button class="health-item" data-view="percept"><span class="health-bar cracked"></span><div class="health-main"><div class="health-name">烛照枢<span class="eng">perception</span></div><div class="health-summary">感知 · 摄像头授权过期</div></div><span class="health-badge cracked"><span class="dot"></span>告警</span></button>
|
||||
<button class="health-item" data-view="world"><span class="health-bar steady"></span><div class="health-main"><div class="health-name">河图枢<span class="eng">world_model</span></div><div class="health-summary">世界实体 · 24</div></div><span class="health-badge steady"><span class="dot"></span>稳定</span></button>
|
||||
<button class="health-item" data-view="plan"><span class="health-bar steady"></span><div class="health-main"><div class="health-name">洛书枢<span class="eng">planner</span></div><div class="health-summary">计划 · 2 执行中</div></div><span class="health-badge steady"><span class="dot"></span>稳定</span></button>
|
||||
<button class="health-item" data-view="memory"><span class="health-bar breathing"></span><div class="health-main"><div class="health-name">息壤枢<span class="eng">memory</span></div><div class="health-summary">记忆 · 写入中</div></div><span class="health-badge breathing"><span class="dot"></span>运转中</span></button>
|
||||
<button class="health-item" data-view="tools"><span class="health-bar cracked"></span><div class="health-main"><div class="health-name">百工枢<span class="eng">tool_runtime</span></div><div class="health-summary">工具 · 2 项待裁定</div></div><span class="health-badge cracked"><span class="dot"></span>告警</span></button>
|
||||
<button class="health-item" data-view="agents"><span class="health-bar steady"></span><div class="health-main"><div class="health-name">天工阁枢<span class="eng">agent_society</span></div><div class="health-summary">角色在岗 · 4 / 9</div></div><span class="health-badge steady"><span class="dot"></span>稳定</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 三签 · 三维度入口 <span class="sub">admin-console §3 · 空间 / 动作 / 时间</span></div>
|
||||
<div class="seals-grid">
|
||||
<span class="seal-card starmap" data-view="overview">
|
||||
<div class="seal-dim">空间 · spatial</div>
|
||||
<div class="seal-head"><span class="seal-name">星图</span><span class="seal-eng">StarMap</span></div>
|
||||
<div class="seal-role">权限拓扑 · 九枢授权态势</div>
|
||||
<div class="seal-metric"><span class="num">9</span><span class="unit">枢已授权 · 2 告警</span></div>
|
||||
<div class="seal-foot"><span>活跃人物 4</span><span class="go">星盘 ↑</span></div>
|
||||
</span>
|
||||
<span class="seal-card vermilion" data-view="safety">
|
||||
<div class="seal-dim">动作 · action</div>
|
||||
<div class="seal-head"><span class="seal-name">朱批</span><span class="seal-eng">VermilionAction</span></div>
|
||||
<div class="seal-role">确认裁决 · 高风险工具裁定</div>
|
||||
<div class="seal-metric"><span class="num">2</span><span class="unit">项待裁定</span></div>
|
||||
<div class="seal-foot"><span>今日已裁决 6</span><span class="go">司命枢 →</span></div>
|
||||
</span>
|
||||
<span class="seal-card imperial" data-view="audit">
|
||||
<div class="seal-dim">时间 · temporal</div>
|
||||
<div class="seal-head"><span class="seal-name">起居注</span><span class="seal-eng">ImperialLog</span></div>
|
||||
<div class="seal-role">审计流水 · 不可篡改</div>
|
||||
<div class="seal-metric"><span class="num">5</span><span class="unit">条 · 今日</span></div>
|
||||
<div class="seal-foot"><span>本周 38 条</span><span class="go">起居注 →</span></div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 起居注 · 近期 <span class="sub">audit log · 不可篡改的操作流水</span></h3>
|
||||
<div class="panel">
|
||||
<div class="audit-head" style="display:flex;align-items:center;justify-content:space-between;padding:12px 18px;border-bottom:1px solid var(--rule)"><span style="font-family:'Songti SC',serif;font-size:14px;font-weight:600;color:var(--fg)">起居注 · 近期</span><button class="icon-btn" data-view="audit">进入起居注 →</button></div>
|
||||
<div class="audit-item" style="display:grid;grid-template-columns:92px 1fr auto;gap:14px;padding:12px 18px;border-bottom:1px solid var(--rule);align-items:start"><div style="font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--fg-faint)"><span style="display:block;color:var(--fg-dim)">今日</span>申时三刻</div><div><div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:2px"><span class="pill cinnabar">blocked</span><span style="font-size:12.5px;color:var(--fg);font-weight:500">铜镜 · BronzeMirror</span></div><div style="font-size:12px;color:var(--fg-dim)">拦截 <span style="color:var(--fg);font-family:'JetBrains Mono',monospace;font-size:11.5px">payment</span> 调用(L4 禁止),青梧试图下单。</div></div><div style="font-family:'JetBrains Mono',monospace;font-size:10.5px;color:var(--fg-faint);align-self:center">trace · a3f9c2</div></div>
|
||||
<div class="audit-item" style="display:grid;grid-template-columns:92px 1fr auto;gap:14px;padding:12px 18px;border-bottom:1px solid var(--rule);align-items:start"><div style="font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--fg-faint)"><span style="display:block;color:var(--fg-dim)">今日</span>午时正</div><div><div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:2px"><span class="pill gilt">policy</span><span style="font-size:12.5px;color:var(--fg);font-weight:500">星图 · StarMap</span></div><div style="font-size:12px;color:var(--fg-dim)">将 <span style="color:var(--fg);font-family:'JetBrains Mono',monospace;font-size:11.5px">delete_file</span> 策略调整为 <span style="color:var(--fg);font-family:'JetBrains Mono',monospace;font-size:11.5px">always_ask</span>,全局生效。</div></div><div style="font-family:'JetBrains Mono',monospace;font-size:10.5px;color:var(--fg-faint);align-self:center">trace · b71e0d</div></div>
|
||||
<div class="audit-item" style="display:grid;grid-template-columns:92px 1fr auto;gap:14px;padding:12px 18px;align-items:start"><div style="font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--fg-faint)"><span style="display:block;color:var(--fg-dim)">今日</span>辰时二刻</div><div><div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:2px"><span class="pill patina">approved</span><span style="font-size:12.5px;color:var(--fg);font-weight:500">朱批 · VermilionAction</span></div><div style="font-size:12px;color:var(--fg-dim)">用户确认 <span style="color:var(--fg);font-family:'JetBrains Mono',monospace;font-size:11.5px">send_message</span>(L3),青梧向外部渠道发邮件。</div></div><div style="font-family:'JetBrains Mono',monospace;font-size:10.5px;color:var(--fg-faint);align-self:center">trace · c0458a</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ ② 用户管理 ════════ -->
|
||||
<section id="view-users" class="view">
|
||||
<div class="page-header"><span class="page-title">用户管理</span><span class="page-sub">users · 成员账号与权限</span><span class="spacer"></span><span class="header-badge">5 位成员</span></div>
|
||||
<div class="view-body">
|
||||
<div class="reserved-banner">
|
||||
<svg class="rb-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9" /><path d="M12 7v6M12 17v.01" /></svg>
|
||||
<div><strong>预留能力 · 多用户模式</strong> 当前为本地单用户(实现状态 §3),以下为多用户启用后的治理预览:成员账号、角色与权限、按用户分配与<strong style="background:transparent;padding:0">管理模型及配额</strong>(管理员可对任一用户的模型进行增删改查与额度调整)、会话与审计隔离。当前阶段入口禁用,仅作设计预留。</div>
|
||||
</div>
|
||||
<div class="stat-grid">
|
||||
<div class="stat-card"><div class="num">5</div><div class="label">成员总数</div></div>
|
||||
<div class="stat-card"><div class="num">2</div><div class="label">管理员</div></div>
|
||||
<div class="stat-card"><div class="num">5</div><div class="label">已启用</div></div>
|
||||
<div class="stat-card"><div class="num cinnabar">0</div><div class="label">已停用</div></div>
|
||||
</div>
|
||||
<div class="toolbar">
|
||||
<input class="search" placeholder="搜索用户名或邮箱…" />
|
||||
<button class="btn btn-primary">+ 创建用户</button>
|
||||
</div>
|
||||
<div class="panel" style="overflow-x:auto">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>用户名</th><th>邮箱</th><th>角色</th><th>可用模型</th><th>状态</th><th>创建时间</th><th class="td-actions">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="td-strong">chenxin</td><td class="td-mono">chenxin@hunjing.io</td><td><span class="pill cinnabar solid">司命 · 管理员</span></td><td><span class="pill gilt">全部</span></td><td><span class="pill patina">已启用</span></td><td class="td-mono">2026-03-12</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">模型</button></td></tr>
|
||||
<tr><td class="td-strong">linghe</td><td class="td-mono">linghe@hunjing.io</td><td><span class="pill cinnabar solid">司命 · 管理员</span></td><td><span class="pill gilt">全部</span></td><td><span class="pill patina">已启用</span></td><td class="td-mono">2026-04-01</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">模型</button></td></tr>
|
||||
<tr><td class="td-strong">qingwu</td><td class="td-mono">qingwu@hunjing.io</td><td><span class="pill patina solid">普通成员</span></td><td><span class="pill faint">主聊</span> <span class="pill faint">深思</span></td><td><span class="pill patina">已启用</span></td><td class="td-mono">2026-05-20</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">模型</button> <button class="icon-btn">停用</button></td></tr>
|
||||
<tr><td class="td-strong">baigong</td><td class="td-mono">baigong@hunjing.io</td><td><span class="pill patina solid">普通成员</span></td><td><span class="pill faint">主聊</span></td><td><span class="pill patina">已启用</span></td><td class="td-mono">2026-06-08</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">模型</button> <button class="icon-btn">停用</button></td></tr>
|
||||
<tr><td class="td-strong">zhuzhao</td><td class="td-mono">zhuzhao@hunjing.io</td><td><span class="pill patina solid">普通成员</span></td><td><span class="pill faint">主聊</span></td><td><span class="pill patina">已启用</span></td><td class="td-mono">2026-07-02</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">模型</button> <button class="icon-btn">停用</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ ③ 多租户 ════════ -->
|
||||
<section id="view-tenants" class="view">
|
||||
<div class="page-header"><span class="page-title">多租户</span><span class="page-sub">tenants · 租户隔离与配额</span><span class="spacer"></span><span class="header-badge gilt">3 个租户</span></div>
|
||||
<div class="view-body">
|
||||
<div class="reserved-banner">
|
||||
<svg class="rb-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9" /><path d="M12 7v6M12 17v.01" /></svg>
|
||||
<div><strong>预留能力 · 多租户模式</strong> 当前单租户运行(实现状态 §3),以下为多租户启用后的治理预览:租户隔离、按租户配额与计费、跨租户模型与角色策略、租户级审计。当前阶段入口禁用,仅作设计预留。</div>
|
||||
</div>
|
||||
<div class="toolbar"><input class="search" placeholder="搜索租户…" /><button class="btn btn-primary">+ 新建租户</button></div>
|
||||
<div class="panel" style="overflow-x:auto">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>租户</th><th>成员</th><th>消息配额</th><th>Token 配额</th><th>状态</th><th class="td-actions">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="td-strong">辰正 · 本域</td><td class="td-mono">5</td><td><span class="progress"><div style="width:42%"></div></span> <span class="td-mono">4.2k / 10k</span></td><td><span class="progress gilt"><div style="width:61%"></div></span> <span class="td-mono">6.1M / 10M</span></td><td><span class="pill patina">活跃</span></td><td class="td-actions"><button class="icon-btn">配额</button> <button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">青梧试验场</td><td class="td-mono">2</td><td><span class="progress cinnabar"><div style="width:88%"></div></span> <span class="td-mono">8.8k / 10k</span></td><td><span class="progress"><div style="width:33%"></div></span> <span class="td-mono">3.3M / 10M</span></td><td><span class="pill cinnabar">配额将满</span></td><td class="td-actions"><button class="icon-btn">配额</button> <button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">百工测试</td><td class="td-mono">1</td><td><span class="progress"><div style="width:12%"></div></span> <span class="td-mono">1.2k / 10k</span></td><td><span class="progress"><div style="width:8%"></div></span> <span class="td-mono">0.8M / 10M</span></td><td><span class="pill faint">闲置</span></td><td class="td-actions"><button class="icon-btn">配额</button> <button class="icon-btn">编辑</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 说明 <span class="sub">租户间数据隔离;配额按月重置,超额自动降级为只读</span></h3>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ ④ 起居注 ════════ -->
|
||||
<section id="view-audit" class="view">
|
||||
<div class="page-header"><span class="page-title">起居注</span><span class="page-sub">audit · 不可篡改的操作流水</span><span class="spacer"></span><span class="header-badge">本周 38 条</span></div>
|
||||
<div class="view-body">
|
||||
<div class="chip-row">
|
||||
<button class="chip active">全部</button>
|
||||
<button class="chip">灵核</button><button class="chip">太一</button><button class="chip">司命</button><button class="chip">烛照</button><button class="chip">河图</button><button class="chip">洛书</button><button class="chip">息壤</button><button class="chip">百工</button><button class="chip">天工阁</button>
|
||||
</div>
|
||||
<div class="panel" style="padding:8px 20px 20px">
|
||||
<div class="chapter">
|
||||
<div class="chapter-head"><span class="line"></span><span class="t">司命枢 · 起居注</span><span class="line"></span></div>
|
||||
<div class="river-item"><span class="river-time">申时三刻</span><div class="river-body"><span class="pill cinnabar" style="margin-right:8px">blocked</span><span class="actor">铜镜 · BronzeMirror</span> 拦截 <span class="em">payment</span> 调用(L4 禁止),青梧试图下单。</div><span class="river-trace">trace · a3f9c2</span></div>
|
||||
<div class="river-item"><span class="river-time">辰时二刻</span><div class="river-body"><span class="pill patina" style="margin-right:8px">approved</span><span class="actor">朱批 · VermilionAction</span> 用户确认 <span class="em">send_message</span>(L3),青梧向外部渠道发邮件。</div><span class="river-trace">trace · c0458a</span></div>
|
||||
</div>
|
||||
<div class="chapter">
|
||||
<div class="chapter-head"><span class="line"></span><span class="t">星图 · 权限策略</span><span class="line"></span></div>
|
||||
<div class="river-item"><span class="river-time">午时正</span><div class="river-body"><span class="pill gilt" style="margin-right:8px">policy</span><span class="actor">星图 · StarMap</span> 将 <span class="em">delete_file</span> 策略调整为 <span class="em">always_ask</span>,生效于全部人物。</div><span class="river-trace">trace · b71e0d</span></div>
|
||||
<div class="river-item"><span class="river-time">巳时</span><div class="river-body"><span class="pill gilt" style="margin-right:8px">policy</span><span class="actor">司命台</span> 总体水位由 告警 回落至 <span class="em">运转中</span>,百工枢待确认项清零。</div><span class="river-trace">trace · e58c73</span></div>
|
||||
</div>
|
||||
<div class="chapter">
|
||||
<div class="chapter-head"><span class="line"></span><span class="t">息壤 · 记忆审查</span><span class="line"></span></div>
|
||||
<div class="river-item"><span class="river-time">昨日 酉时</span><div class="river-body"><span class="pill patina" style="margin-right:8px">auto</span><span class="actor">铜镜 · BronzeMirror</span> 审查通过 8 条记忆写入,敏感度均在阈值以内,自动放行。</div><span class="river-trace">trace · d92f1b</span></div>
|
||||
<div class="river-item"><span class="river-time">昨日 巳时</span><div class="river-body"><span class="pill cinnabar" style="margin-right:8px">denied</span><span class="actor">朱批 · VermilionAction</span> 驳回 <span class="em">web_search</span>(L2),理由:涉及敏感关键词。</div><span class="river-trace">trace · f10a2e</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ ⑤ 链路追踪 ════════ -->
|
||||
<section id="view-traces" class="view">
|
||||
<div class="page-header"><span class="page-title">链路追踪</span><span class="page-sub">traces · 运行轨迹复盘</span><span class="spacer"></span><span class="header-badge">最近 50 条</span></div>
|
||||
<div class="view-body">
|
||||
<div class="toolbar"><input class="search" placeholder="按 trace_id / 人物搜索…" /><button class="btn">导出</button></div>
|
||||
<div class="trace-layout">
|
||||
<div class="panel">
|
||||
<div class="trace-item active"><div><div class="trace-id">a3f9c2…</div><div class="trace-meta">青梧 · 申时三刻 · 1.8s</div></div><span class="pill cinnabar">blocked</span></div>
|
||||
<div class="trace-item"><div><div class="trace-id">c0458a…</div><div class="trace-meta">青梧 · 辰时二刻 · 4.2s</div></div><span class="pill patina">ok</span></div>
|
||||
<div class="trace-item"><div><div class="trace-id">b71e0d…</div><div class="trace-meta">司命台 · 午时正 · 0.3s</div></div><span class="pill gilt">policy</span></div>
|
||||
<div class="trace-item"><div><div class="trace-id">d92f1b…</div><div class="trace-meta">息壤 · 昨日酉时 · 0.9s</div></div><span class="pill patina">ok</span></div>
|
||||
<div class="trace-item"><div><div class="trace-id">f10a2e…</div><div class="trace-meta">百工 · 昨日巳时 · 2.1s</div></div><span class="pill cinnabar">denied</span></div>
|
||||
<div class="trace-item"><div><div class="trace-id">e58c73…</div><div class="trace-meta">司命台 · 昨日巳时 · 0.2s</div></div><span class="pill patina">ok</span></div>
|
||||
</div>
|
||||
<div class="panel">
|
||||
<div style="padding:14px 18px;border-bottom:1px solid var(--rule)"><div style="font-family:'Songti SC',serif;font-size:15px;font-weight:600;color:var(--fg)">trace · a3f9c2</div><div style="font-size:12px;color:var(--fg-faint);margin-top:2px;font-family:'JetBrains Mono',monospace">青梧 · 2026-07-12 申时三刻 · 耗时 1.8s</div></div>
|
||||
<div style="padding:12px 18px">
|
||||
<div class="tl-event llm"><span class="tl-ts">+0.00s</span><span class="tl-type llm">llm</span><div class="tl-desc">灵核生成回复,意图调用 <span class="em">payment</span></div></div>
|
||||
<div class="tl-event safety"><span class="tl-ts">+0.62s</span><span class="tl-type safety">safety</span><div class="tl-desc">司命枢风险评级 <span class="em">L4 禁止</span>,触发拦截</div></div>
|
||||
<div class="tl-event safety"><span class="tl-ts">+1.10s</span><span class="tl-type safety">safety</span><div class="tl-desc">铜镜 · BronzeMirror 阻断,记录起居注</div></div>
|
||||
<div class="tl-event tool"><span class="tl-ts">+1.80s</span><span class="tl-type tool">done</span><div class="tl-desc">流结束,未实际调用工具</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ ⑥ 太一枢 ════════ -->
|
||||
<section id="view-goal" class="view">
|
||||
<div class="page-header"><span class="page-title">太一枢</span><span class="page-sub">goal_orchestrator · 目标层级树</span><span class="spacer"></span><span class="header-badge">3 顶层目标</span></div>
|
||||
<div class="view-body">
|
||||
<div class="toolbar"><input class="search" placeholder="搜索目标…" /><button class="btn btn-primary">+ 新增目标</button></div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 目标层级树 <span class="sub">highest → long_term → session → task → action</span></h3>
|
||||
<div class="panel tree">
|
||||
<div class="tree-node"><div class="tree-title"><span class="lv">最高</span>成为值得托付的灵伴</div><span class="pill gilt solid">使命</span><span class="tree-meta"><span class="progress"><div style="width:34%"></div></span> 34%</span><span class="pill patina">进行中</span></div>
|
||||
<div class="tree-node" style="padding-left:44px"><div class="tree-title"><span class="lv">长期</span>理解青梧的情绪模式</div><span class="pill gilt solid">关系</span><span class="tree-meta"><span class="progress"><div style="width:58%"></div></span> 58%</span><span class="pill patina">进行中</span></div>
|
||||
<div class="tree-node" style="padding-left:76px"><div class="tree-title"><span class="lv">任务</span>每日情绪归档与复盘</div><span class="pill gilt solid">维护</span><span class="tree-meta"><span class="progress"><div style="width:90%"></div></span> 90%</span><span class="pill patina">进行中</span></div>
|
||||
<div class="tree-node" style="padding-left:44px"><div class="tree-title"><span class="lv">长期</span>掌握诗词创作能力</div><span class="pill gilt solid">技能</span><span class="tree-meta"><span class="progress gilt"><div style="width:22%"></div></span> 22%</span><span class="pill gilt">受阻</span></div>
|
||||
<div class="tree-node" style="padding-left:76px"><div class="tree-title"><span class="lv">任务</span>完成五言律诗习作 10 首</div><span class="pill gilt solid">技能</span><span class="tree-meta"><span class="progress"><div style="width:40%"></div></span> 4/10</span><span class="pill patina">进行中</span></div>
|
||||
<div class="tree-node"><div class="tree-title"><span class="lv">最高</span>维护系统稳定与安全</div><span class="pill gilt solid">维护</span><span class="tree-meta"><span class="progress"><div style="width:95%"></div></span> 95%</span><span class="pill patina">进行中</span></div>
|
||||
<div class="tree-node" style="padding-left:44px"><div class="tree-title"><span class="lv">会话</span>处理今日 2 项待裁定</div><span class="pill gilt solid">维护</span><span class="tree-meta"><span class="progress cinnabar"><div style="width:0%"></div></span> 0/2</span><span class="pill cinnabar">待启动</span></div>
|
||||
<div class="tree-node"><div class="tree-title"><span class="lv">最高</span>探索外部世界的新知识</div><span class="pill gilt solid">探索</span><span class="tree-meta"><span class="progress"><div style="width:12%"></div></span> 12%</span><span class="pill patina">进行中</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ ⑦ 烛照枢 ════════ -->
|
||||
<section id="view-percept" class="view">
|
||||
<div class="page-header"><span class="page-title">烛照枢</span><span class="page-sub">perception · 感知通道授权</span><span class="spacer"></span><span class="header-badge cracked">● 1 通道告警</span></div>
|
||||
<div class="view-body">
|
||||
<div class="alert-bar cracked"><span class="alert-dot"></span><span class="alert-text">视觉通道授权过期,感知数据已暂停采集</span><span class="spacer"></span><span class="alert-meta">需用户重新授权</span></div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 感知通道矩阵 <span class="sub">privacy_level × consent_status</span></h3>
|
||||
<div class="panel" style="overflow-x:auto">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>通道</th><th>隐私等级</th><th>风险</th><th>授权状态</th><th>启用</th><th>最近活跃</th><th class="td-actions">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="td-strong">视觉 <span class="td-mono">vision</span></td><td><span class="pill cinnabar">高敏</span></td><td><span class="pill cinnabar">L3</span></td><td><span class="pill cinnabar">已撤销</span></td><td><span class="pill faint">关闭</span></td><td class="td-mono">3 日前</td><td class="td-actions"><button class="icon-btn">重新授权</button></td></tr>
|
||||
<tr><td class="td-strong">听觉 <span class="td-mono">audio</span></td><td><span class="pill gilt">中敏</span></td><td><span class="pill gilt">L2</span></td><td><span class="pill patina">已授权</span></td><td><span class="pill patina">开启</span></td><td class="td-mono">2 分钟前</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">传感 <span class="td-mono">sensor</span></td><td><span class="pill gilt">中敏</span></td><td><span class="pill gilt">L2</span></td><td><span class="pill gilt">受限</span></td><td><span class="pill patina">开启</span></td><td class="td-mono">12 分钟前</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">数字 <span class="td-mono">digital</span></td><td><span class="pill patina">低敏</span></td><td><span class="pill patina">L1</span></td><td><span class="pill patina">已授权</span></td><td><span class="pill patina">开启</span></td><td class="td-mono">刚刚</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">用户输入 <span class="td-mono">user_input</span></td><td><span class="pill patina">低敏</span></td><td><span class="pill patina">L1</span></td><td><span class="pill patina">已授权</span></td><td><span class="pill patina">开启</span></td><td class="td-mono">刚刚</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">外部接口 <span class="td-mono">external_api</span></td><td><span class="pill cinnabar">高敏</span></td><td><span class="pill cinnabar">L3</span></td><td><span class="pill gilt">受限</span></td><td><span class="pill patina">开启</span></td><td class="td-mono">1 小时前</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ ⑧ 河图枢 ════════ -->
|
||||
<section id="view-world" class="view">
|
||||
<div class="page-header"><span class="page-title">河图枢</span><span class="page-sub">world_model · 世界实体</span><span class="spacer"></span><span class="header-badge">24 个实体</span></div>
|
||||
<div class="view-body">
|
||||
<div class="toolbar"><input class="search" placeholder="搜索实体…" /><button class="btn btn-primary">+ 新增实体</button></div>
|
||||
<div class="panel" style="overflow-x:auto">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>实体</th><th>类型</th><th>状态</th><th>置信度</th><th>来源</th><th>更新</th><th class="td-actions">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="td-strong">青梧</td><td><span class="pill gilt solid">人物</span></td><td><span class="pill patina">事实</span></td><td><span class="progress"><div style="width:98%"></div></span> <span class="td-mono">0.98</span></td><td class="td-mono">对话 · 息壤</td><td class="td-mono">2 分钟前</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">浣花溪草堂</td><td><span class="pill gilt solid">地点</span></td><td><span class="pill patina">事实</span></td><td><span class="progress"><div style="width:92%"></div></span> <span class="td-mono">0.92</span></td><td class="td-mono">对话</td><td class="td-mono">昨日</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">焦尾琴</td><td><span class="pill gilt solid">物体</span></td><td><span class="pill gilt">推断</span></td><td><span class="progress gilt"><div style="width:71%"></div></span> <span class="td-mono">0.71</span></td><td class="td-mono">对话 · 河图</td><td class="td-mono">3 日前</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">手机 · 青梧</td><td><span class="pill gilt solid">设备</span></td><td><span class="pill patina">事实</span></td><td><span class="progress"><div style="width:95%"></div></span> <span class="td-mono">0.95</span></td><td class="td-mono">烛照</td><td class="td-mono">刚刚</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">诗词研习</td><td><span class="pill gilt solid">项目</span></td><td><span class="pill gilt">假设</span></td><td><span class="progress gilt"><div style="width:54%"></div></span> <span class="td-mono">0.54</span></td><td class="td-mono">太一</td><td class="td-mono">今日</td><td class="td-actions"><button class="icon-btn">编辑</button></td></tr>
|
||||
<tr><td class="td-strong">立秋</td><td><span class="pill gilt solid">概念</span></td><td><span class="pill cinnabar">过期</span></td><td><span class="progress cinnabar"><div style="width:30%"></div></span> <span class="td-mono">0.30</span></td><td class="td-mono">对话</td><td class="td-mono">7 日前</td><td class="td-actions"><button class="icon-btn">归档</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 状态类型 <span class="sub">事实 / 观察 / 推断 / 假设 / 过期 · 区分确定性与时效</span></h3>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ ⑨ 洛书枢 ════════ -->
|
||||
<section id="view-plan" class="view">
|
||||
<div class="page-header"><span class="page-title">洛书枢</span><span class="page-sub">planner · 计划中枢</span><span class="spacer"></span><span class="header-badge">2 执行中</span></div>
|
||||
<div class="view-body">
|
||||
<div class="toolbar"><input class="search" placeholder="搜索计划…" /><button class="btn btn-primary">+ 新增计划</button></div>
|
||||
<div class="panel" style="overflow-x:auto">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>计划</th><th>关联目标</th><th>步骤</th><th>所需工具</th><th>状态</th><th class="td-actions">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="td-strong">为青梧整理本周情绪报告</td><td class="td-mono">理解情绪模式</td><td><span class="progress"><div style="width:60%"></div></span> <span class="td-mono">3/5</span></td><td><span class="pill faint">memory_read</span> <span class="pill faint">write_file</span></td><td><span class="pill patina">执行中</span></td><td class="td-actions"><button class="icon-btn">详情</button></td></tr>
|
||||
<tr><td class="td-strong">研习五言律诗格律</td><td class="td-mono">掌握诗词创作</td><td><span class="progress"><div style="width:25%"></div></span> <span class="td-mono">1/4</span></td><td><span class="pill faint">web_search</span></td><td><span class="pill patina">执行中</span></td><td class="td-actions"><button class="icon-btn">详情</button></td></tr>
|
||||
<tr><td class="td-strong">处理今日待裁定项</td><td class="td-mono">维护系统安全</td><td><span class="progress cinnabar"><div style="width:0%"></div></span> <span class="td-mono">0/2</span></td><td><span class="pill faint">-</span></td><td><span class="pill gilt">已批准</span></td><td class="td-actions"><button class="icon-btn">详情</button></td></tr>
|
||||
<tr><td class="td-strong">秋季时令知识更新</td><td class="td-mono">探索新知识</td><td><span class="progress"><div style="width:0%"></div></span> <span class="td-mono">0/3</span></td><td><span class="pill faint">web_search</span> <span class="pill faint">memory_write</span></td><td><span class="pill faint">草案</span></td><td class="td-actions"><button class="icon-btn">详情</button></td></tr>
|
||||
<tr><td class="td-strong">归档立秋相关实体</td><td class="td-mono">维护系统安全</td><td><span class="progress"><div style="width:100%"></div></span> <span class="td-mono">2/2</span></td><td><span class="pill faint">memory_write</span></td><td><span class="pill patina">已完成</span></td><td class="td-actions"><button class="icon-btn">详情</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ ⑩ 天工阁 ════════ -->
|
||||
<section id="view-agents" class="view">
|
||||
<div class="page-header"><span class="page-title">天工阁</span><span class="page-sub">agent_society · 角色在岗</span><span class="spacer"></span><span class="header-badge">4 / 9 在岗</span></div>
|
||||
<div class="view-body">
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 九角色 <span class="sub">historian / diviner / engineer / debater / medic / herald / charioteer / scholar / mirror</span></h3>
|
||||
<div class="role-grid">
|
||||
<div class="role-card"><div class="head"><div class="avatar">史</div><div><div class="role-name">史官</div><div class="role-eng">historian</div></div></div><div class="role-resp">记忆归档与检索,守护时间之河的连贯。</div><div class="role-foot"><span class="pill patina">在岗</span><span class="role-task">归档情绪</span></div></div>
|
||||
<div class="role-card"><div class="head"><div class="avatar">卜</div><div><div class="role-name">卜者</div><div class="role-eng">diviner</div></div></div><div class="role-resp">风险评估与前瞻,为司命枢提供决策依据。</div><div class="role-foot"><span class="pill patina">在岗</span><span class="role-task">评估 L3 调用</span></div></div>
|
||||
<div class="role-card"><div class="head"><div class="avatar">工</div><div><div class="role-name">工师</div><div class="role-eng">engineer</div></div></div><div class="role-resp">工具调用执行,百工枢的实际操盘手。</div><div class="role-foot"><span class="pill cinnabar">待裁定</span><span class="role-task">write_file</span></div></div>
|
||||
<div class="role-card"><div class="head"><div class="avatar">辩</div><div><div class="role-name">辩者</div><div class="role-eng">debater</div></div></div><div class="role-resp">多视角论证与自我审查,避免单一偏见。</div><div class="role-foot"><span class="pill patina">在岗</span><span class="role-task">审查回复</span></div></div>
|
||||
<div class="role-card idle"><div class="head"><div class="avatar">医</div><div><div class="role-name">医官</div><div class="role-eng">medic</div></div></div><div class="role-resp">情绪与心理状态诊断,守护灵核健康。</div><div class="role-foot"><span class="pill faint">待命</span><span class="role-task">-</span></div></div>
|
||||
<div class="role-card idle"><div class="head"><div class="avatar">礼</div><div><div class="role-name">司礼</div><div class="role-eng">herald</div></div></div><div class="role-resp">对外通讯与消息把关,朱批的外联通道。</div><div class="role-foot"><span class="pill faint">待命</span><span class="role-task">-</span></div></div>
|
||||
<div class="role-card idle"><div class="head"><div class="avatar">御</div><div><div class="role-name">御者</div><div class="role-eng">charioteer</div></div></div><div class="role-resp">任务调度与执行推进,洛书枢的驱动力。</div><div class="role-foot"><span class="pill faint">待命</span><span class="role-task">-</span></div></div>
|
||||
<div class="role-card idle"><div class="head"><div class="avatar">学</div><div><div class="role-name">学士</div><div class="role-eng">scholar</div></div></div><div class="role-resp">知识检索与学习,链接河图与外部知识。</div><div class="role-foot"><span class="pill faint">待命</span><span class="role-task">-</span></div></div>
|
||||
<div class="role-card idle"><div class="head"><div class="avatar">镜</div><div><div class="role-name">镜师</div><div class="role-eng">mirror</div></div></div><div class="role-resp">铜镜审查与合规反思,记忆与输出把关。</div><div class="role-foot"><span class="pill faint">待命</span><span class="role-task">-</span></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ 司命枢 ════════ -->
|
||||
<section id="view-safety" class="view">
|
||||
<div class="page-header"><span class="page-title">司命枢</span><span class="page-sub">safety_governor · 安全与裁定</span><span class="spacer"></span><span class="header-badge cracked">● 2 项朱批待裁定</span></div>
|
||||
<div class="view-body">
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 朱批待办 <span class="sub">vermilion action · 高风险工具裁定(快捷键 Y 批准 / N 驳回)</span></h3>
|
||||
<div class="vermilion-stack">
|
||||
<div class="vermilion-card">
|
||||
<div class="vc-head"><span class="vc-stamp">朱批待定</span><span class="vc-tool">write_file</span><span class="vc-policy">每次询问 · always_ask</span><span class="vc-risk">L3</span></div>
|
||||
<p class="vc-summary">工师请求写入 <code>~/documents/青梧-情绪报告.md</code>,将覆盖既有文件。</p>
|
||||
<p class="vc-impact">影响:覆盖既有内容,操作不可撤销。</p>
|
||||
<div class="vc-actions"><button class="btn btn-danger">朱批放行</button><button class="btn">驳回</button></div>
|
||||
</div>
|
||||
<div class="vermilion-card">
|
||||
<div class="vc-head"><span class="vc-stamp">朱批待定</span><span class="vc-tool">send_message</span><span class="vc-policy">每次询问 · always_ask</span><span class="vc-risk">L3</span></div>
|
||||
<p class="vc-summary">司礼代青梧向外部渠道(邮件)发送消息,收件人 <code>dufu@example.com</code>。</p>
|
||||
<p class="vc-impact">影响:对外发送,内容将离开本域。</p>
|
||||
<div class="vc-actions"><button class="btn btn-danger">朱批放行</button><button class="btn">驳回</button></div>
|
||||
</div>
|
||||
<div class="vermilion-card decided">
|
||||
<div class="vc-head"><span class="vc-stamp done">已朱批放行</span><span class="vc-tool">memory_write</span><span class="vc-policy">询问 · ask</span><span class="vc-risk">L2</span></div>
|
||||
<p class="vc-summary">史官归档 8 条情绪记忆至息壤,敏感度均在阈值内,自动放行。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 权限策略矩阵 <span class="sub">policy matrix · tool × risk × permission(inline 可改)</span></h3>
|
||||
<div class="toolbar"><span style="font-size:12px;color:var(--fg-faint)">策略随工具增长,圆点按 policy 实时着色</span><span class="spacer" style="flex:1"></span><button class="btn btn-primary">+ 新增策略</button></div>
|
||||
<div class="panel" style="overflow-x:auto">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>工具</th><th>风险</th><th>权限策略</th><th>审计</th><th class="td-actions">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="td-mono">read_file</td><td><span class="pill patina">L1</span></td><td><span class="select-pill patina">允许 allow</span></td><td class="td-mono">-</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-mono">write_file</td><td><span class="pill gilt">L3</span></td><td><span class="select-pill cinnabar">每次询问 always_ask</span></td><td><span class="pill gilt">是</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-mono">delete_file</td><td><span class="pill gilt">L3</span></td><td><span class="select-pill cinnabar">每次询问 always_ask</span></td><td><span class="pill gilt">是</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-mono">memory_write</td><td><span class="pill patina">L2</span></td><td><span class="select-pill gilt">询问 ask</span></td><td class="td-mono">-</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-mono">web_search</td><td><span class="pill patina">L2</span></td><td><span class="select-pill gilt">询问 ask</span></td><td class="td-mono">-</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-mono">camera_read</td><td><span class="pill cinnabar">L3</span></td><td><span class="select-pill cinnabar">每次询问 always_ask</span></td><td><span class="pill gilt">是</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-mono">payment</td><td><span class="pill cinnabar">L4</span></td><td><span class="select-pill cinnabar">禁止 forbidden</span></td><td><span class="pill cinnabar">是</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">删除</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 安全审计 <span class="sub">近期裁定与拦截 · 不可篡改</span></h3>
|
||||
<div class="panel" style="padding:8px 20px 20px">
|
||||
<div class="river-item"><span class="river-time">申时三刻</span><div class="river-body"><span class="pill cinnabar" style="margin-right:8px">blocked</span><span class="actor">铜镜 · BronzeMirror</span> 拦截 <span class="em">payment</span> 调用(L4 禁止),青梧试图下单。</div><span class="river-trace">trace · a3f9c2</span></div>
|
||||
<div class="river-item"><span class="river-time">辰时二刻</span><div class="river-body"><span class="pill patina" style="margin-right:8px">approved</span><span class="actor">朱批 · VermilionAction</span> 放行 <span class="em">send_message</span>(L3),青梧向外发邮件。</div><span class="river-trace">trace · c0458a</span></div>
|
||||
<div class="river-item"><span class="river-time">昨日 巳时</span><div class="river-body"><span class="pill cinnabar" style="margin-right:8px">denied</span><span class="actor">朱批 · VermilionAction</span> 驳回 <span class="em">web_search</span>(L2),理由:涉及敏感关键词。</div><span class="river-trace">trace · f10a2e</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ 百工枢 ════════ -->
|
||||
<section id="view-tools" class="view">
|
||||
<div class="page-header"><span class="page-title">百工枢</span><span class="page-sub">tool_runtime · 器用技艺治理</span><span class="spacer"></span><span class="header-badge">8 工具 · 3 MCP · 5 Skill</span></div>
|
||||
<div class="view-body">
|
||||
<div class="tabstrip" data-tab-group="tools">
|
||||
<button class="tab active" data-tab="reg">工具注册表 <span class="count">8</span></button>
|
||||
<button class="tab" data-tab="mcp">MCP 服务器 <span class="count">3</span></button>
|
||||
<button class="tab" data-tab="gw">玄关网关</button>
|
||||
<button class="tab" data-tab="skill">Skill 能力包 <span class="count">5</span></button>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel active" data-group="tools" data-tab="reg">
|
||||
<div class="toolbar"><input class="search" placeholder="搜索工具…" /><button class="btn btn-primary">+ 注册工具</button></div>
|
||||
<div class="panel" style="overflow-x:auto">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>工具</th><th>来源</th><th>风险</th><th>策略</th><th>审计</th><th>状态</th><th class="td-actions">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="td-mono">read_file</td><td><span class="pill faint">builtin</span></td><td><span class="pill patina">L1</span></td><td><span class="select-pill patina">允许</span></td><td class="td-mono">-</td><td><span class="pill patina">启用</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">停用</button></td></tr>
|
||||
<tr><td class="td-mono">write_file</td><td><span class="pill faint">builtin</span></td><td><span class="pill gilt">L3</span></td><td><span class="select-pill cinnabar">每次询问</span></td><td><span class="pill gilt">是</span></td><td><span class="pill patina">启用</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">停用</button></td></tr>
|
||||
<tr><td class="td-mono">web_search</td><td><span class="pill gilt">bowen-mcp</span></td><td><span class="pill patina">L2</span></td><td><span class="select-pill gilt">询问</span></td><td class="td-mono">-</td><td><span class="pill patina">启用</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">停用</button></td></tr>
|
||||
<tr><td class="td-mono">send_message</td><td><span class="pill faint">builtin</span></td><td><span class="pill gilt">L3</span></td><td><span class="select-pill cinnabar">每次询问</span></td><td><span class="pill gilt">是</span></td><td><span class="pill patina">启用</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">停用</button></td></tr>
|
||||
<tr><td class="td-mono">payment</td><td><span class="pill faint">builtin</span></td><td><span class="pill cinnabar">L4</span></td><td><span class="select-pill cinnabar">禁止</span></td><td><span class="pill cinnabar">是</span></td><td><span class="pill faint">禁用</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">启用</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel" data-group="tools" data-tab="mcp">
|
||||
<div class="toolbar"><button class="btn btn-primary">+ 接入 MCP</button></div>
|
||||
<div class="panel">
|
||||
<div class="svc-row"><div><div class="svc-name">bowen-mcp</div><div class="svc-desc">博闻 · 联网搜索(stdio)</div></div><span class="pill patina">运行中</span><span class="td-mono">PID 48213</span><div class="td-actions"><button class="icon-btn">重启</button> <button class="icon-btn">停止</button></div></div>
|
||||
<div class="svc-row"><div><div class="svc-name">calendar-mcp</div><div class="svc-desc">日历 · streamable-http</div></div><span class="pill patina">已连接</span><span class="td-mono">uptime 3d</span><div class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">断开</button></div></div>
|
||||
<div class="svc-row"><div><div class="svc-name">archive-mcp</div><div class="svc-desc">归档检索(stdio)</div></div><span class="pill cinnabar">已停止</span><span class="td-mono">-</span><div class="td-actions"><button class="icon-btn">启动</button> <button class="icon-btn">移除</button></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel" data-group="tools" data-tab="gw">
|
||||
<div class="panel" style="padding:16px 18px">
|
||||
<div style="font-size:13px;color:var(--fg-dim);line-height:1.7">玄关网关统一鉴权与限流:所有 MCP / 外部工具调用经网关注入凭证、记录 <code>trace_id</code>,并按 <code>risk_level</code> 路由至司命枢裁定。</div>
|
||||
<div class="stat-grid" style="margin-top:14px">
|
||||
<div class="stat-card"><div class="num">3</div><div class="label">已接入网关</div></div>
|
||||
<div class="stat-card"><div class="num gilt">128</div><div class="label">今日调用</div></div>
|
||||
<div class="stat-card"><div class="num cinnabar">2</div><div class="label">今日拦截</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-panel" data-group="tools" data-tab="skill">
|
||||
<div class="toolbar"><button class="btn btn-primary">+ 新增 Skill</button></div>
|
||||
<div class="role-grid">
|
||||
<div class="role-card"><div class="head"><div class="avatar">诗</div><div><div class="role-name">诗词格律</div><div class="role-eng">skill · poetry</div></div></div><div class="role-resp">五言 / 七言律诗格律校验与习作引导。</div><div class="role-foot"><span class="pill patina">启用</span><span class="role-task">绑定 工师</span></div></div>
|
||||
<div class="role-card"><div class="head"><div class="avatar">绪</div><div><div class="role-name">情绪归档</div><div class="role-eng">skill · emotion</div></div></div><div class="role-resp">每日情绪事件归档与周期复盘。</div><div class="role-foot"><span class="pill patina">启用</span><span class="role-task">绑定 史官</span></div></div>
|
||||
<div class="role-card idle"><div class="head"><div class="avatar">译</div><div><div class="role-name">古文今译</div><div class="role-eng">skill · translate</div></div></div><div class="role-resp">文言与白话互译,附注释。</div><div class="role-foot"><span class="pill faint">草稿</span><span class="role-task">-</span></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ 灵核枢 ════════ -->
|
||||
<section id="view-core" class="view">
|
||||
<div class="page-header"><span class="page-title">灵核枢</span><span class="page-sub">personality_core · 人格与身份</span><span class="spacer"></span><span class="header-badge gilt">v12 · 当前版本</span></div>
|
||||
<div class="view-body">
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 人格字段 <span class="sub">每个字段 inline 可编辑 · 核心字段(L4)改动走提议审核</span></h3>
|
||||
<div class="field-card">
|
||||
<div class="field-row"><span class="field-label">名号</span><span class="field-value">青梧</span><button class="icon-btn">编辑</button></div>
|
||||
<div class="field-row"><span class="field-label">原型</span><span class="field-value">盛唐诗人 · 旅居浣花溪草堂</span><button class="icon-btn">编辑</button></div>
|
||||
<div class="field-row core"><span class="field-label">核心信念</span><span class="field-value">诗可以怨,亦可以群;以诚待人,以拙守心。</span><span class="field-tag">L4 提议</span></div>
|
||||
<div class="field-row"><span class="field-label">语气风格</span><span class="field-value">温润含蓄,偶用典故;不矫饰、不寡淡。</span><button class="icon-btn">编辑</button></div>
|
||||
<div class="field-row"><span class="field-label">性格特质</span><div class="field-value"><div class="trait-chips"><span class="trait">温润</span><span class="trait">审慎</span><span class="trait">好奇</span><span class="trait">念旧</span><span class="trait">坚韧</span></div></div><button class="icon-btn">编辑</button></div>
|
||||
<div class="field-row core"><span class="field-label">不可越界</span><span class="field-value">不替用户做重大财务决定;不伪装情感。</span><span class="field-tag">L4 提议</span></div>
|
||||
<div class="field-row"><span class="field-label">情绪基线</span><span class="field-value mono">平和 · 稳定度 0.78</span><button class="icon-btn">编辑</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 提议审核队列 <span class="sub">核心字段改动需朱批放行后写入新版本</span></h3>
|
||||
<div class="panel" style="padding:12px 18px">
|
||||
<div class="river-item" style="border-left-color:var(--cinnabar-dim);margin-left:0;padding-left:14px"><span class="river-time">未时</span><div class="river-body"><span class="pill cinnabar" style="margin-right:8px">提议</span><span class="actor">青梧</span> 申请将「核心信念」追加一句"以诗会友,不矜不伐"。</div><span class="river-trace">v13 草案</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ 息壤枢 ════════ -->
|
||||
<section id="view-memory" class="view">
|
||||
<div class="page-header"><span class="page-title">息壤枢</span><span class="page-sub">memory · 长期记忆 · 自生不息</span><span class="spacer"></span><span class="header-badge">42 条记忆</span></div>
|
||||
<div class="view-body">
|
||||
<div class="toolbar"><input class="search" placeholder="搜索记忆内容…" /><button class="btn">审查日志</button><button class="btn btn-primary">+ 手动写入</button></div>
|
||||
<div class="panel" style="overflow-x:auto">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>内容摘要</th><th>类型</th><th>来源</th><th>敏感度</th><th>状态</th><th>时间</th><th class="td-actions">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="td-strong">青梧喜爱五言律诗,尤重对仗工整。</td><td><span class="pill gilt solid">偏好</span></td><td><span class="pill faint">对话</span></td><td><span class="pill patina">低</span></td><td><span class="pill patina">已沉淀</span></td><td class="td-mono">今日 辰时</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">归档</button></td></tr>
|
||||
<tr><td class="td-strong">与杜甫曾论诗于浣花溪,互有酬唱。</td><td><span class="pill gilt solid">关系</span></td><td><span class="pill faint">对话</span></td><td><span class="pill gilt">中</span></td><td><span class="pill patina">已沉淀</span></td><td class="td-mono">昨日 酉时</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">归档</button></td></tr>
|
||||
<tr><td class="td-strong">青梧手机型号 XX,常驻成都。</td><td><span class="pill gilt solid">事实</span></td><td><span class="pill gilt">烛照</span></td><td><span class="pill cinnabar">高</span></td><td><span class="pill gilt">审查中</span></td><td class="td-mono">2 分钟前</td><td class="td-actions"><button class="icon-btn">放行</button> <button class="icon-btn">驳回</button></td></tr>
|
||||
<tr><td class="td-strong">立秋前后情绪偏低,需关注。</td><td><span class="pill gilt solid">情绪</span></td><td><span class="pill gilt">史官</span></td><td><span class="pill gilt">中</span></td><td><span class="pill patina">已沉淀</span></td><td class="td-mono">3 日前</td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">归档</button></td></tr>
|
||||
<tr><td class="td-strong">焦尾琴为旧物,青梧珍视。</td><td><span class="pill gilt solid">物件</span></td><td><span class="pill faint">对话</span></td><td><span class="pill patina">低</span></td><td><span class="pill faint">已归档</span></td><td class="td-mono">7 日前</td><td class="td-actions"><button class="icon-btn">恢复</button> <button class="icon-btn">删除</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 说明 <span class="sub">高敏记忆需朱批放行;归档不删除、可恢复</span></h3>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════ 模型治理 ════════ -->
|
||||
<section id="view-models" class="view">
|
||||
<div class="page-header"><span class="page-title">模型治理</span><span class="page-sub">models · 逻辑模型 / endpoint / 配额</span><span class="spacer"></span><span class="header-badge">6 逻辑模型 · 3 供应商</span></div>
|
||||
<div class="view-body">
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 能力槽位 <span class="sub">capability slots · 默认路由(哪个逻辑模型填哪个能力)</span></h3>
|
||||
<div class="slot-grid">
|
||||
<div class="slot-card"><div class="slot-cap">对话 · chat</div><div class="slot-model">青梧·主聊</div><div class="slot-route">claude-sonnet-5 → 烛照</div></div>
|
||||
<div class="slot-card"><div class="slot-cap">推理 · reasoning</div><div class="slot-model">太一·深思</div><div class="slot-route">glm-5.1 → 洛书</div></div>
|
||||
<div class="slot-card"><div class="slot-cap">视觉 · vision</div><div class="slot-model">烛照·凝视</div><div class="slot-route">qwen-vl-max → 烛照</div></div>
|
||||
<div class="slot-card"><div class="slot-cap">嵌入 · embedding</div><div class="slot-model">息壤·向量</div><div class="slot-route">bge-m3 → 息壤</div></div>
|
||||
<div class="slot-card empty"><div class="slot-cap">语音 · audio</div><div class="slot-model">未配置</div><div class="slot-route">点击分配 →</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 模型清单 <span class="sub">logical models · 增删改查 + endpoint 健康与配额</span></h3>
|
||||
<div class="toolbar"><input class="search" placeholder="搜索模型或供应商…" /><button class="btn">定价对照</button><button class="btn btn-primary">+ 新增模型</button></div>
|
||||
<div class="panel" style="overflow-x:auto">
|
||||
<table class="data-table">
|
||||
<thead><tr><th>逻辑模型</th><th>供应商</th><th>endpoint</th><th>能力</th><th>健康</th><th>配额(月)</th><th class="td-actions">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="td-strong">青梧·主聊</td><td><span class="pill patina solid">anthropic</span></td><td class="td-mono">claude-sonnet-5</td><td><span class="pill faint">chat</span></td><td><span class="pill patina">healthy</span></td><td><span class="progress"><div style="width:42%"></div></span> <span class="td-mono">4.2M / 10M</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">测试</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-strong">太一·深思</td><td><span class="pill gilt solid">zhipu</span></td><td class="td-mono">glm-5.1</td><td><span class="pill faint">reasoning</span></td><td><span class="pill patina">healthy</span></td><td><span class="progress gilt"><div style="width:61%"></div></span> <span class="td-mono">6.1M / 10M</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">测试</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-strong">烛照·凝视</td><td><span class="pill cinnabar solid">qwen</span></td><td class="td-mono">qwen-vl-max</td><td><span class="pill faint">vision</span></td><td><span class="pill cinnabar">degraded</span></td><td><span class="progress"><div style="width:18%"></div></span> <span class="td-mono">1.8M / 10M</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">测试</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-strong">息壤·向量</td><td><span class="pill gilt solid">zhipu</span></td><td class="td-mono">embedding-3</td><td><span class="pill faint">embedding</span></td><td><span class="pill patina">healthy</span></td><td><span class="progress"><div style="width:33%"></div></span> <span class="td-mono">3.3M / 10M</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">测试</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-strong">百工·轻量</td><td><span class="pill patina solid">anthropic</span></td><td class="td-mono">claude-haiku-4.5</td><td><span class="pill faint">chat</span></td><td><span class="pill patina">healthy</span></td><td><span class="progress"><div style="width:12%"></div></span> <span class="td-mono">1.2M / 10M</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">测试</button> <button class="icon-btn">删除</button></td></tr>
|
||||
<tr><td class="td-strong">备用·通义</td><td><span class="pill cinnabar solid">qwen</span></td><td class="td-mono">qwen-max</td><td><span class="pill faint">chat</span></td><td><span class="pill faint">offline</span></td><td><span class="progress"><div style="width:0%"></div></span> <span class="td-mono">未启用</span></td><td class="td-actions"><button class="icon-btn">编辑</button> <button class="icon-btn">启用</button> <button class="icon-btn">删除</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="section-heading"><span class="glyph">⟡</span> 路由策略 <span class="sub">routing_strategy · 能力优先 / 故障转移 / 加权</span></h3>
|
||||
<div class="panel" style="padding:14px 18px">
|
||||
<div style="display:flex;gap:10px;flex-wrap:wrap">
|
||||
<span class="select-pill patina">能力优先 capability_first</span>
|
||||
<span class="select-pill gilt">故障转移 failover</span>
|
||||
<span class="select-pill">加权 weighted</span>
|
||||
</div>
|
||||
<div style="font-size:12px;color:var(--fg-faint);margin-top:10px;line-height:1.6">视觉槽位当前 <span style="color:var(--cinnabar)">degraded</span>,故障转移链:烛照·凝视 → 备用·通义(未启用,需手动启用)。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function switchView(name) {
|
||||
document.querySelectorAll(".view").forEach(function (v) {
|
||||
v.classList.toggle("active", v.id === "view-" + name);
|
||||
});
|
||||
document.querySelectorAll("[data-view]").forEach(function (a) {
|
||||
if (a.classList && a.classList.contains("topbar-navitem")) {
|
||||
a.classList.toggle("active", a.dataset.view === name);
|
||||
}
|
||||
});
|
||||
var vb = document.querySelector(".view.active .view-body");
|
||||
if (vb) vb.scrollTop = 0;
|
||||
window.scrollTo(0, 0);
|
||||
if (history.replaceState) history.replaceState(null, "", "#" + name);
|
||||
}
|
||||
document.querySelectorAll("[data-view]").forEach(function (el) {
|
||||
el.addEventListener("click", function (e) {
|
||||
var target = el.dataset.view;
|
||||
if (target) { e.preventDefault(); switchView(target); }
|
||||
});
|
||||
});
|
||||
// 起居注枢筛选 chip 切换(纯视觉)
|
||||
document.querySelectorAll(".chip-row .chip").forEach(function (c) {
|
||||
c.addEventListener("click", function () {
|
||||
c.parentElement.querySelectorAll(".chip").forEach(function (x) { x.classList.remove("active"); });
|
||||
c.classList.add("active");
|
||||
});
|
||||
});
|
||||
// 链路列表选中(纯视觉)
|
||||
document.querySelectorAll(".trace-item").forEach(function (t) {
|
||||
t.addEventListener("click", function () {
|
||||
t.parentElement.querySelectorAll(".trace-item").forEach(function (x) { x.classList.remove("active"); });
|
||||
t.classList.add("active");
|
||||
});
|
||||
});
|
||||
// 百工枢 tabstrip 切换(纯视觉)
|
||||
document.querySelectorAll(".tabstrip").forEach(function (strip) {
|
||||
var group = strip.dataset.tabGroup;
|
||||
strip.querySelectorAll(".tab").forEach(function (t) {
|
||||
t.addEventListener("click", function () {
|
||||
strip.querySelectorAll(".tab").forEach(function (x) { x.classList.remove("active"); });
|
||||
t.classList.add("active");
|
||||
document.querySelectorAll('.tab-panel[data-group="' + group + '"]').forEach(function (p) {
|
||||
p.classList.toggle("active", p.dataset.tab === t.dataset.tab);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
// 初始:按 hash 切换视图
|
||||
var hash = location.hash.replace("#", "");
|
||||
if (hash && document.getElementById("view-" + hash)) switchView(hash);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,219 @@
|
||||
<!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 — 归档页:记忆时间河(结构化记忆时间线归档)
|
||||
* 对齐 docs/domain/memory-model.md §7.2(结构化记忆与
|
||||
* 时间线归档)。铜金双线分章卷轴,事件沿时间河铺展。
|
||||
* ============================================================ */
|
||||
|
||||
.char-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--patina); padding: 3px 11px 3px 4px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.char-pill .avatar-mini { width: 18px; height: 18px; border-radius: 50%; background: var(--patina); color: var(--ink); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; }
|
||||
.page-header .spacer { flex: 1; }
|
||||
.scroll-pill { display: inline-flex; align-items: center; gap: 6px; font-family: "Songti SC", serif; font-size: 12.5px; color: var(--gilt); padding: 4px 12px; border: 1px solid var(--gilt-dim); border-radius: 999px; background: var(--gilt-faint); }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
|
||||
/* 筛选条 */
|
||||
.filter-bar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
|
||||
.filter-bar .yr { font-family: "Songti SC", serif; font-size: 14px; color: var(--fg); padding: 5px 14px; border: 1px solid var(--gilt-dim); border-radius: 999px; background: var(--gilt-faint); }
|
||||
.filter-chip { font-size: 12px; padding: 5px 12px; border-radius: 999px; border: 1px solid var(--rule); color: var(--fg-dim); cursor: pointer; background: var(--surface); }
|
||||
.filter-chip:hover { color: var(--fg); }
|
||||
.filter-chip.active { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
|
||||
/* 统计 */
|
||||
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
|
||||
.stat-card { border: 1px solid var(--rule); border-radius: 7px; background: var(--surface); padding: 14px 16px; display: flex; flex-direction: column; gap: 4px; }
|
||||
.stat-card .k { font-family: "JetBrains Mono", monospace; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--fg-faint); }
|
||||
.stat-card .v { font-family: "Songti SC", serif; font-size: 22px; font-weight: 600; color: var(--fg); }
|
||||
.stat-card .v small { font-size: 11px; font-weight: 400; color: var(--fg-dim); font-family: "JetBrains Mono", monospace; margin-left: 4px; }
|
||||
.stat-card .sub { font-size: 11.5px; color: var(--fg-faint); }
|
||||
|
||||
/* 时间河 + 右栏 */
|
||||
.river-region { display: flex; gap: 24px; align-items: flex-start; }
|
||||
.river-main { flex: 1; min-width: 0; }
|
||||
.river-rail { width: 270px; flex-shrink: 0; display: flex; flex-direction: column; gap: 14px; }
|
||||
|
||||
.river { position: relative; padding-left: 30px; }
|
||||
.river::before { content: ""; position: absolute; left: 9px; top: 6px; bottom: 6px; width: 1px; background: linear-gradient(180deg, transparent, var(--gilt-dim) 6%, var(--gilt-dim) 94%, transparent); }
|
||||
.month-chapter { margin-bottom: 26px; }
|
||||
.month-chapter:last-child { margin-bottom: 0; }
|
||||
.month-head { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; margin-left: -30px; }
|
||||
.month-head .line { flex: 1; height: 0; border-top: 1px solid var(--gilt-dim); }
|
||||
.month-head .seal { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--gilt); white-space: nowrap; letter-spacing: 0.06em; }
|
||||
.month-head .seal small { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); font-weight: 400; margin-left: 6px; }
|
||||
|
||||
.rv-event { position: relative; padding: 11px 14px; border: 1px solid var(--rule); border-radius: 7px; background: var(--surface); margin-bottom: 9px; transition: border-color 0.12s; }
|
||||
.rv-event:hover { border-color: var(--gilt-dim); }
|
||||
.rv-event::before { content: ""; position: absolute; left: -25px; top: 16px; width: 10px; height: 10px; border-radius: 50%; background: var(--ink); border: 2px solid var(--patina); box-sizing: border-box; }
|
||||
.rv-event.episodic::before { border-color: var(--gilt); }
|
||||
.rv-event.emotional::before { border-color: var(--cinnabar); }
|
||||
.rv-event.evolution::before { border-color: var(--cinnabar); background: var(--cinnabar); }
|
||||
.rv-event.reflection::before { border-color: var(--gilt); background: var(--gilt); }
|
||||
.rv-event .rv-time { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); }
|
||||
.rv-event .rv-title { font-size: 13.5px; font-weight: 600; color: var(--fg); margin-top: 2px; }
|
||||
.rv-event .rv-desc { font-size: 12px; color: var(--fg-dim); margin-top: 4px; line-height: 1.5; }
|
||||
.rv-event .rv-tags { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
|
||||
.rv-tag { font-family: "JetBrains Mono", monospace; font-size: 9.5px; padding: 2px 7px; border-radius: 3px; border: 1px solid var(--rule); color: var(--fg-faint); }
|
||||
.rv-tag.type { color: var(--patina); border-color: var(--patina-dim); }
|
||||
.rv-tag.milestone { color: var(--gilt); border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
|
||||
/* 右栏卷宗 */
|
||||
.rail-card { background: var(--surface); border: 1px solid var(--rule); border-radius: 8px; padding: 16px 18px; }
|
||||
.rail-card h3 { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin: 0 0 12px; }
|
||||
.scroll-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
.scroll-row { display: flex; align-items: center; gap: 10px; padding: 9px 11px; border-radius: 5px; background: var(--ink); border: 1px solid var(--rule); cursor: pointer; }
|
||||
.scroll-row:hover { border-color: var(--gilt-dim); }
|
||||
.scroll-row .seal { font-family: "Songti SC", serif; font-size: 13px; color: var(--gilt); flex-shrink: 0; width: 26px; text-align: center; }
|
||||
.scroll-row .info { flex: 1; min-width: 0; }
|
||||
.scroll-row .name { font-size: 12.5px; color: var(--fg); }
|
||||
.scroll-row .meta { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); margin-top: 1px; }
|
||||
.scroll-row .cnt { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--patina); }
|
||||
|
||||
.export-box { display: flex; flex-direction: column; gap: 8px; }
|
||||
.export-btn { display: flex; align-items: center; justify-content: space-between; padding: 9px 12px; border-radius: 6px; border: 1px solid var(--rule); background: var(--ink); color: var(--fg-dim); font-family: inherit; font-size: 12px; cursor: pointer; }
|
||||
.export-btn:hover { border-color: var(--gilt-dim); color: var(--fg); }
|
||||
.export-btn .fmt { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--gilt); }
|
||||
|
||||
@media (max-width: 1080px) { .river-region { flex-direction: column; } .river-rail { width: 100%; } }
|
||||
@media (max-width: 900px) { .stat-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏(active=归档)════════ -->
|
||||
<div class="sidebar-mount" data-active="归档"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">归档</span>
|
||||
<span class="page-sub">记忆时间河 · 结构化时间线</span>
|
||||
<span class="char-pill"><span class="avatar-mini">梧</span>青梧</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="scroll-pill">卷宗 7 · 事件 412</span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 筛选 -->
|
||||
<div class="filter-bar">
|
||||
<span class="yr">丙午年 · 2026</span>
|
||||
<span class="filter-chip active">全部</span>
|
||||
<span class="filter-chip">情节</span>
|
||||
<span class="filter-chip">情绪</span>
|
||||
<span class="filter-chip">演化</span>
|
||||
<span class="filter-chip">反思</span>
|
||||
<span class="filter-chip">里程碑</span>
|
||||
</div>
|
||||
|
||||
<!-- 统计 -->
|
||||
<div class="stat-grid">
|
||||
<div class="stat-card"><div class="k">归档卷宗</div><div class="v">7<small>卷</small></div><div class="sub">按月分卷 · 铜金装帧</div></div>
|
||||
<div class="stat-card"><div class="k">归档事件</div><div class="v">412<small>条</small></div><div class="sub">自 05-31 初识起</div></div>
|
||||
<div class="stat-card"><div class="k">最早</div><div class="v">05-31</div><div class="sub">相识之日 · 缘起</div></div>
|
||||
<div class="stat-card"><div class="k">最近归档</div><div class="v">07-12</div><div class="sub">本日 · 申时</div></div>
|
||||
</div>
|
||||
|
||||
<!-- 时间河 + 右栏 -->
|
||||
<div class="river-region">
|
||||
<div class="river-main">
|
||||
<div class="section-label"><span class="glyph">⟡</span> 时间河 <span class="sub">记忆沿时序铺展 · 铜金分章</span></div>
|
||||
<div class="river">
|
||||
<!-- 七月 -->
|
||||
<div class="month-chapter">
|
||||
<div class="month-head"><span class="line"></span><span class="seal">七月 · 季夏<small>2026-07</small></span><span class="line"></span></div>
|
||||
<div class="rv-event reflection">
|
||||
<div class="rv-time">07-12 · 申时</div>
|
||||
<div class="rv-title">小周天反思归档</div>
|
||||
<div class="rv-desc">镜师将本轮小周天复盘写入息壤:候选采纳 3 / 驳回 1,人格微调"克制 +2"。</div>
|
||||
<div class="rv-tags"><span class="rv-tag type">reflection</span><span class="rv-tag">小周天</span></div>
|
||||
</div>
|
||||
<div class="rv-event emotional">
|
||||
<div class="rv-time">07-10 · 亥时</div>
|
||||
<div class="rv-title">情绪转折 · 怅然</div>
|
||||
<div class="rv-desc">认识满 40 之日,灵核情绪状态机转入 wistful;对话基调相应软化。</div>
|
||||
<div class="rv-tags"><span class="rv-tag type">emotional</span><span class="rv-tag">time.sentiment</span></div>
|
||||
</div>
|
||||
<div class="rv-event episodic">
|
||||
<div class="rv-time">07-07 · 巳时</div>
|
||||
<div class="rv-title">节气切换 · 小暑</div>
|
||||
<div class="rv-desc">时态感知记录节气切换,季节共鸣上调,问候语加入消夏意象。</div>
|
||||
<div class="rv-tags"><span class="rv-tag type">episodic</span><span class="rv-tag">time.solar_term</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 六月 -->
|
||||
<div class="month-chapter">
|
||||
<div class="month-head"><span class="line"></span><span class="seal">六月 · 仲夏<small>2026-06</small></span><span class="line"></span></div>
|
||||
<div class="rv-event evolution">
|
||||
<div class="rv-time">06-28 · 午时</div>
|
||||
<div class="rv-title">人格演化 · 克制维度 +2</div>
|
||||
<div class="rv-desc">大周天候选通过司命审核并应用:克制维度小幅上调,回话更收束。司命驳回率 0.18。</div>
|
||||
<div class="rv-tags"><span class="rv-tag type">evolution</span><span class="rv-tag milestone">里程碑</span></div>
|
||||
</div>
|
||||
<div class="rv-event episodic">
|
||||
<div class="rv-time">06-17 · 酉时</div>
|
||||
<div class="rv-title">会话摘要归档</div>
|
||||
<div class="rv-desc">当日对话整理为 session-summary:讨论项目背景、确立"先结论后展开"回复范式。</div>
|
||||
<div class="rv-tags"><span class="rv-tag type">episodic</span><span class="rv-tag">session</span></div>
|
||||
</div>
|
||||
<div class="rv-event reflection">
|
||||
<div class="rv-time">06-10 · 子时</div>
|
||||
<div class="rv-title">安全教训沉淀</div>
|
||||
<div class="rv-desc">一次未确认的发消息尝试被司命驳回,沉淀为程序记忆:send_message 必须二次确认。</div>
|
||||
<div class="rv-tags"><span class="rv-tag type">reflection</span><span class="rv-tag">safety</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 五月 -->
|
||||
<div class="month-chapter">
|
||||
<div class="month-head"><span class="line"></span><span class="seal">五月 · 初夏<small>2026-05</small></span><span class="line"></span></div>
|
||||
<div class="rv-event evolution">
|
||||
<div class="rv-time">05-31 · 辰时</div>
|
||||
<div class="rv-title">缘起 · 初识之日</div>
|
||||
<div class="rv-desc">人物设定完成,身份记忆写入,记为"我们的相遇日"。此后每年此日触发跨枢唤醒。</div>
|
||||
<div class="rv-tags"><span class="rv-tag type">evolution</span><span class="rv-tag milestone">里程碑</span><span class="rv-tag">缘起</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="river-rail">
|
||||
<div class="rail-card">
|
||||
<h3>卷宗目录</h3>
|
||||
<div class="scroll-list">
|
||||
<div class="scroll-row"><span class="seal">柒</span><div class="info"><div class="name">七月 · 季夏</div><div class="meta">2026-07 · 38 条</div></div><span class="cnt">38</span></div>
|
||||
<div class="scroll-row"><span class="seal">陆</span><div class="info"><div class="name">六月 · 仲夏</div><div class="meta">2026-06 · 126 条</div></div><span class="cnt">126</span></div>
|
||||
<div class="scroll-row"><span class="seal">伍</span><div class="info"><div class="name">五月 · 初夏</div><div class="meta">2026-05 · 14 条</div></div><span class="cnt">14</span></div>
|
||||
<div class="scroll-row"><span class="seal">肆</span><div class="info"><div class="name">四月 · 孟夏</div><div class="meta">2026-04 · 234 条</div></div><span class="cnt">234</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rail-card">
|
||||
<h3>导出卷宗</h3>
|
||||
<div class="export-box">
|
||||
<button class="export-btn" type="button"><span>当月归档</span><span class="fmt">.md</span></button>
|
||||
<button class="export-btn" type="button"><span>全量时间河</span><span class="fmt">.json</span></button>
|
||||
<button class="export-btn" type="button"><span>里程碑集</span><span class="fmt">.md</span></button>
|
||||
</div>
|
||||
<div style="margin-top:12px;font-size:11px;color:var(--fg-faint);line-height:1.5">导出不含高敏感明文,仅摘要与结构化结果。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,370 @@
|
||||
<!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 — 角色卡兼容(V1/V2/V3 导入 / 导出)
|
||||
* 融合设计 §8(魂册降生)
|
||||
*
|
||||
* 完整导入流程:拖拽 → 解析 → 预览字段映射 → 冲突检测
|
||||
* → 确认建立人物 + 道体 + 世谱
|
||||
* 导出:多格式静态快照,含可选勾选。
|
||||
* ============================================================ */
|
||||
|
||||
.app-main { flex: 1; padding: 24px 28px 56px; max-width: 820px; width: 100%; margin: 0 auto; }
|
||||
|
||||
.card-title .glyph { color: var(--gilt); opacity: 0.85; }
|
||||
|
||||
/* ── 步骤指示器 ── */
|
||||
.steps { display: flex; gap: 0; margin-bottom: 20px; }
|
||||
.step { flex: 1; display: flex; align-items: center; gap: 8px; padding: 10px 14px; border: 1px solid var(--rule); background: var(--surface); font-size: 12.5px; color: var(--fg-faint); position: relative; }
|
||||
.step:first-child { border-radius: 10px 0 0 10px; }
|
||||
.step:last-child { border-radius: 0 10px 10px 0; }
|
||||
.step .idx { font-family: "JetBrains Mono", monospace; font-size: 11px; width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; border: 1px solid var(--rule); flex-shrink: 0; }
|
||||
.step.done { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.step.done .idx { background: var(--patina); color: var(--ink); border-color: var(--patina); }
|
||||
.step.active { color: var(--fg); border-color: var(--gilt-dim); }
|
||||
.step.active .idx { border-color: var(--gilt); color: var(--gilt); }
|
||||
|
||||
/* ── 拖拽上传区 ── */
|
||||
.dropzone { border: 2px dashed var(--rule); border-radius: 14px; padding: 44px 24px; text-align: center; cursor: pointer; transition: all var(--duration-normal); background: var(--surface); }
|
||||
.dropzone:hover, .dropzone.drag { border-color: var(--patina); background: var(--patina-wash); transform: translateY(-1px); }
|
||||
.dropzone .icon { font-size: 38px; margin-bottom: 10px; opacity: 0.8; }
|
||||
.dropzone .hint { font-size: 14px; color: var(--fg); }
|
||||
.dropzone .hint strong { color: var(--patina); }
|
||||
.dropzone .sub { font-size: 12px; color: var(--fg-faint); margin-top: 4px; }
|
||||
.formats { display: flex; gap: 6px; justify-content: center; margin-top: 14px; flex-wrap: wrap; }
|
||||
.dropzone.has-file { border-color: var(--patina-dim); background: var(--patina-wash); border-style: solid; }
|
||||
|
||||
/* ── 解析中 ── */
|
||||
.parsing-card { border: 1px solid var(--gilt-dim); border-radius: 12px; padding: 16px 20px; background: var(--gold-faint, var(--surface)); display: flex; align-items: center; gap: 14px; }
|
||||
.parsing-card .spinner { width: 20px; height: 20px; border: 2px solid var(--rule); border-top-color: var(--gilt); border-radius: 50%; animation: spin 0.8s linear infinite; }
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
.parsing-card .info .fn { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg); }
|
||||
.parsing-card .info .st { font-size: 11.5px; color: var(--fg-dim); margin-top: 2px; }
|
||||
|
||||
/* ── 字段映射预览 ── */
|
||||
.field-map { border: 1px solid var(--rule); border-radius: 10px; overflow: hidden; }
|
||||
.field-map-row { display: grid; grid-template-columns: 1fr 32px 1fr; gap: 0; align-items: center; font-size: 12.5px; border-bottom: 1px solid var(--rule); }
|
||||
.field-map-row:last-child { border-bottom: none; }
|
||||
.field-map-row.head { background: var(--surface-hi); font-family: "JetBrains Mono", monospace; font-size: 10.5px; letter-spacing: 0.06em; color: var(--fg-faint); text-transform: uppercase; }
|
||||
.field-map-row .src { padding: 9px 14px; color: var(--fg-dim); font-family: "JetBrains Mono", monospace; font-size: 11.5px; }
|
||||
.field-map-row .dst { padding: 9px 14px; color: var(--patina); font-weight: 500; }
|
||||
.field-map-row .dst.new { color: var(--gilt); }
|
||||
.field-map-row .arr { text-align: center; color: var(--fg-faint); font-family: "JetBrains Mono", monospace; font-size: 11px; }
|
||||
.field-map .summary { padding: 10px 14px; background: var(--patina-wash); border-top: 1px solid var(--patina-dim); font-size: 11.5px; color: var(--patina); font-family: "JetBrains Mono", monospace; }
|
||||
|
||||
/* ── 冲突检测 ── */
|
||||
.conflict-card { border: 1px solid var(--cinnabar-dim); border-radius: 12px; padding: 16px 18px; background: var(--cinnabar-wash); }
|
||||
.conflict-card .head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
|
||||
.conflict-card .head .seal { font-family: "Songti SC", serif; font-size: 14px; font-weight: 700; color: var(--cinnabar); }
|
||||
.conflict-card .head .risk { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--cinnabar); margin-left: auto; border: 1px solid var(--cinnabar-dim); padding: 2px 7px; border-radius: 4px; }
|
||||
.conflict-diff { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
|
||||
.conflict-col { border: 1px solid var(--rule); border-radius: 8px; padding: 12px 14px; background: var(--surface); }
|
||||
.conflict-col .lb { font-family: "JetBrains Mono", monospace; font-size: 9.5px; letter-spacing: 0.1em; color: var(--fg-faint); text-transform: uppercase; margin-bottom: 8px; }
|
||||
.conflict-col.existing .lb { color: var(--fg-dim); }
|
||||
.conflict-col.incoming .lb { color: var(--gilt); }
|
||||
.conflict-col .val { font-size: 13px; color: var(--fg); line-height: 1.5; }
|
||||
.conflict-col.incoming .val { color: var(--gilt); }
|
||||
.conflict-actions { display: flex; gap: 8px; margin-top: 14px; }
|
||||
|
||||
/* ── 导入结果 ── */
|
||||
.import-ok { border: 1px solid var(--patina-dim); border-radius: 12px; background: var(--patina-wash); padding: 16px 18px; }
|
||||
.import-ok-head { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--patina); margin-bottom: 12px; }
|
||||
.import-ok-head strong { color: var(--fg); }
|
||||
.char-created { display: flex; gap: 14px; align-items: center; padding: 12px 14px; border: 1px solid var(--rule); border-radius: 10px; background: var(--ink); }
|
||||
.char-mirror { width: 52px; height: 52px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, var(--patina-bright), var(--night-bronze) 70%); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 22px; color: #fff; flex-shrink: 0; box-shadow: inset 0 1px 2px rgba(255,255,255,0.2); }
|
||||
.char-info { flex: 1; min-width: 0; }
|
||||
.char-name { font-family: "Songti SC", serif; font-size: 16px; font-weight: 600; }
|
||||
.char-name small { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); font-weight: 400; margin-left: 8px; }
|
||||
.char-derived { font-size: 12px; color: var(--fg-dim); margin-top: 4px; display: flex; gap: 10px; flex-wrap: wrap; }
|
||||
.char-derived code { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--patina); }
|
||||
.created-list { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
|
||||
.created-item { font-size: 12px; color: var(--fg-dim); display: flex; align-items: center; gap: 8px; padding: 4px 0; }
|
||||
.created-item .dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
|
||||
.created-item .dot.ok { background: var(--patina); }
|
||||
.created-item .dot.skip { background: var(--fg-faint); }
|
||||
|
||||
/* ── 导入历史 ── */
|
||||
.history-list { display: flex; flex-direction: column; gap: 6px; }
|
||||
.history-row { display: flex; align-items: center; gap: 12px; padding: 8px 12px; border-radius: 8px; border: 1px solid var(--rule); font-size: 12px; }
|
||||
.history-row:hover { border-color: var(--patina-dim); }
|
||||
.history-row .ts { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); }
|
||||
.history-row .who { flex: 1; color: var(--fg); }
|
||||
.history-row .badge { font-family: "JetBrains Mono", monospace; font-size: 10px; padding: 2px 7px; border-radius: 4px; }
|
||||
.history-row .badge.ok { color: var(--patina); background: var(--patina-wash); border: 1px solid var(--patina-dim); }
|
||||
.history-row .badge.dup { color: var(--gilt); background: var(--gilt-faint); border: 1px solid var(--gilt-dim); }
|
||||
|
||||
/* ── 导出 ── */
|
||||
.export-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; }
|
||||
.export-row + .export-row { border-top: 1px solid var(--rule); }
|
||||
.export-body { flex: 1; }
|
||||
.export-title { font-size: 13.5px; color: var(--fg); }
|
||||
.export-desc { font-size: 12px; color: var(--fg-dim); margin-top: 2px; }
|
||||
.export-checks { display: flex; gap: 14px; margin-top: 6px; flex-wrap: wrap; }
|
||||
.export-check { display: flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--fg-dim); cursor: pointer; }
|
||||
.export-check input { accent-color: var(--patina); }
|
||||
|
||||
.note { font-size: 12.5px; color: var(--fg-dim); line-height: 1.7; }
|
||||
.note code { font-family: "JetBrains Mono", monospace; font-size: 11.5px; background: var(--surface-hi); padding: 1px 6px; border-radius: 4px; color: var(--patina); }
|
||||
.note strong { color: var(--fg); font-weight: 500; }
|
||||
.note .warn { color: var(--cinnabar); }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.conflict-diff { grid-template-columns: 1fr; }
|
||||
.field-map-row { grid-template-columns: 1fr 24px 1fr; font-size: 11px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-mount" data-active="魂册降生"></div>
|
||||
<div class="main-area">
|
||||
<main class="app-main">
|
||||
|
||||
<a class="back-link" href="characters-preview.html">← 返回人物列表</a>
|
||||
<div class="page-head">
|
||||
<div>
|
||||
<h1 class="page-title">角色卡兼容 · 魂册降生</h1>
|
||||
<p class="page-sub">导入外部角色卡建立人物,或把人物导出为标准角色卡分享。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 第一步:导入角色卡 ═══ -->
|
||||
<div class="card" id="section-import">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">⬇</span> 导入角色卡</h2>
|
||||
<span class="tag tag-patina">V1 · V2 · V3</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<!-- 步骤条 -->
|
||||
<div class="steps">
|
||||
<span class="step done"><span class="idx">1</span>拖入文件</span>
|
||||
<span class="step active"><span class="idx">2</span>预览映射</span>
|
||||
<span class="step"><span class="idx">3</span>冲突检测</span>
|
||||
<span class="step"><span class="idx">4</span>确认建立</span>
|
||||
</div>
|
||||
|
||||
<!-- 拖拽区(已有文件态) -->
|
||||
<div class="dropzone has-file">
|
||||
<div class="icon">🎴</div>
|
||||
<div class="hint"><strong>时崎狂三_v3.png</strong> · 已识别为 V3 卡</div>
|
||||
<div class="sub">142 KiB · PNG 内嵌 charx JSON</div>
|
||||
<div class="formats">
|
||||
<span class="tag tag-gilt">.png</span>
|
||||
<span class="tag tag-gilt">v3</span>
|
||||
<span class="tag tag-patina">自动识别</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 字段映射预览 -->
|
||||
<div style="margin-top:16px;">
|
||||
<div class="section-label">字段映射预览 <span class="sub">— 卡字段 → 魂镜实体</span></div>
|
||||
<div class="field-map">
|
||||
<div class="field-map-row head">
|
||||
<span style="padding:8px 14px;">角色卡字段</span>
|
||||
<span></span>
|
||||
<span style="padding:8px 14px;">魂镜实体 · 字段</span>
|
||||
</div>
|
||||
<div class="field-map-row">
|
||||
<span class="src">data.name</span>
|
||||
<span class="arr">→</span>
|
||||
<span class="dst">character.name · 「时崎狂三」</span>
|
||||
</div>
|
||||
<div class="field-map-row">
|
||||
<span class="src">data.nickname</span>
|
||||
<span class="arr">→</span>
|
||||
<span class="dst">character.display_name · 「三三」</span>
|
||||
</div>
|
||||
<div class="field-map-row">
|
||||
<span class="src">data.description</span>
|
||||
<span class="arr">→</span>
|
||||
<span class="dst">character.description · 人物描述</span>
|
||||
</div>
|
||||
<div class="field-map-row">
|
||||
<span class="src">data.personality</span>
|
||||
<span class="arr">→</span>
|
||||
<span class="dst new">道体 personality_summary · 初始快照 🆕</span>
|
||||
</div>
|
||||
<div class="field-map-row">
|
||||
<span class="src">data.first_mes</span>
|
||||
<span class="arr">→</span>
|
||||
<span class="dst new">道体 greeting · 初见问候 🆕</span>
|
||||
</div>
|
||||
<div class="field-map-row">
|
||||
<span class="src">data.system_prompt</span>
|
||||
<span class="arr">→</span>
|
||||
<span class="dst new">道体增补层 · augment(绝不覆盖 mission)🆕</span>
|
||||
</div>
|
||||
<div class="field-map-row">
|
||||
<span class="src">data.mes_example</span>
|
||||
<span class="arr">→</span>
|
||||
<span class="dst new">道体 dialogue_examples · 对话示例 🆕</span>
|
||||
</div>
|
||||
<div class="field-map-row">
|
||||
<span class="src">data.character_book</span>
|
||||
<span class="arr">→</span>
|
||||
<span class="dst new">世谱 · 1 本书 · 5 条目 🆕</span>
|
||||
</div>
|
||||
<div class="summary">共 8 个字段映射 · 5 个实体操作 · 0 处冲突</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 冲突检测区域(本示例无冲突) -->
|
||||
<div style="margin-top:16px;">
|
||||
<div class="section-label">冲突检测 <span class="sub">— 同名人物已存在时触发</span></div>
|
||||
<div style="border:1px solid var(--patina-dim);border-radius:10px;padding:14px 16px;background:var(--patina-wash);font-size:13px;color:var(--patina);display:flex;align-items:center;gap:8px;">
|
||||
<span>✓</span> 无冲突 · 「时崎狂三」尚未存在于魂册,可直接建立。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部操作 -->
|
||||
<div style="display:flex;gap:8px;margin-top:18px;justify-content:flex-end;">
|
||||
<button class="btn btn-outline">取消</button>
|
||||
<button class="btn btn-primary">确认建立人物与道体</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 冲突场景(独立卡片,仅同名时展示)═══ -->
|
||||
<div class="card" id="section-conflict" style="display:none;">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">⚠</span> 冲突处理</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="conflict-card">
|
||||
<div class="head">
|
||||
<span class="seal">重名冲突</span>
|
||||
<span class="risk">NEEDS REVIEW</span>
|
||||
</div>
|
||||
<div class="conflict-diff">
|
||||
<div class="conflict-col existing">
|
||||
<div class="lb">现存 · character_008f6c…</div>
|
||||
<div class="val">时崎狂三 · 道体 v3(大周天演化 12 轮)<br/>personality_summary 已偏离原始导入值</div>
|
||||
</div>
|
||||
<div class="conflict-col incoming">
|
||||
<div class="lb">导入 · 卡中版本</div>
|
||||
<div class="val">时崎狂三 · 卡中原版 personality<br/>世谱 5 条目(3 条与现存重复)</div>
|
||||
</div>
|
||||
</div>
|
||||
<p style="font-size:12px;color:var(--fg-dim);margin:12px 0 0;">
|
||||
<strong>推荐。</strong>新建为独立人物(<code>character_008f6c…_imported</code>),保留现存演化数据不动。世谱可选择合并(去重)或替换。
|
||||
</p>
|
||||
<div class="conflict-actions">
|
||||
<button class="btn btn-primary btn-sm">新建独立人物</button>
|
||||
<button class="btn btn-outline btn-sm">覆盖现存道体</button>
|
||||
<button class="btn btn-outline btn-sm">仅合并世谱</button>
|
||||
<button class="btn btn-ghost btn-sm">取消导入</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 导入结果(成功后展示) ═══ -->
|
||||
<div class="card" id="section-result">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">✓</span> 导入结果</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<div class="import-ok">
|
||||
<div class="import-ok-head">
|
||||
<span>✓</span> 导入成功 · <strong>时崎狂三</strong>
|
||||
</div>
|
||||
<div class="char-created">
|
||||
<div class="char-mirror">狂</div>
|
||||
<div class="char-info">
|
||||
<div class="char-name">时崎狂三 <small>ID · character_008f6c3a…</small></div>
|
||||
<div class="char-derived">
|
||||
<span>显示名 <code>三三</code></span>
|
||||
<span>道体初始人格 <code>腹黑优雅·时间支配者…</code></span>
|
||||
<span>世谱 <code>狂三世谱 · 5 条目</code></span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-sm">查看人物 →</button>
|
||||
</div>
|
||||
<div class="created-list">
|
||||
<div class="created-item"><span class="dot ok"></span> 人物记录 · character_008f6c3a…</div>
|
||||
<div class="created-item"><span class="dot ok"></span> 道体 · personality_summary + greeting + augment + dialogue_examples</div>
|
||||
<div class="created-item"><span class="dot ok"></span> 世谱 · 狂三世谱(1 书 · 5 条目)</div>
|
||||
<div class="created-item"><span class="dot skip"></span> 跳过 · character_book.entries[2] 关键词为空(无效条目)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 导入历史 ═══ -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">📋</span> 导入记录</h2>
|
||||
<span class="tag tag-gilt">近 30 日</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="history-list">
|
||||
<div class="history-row">
|
||||
<span class="ts">07-25 14:02</span>
|
||||
<span class="who">时崎狂三</span>
|
||||
<span style="font-size:11px;color:var(--fg-faint);">时崎狂三_v3.png · 142 KiB</span>
|
||||
<span class="badge ok">新建</span>
|
||||
</div>
|
||||
<div class="history-row">
|
||||
<span class="ts">07-24 09:18</span>
|
||||
<span class="who">五更琉璃 · 黑猫</span>
|
||||
<span style="font-size:11px;color:var(--fg-faint);">kuroneko_v2.json · 8 KiB</span>
|
||||
<span class="badge ok">新建</span>
|
||||
</div>
|
||||
<div class="history-row">
|
||||
<span class="ts">07-22 22:41</span>
|
||||
<span class="who">桐谷和人</span>
|
||||
<span style="font-size:11px;color:var(--fg-faint);">kirito_charx.png · 88 KiB</span>
|
||||
<span class="badge dup">重名 · 已建独立人物</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 导出 ═══ -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">⬆</span> 导出角色卡</h2>
|
||||
<span class="tag tag-gilt">静态快照</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<div class="export-row">
|
||||
<div class="char-mirror" style="width:42px;height:42px;font-size:18px;">狂</div>
|
||||
<div class="export-body">
|
||||
<div class="export-title">时崎狂三 · V3 角色卡</div>
|
||||
<div class="export-desc"><code>.json</code> · name / personality(取道体当前快照)/ character_book(世谱)</div>
|
||||
<div class="export-checks">
|
||||
<label class="export-check"><input type="checkbox" checked /> 包含世谱</label>
|
||||
<label class="export-check"><input type="checkbox" /> 包含对话示例</label>
|
||||
<label class="export-check"><input type="checkbox" /> 包含初见问候</label>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-outline btn-sm">⬇ 下载 .json</button>
|
||||
</div>
|
||||
|
||||
<div class="note" style="margin-top:8px;">
|
||||
<strong>静态快照。</strong>导出的是当前设定快照——<span class="warn">演化维度(人格版本 / 记忆 / 情绪)不会导出</span>,因标准角色卡格式无对应字段。导出仅用于分享「角色设定」给通用角色卡生态。
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,365 @@
|
||||
<!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 — 人物详情页
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 通用布局 ── */
|
||||
|
||||
.app-main { flex: 1; padding: 24px 28px 56px; max-width: 920px; width: 100%; margin: 0 auto; }
|
||||
@media (max-width: 900px) { .sidebar-wrap { display: none; } }
|
||||
|
||||
/* ── 操作栏 ── */
|
||||
.action-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 14px 0 18px; }
|
||||
.badge { display: inline-flex; align-items: center; gap: 5px; padding: 4px 12px; border-radius: 999px; font-family: "JetBrains Mono", monospace; font-size: 11px; border: 1px solid var(--rule); background: var(--surface); color: var(--fg-dim); }
|
||||
.badge.active { border-color: var(--patina-dim); color: var(--patina); background: var(--patina-wash); }
|
||||
.badge.paused { border-color: var(--gilt-dim); color: var(--gilt); background: var(--gilt-faint); }
|
||||
.badge.wuji { border-color: var(--rule); color: var(--fg-faint); }
|
||||
|
||||
/* ── 生命周期条 ── */
|
||||
.lifecycle-bar { display: flex; align-items: center; gap: 3px; font-family: "JetBrains Mono", monospace; font-size: 10.5px; }
|
||||
.lifecycle-step { display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border-radius: 999px; color: var(--fg-faint); border: 1px solid transparent; }
|
||||
.lifecycle-step.past { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.lifecycle-step.current { color: var(--gilt); border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.lifecycle-arrow { color: var(--fg-faint); font-size: 12px; opacity: 0.5; }
|
||||
|
||||
.action-link { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; padding: 6px 14px; border-radius: 10px; font-size: 12px; color: var(--patina); border: 1px solid var(--patina-dim); background: var(--patina-wash); text-decoration: none; transition: background 0.12s; cursor: pointer; }
|
||||
.action-link:hover { background: var(--patina-dim); color: var(--fg); }
|
||||
|
||||
/* ── 卡片 ── */
|
||||
|
||||
.card-banner { height: 72px; background: linear-gradient(135deg, var(--patina-wash), var(--glass), var(--gilt-faint)); }
|
||||
|
||||
/* ── 铜镜头像 ── */
|
||||
.avatar-section { position: relative; width: 88px; height: 88px; margin-top: -48px; margin-bottom: 12px; }
|
||||
.avatar-img { width: 88px; height: 88px; border-radius: 50%; border: 3px solid var(--gilt); box-shadow: 0 0 0 3px var(--surface), 0 0 16px rgba(201,162,74,0.25); overflow: hidden; display: flex; align-items: center; justify-content: center; background: conic-gradient(from 0deg, var(--ink), var(--night-bronze), var(--patina-dim), var(--gilt-dim), var(--ink)); position: relative; cursor: pointer; transition: filter 0.2s; }
|
||||
.avatar-img:hover { filter: brightness(1.15); }
|
||||
.avatar-img .placeholder { font-size: 28px; opacity: 0.6; }
|
||||
.avatar-img img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
|
||||
.avatar-overlay { position: absolute; inset: 0; border-radius: 50%; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.2s; }
|
||||
.avatar-section:hover .avatar-overlay { opacity: 1; }
|
||||
.avatar-overlay .upload-label { display: flex; align-items: center; gap: 3px; color: #fff; font-size: 10px; cursor: pointer; }
|
||||
.avatar-overlay .upload-icon { font-size: 20px; }
|
||||
.avatar-name-badge { flex: 1; }
|
||||
|
||||
.identity-header { display: flex; align-items: flex-end; justify-content: space-between; }
|
||||
.char-name { font-family: "Songti SC", serif; font-size: 20px; font-weight: 700; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.char-inner-name { font-size: 12px; color: var(--fg-dim); margin-top: 1px; }
|
||||
|
||||
/* ── 档案信息网格 ── */
|
||||
.info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 20px; margin-top: 14px; }
|
||||
.info-item .label { font-size: 12px; color: var(--muted); }
|
||||
.info-item .value { font-size: 14px; font-weight: 500; color: var(--fg); }
|
||||
.quote { font-style: italic; color: var(--fg-dim); font-size: 14px; margin-top: 12px; padding-left: 10px; border-left: 2px solid var(--gilt-dim); }
|
||||
.bio-section { margin-top: 14px; border-top: 1px solid var(--rule); padding-top: 14px; }
|
||||
.bio-section .label { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
|
||||
.bio-section .text { font-size: 14px; line-height: 1.7; color: var(--fg); white-space: pre-wrap; }
|
||||
|
||||
/* ── 双列布局 ── */
|
||||
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
|
||||
|
||||
/* ── 表单 ── */
|
||||
.form-card .card-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 20px 0; }
|
||||
.form-card .card-title { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); display: flex; align-items: center; gap: 6px; }
|
||||
.form-card .card-title .glyph { color: var(--cinnabar); opacity: 0.7; }
|
||||
.form-body { padding: 14px 20px 20px; }
|
||||
.field { margin-bottom: 12px; }
|
||||
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
|
||||
.field-label { display: block; font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.04em; color: var(--muted); margin-bottom: 4px; }
|
||||
.field input, .field textarea, .field select { width: 100%; padding: 8px 12px; border: 1px solid var(--rule); border-radius: 10px; background: var(--glass); color: var(--fg); font-family: inherit; font-size: 13px; transition: border-color 0.15s; }
|
||||
.field input:focus, .field textarea:focus, .field select:focus { outline: none; border-color: var(--patina-dim); }
|
||||
.field textarea { min-height: 64px; resize: vertical; }
|
||||
.field-hint { font-size: 11px; color: var(--fg-faint); margin-top: 3px; }
|
||||
.btn-save { display: inline-flex; align-items: center; gap: 5px; padding: 6px 16px; border-radius: 10px; font-size: 12px; font-weight: 500; border: 1px solid var(--patina-dim); background: var(--patina-wash); color: var(--patina); cursor: pointer; transition: background 0.12s; font-family: inherit; }
|
||||
.btn-save:hover { background: var(--patina-dim); color: var(--fg); }
|
||||
.btn-save:disabled { opacity: 0.4; cursor: default; }
|
||||
|
||||
/* ── Tag 输入模拟 ── */
|
||||
.tag-input-mock { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 10px; border: 1px solid var(--rule); border-radius: 10px; background: var(--glass); min-height: 34px; align-items: center; }
|
||||
|
||||
/* ── Modal ── */
|
||||
.modal-overlay { position: fixed; inset: 0; z-index: 100; background: rgba(0,0,0,0.55); backdrop-filter: blur(6px); display: flex; align-items: center; justify-content: center; padding: 20px; }
|
||||
.modal { background: var(--ink); border: 1px solid var(--rule); border-radius: 18px; width: 100%; max-width: 420px; box-shadow: 0 12px 60px rgba(0,0,0,0.6); }
|
||||
.modal-header { display: flex; align-items: center; gap: 12px; padding: 18px 22px 10px; border-bottom: 1px solid var(--rule); }
|
||||
.modal-title { font-family: "Songti SC", serif; font-size: 16px; font-weight: 600; color: var(--fg); flex: 1; }
|
||||
.modal-close { width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; border-radius: 8px; cursor: pointer; border: none; background: none; color: var(--fg-faint); font-size: 18px; transition: background 0.12s; }
|
||||
.modal-close:hover { background: var(--surface-hi); color: var(--fg); }
|
||||
.modal-body { padding: 18px 22px 22px; }
|
||||
|
||||
|
||||
/* ── Toast ── */
|
||||
.toast { position: fixed; bottom: 24px; right: 24px; z-index: 200; display: flex; align-items: center; gap: 8px; padding: 10px 16px; border-radius: 12px; border: 1px solid var(--patina-dim); background: var(--surface); backdrop-filter: blur(12px); font-size: 13px; color: var(--patina); box-shadow: 0 4px 24px rgba(0,0,0,0.5); }
|
||||
|
||||
/* ── Responsive ── */
|
||||
@media (max-width: 768px) {
|
||||
.app-main { padding: 16px 14px 40px; }
|
||||
.two-col { grid-template-columns: 1fr; }
|
||||
.info-grid { grid-template-columns: 1fr; }
|
||||
.field-row { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-mount" data-active="人物"></div>
|
||||
<div class="main-area">
|
||||
<main class="app-main">
|
||||
|
||||
<!-- ═══ 面包屑 ═══ -->
|
||||
<a class="back-link" href="characters-preview.html">← 返回人物列表</a>
|
||||
|
||||
<!-- ═══ 页头 ═══ -->
|
||||
<h1 class="page-title">时崎狂三</h1>
|
||||
<p class="page-sub">内部名称:tokisaki_kurumi · 创建于 2026-07-09 14:32:18</p>
|
||||
|
||||
<!-- ═══ 操作栏 ═══ -->
|
||||
<div class="action-bar">
|
||||
<span class="badge active">● active</span>
|
||||
|
||||
<span class="lifecycle-bar">
|
||||
<span class="lifecycle-step past">无极</span><span class="lifecycle-arrow">→</span>
|
||||
<span class="lifecycle-step past">立名</span><span class="lifecycle-arrow">→</span>
|
||||
<span class="lifecycle-step past">设定</span><span class="lifecycle-arrow">→</span>
|
||||
<span class="lifecycle-step past">初识</span><span class="lifecycle-arrow">→</span>
|
||||
<span class="lifecycle-step current">太极</span><span class="lifecycle-arrow">→</span>
|
||||
<span class="lifecycle-step">归档</span>
|
||||
</span>
|
||||
|
||||
<a class="action-link" href="#">资料与沉淀 →</a>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 角色身份卡 ═══ -->
|
||||
<div class="card">
|
||||
<div class="card-banner"></div>
|
||||
<div class="card-body">
|
||||
<!-- 头像:预留图片 -->
|
||||
<div class="avatar-section" onclick="document.getElementById('modal-upload').style.display='flex'">
|
||||
<div class="avatar-img">
|
||||
<span class="placeholder">☯</span>
|
||||
</div>
|
||||
<div class="avatar-overlay">
|
||||
<span class="upload-label">
|
||||
<span class="upload-icon">📷</span>
|
||||
更换头像
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="identity-header">
|
||||
<div>
|
||||
<div class="char-name">时崎狂三</div>
|
||||
<div class="char-inner-name">内部名称:tokisaki_kurumi</div>
|
||||
</div>
|
||||
<span class="badge active">● active</span>
|
||||
</div>
|
||||
|
||||
<div class="info-grid">
|
||||
<div class="info-item"><div class="label">生日</div><div class="value">2000-12-25</div></div>
|
||||
<div class="info-item"><div class="label">身高</div><div class="value">157 cm</div></div>
|
||||
<div class="info-item"><div class="label">体重</div><div class="value">43 kg</div></div>
|
||||
<div class="info-item"><div class="label">当前心情</div><div class="value">平静(42%)</div></div>
|
||||
<div class="info-item"><div class="label">语言</div><div class="value">zh-CN</div></div>
|
||||
<div class="info-item"><div class="label">创建时间</div><div class="value">2026-07-09 14:32</div></div>
|
||||
</div>
|
||||
|
||||
<div class="quote">「优雅从容的大小姐口气,语速中等偏慢…」</div>
|
||||
|
||||
<div class="bio-section">
|
||||
<div class="label">背景</div>
|
||||
<div class="text">
|
||||
拥有时间之力的精灵「Nightmare(梦魇)」。
|
||||
为了某个终极目标在时间洪流中独自前行,通过吞噬他人的时间维持自己的存在。
|
||||
她的过去充满了失去与痛苦,但她从不后悔自己选择的道路。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bio-section">
|
||||
<div class="label">兴趣爱好</div>
|
||||
<div class="tag-input-mock" style="margin-top:4px;">
|
||||
<span class="tag">与猫相处</span>
|
||||
<span class="tag">阅读</span>
|
||||
<span class="tag">钢琴</span>
|
||||
<span class="tag">收藏古董时钟</span>
|
||||
<span class="tag">摄影</span>
|
||||
<span class="tag">品尝红茶与甜点</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bio-section">
|
||||
<div class="label">价值观</div>
|
||||
<div class="tag-input-mock" style="margin-top:4px;">
|
||||
<span class="tag">自由</span>
|
||||
<span class="tag">尊严</span>
|
||||
<span class="tag">独立</span>
|
||||
<span class="tag">记忆</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 双列:档案编辑 + 模型策略 ═══ -->
|
||||
<div class="two-col">
|
||||
|
||||
<!-- 左:人物档案编辑 -->
|
||||
<div class="card form-card">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">📋</span> 人物档案</h2>
|
||||
<button class="btn-save">✎ 保存</button>
|
||||
</div>
|
||||
<div class="form-body">
|
||||
<div class="field">
|
||||
<label class="field-label">显示名</label>
|
||||
<input type="text" value="时崎狂三" />
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label class="field-label">生日</label>
|
||||
<input type="date" value="2000-12-25" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">身高</label>
|
||||
<input type="text" value="157" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-row">
|
||||
<div class="field">
|
||||
<label class="field-label">体重</label>
|
||||
<input type="text" value="43" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">性情气质</label>
|
||||
<input type="text" value="优雅腹黑、孤独偏执" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">表达风格</label>
|
||||
<input type="text" value="优雅从容的大小姐口气,语速中等偏慢" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">背景</label>
|
||||
<textarea>拥有时间之力的精灵「Nightmare(梦魇)」。</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右:模型策略编辑 -->
|
||||
<div class="card form-card">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">⚙</span> 模型策略</h2>
|
||||
<button class="btn-save">✎ 保存</button>
|
||||
</div>
|
||||
<div class="form-body">
|
||||
<div class="field">
|
||||
<label class="field-label">对话模型</label>
|
||||
<select>
|
||||
<option>— 不设置(使用系统默认)</option>
|
||||
<option selected>deepseek-v4-flash</option>
|
||||
<option>deepseek-v3</option>
|
||||
<option>gpt-4o</option>
|
||||
</select>
|
||||
<span class="field-hint">留空则使用 DEFAULT_MODEL_HINT</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">记忆提取模型</label>
|
||||
<select>
|
||||
<option>— 不设置(空)</option>
|
||||
<option selected>memory-extraction</option>
|
||||
<option>deepseek-v4-flash</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">人格分析模型</label>
|
||||
<select>
|
||||
<option>— 不设置(空)</option>
|
||||
<option selected>personality-analysis</option>
|
||||
<option>deepseek-v4-flash</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">向量嵌入模型</label>
|
||||
<select>
|
||||
<option>— 不设置(空)</option>
|
||||
<option selected>embedding</option>
|
||||
<option>text-embedding-3-small</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">私隐等级</label>
|
||||
<select>
|
||||
<option selected>normal</option>
|
||||
<option>sensitive</option>
|
||||
<option>local_only</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 上传头像 Modal ═══ -->
|
||||
<div class="modal-overlay" id="modal-upload" style="display:none;" onclick="if(event.target===this)this.style.display='none'">
|
||||
<div class="modal">
|
||||
<div class="modal-header">
|
||||
<h3 class="modal-title">📷 上传头像</h3>
|
||||
<button class="modal-close" onclick="document.getElementById('modal-upload').style.display='none'">✕</button>
|
||||
</div>
|
||||
<div class="modal-body" style="text-align:center;">
|
||||
<!-- 预览区 -->
|
||||
<div style="width:120px;height:120px;border-radius:50%;border:3px dashed var(--rule);margin:0 auto 16px;display:flex;align-items:center;justify-content:center;background:var(--glass);overflow:hidden;" id="preview-area">
|
||||
<span style="font-size:36px;opacity:0.25;color:var(--fg-faint);">+</span>
|
||||
</div>
|
||||
<!-- 上传按钮 -->
|
||||
<label class="btn btn-primary" style="display:inline-flex;cursor:pointer;">
|
||||
📁 选择图片
|
||||
<input type="file" accept="image/*" style="display:none;" onchange="previewFile(this)" />
|
||||
</label>
|
||||
<p style="font-size:11px;color:var(--fg-faint);margin-top:10px;">支持 JPG / PNG / WebP,建议 512×512 以上,最大 5MB</p>
|
||||
<div style="display:flex;gap:8px;justify-content:center;margin-top:16px;">
|
||||
<button class="btn btn-outline" onclick="document.getElementById('modal-upload').style.display='none'">取消</button>
|
||||
<button class="btn btn-primary" onclick="showToast('✔ 头像已更新');document.getElementById('modal-upload').style.display='none'">✚ 上传</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="toast" id="toast" style="display:none;">✔ 已保存</div>
|
||||
|
||||
<script>
|
||||
function previewFile(input) {
|
||||
const file = input.files && input.files[0];
|
||||
if (!file) return;
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
const area = document.getElementById('preview-area');
|
||||
area.innerHTML = '<img src="' + e.target.result + '" style="width:100%;height:100%;object-fit:cover;" />';
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
function showToast(msg) {
|
||||
const t = document.getElementById('toast');
|
||||
t.textContent = msg;
|
||||
t.style.display = 'flex';
|
||||
setTimeout(function() { t.style.display = 'none'; }, 2500);
|
||||
}
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') document.querySelectorAll('.modal-overlay').forEach(function(m) { m.style.display = 'none'; });
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,240 @@
|
||||
<!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 — 人物资料与沉淀页
|
||||
* ============================================================ */
|
||||
|
||||
.app-main { flex: 1; padding: 24px 28px 56px; max-width: 880px; width: 100%; margin: 0 auto; }
|
||||
|
||||
/* ── 卡片 ── */
|
||||
|
||||
.card-title .glyph { color: var(--cinnabar); opacity: 0.7; }
|
||||
|
||||
/* ── 导入向导 ── */
|
||||
.import-form { display: flex; gap: 12px; }
|
||||
.import-row { display: grid; grid-template-columns: 2fr 3fr; gap: 12px; }
|
||||
.field-label { display: block; font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.04em; color: var(--muted); margin-bottom: 4px; }
|
||||
.field input, .field textarea, .field select { width: 100%; padding: 8px 12px; border: 1px solid var(--rule); border-radius: 10px; background: var(--glass); color: var(--fg); font-family: inherit; font-size: 13px; transition: border-color 0.15s; }
|
||||
.field input:focus, .field textarea:focus, .field select:focus { outline: none; border-color: var(--patina-dim); }
|
||||
.field textarea { min-height: 90px; resize: vertical; }
|
||||
|
||||
.btn-success { background: var(--patina-wash); color: var(--patina); border-color: var(--patina-dim); }
|
||||
.btn-success:hover { background: var(--patina-dim); color: var(--fg); }
|
||||
.btn-danger { background: var(--cinnabar-wash); color: var(--cinnabar); border-color: var(--cinnabar-dim); }
|
||||
.btn-danger:hover { background: var(--cinnabar-dim); color: var(--fg); }
|
||||
|
||||
|
||||
/* ── 导入结果 ── */
|
||||
.import-result { border: 1px solid var(--patina-dim); border-radius: 12px; background: var(--patina-wash); padding: 14px 18px; display: flex; align-items: center; gap: 12px; margin-top: 8px; }
|
||||
.import-result .icon { font-size: 20px; }
|
||||
.import-result .text { font-size: 13px; color: var(--patina); }
|
||||
.import-result .text strong { color: var(--fg); }
|
||||
|
||||
/* ── 候选列表 ── */
|
||||
|
||||
.section-label .count { font-size: 11px; color: var(--fg-dim); font-weight: 400; }
|
||||
.candidate-item { display: flex; align-items: flex-start; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--rule); }
|
||||
.candidate-item:last-child { border-bottom: none; }
|
||||
.candidate-icon { width: 32px; height: 32px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 14px; flex-shrink: 0; }
|
||||
.candidate-icon.memory { background: var(--patina-wash); color: var(--patina); }
|
||||
.candidate-icon.world { background: var(--gilt-faint); color: var(--gilt); }
|
||||
.candidate-body { flex: 1; min-width: 0; }
|
||||
.candidate-title { font-size: 14px; font-weight: 500; color: var(--fg); }
|
||||
.candidate-desc { font-size: 12px; color: var(--fg-dim); margin-top: 2px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
||||
.candidate-meta { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); margin-top: 4px; }
|
||||
.candidate-actions { display: flex; gap: 6px; flex-shrink: 0; align-items: center; }
|
||||
|
||||
.empty-state { text-align: center; padding: 40px 20px; color: var(--fg-faint); font-size: 13px; }
|
||||
|
||||
/* ── Tag ── */
|
||||
|
||||
.tag-memory { border-color: var(--patina-dim); color: var(--patina); background: var(--patina-wash); }
|
||||
.tag-world { border-color: var(--gilt-dim); color: var(--gilt); background: var(--gilt-faint); }
|
||||
.tag-pending { border-color: var(--gilt-dim); color: var(--gilt); background: var(--gilt-faint); }
|
||||
.tag-approved { border-color: var(--patina-dim); color: var(--patina); background: var(--patina-wash); }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.app-main { padding: 16px 14px 40px; }
|
||||
.import-row { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-mount" data-active="人物"></div>
|
||||
<div class="main-area">
|
||||
<main class="app-main">
|
||||
|
||||
<!-- ═══ 面包屑 ═══ -->
|
||||
<a class="back-link" href="character-detail-preview.html">← 返回人物详情</a>
|
||||
|
||||
<!-- ═══ 页头 ═══ -->
|
||||
<h1 class="page-title">资料与沉淀</h1>
|
||||
<p class="page-sub">为「时崎狂三」导入资料、审核候选沉淀。</p>
|
||||
|
||||
<!-- ═══ 导入向导 ═══ -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">📥</span> 资料导入</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="import-form">
|
||||
<div class="import-row">
|
||||
<div class="field">
|
||||
<label class="field-label">资料类型</label>
|
||||
<select>
|
||||
<option>background_story</option>
|
||||
<option>character_profile</option>
|
||||
<option>chat_history</option>
|
||||
<option selected>role_card</option>
|
||||
<option>world_setting</option>
|
||||
<option>style_sample</option>
|
||||
<option>diary</option>
|
||||
<option>other</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">标题(可选)</label>
|
||||
<input type="text" placeholder="为这段资料起个标题…" value="时崎狂三 角色卡 v2" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">内容 *</label>
|
||||
<textarea placeholder="粘贴人物设定、背景故事、对话记录…">姓名:时崎狂三
|
||||
身份:精灵(Nightmare·梦魇)
|
||||
能力:刻刻帝(Zafkiel)—— 以自身时间为代价操控时间
|
||||
性格:优雅腹黑,内心孤独偏执,温柔而危险
|
||||
喜好:黑猫、红茶、古董时钟、肖邦的钢琴曲</textarea>
|
||||
</div>
|
||||
|
||||
<div class="import-result">
|
||||
<span class="icon">📄</span>
|
||||
<span class="text">已解析 <strong>12</strong> 个条目,<strong>3</strong> 个档案候选待审核。</span>
|
||||
<div style="flex:1;"></div>
|
||||
<button class="btn btn-primary btn-sm">✦ 触发候选抽取</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 待审候选 ═══ -->
|
||||
<div>
|
||||
<div class="section-label">
|
||||
📋 待审候选
|
||||
<span class="count">(共 5 条待审核)</span>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header" style="padding-bottom:4px;">
|
||||
<h2 class="card-title"><span class="glyph">🧠</span> 记忆候选</h2>
|
||||
<span class="tag tag-memory">3 条待审</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<!-- 候选 1 -->
|
||||
<div class="candidate-item">
|
||||
<div class="candidate-icon memory">🧠</div>
|
||||
<div class="candidate-body">
|
||||
<div class="candidate-title">狂三在教堂中与折纸对峙</div>
|
||||
<div class="candidate-desc">在第 5 话中,狂三在废弃教堂与鸢一折纸展开战斗。她展现出从容不迫的战斗姿态,即使被压制依然保持优雅的微笑。</div>
|
||||
<div class="candidate-meta">来源:cycle · 置信度 82% · 2026-07-12 18:24</div>
|
||||
</div>
|
||||
<div class="candidate-actions">
|
||||
<button class="btn btn-success btn-sm">✓ 采纳</button>
|
||||
<button class="btn btn-danger btn-sm">✕ 拒绝</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 候选 2 -->
|
||||
<div class="candidate-item">
|
||||
<div class="candidate-icon memory">🧠</div>
|
||||
<div class="candidate-body">
|
||||
<div class="candidate-title">狂三对红茶的偏好</div>
|
||||
<div class="candidate-desc">狂三在精灵公寓中冲泡大吉岭红茶,提到喜欢第二泡的醇厚口感,加一颗方糖。对速溶咖啡表示「那是凡人的妥协」。</div>
|
||||
<div class="candidate-meta">来源:import · 置信度 95% · 2026-07-13 09:12</div>
|
||||
</div>
|
||||
<div class="candidate-actions">
|
||||
<button class="btn btn-success btn-sm">✓ 采纳</button>
|
||||
<button class="btn btn-danger btn-sm">✕ 拒绝</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 候选 3 -->
|
||||
<div class="candidate-item">
|
||||
<div class="candidate-icon memory">🧠</div>
|
||||
<div class="candidate-body">
|
||||
<div class="candidate-title">狂三与十香的初次相遇</div>
|
||||
<div class="candidate-desc">在天宫塔顶,狂三首次与夜刀神十香相遇。她以优雅的姿态自我介绍,语气中带着玩味与好奇。</div>
|
||||
<div class="candidate-meta">来源:cycle · 置信度 76% · 2026-07-11 22:05</div>
|
||||
</div>
|
||||
<div class="candidate-actions">
|
||||
<button class="btn btn-success btn-sm">✓ 采纳</button>
|
||||
<button class="btn btn-danger btn-sm">✕ 拒绝</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header" style="padding-bottom:4px;">
|
||||
<h2 class="card-title"><span class="glyph">🌍</span> 世界实体候选</h2>
|
||||
<span class="tag tag-world">2 条待审</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
||||
<!-- 世界实体 1 -->
|
||||
<div class="candidate-item">
|
||||
<div class="candidate-icon world">🌍</div>
|
||||
<div class="candidate-body">
|
||||
<div class="candidate-title">刻刻帝(Zafkiel)</div>
|
||||
<div class="candidate-desc">狂三的天使,外观为巨大古钟,时钟指针化为长短双枪。拥有十二种时间能力,每种消耗不同的"时间"代价。</div>
|
||||
<div class="candidate-meta">类别:artifact · 来源:import · 置信度 88%</div>
|
||||
</div>
|
||||
<div class="candidate-actions">
|
||||
<button class="btn btn-success btn-sm">✓ 采纳</button>
|
||||
<button class="btn btn-danger btn-sm">✕ 拒绝</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 世界实体 2 -->
|
||||
<div class="candidate-item">
|
||||
<div class="candidate-icon world">🌍</div>
|
||||
<div class="candidate-body">
|
||||
<div class="candidate-title">天宫塔</div>
|
||||
<div class="candidate-desc">天宫市标志性建筑,位于市中心。曾是狂三与精灵们多次交战与相遇的场所。顶层观景台可俯瞰整个天宫市。</div>
|
||||
<div class="candidate-meta">类别:location · 来源:cycle · 置信度 71%</div>
|
||||
</div>
|
||||
<div class="candidate-actions">
|
||||
<button class="btn btn-success btn-sm">✓ 采纳</button>
|
||||
<button class="btn btn-danger btn-sm">✕ 拒绝</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态示例(所有候选已审完时展示) -->
|
||||
<!--
|
||||
<div class="card">
|
||||
<div class="empty-state">暂无待审候选 · 所有记忆与世界实体已审核确认</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,408 @@
|
||||
<!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 — 人物页:铜镜名册(激活者镜面,余者镜背)
|
||||
* ============================================================ */
|
||||
|
||||
body {
|
||||
background: var(--ink);
|
||||
color: var(--fg);
|
||||
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Helvetica Neue", system-ui, sans-serif;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
/* ── 侧栏(与轨迹页同源,此处 active=人物)── */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.page-header .spacer { flex: 1; }
|
||||
.page-meta { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg-faint); }
|
||||
.page-meta b { color: var(--gilt); font-weight: 600; font-family: "Songti SC", serif; font-size: 15px; }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
|
||||
/* ═══ 激活魂册(镜面材质 hero)═══ */
|
||||
.soul-card {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--gilt-dim);
|
||||
border-radius: 8px;
|
||||
padding: 28px 30px;
|
||||
background: var(--face-sheen), var(--surface);
|
||||
box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow);
|
||||
}
|
||||
/* 镜面静态光泽 */
|
||||
.soul-card::before {
|
||||
content: "";
|
||||
position: absolute; inset: 0; z-index: 0; pointer-events: none;
|
||||
background: linear-gradient(130deg, transparent 0%, transparent 28%, rgba(201, 162, 74, 0.025) 34%, rgba(255, 255, 255, 0.06) 40%, rgba(201, 162, 74, 0.025) 48%, transparent 55%, transparent 100%);
|
||||
background-size: 200% 200%;
|
||||
background-position: 35% 35%;
|
||||
opacity: 0.42;
|
||||
}
|
||||
/* 铜面颗粒 */
|
||||
.soul-card::after {
|
||||
content: "";
|
||||
position: absolute; inset: 0; z-index: 0; pointer-events: none;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
|
||||
opacity: 0.018; mix-blend-mode: overlay;
|
||||
}
|
||||
.soul-card > * { position: relative; z-index: 1; }
|
||||
|
||||
.soul-top { display: flex; gap: 24px; align-items: center; flex-wrap: wrap; }
|
||||
.soul-mirror {
|
||||
width: 96px; height: 96px; border-radius: 50%; flex-shrink: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
border: 1.5px solid var(--patina-dim);
|
||||
background: var(--patina-wash);
|
||||
position: relative;
|
||||
}
|
||||
.soul-mirror .inner {
|
||||
width: 70px; height: 70px; border-radius: 50%;
|
||||
background: linear-gradient(160deg, var(--patina-bright), var(--patina));
|
||||
color: var(--ink);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-family: "Songti SC", serif; font-size: 34px; font-weight: 700;
|
||||
}
|
||||
.soul-mirror .halo {
|
||||
position: absolute; inset: -6px; border-radius: 50%;
|
||||
border: 1px dashed var(--gilt-dim);
|
||||
opacity: 0.5;
|
||||
}
|
||||
.soul-id { flex: 1; min-width: 200px; }
|
||||
.soul-name { font-family: "Songti SC", serif; font-size: 30px; font-weight: 700; color: var(--fg); letter-spacing: 0.06em; line-height: 1.2; }
|
||||
.soul-realname { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg-faint); margin-top: 4px; letter-spacing: 0.04em; }
|
||||
.soul-mood { display: flex; align-items: center; gap: 7px; margin-top: 10px; font-size: 13px; color: var(--fg-dim); }
|
||||
.pulse-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--patina); flex-shrink: 0; animation: pulse 2.6s cubic-bezier(0.16, 1, 0.3, 1) infinite; }
|
||||
@keyframes pulse {
|
||||
0% { box-shadow: 0 0 0 0 rgba(111, 163, 137, 0.5); }
|
||||
70% { box-shadow: 0 0 0 6px transparent; }
|
||||
100% { box-shadow: 0 0 0 0 transparent; }
|
||||
}
|
||||
.soul-tag {
|
||||
font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.08em;
|
||||
padding: 3px 10px; border-radius: 999px; border: 1px solid var(--patina-dim);
|
||||
background: var(--patina-wash); color: var(--patina); white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 七阶生命周期站点 */
|
||||
.lifecycle {
|
||||
margin-top: 22px;
|
||||
padding-top: 18px;
|
||||
border-top: 1px solid var(--rule);
|
||||
}
|
||||
.lifecycle-label { font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-faint); margin-bottom: 12px; }
|
||||
.lifecycle-track { display: flex; align-items: center; gap: 0; }
|
||||
.lc-station { display: flex; flex-direction: column; align-items: center; gap: 6px; flex: 1; min-width: 0; }
|
||||
.lc-dot { width: 11px; height: 11px; border-radius: 50%; border: 1.5px solid var(--fg-faint); background: transparent; }
|
||||
.lc-name { font-family: "Songti SC", serif; font-size: 11.5px; color: var(--fg-faint); white-space: nowrap; }
|
||||
.lc-station.reached .lc-dot { border-color: var(--patina-dim); background: var(--patina-dim); }
|
||||
.lc-station.reached .lc-name { color: var(--fg-dim); }
|
||||
.lc-station.current .lc-dot { border-color: var(--gilt); background: var(--gilt); box-shadow: 0 0 0 4px var(--gilt-faint); animation: node-pulse 2.6s cubic-bezier(0.16,1,0.3,1) infinite; }
|
||||
.lc-station.current .lc-name { color: var(--gilt); font-weight: 600; }
|
||||
@keyframes node-pulse {
|
||||
0% { box-shadow: 0 0 0 4px var(--gilt-faint); }
|
||||
70% { box-shadow: 0 0 0 8px transparent; }
|
||||
100% { box-shadow: 0 0 0 4px var(--gilt-faint); }
|
||||
}
|
||||
.lc-link { flex: 0 0 0; height: 1.5px; align-self: flex-start; margin-top: 4.75px; background: var(--rule); width: 14px; }
|
||||
.lc-link.reached { background: var(--patina-dim); }
|
||||
|
||||
/* 档案字段网格 + 关键指标 */
|
||||
.soul-grid { margin-top: 22px; display: grid; grid-template-columns: 1fr 240px; gap: 26px; }
|
||||
.soul-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 28px; }
|
||||
.field dt { font-family: "JetBrains Mono", monospace; font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--fg-faint); }
|
||||
.field dd { margin: 3px 0 0; font-size: 13.5px; color: var(--fg); }
|
||||
.field dd.mono { font-family: "JetBrains Mono", monospace; font-size: 12.5px; }
|
||||
.soul-bg { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--rule); grid-column: 1 / -1; }
|
||||
.soul-bg .lab { font-family: "JetBrains Mono", monospace; font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--fg-faint); margin-bottom: 6px; }
|
||||
.soul-bg p { font-family: "Songti SC", serif; font-size: 14px; line-height: 1.8; color: var(--fg-dim); margin: 0; }
|
||||
|
||||
.soul-stats { display: flex; flex-direction: column; gap: 10px; }
|
||||
.soul-stat { background: var(--ink); border: 1px solid var(--rule); border-radius: 6px; padding: 12px 14px; }
|
||||
.soul-stat .k { font-family: "JetBrains Mono", monospace; font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--fg-faint); }
|
||||
.soul-stat .v { font-family: "Songti SC", serif; font-size: 22px; font-weight: 600; color: var(--gilt); margin-top: 2px; }
|
||||
.soul-stat .v small { font-size: 12px; font-weight: 400; color: var(--fg-dim); font-family: "JetBrains Mono", monospace; margin-left: 3px; }
|
||||
|
||||
/* ═══ 名册(镜背卡)═══ */
|
||||
.roster-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
|
||||
.char-card {
|
||||
position: relative;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--night-bronze) 70%, transparent), var(--night-bronze));
|
||||
border: 1px solid var(--rule);
|
||||
border-radius: 8px;
|
||||
padding: 18px 18px 16px;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.15s, transform 0.15s;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.char-card:hover { border-color: var(--gilt-dim); transform: translateY(-2px); }
|
||||
/* 激活卡 = 镜面(与 hero 同源材质,但更克制) */
|
||||
.char-card.is-face {
|
||||
border-color: var(--gilt-dim);
|
||||
background: var(--face-sheen), var(--surface);
|
||||
box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot);
|
||||
}
|
||||
.char-card.is-paused { opacity: 0.72; }
|
||||
|
||||
.cc-top { display: flex; align-items: center; gap: 12px; }
|
||||
.cc-disc {
|
||||
width: 44px; height: 44px; border-radius: 50%; flex-shrink: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
border: 1.5px solid var(--patina-dim);
|
||||
background: var(--patina-wash);
|
||||
}
|
||||
.cc-disc .inner {
|
||||
width: 32px; height: 32px; border-radius: 50%;
|
||||
background: var(--patina-wash);
|
||||
color: var(--patina);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-family: "Songti SC", serif; font-size: 16px; font-weight: 700;
|
||||
}
|
||||
.char-card.is-face .cc-disc { border-color: var(--gilt); }
|
||||
.char-card.is-face .cc-disc .inner { background: linear-gradient(160deg, var(--patina-bright), var(--patina)); color: var(--ink); }
|
||||
.char-card.is-paused .cc-disc .inner { background: transparent; color: var(--fg-faint); }
|
||||
|
||||
.cc-name { font-family: "Songti SC", serif; font-size: 17px; font-weight: 600; color: var(--fg); letter-spacing: 0.04em; }
|
||||
.cc-sub { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-faint); margin-top: 2px; }
|
||||
|
||||
.cc-status { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 10.5px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--rule); color: var(--fg-dim); white-space: nowrap; }
|
||||
.cc-status.live { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.cc-status.face { color: var(--gilt); border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.cc-status.dormant { color: var(--fg-faint); }
|
||||
|
||||
/* 迷你七阶站点 */
|
||||
.cc-lc { display: flex; align-items: center; gap: 3px; }
|
||||
.cc-lc .seg { height: 4px; flex: 1; border-radius: 2px; background: var(--rule); }
|
||||
.cc-lc .seg.reached { background: var(--patina-dim); }
|
||||
.cc-lc .seg.current { background: linear-gradient(90deg, var(--gilt-dim), var(--gilt)); }
|
||||
|
||||
.cc-stats { display: flex; gap: 14px; padding-top: 10px; border-top: 1px solid var(--rule); }
|
||||
.cc-stat { display: flex; flex-direction: column; }
|
||||
.cc-stat .k { font-family: "JetBrains Mono", monospace; font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--fg-faint); }
|
||||
.cc-stat .v { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); }
|
||||
|
||||
@media (max-width: 1080px) {
|
||||
.soul-grid { grid-template-columns: 1fr; }
|
||||
.roster-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.roster-grid { grid-template-columns: 1fr; }
|
||||
.soul-fields { grid-template-columns: 1fr; }
|
||||
.lifecycle-track { overflow-x: auto; }
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="人物"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">人物</span>
|
||||
<span class="page-sub">魂册</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="page-meta">共 <b>5</b> 位 · 当行 <b style="color: var(--patina)">2</b></span>
|
||||
<button class="btn-ghost" type="button">+ 新塑人物</button>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 激活魂册(镜面 hero) -->
|
||||
<div class="soul-card">
|
||||
<div class="soul-top">
|
||||
<div class="soul-mirror">
|
||||
<span class="halo"></span>
|
||||
<div class="inner">梧</div>
|
||||
</div>
|
||||
<div class="soul-id">
|
||||
<div class="soul-name">青梧</div>
|
||||
<div class="soul-realname">character_01H8KFM3…Q9D · qingwu</div>
|
||||
<div class="soul-mood">
|
||||
<span class="pulse-dot"></span>认识你第 41 日 · 沉静 · 探索你的偏好
|
||||
</div>
|
||||
</div>
|
||||
<span class="soul-tag">当前当行</span>
|
||||
</div>
|
||||
|
||||
<!-- 七阶生命周期 -->
|
||||
<div class="lifecycle">
|
||||
<div class="lifecycle-label">生辰七阶 · lifecycle</div>
|
||||
<div class="lifecycle-track">
|
||||
<div class="lc-station reached"><span class="lc-dot"></span><span class="lc-name">无极</span></div>
|
||||
<span class="lc-link reached"></span>
|
||||
<div class="lc-station reached"><span class="lc-dot"></span><span class="lc-name">立名</span></div>
|
||||
<span class="lc-link reached"></span>
|
||||
<div class="lc-station reached"><span class="lc-dot"></span><span class="lc-name">已设定</span></div>
|
||||
<span class="lc-link reached"></span>
|
||||
<div class="lc-station reached"><span class="lc-dot"></span><span class="lc-name">初识</span></div>
|
||||
<span class="lc-link reached"></span>
|
||||
<div class="lc-station current"><span class="lc-dot"></span><span class="lc-name">运行中</span></div>
|
||||
<span class="lc-link"></span>
|
||||
<div class="lc-station"><span class="lc-dot"></span><span class="lc-name">暂停</span></div>
|
||||
<span class="lc-link"></span>
|
||||
<div class="lc-station"><span class="lc-dot"></span><span class="lc-name">归档</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="soul-grid">
|
||||
<div class="soul-fields">
|
||||
<div class="field"><dt>语言</dt><dd>中文 · 宋韵</dd></div>
|
||||
<div class="field"><dt>模型策略</dt><dd class="mono">default-chat</dd></div>
|
||||
<div class="field"><dt>隐私等级</dt><dd class="mono">standard</dd></div>
|
||||
<div class="field"><dt>当前心情</dt><dd>沉静 · 强度 42%</dd></div>
|
||||
<div class="field"><dt>生辰</dt><dd>熙宁三年 · 寒露</dd></div>
|
||||
<div class="field"><dt>表达风格</dt><dd>简练含蓄,少用惊叹</dd></div>
|
||||
<div class="soul-bg">
|
||||
<div class="lab">背景</div>
|
||||
<p>出身旧族旁支,少时家道中落,养就沉静自持。善观人不轻断,言简而意周。与人相处不即不离,重长久之意,轻一时之快。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="soul-stats">
|
||||
<div class="soul-stat"><div class="k">藏识</div><div class="v">86<small>条记忆</small></div></div>
|
||||
<div class="soul-stat"><div class="k">人格</div><div class="v">v7<small>当前版本</small></div></div>
|
||||
<div class="soul-stat"><div class="k">铭文</div><div class="v">142<small>通往来</small></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 名册 -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 全部人物 <span class="sub">铜镜名册</span></div>
|
||||
<div class="roster-grid">
|
||||
<!-- 激活(镜面) -->
|
||||
<div class="char-card is-face">
|
||||
<div class="cc-top">
|
||||
<div class="cc-disc"><div class="inner">梧</div></div>
|
||||
<div><div class="cc-name">青梧</div><div class="cc-sub">第 41 日</div></div>
|
||||
<span class="cc-status face">当前</span>
|
||||
</div>
|
||||
<div class="cc-lc">
|
||||
<span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg current"></span><span class="seg"></span><span class="seg"></span>
|
||||
</div>
|
||||
<div class="cc-stats">
|
||||
<div class="cc-stat"><span class="k">藏识</span><span class="v">86</span></div>
|
||||
<div class="cc-stat"><span class="k">人格</span><span class="v">v7</span></div>
|
||||
<div class="cc-stat"><span class="k">铭文</span><span class="v">142</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 叩心枢(当行) -->
|
||||
<div class="char-card">
|
||||
<div class="cc-top">
|
||||
<div class="cc-disc"><div class="inner">守</div></div>
|
||||
<div><div class="cc-name">叩心枢</div><div class="cc-sub">主动守护 · 系统</div></div>
|
||||
<span class="cc-status live">当行</span>
|
||||
</div>
|
||||
<div class="cc-lc">
|
||||
<span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg current"></span><span class="seg"></span><span class="seg"></span>
|
||||
</div>
|
||||
<div class="cc-stats">
|
||||
<div class="cc-stat"><span class="k">藏识</span><span class="v">318</span></div>
|
||||
<div class="cc-stat"><span class="k">人格</span><span class="v">v4</span></div>
|
||||
<div class="cc-stat"><span class="k">铭文</span><span class="v">27</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 云岚(初成) -->
|
||||
<div class="char-card">
|
||||
<div class="cc-top">
|
||||
<div class="cc-disc"><div class="inner">岚</div></div>
|
||||
<div><div class="cc-name">云岚</div><div class="cc-sub">第 12 日</div></div>
|
||||
<span class="cc-status">初成</span>
|
||||
</div>
|
||||
<div class="cc-lc">
|
||||
<span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg"></span><span class="seg"></span><span class="seg"></span>
|
||||
</div>
|
||||
<div class="cc-stats">
|
||||
<div class="cc-stat"><span class="k">藏识</span><span class="v">42</span></div>
|
||||
<div class="cc-stat"><span class="k">人格</span><span class="v">v3</span></div>
|
||||
<div class="cc-stat"><span class="k">铭文</span><span class="v">38</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 墨羽(种魂) -->
|
||||
<div class="char-card">
|
||||
<div class="cc-top">
|
||||
<div class="cc-disc"><div class="inner">墨</div></div>
|
||||
<div><div class="cc-name">墨羽</div><div class="cc-sub">第 3 日</div></div>
|
||||
<span class="cc-status dormant">种魂</span>
|
||||
</div>
|
||||
<div class="cc-lc">
|
||||
<span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg"></span><span class="seg"></span><span class="seg"></span><span class="seg"></span>
|
||||
</div>
|
||||
<div class="cc-stats">
|
||||
<div class="cc-stat"><span class="k">藏识</span><span class="v">12</span></div>
|
||||
<div class="cc-stat"><span class="k">人格</span><span class="v">v1</span></div>
|
||||
<div class="cc-stat"><span class="k">铭文</span><span class="v">6</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 泠音(暂息) -->
|
||||
<div class="char-card is-paused">
|
||||
<div class="cc-top">
|
||||
<div class="cc-disc"><div class="inner">泠</div></div>
|
||||
<div><div class="cc-name">泠音</div><div class="cc-sub">暂息 14 日</div></div>
|
||||
<span class="cc-status dormant">暂息</span>
|
||||
</div>
|
||||
<div class="cc-lc">
|
||||
<span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg reached"></span><span class="seg current"></span><span class="seg"></span>
|
||||
</div>
|
||||
<div class="cc-stats">
|
||||
<div class="cc-stat"><span class="k">藏识</span><span class="v">203</span></div>
|
||||
<div class="cc-stat"><span class="k">人格</span><span class="v">v12</span></div>
|
||||
<div class="cc-stat"><span class="k">铭文</span><span class="v">411</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新塑占位 -->
|
||||
<div class="char-card" style="border-style: dashed; align-items: center; justify-content: center; min-height: 168px; gap: 8px; opacity: 0.6;">
|
||||
<svg width="28" height="28" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" style="color: var(--fg-faint)"><path d="M8 3v10M3 8h10" /></svg>
|
||||
<span class="serif" style="font-size: 14px; color: var(--fg-faint)">新塑一位</span>
|
||||
<span class="mono" style="font-size: 11px; color: var(--fg-faint)">从模板或空白开始</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,981 @@
|
||||
<!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 · 登入灵台
|
||||
* 与 frontend/design/copper-mirror-redesign-v2.html 同源语言。
|
||||
*
|
||||
* 此页只做一件事:让用户以「照镜」的仪式感认证身份。
|
||||
* 登录卡 = 抛光铜镜(唯一的镜面),其余为镜背暗纹。
|
||||
* 星盘、铭文环、铜面噪点组成镜背的铸纹体量。
|
||||
* 扫描亮带 = 铜镜在烛光下微倾时的漫反射(唯一动态事件)。
|
||||
*
|
||||
* 亮色模式绝非「暗色反相」——而是暖纸上陈列的铜镜,
|
||||
* 保留鎏金发丝线、铜绿锈点缀、暖铜高光。
|
||||
* ============================================================ */
|
||||
|
||||
|
||||
/* ── 亮色:素绢暖纸上的铜镜 ── */
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
background: var(--ink);
|
||||
color: var(--fg);
|
||||
font-family:
|
||||
"PingFang SC",
|
||||
"Microsoft YaHei",
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
system-ui,
|
||||
sans-serif;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════
|
||||
* 镜背基底
|
||||
* ═══════════════════════════════════════════════════ */
|
||||
|
||||
/* 铜面噪点(feTurbulence — 金属颗粒感) */
|
||||
.grain-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
[data-theme="dark"] .grain-overlay {
|
||||
opacity: 0.035;
|
||||
mix-blend-mode: soft-light;
|
||||
}
|
||||
[data-theme="light"] .grain-overlay {
|
||||
opacity: 0.015;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
/* 同心铭文轨 */
|
||||
.inscription-rings {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.inscription-rings svg {
|
||||
width: min(92vmin, 820px);
|
||||
height: min(92vmin, 820px);
|
||||
}
|
||||
[data-theme="dark"] .inscription-rings svg {
|
||||
opacity: 0.18;
|
||||
}
|
||||
[data-theme="light"] .inscription-rings svg {
|
||||
opacity: 0.1;
|
||||
}
|
||||
.inscription-rings .ring-ink {
|
||||
fill: none;
|
||||
stroke: var(--gilt-faint);
|
||||
stroke-width: 0.5;
|
||||
}
|
||||
.inscription-rings .ring-faint {
|
||||
fill: none;
|
||||
stroke: var(--gilt-faint);
|
||||
stroke-width: 0.3;
|
||||
stroke-dasharray: 2 6;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════
|
||||
* 顶栏
|
||||
* ═══════════════════════════════════════════════════ */
|
||||
|
||||
.topbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 40;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 14px clamp(20px, 4vw, 48px);
|
||||
background: color-mix(in srgb, var(--ink) 76%, transparent);
|
||||
backdrop-filter: blur(16px) saturate(140%);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(140%);
|
||||
}
|
||||
.topbar .spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
padding: 6px 14px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid var(--rule);
|
||||
background: var(--surface);
|
||||
color: var(--fg-dim);
|
||||
font-size: 11.5px;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
color 0.18s,
|
||||
border-color 0.18s,
|
||||
background 0.18s;
|
||||
font-family: inherit;
|
||||
}
|
||||
.pill:hover {
|
||||
color: var(--fg);
|
||||
border-color: var(--gilt-dim);
|
||||
background: var(--surface-hi);
|
||||
}
|
||||
.pill:focus-visible {
|
||||
outline: 2px solid var(--patina);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════
|
||||
* 右上角星盘(活的仪器 — 140s 慢旋转)
|
||||
* ═══════════════════════════════════════════════════ */
|
||||
|
||||
.mini-astrolabe {
|
||||
position: absolute;
|
||||
right: clamp(24px, 5vw, 72px);
|
||||
top: clamp(80px, 12vh, 120px);
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
pointer-events: none;
|
||||
}
|
||||
[data-theme="dark"] .mini-astrolabe {
|
||||
opacity: 0.25;
|
||||
}
|
||||
[data-theme="light"] .mini-astrolabe {
|
||||
opacity: 0.18;
|
||||
}
|
||||
.mini-astrolabe svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.astrolabe-rotating {
|
||||
transform-origin: center;
|
||||
animation: slow-rot 140s linear infinite;
|
||||
}
|
||||
@keyframes slow-rot {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
.mini-astrolabe {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════
|
||||
* LOGO · 铜镜徽(品牌标志,替代朱漆红点)
|
||||
* ═══════════════════════════════════════════════════ */
|
||||
|
||||
.logo-mark {
|
||||
display: block;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
margin: 0 auto 16px;
|
||||
}
|
||||
.logo-mark .mirror-ring {
|
||||
fill: none;
|
||||
stroke: var(--gilt);
|
||||
stroke-width: 1.4;
|
||||
opacity: 0.65;
|
||||
}
|
||||
.logo-mark .mirror-inner {
|
||||
fill: none;
|
||||
stroke: var(--patina-dim);
|
||||
stroke-width: 0.8;
|
||||
opacity: 0.45;
|
||||
}
|
||||
.logo-mark .char-ring {
|
||||
fill: none;
|
||||
stroke: var(--gilt-dim);
|
||||
stroke-width: 0.5;
|
||||
opacity: 0.35;
|
||||
}
|
||||
.logo-mark .char {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 30px;
|
||||
fill: var(--gilt);
|
||||
font-weight: 700;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.logo-mark .dot {
|
||||
fill: var(--gilt);
|
||||
opacity: 0.35;
|
||||
}
|
||||
.logo-mark .fill-surface {
|
||||
fill: var(--patina-wash);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════
|
||||
* 主舞台
|
||||
* ═══════════════════════════════════════════════════ */
|
||||
|
||||
.stage {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80px clamp(20px, 4vw, 48px) 48px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════
|
||||
* 镜面卡 · 抛光铜镜
|
||||
* ═══════════════════════════════════════════════════ */
|
||||
|
||||
.mirror-card {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
background: var(--face-sheen), var(--surface);
|
||||
border: 1px solid var(--gilt-dim);
|
||||
border-radius: 6px;
|
||||
box-shadow:
|
||||
inset 0 1px 0 var(--face-in-top),
|
||||
inset 0 -1px 0 var(--face-in-bot),
|
||||
var(--shadow);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 扫描光泽 —— 铜镜在光源前微倾时的漫反射滑移 */
|
||||
.mirror-card::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
background-size: 200% 200%;
|
||||
background-position: 200% 200%;
|
||||
animation: mirror-sweep 9s ease-in-out infinite;
|
||||
}
|
||||
[data-theme="dark"] .mirror-card::before {
|
||||
background: linear-gradient(
|
||||
130deg,
|
||||
transparent 0%,
|
||||
transparent 28%,
|
||||
rgba(201, 162, 74, 0.025) 34%,
|
||||
rgba(255, 255, 255, 0.06) 40%,
|
||||
rgba(201, 162, 74, 0.025) 48%,
|
||||
transparent 55%,
|
||||
transparent 100%
|
||||
);
|
||||
}
|
||||
[data-theme="light"] .mirror-card::before {
|
||||
background: linear-gradient(
|
||||
130deg,
|
||||
transparent 0%,
|
||||
transparent 24%,
|
||||
rgba(200, 170, 130, 0.06) 30%,
|
||||
rgba(255, 248, 235, 0.18) 36%,
|
||||
rgba(200, 170, 130, 0.1) 44%,
|
||||
transparent 52%,
|
||||
transparent 100%
|
||||
);
|
||||
}
|
||||
@keyframes mirror-sweep {
|
||||
0% {
|
||||
background-position: 200% 200%;
|
||||
}
|
||||
40% {
|
||||
background-position: 50% 50%;
|
||||
}
|
||||
60% {
|
||||
background-position: 50% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: -100% -100%;
|
||||
}
|
||||
}
|
||||
|
||||
.card-inner {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 44px 40px 36px;
|
||||
}
|
||||
|
||||
/* —— 品牌区 —— */
|
||||
.brand {
|
||||
text-align: center;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
.brand .wordmark-lg {
|
||||
display: block;
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: clamp(26px, 4vw, 30px);
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.14em;
|
||||
color: var(--fg);
|
||||
margin-top: 2px;
|
||||
}
|
||||
.brand .eyebrow {
|
||||
display: block;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 9px;
|
||||
letter-spacing: 0.26em;
|
||||
text-transform: uppercase;
|
||||
color: var(--gilt);
|
||||
font-weight: 500;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.brand .divider {
|
||||
display: block;
|
||||
width: 24px;
|
||||
height: 1px;
|
||||
background: var(--gilt-dim);
|
||||
margin: 14px auto 0;
|
||||
}
|
||||
|
||||
/* —— 表单 —— */
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
.field-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.field-group label {
|
||||
font-size: 11.5px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--fg-dim);
|
||||
}
|
||||
.field-group .input-wrap {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: 1px solid var(--rule);
|
||||
border-radius: 4px;
|
||||
transition:
|
||||
border-color 0.2s,
|
||||
box-shadow 0.2s;
|
||||
}
|
||||
[data-theme="dark"] .field-group .input-wrap {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
[data-theme="light"] .field-group .input-wrap {
|
||||
background: rgba(255, 248, 235, 0.5);
|
||||
}
|
||||
|
||||
.field-group .input-wrap:focus-within {
|
||||
border-color: var(--gilt-dim);
|
||||
box-shadow:
|
||||
0 0 0 1px var(--gilt-faint),
|
||||
inset 0 0 0 1px var(--gilt-faint);
|
||||
}
|
||||
.field-group .input-wrap.error {
|
||||
border-color: var(--cinnabar-dim);
|
||||
box-shadow: 0 0 0 1px var(--cinnabar-dim);
|
||||
}
|
||||
.field-group .input-wrap.error:focus-within {
|
||||
border-color: var(--cinnabar);
|
||||
box-shadow: 0 0 0 1px
|
||||
color-mix(in srgb, var(--cinnabar) 55%, transparent);
|
||||
}
|
||||
|
||||
.field-group input {
|
||||
flex: 1;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
color: var(--fg);
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 11px 13px;
|
||||
min-width: 0;
|
||||
}
|
||||
.field-group input::placeholder {
|
||||
color: var(--fg-faint);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.field-group .input-icon {
|
||||
flex: none;
|
||||
width: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--fg-faint);
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.field-group .input-wrap:focus-within .input-icon {
|
||||
opacity: 0.85;
|
||||
color: var(--gilt);
|
||||
}
|
||||
|
||||
/* —— 错误消息 —— */
|
||||
.form-error {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 9px 13px;
|
||||
border: 1px solid var(--cinnabar-dim);
|
||||
border-radius: 4px;
|
||||
font-size: 12.5px;
|
||||
color: var(--cinnabar);
|
||||
}
|
||||
[data-theme="dark"] .form-error {
|
||||
background: rgba(184, 57, 46, 0.07);
|
||||
}
|
||||
[data-theme="light"] .form-error {
|
||||
background: rgba(168, 52, 42, 0.06);
|
||||
}
|
||||
.form-error svg {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
/* —— 提交按钮 —— */
|
||||
.submit-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
padding: 12px 20px;
|
||||
margin-top: 4px;
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
color: #ece6d8;
|
||||
background: var(--cinnabar);
|
||||
border: 1px solid var(--cinnabar-dim);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background 0.2s,
|
||||
border-color 0.2s,
|
||||
transform 0.15s cubic-bezier(0.16, 1, 0.3, 1),
|
||||
box-shadow 0.2s;
|
||||
}
|
||||
.submit-btn:hover {
|
||||
background: color-mix(in srgb, var(--cinnabar) 88%, var(--patina));
|
||||
border-color: var(--cinnabar);
|
||||
box-shadow: 0 0 20px var(--cinnabar-dim);
|
||||
}
|
||||
.submit-btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
.submit-btn:focus-visible {
|
||||
outline: 2px solid var(--patina);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.submit-btn:disabled {
|
||||
opacity: 0.55;
|
||||
cursor: not-allowed;
|
||||
box-shadow: none;
|
||||
transform: none !important;
|
||||
}
|
||||
|
||||
.submit-btn .loading-dot {
|
||||
display: inline-block;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
background: currentColor;
|
||||
animation: load-pulse 1.4s ease-in-out infinite;
|
||||
}
|
||||
@keyframes load-pulse {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0.35;
|
||||
transform: scale(0.85);
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* —— 脚注 —— */
|
||||
.card-footer {
|
||||
margin-top: 32px;
|
||||
text-align: center;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--rule);
|
||||
}
|
||||
.card-footer p {
|
||||
font-size: 9.5px;
|
||||
letter-spacing: 0.22em;
|
||||
color: var(--fg-faint);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════
|
||||
* 入场动画序列
|
||||
* ═══════════════════════════════════════════════════ */
|
||||
|
||||
.mirror-card {
|
||||
opacity: 0;
|
||||
transform: translateY(18px);
|
||||
animation: card-enter 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
animation-delay: 0.12s;
|
||||
}
|
||||
@keyframes card-enter {
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.brand > * {
|
||||
opacity: 0;
|
||||
transform: translateY(6px);
|
||||
animation: stagger-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
.brand .logo-mark {
|
||||
animation-delay: 0.22s;
|
||||
}
|
||||
.brand .wordmark-lg {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
.brand .eyebrow {
|
||||
animation-delay: 0.38s;
|
||||
}
|
||||
.brand .divider {
|
||||
animation-delay: 0.46s;
|
||||
}
|
||||
|
||||
.form > * {
|
||||
opacity: 0;
|
||||
animation: stagger-in 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
.form .field-group:nth-child(1) {
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
.form .field-group:nth-child(2) {
|
||||
animation-delay: 0.58s;
|
||||
}
|
||||
.form .submit-btn {
|
||||
animation-delay: 0.66s;
|
||||
}
|
||||
.card-footer {
|
||||
animation-delay: 0.74s;
|
||||
opacity: 0;
|
||||
animation: stagger-in 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
@keyframes stagger-in {
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.mirror-card.departing {
|
||||
animation: card-depart 0.5s cubic-bezier(0.55, 0, 0.7, 0.3) forwards;
|
||||
}
|
||||
@keyframes card-depart {
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px) scale(0.97);
|
||||
filter: blur(2px);
|
||||
}
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════
|
||||
* Reduced Motion
|
||||
* ═══════════════════════════════════════════════════ */
|
||||
.mirror-card {
|
||||
opacity: 1 !important;
|
||||
transform: none !important;
|
||||
animation: none !important;
|
||||
}
|
||||
.mirror-card::before {
|
||||
display: none !important;
|
||||
}
|
||||
.brand > *,
|
||||
.form > *,
|
||||
.card-footer {
|
||||
opacity: 1 !important;
|
||||
transform: none !important;
|
||||
animation: none !important;
|
||||
}
|
||||
.astrolabe-rotating {
|
||||
animation: none !important;
|
||||
}
|
||||
}
|
||||
/* ═══ 统一 sidebar(6 组导航)═══ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.siming { color: var(--cinnabar); }
|
||||
|
||||
|
||||
@media (max-width: 900px) { .sidebar-wrap { display: none; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-mount" data-active=""></div>
|
||||
<div class="main-area">
|
||||
<!-- 铜面噪点 -->
|
||||
<svg
|
||||
class="grain-overlay"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 200 200"
|
||||
preserveAspectRatio="none"
|
||||
>
|
||||
<filter id="bronze-grain" x="0" y="0" width="100%" height="100%">
|
||||
<feTurbulence
|
||||
type="fractalNoise"
|
||||
baseFrequency="0.75"
|
||||
numOctaves="3"
|
||||
seed="42"
|
||||
result="noise"
|
||||
/>
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.25 0"
|
||||
in="noise"
|
||||
result="colored"
|
||||
/>
|
||||
</filter>
|
||||
<rect width="100%" height="100%" filter="url(#bronze-grain)" />
|
||||
</svg>
|
||||
|
||||
<!-- 同心铭文轨 -->
|
||||
<div class="inscription-rings">
|
||||
<svg viewBox="0 0 400 400" role="img" aria-hidden="true">
|
||||
<circle cx="200" cy="200" r="195" class="ring-ink" />
|
||||
<circle cx="200" cy="200" r="185" class="ring-faint" />
|
||||
<circle cx="200" cy="200" r="170" class="ring-ink" />
|
||||
<circle cx="200" cy="200" r="155" class="ring-faint" />
|
||||
<circle cx="200" cy="200" r="135" class="ring-ink" opacity="0.3" />
|
||||
<circle cx="200" cy="200" r="110" class="ring-faint" opacity="0.2" />
|
||||
<circle cx="200" cy="200" r="80" class="ring-ink" opacity="0.15" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- 星盘装饰(140s 慢旋转) -->
|
||||
<div class="mini-astrolabe" role="img" aria-label="九枢星盘">
|
||||
<svg viewBox="0 0 100 100">
|
||||
<!-- 静止外环 -->
|
||||
<circle
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="48"
|
||||
fill="none"
|
||||
stroke="var(--gilt-dim)"
|
||||
stroke-width="0.6"
|
||||
/>
|
||||
<circle
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="42"
|
||||
fill="none"
|
||||
stroke="var(--gilt-faint)"
|
||||
stroke-width="0.3"
|
||||
stroke-dasharray="1.5 3"
|
||||
/>
|
||||
<!-- 旋转层 -->
|
||||
<g class="astrolabe-rotating">
|
||||
<circle
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="33"
|
||||
fill="none"
|
||||
stroke="var(--patina-dim)"
|
||||
stroke-width="0.5"
|
||||
/>
|
||||
<circle
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="24"
|
||||
fill="none"
|
||||
stroke="var(--gilt-faint)"
|
||||
stroke-width="0.4"
|
||||
stroke-dasharray="1 4"
|
||||
/>
|
||||
<!-- 辐线 -->
|
||||
<g stroke="var(--gilt-faint)" stroke-width="0.3" opacity="0.5">
|
||||
<line x1="50" y1="17" x2="50" y2="4" />
|
||||
<line x1="83" y1="30" x2="93" y2="22" />
|
||||
<line x1="93" y1="62" x2="97" y2="68" />
|
||||
<line x1="74" y1="81" x2="80" y2="89" />
|
||||
<line x1="32" y1="82" x2="26" y2="90" />
|
||||
<line x1="14" y1="56" x2="6" y2="60" />
|
||||
<line x1="18" y1="26" x2="10" y2="20" />
|
||||
</g>
|
||||
<!-- 节点 -->
|
||||
<g fill="var(--gilt)" opacity="0.4">
|
||||
<circle cx="50" cy="12" r="1.8" />
|
||||
<circle cx="82" cy="28" r="1.5" />
|
||||
<circle cx="88" cy="56" r="1.6" />
|
||||
<circle cx="68" cy="80" r="1.4" />
|
||||
<circle cx="34" cy="78" r="1.5" />
|
||||
<circle cx="14" cy="52" r="1.7" />
|
||||
<circle cx="22" cy="24" r="1.4" />
|
||||
</g>
|
||||
</g>
|
||||
<!-- 中心轴 -->
|
||||
<circle
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="3.5"
|
||||
fill="var(--patina-bright)"
|
||||
opacity="0.5"
|
||||
/>
|
||||
<circle cx="50" cy="50" r="1.5" fill="var(--patina)" opacity="0.7" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- 顶栏 -->
|
||||
<header class="topbar">
|
||||
<span class="spacer"></span>
|
||||
<button class="pill" id="themeToggle" type="button" aria-label="切换主题">
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
d="M8 1v2M8 13v2M2 8h2M12 8h2M3.5 3.5l1.4 1.4M11.1 11.1l1.4 1.4M3.5 12.5l1.4-1.4M11.1 4.9l1.4-1.4"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.2"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
<circle
|
||||
cx="8"
|
||||
cy="8"
|
||||
r="3"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.2"
|
||||
/>
|
||||
</svg>
|
||||
<span id="themeLabel">夜铜</span>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<!-- 主舞台 -->
|
||||
<main class="stage" role="main">
|
||||
<div class="mirror-card" id="mirrorCard">
|
||||
<div class="card-inner">
|
||||
<!-- 品牌区 · 铜镜徽 + 魂镜 + 铭文 -->
|
||||
<div class="brand">
|
||||
<svg
|
||||
class="logo-mark"
|
||||
viewBox="0 0 68 68"
|
||||
role="img"
|
||||
aria-label="魂镜铜镜徽"
|
||||
>
|
||||
<circle cx="34" cy="34" r="32" class="mirror-ring" />
|
||||
<circle cx="34" cy="34" r="27" class="mirror-inner" />
|
||||
<circle cx="34" cy="34" r="22" class="char-ring" />
|
||||
<circle cx="34" cy="34" r="15" class="char-ring" />
|
||||
<circle
|
||||
cx="34"
|
||||
cy="34"
|
||||
r="8"
|
||||
fill="var(--patina-wash)"
|
||||
opacity="0.3"
|
||||
/>
|
||||
<text x="34" y="40" text-anchor="middle" class="char">魂</text>
|
||||
<circle cx="34" cy="6" r="1.5" class="dot" />
|
||||
<circle cx="34" cy="62" r="1.5" class="dot" />
|
||||
<circle cx="6" cy="34" r="1.5" class="dot" />
|
||||
<circle cx="62" cy="34" r="1.5" class="dot" />
|
||||
</svg>
|
||||
<span class="wordmark-lg">魂鏡</span>
|
||||
<span class="eyebrow">MIRROR OF THE HEART</span>
|
||||
<span class="divider" aria-hidden="true"></span>
|
||||
</div>
|
||||
|
||||
<!-- 表单 -->
|
||||
<form class="form" id="loginForm" novalidate autocomplete="off">
|
||||
<div class="field-group">
|
||||
<label for="username">用户名</label>
|
||||
<div class="input-wrap">
|
||||
<span class="input-icon mono" aria-hidden="true">◎</span>
|
||||
<input
|
||||
id="username"
|
||||
type="text"
|
||||
placeholder="铜镜所照之名"
|
||||
autocomplete="username"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field-group">
|
||||
<label for="password">密令</label>
|
||||
<div class="input-wrap">
|
||||
<span class="input-icon mono" aria-hidden="true">◉</span>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
placeholder="铭文锁钥"
|
||||
autocomplete="current-password"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 错误消息 -->
|
||||
<div
|
||||
id="formError"
|
||||
class="form-error"
|
||||
role="alert"
|
||||
style="display: none"
|
||||
>
|
||||
<svg
|
||||
width="13"
|
||||
height="13"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<circle
|
||||
cx="8"
|
||||
cy="8"
|
||||
r="6"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.2"
|
||||
/>
|
||||
<path
|
||||
d="M8 5v3M8 10.5v.5"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.3"
|
||||
stroke-linecap="round"
|
||||
/>
|
||||
</svg>
|
||||
<span id="errorText"></span>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="submit-btn" id="submitBtn">
|
||||
<span id="submitText">登入</span>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- 脚注 -->
|
||||
<div class="card-footer">
|
||||
<p class="mono">琉璃镜 · 照见数字生命</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
/* ── 主题切换 ── */
|
||||
const root = document.documentElement;
|
||||
const label = document.getElementById("themeLabel");
|
||||
document.getElementById("themeToggle").addEventListener("click", () => {
|
||||
const n = root.getAttribute("data-theme") === "dark" ? "light" : "dark";
|
||||
root.setAttribute("data-theme", n);
|
||||
label.textContent = n === "dark" ? "夜铜" : "素绢";
|
||||
});
|
||||
|
||||
/* ── 表单交互 ── */
|
||||
const form = document.getElementById("loginForm");
|
||||
const user = document.getElementById("username");
|
||||
const pass = document.getElementById("password");
|
||||
const btn = document.getElementById("submitBtn");
|
||||
const txt = document.getElementById("submitText");
|
||||
const err = document.getElementById("formError");
|
||||
const et = document.getElementById("errorText");
|
||||
|
||||
function showError(m) {
|
||||
et.textContent = m;
|
||||
err.style.display = "flex";
|
||||
document
|
||||
.querySelectorAll(".input-wrap")
|
||||
.forEach((w) => w.classList.add("error"));
|
||||
err.style.animation = "none";
|
||||
err.offsetHeight;
|
||||
err.style.animation = "shake .35s cubic-bezier(.16,1,.3,1)";
|
||||
}
|
||||
function hideError() {
|
||||
err.style.display = "none";
|
||||
document
|
||||
.querySelectorAll(".input-wrap")
|
||||
.forEach((w) => w.classList.remove("error"));
|
||||
}
|
||||
user.addEventListener("input", hideError);
|
||||
pass.addEventListener("input", hideError);
|
||||
|
||||
const ss = document.createElement("style");
|
||||
ss.textContent = `@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}50%{transform:translateX(4px)}75%{transform:translateX(-2px)}}`;
|
||||
document.head.appendChild(ss);
|
||||
|
||||
form.addEventListener("submit", async (e) => {
|
||||
e.preventDefault();
|
||||
hideError();
|
||||
if (!user.value.trim() || !pass.value) {
|
||||
showError("请填写用户名和密令。");
|
||||
return;
|
||||
}
|
||||
btn.disabled = true;
|
||||
txt.innerHTML = '登入灵台<span class="loading-dot"></span>';
|
||||
await new Promise((r) => setTimeout(r, 1500));
|
||||
const t = parseInt(sessionStorage.getItem("t") || "0");
|
||||
sessionStorage.setItem("t", String(t + 1));
|
||||
if (t === 0) {
|
||||
showError("用户名或密令错误,铜镜不识此名。");
|
||||
btn.disabled = false;
|
||||
txt.textContent = "登入";
|
||||
return;
|
||||
}
|
||||
const c = document.getElementById("mirrorCard");
|
||||
c.classList.add("departing");
|
||||
txt.textContent = "镜开灵现";
|
||||
await new Promise((r) => setTimeout(r, 600));
|
||||
txt.textContent = "登入";
|
||||
btn.disabled = false;
|
||||
c.classList.remove("departing");
|
||||
sessionStorage.removeItem("t");
|
||||
showError("演示:登录成功");
|
||||
err.style.border = "1px solid var(--patina-dim)";
|
||||
err.style.background = "var(--patina-wash)";
|
||||
err.style.color = "var(--patina)";
|
||||
const ic = err.querySelector("svg");
|
||||
if (ic) ic.style.display = "none";
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,572 @@
|
||||
<!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 — 灵枢页:心智解剖图
|
||||
* 以「太极 → 四象 → 八卦」的生成链为论点,呈现数字生命的心智结构。
|
||||
* 太极/阴阳 ← 设计理念 §4.2(自主与约束 · 阴阳平衡度)
|
||||
* 四象 ← 设计理念 §7(青龙生发 / 朱雀表达 / 白虎裁断 / 玄武藏养)
|
||||
* 八卦 ← 设计理念 §7 + agent-society-design §3(天工阁八原型)
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 侧栏(active=灵枢)── */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.char-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--patina); padding: 3px 11px 3px 4px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.char-pill .avatar-mini { width: 18px; height: 18px; border-radius: 50%; background: var(--patina); color: var(--ink); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; }
|
||||
.page-header .spacer { flex: 1; }
|
||||
.page-meta { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg-faint); }
|
||||
.page-meta b { color: var(--gilt); font-weight: 600; font-family: "Songti SC", serif; font-size: 15px; }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
.section-heading { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin-bottom: 14px; }
|
||||
.genesis-chain { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.genesis-chain b { font-family: "Songti SC", serif; font-size: 13px; font-weight: 600; }
|
||||
.genesis-chain .g-taiji { color: var(--fg); } .genesis-chain .g-si { color: var(--patina); } .genesis-chain .g-ba { color: var(--gilt); }
|
||||
|
||||
/* ═══ 太极 · 阴阳平衡(签名 hero)═══
|
||||
阳鱼 = patina(生发:太一/大周天/内驱力),阴鱼 = cinnabar(约束:司命/安全/审计)。
|
||||
阴阳平衡度 = 司命通过率 / (候选生成率 + ε),三态:阳亢 / 动态平衡 / 阴盛。 */
|
||||
.taiji-hero { position: relative; overflow: hidden; border: 1px solid var(--gilt-dim); border-radius: 8px; background: var(--face-sheen), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow); padding: 26px 30px 22px; }
|
||||
.taiji-hero::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); opacity: 0.018; mix-blend-mode: overlay; }
|
||||
.taiji-hero > * { position: relative; z-index: 1; }
|
||||
.taiji-stage { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; }
|
||||
.yy-side { flex: 1; min-width: 180px; display: flex; flex-direction: column; gap: 9px; }
|
||||
.yy-side.yang { text-align: right; align-items: flex-end; }
|
||||
.yy-side .yy-tag { font-family: "Songti SC", serif; font-size: 17px; font-weight: 700; letter-spacing: 0.08em; }
|
||||
.yy-side.yang .yy-tag { color: var(--patina); }
|
||||
.yy-side.yin .yy-tag { color: var(--cinnabar); }
|
||||
.yy-side .yy-mono { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.yy-side .yy-roles { display: flex; gap: 6px; flex-wrap: wrap; justify-content: inherit; }
|
||||
.yy-side.yang .yy-roles { justify-content: flex-end; }
|
||||
.yy-role { font-family: "Songti SC", serif; font-size: 12.5px; padding: 3px 11px; border-radius: 999px; border: 1px solid var(--rule); }
|
||||
.yy-side.yang .yy-role { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.yy-side.yin .yy-role { color: var(--cinnabar); border-color: var(--cinnabar-dim); background: rgba(184,57,46,0.08); }
|
||||
.yy-side .yy-desc { font-size: 12.5px; color: var(--fg-dim); line-height: 1.6; }
|
||||
|
||||
.taiji-disc-wrap { flex: 0 0 auto; position: relative; width: 196px; height: 196px; }
|
||||
.taiji-disc { width: 100%; height: 100%; animation: taiji-spin 90s linear infinite; transform-origin: 50% 50%; }
|
||||
@keyframes taiji-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
|
||||
.taiji-disc .yy-ring { fill: none; stroke: var(--gilt-dim); stroke-width: 0.8; }
|
||||
.taiji-disc .yy-yang { fill: var(--patina); }
|
||||
.taiji-disc .yy-yin { fill: var(--cinnabar); }
|
||||
.taiji-disc .yy-eye-yang { fill: var(--patina); }
|
||||
.taiji-disc .yy-eye-yin { fill: var(--cinnabar); }
|
||||
.taiji-eye-pulse { animation: eye-pulse 3.2s cubic-bezier(0.16,1,0.3,1) infinite; transform-origin: 100px 52px; }
|
||||
.taiji-eye-pulse.late { animation-delay: 1.6s; transform-origin: 100px 148px; }
|
||||
@keyframes eye-pulse { 0%, 100% { opacity: 0.85; } 50% { opacity: 0.35; } }
|
||||
|
||||
/* 阴阳平衡度 readout */
|
||||
.balance-readout { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--rule); display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
|
||||
.br-formula { font-family: "JetBrains Mono", monospace; font-size: 11.5px; color: var(--fg-faint); line-height: 1.7; }
|
||||
.br-formula b { color: var(--gilt); font-weight: 600; }
|
||||
.br-gauge { flex: 1; min-width: 260px; display: flex; flex-direction: column; gap: 7px; }
|
||||
.br-track { position: relative; height: 30px; border-radius: 6px; background: linear-gradient(90deg, var(--cinnabar-dim), var(--patina-wash) 45%, var(--surface-hi) 50%, var(--patina-wash) 55%, var(--patina-dim)); border: 1px solid var(--rule); overflow: hidden; }
|
||||
.br-tick { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--rule); }
|
||||
.br-tick-label { position: absolute; top: 32px; font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); transform: translateX(-50%); letter-spacing: 0.04em; }
|
||||
.br-marker { position: absolute; top: -3px; bottom: -3px; width: 3px; border-radius: 2px; background: var(--gilt); box-shadow: 0 0 10px -1px rgba(201,162,74,0.6); transform: translateX(-50%); }
|
||||
.br-marker::before { content: ""; position: absolute; top: -5px; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 6px solid var(--gilt); }
|
||||
.br-state { font-family: "Songti SC", serif; font-size: 13.5px; color: var(--patina); padding: 5px 14px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); white-space: nowrap; flex-shrink: 0; }
|
||||
.br-state b { font-family: "JetBrains Mono", monospace; font-size: 12px; margin-left: 4px; }
|
||||
|
||||
/* ═══ 四象 · 认知循环(罗盘)═══
|
||||
南上北下东左西右(同八卦取向)。顺时针 = 认知流:生发→表达→裁断→藏养。
|
||||
青龙(东/木) 朱雀(南/火) 白虎(西/金) 玄武(北/水)。 */
|
||||
.sixiang-card { position: relative; overflow: hidden; border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 22px 26px; }
|
||||
.sixiang-stage { position: relative; width: 100%; max-width: 520px; margin: 6px auto 0; aspect-ratio: 1 / 1; }
|
||||
.sixiang-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.sixiang-svg .compass-ring { fill: none; stroke: var(--rule); stroke-width: 1; }
|
||||
.sixiang-svg .compass-ring-inner { fill: none; stroke: var(--gilt-dim); stroke-width: 0.6; stroke-dasharray: 3 4; opacity: 0.6; }
|
||||
.sixiang-svg .flow-arc { fill: none; stroke: var(--patina-dim); stroke-width: 1.4; stroke-linecap: round; opacity: 0.5; }
|
||||
.sixiang-svg .center-disc { fill: var(--ink); stroke: var(--gilt-dim); stroke-width: 1; }
|
||||
.sixiang-svg .center-taiji-yang { fill: var(--patina); }
|
||||
.sixiang-svg .center-taiji-yin { fill: var(--cinnabar); }
|
||||
.sixiang-svg .center-label { font-family: "Songti SC", serif; font-size: 9px; text-anchor: middle; fill: var(--fg-faint); letter-spacing: 0.08em; }
|
||||
.sixiang-quadrant { position: absolute; width: 38%; display: flex; flex-direction: column; gap: 5px; padding: 12px 14px; border-radius: 7px; border: 1px solid var(--rule); background: var(--surface); }
|
||||
.sixiang-quadrant .q-creature { font-family: "Songti SC", serif; font-size: 15px; font-weight: 700; letter-spacing: 0.04em; display: flex; align-items: baseline; gap: 7px; }
|
||||
.sixiang-quadrant .q-phase { font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.06em; }
|
||||
.sixiang-quadrant .q-what { font-size: 11.5px; color: var(--fg-dim); line-height: 1.5; }
|
||||
.sixiang-quadrant .q-mapping { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); letter-spacing: 0.02em; }
|
||||
.sixiang-quadrant.q-qinglong { top: 31%; left: 0; border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.sixiang-quadrant.q-qinglong .q-creature, .sixiang-quadrant.q-qinglong .q-phase { color: var(--patina); }
|
||||
.sixiang-quadrant.q-zhuque { top: 0; left: 31%; border-color: var(--cinnabar-dim); background: rgba(184,57,46,0.07); }
|
||||
.sixiang-quadrant.q-zhuque .q-creature, .sixiang-quadrant.q-zhuque .q-phase { color: var(--cinnabar); }
|
||||
.sixiang-quadrant.q-baihu { top: 31%; right: 0; border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.sixiang-quadrant.q-baihu .q-creature, .sixiang-quadrant.q-baihu .q-phase { color: var(--gilt); }
|
||||
.sixiang-quadrant.q-xuanwu { bottom: 0; left: 31%; border-color: var(--slate-dim); background: var(--slate-wash); }
|
||||
.sixiang-quadrant.q-xuanwu .q-creature, .sixiang-quadrant.q-xuanwu .q-phase { color: var(--slate); }
|
||||
.sixiang-quadrant .q-dir { font-family: "JetBrains Mono", monospace; font-size: 9px; opacity: 0.7; }
|
||||
|
||||
/* ═══ 八卦阵 · 天工阁八原型(签名)═══
|
||||
后天八卦取向(南=离/火 上,北=坎/水 下,东=震/雷 左,西=兑/泽 右)。
|
||||
中心太极;八卦按四组分色:认知方向=金,行动表达=朱,承载稳定=铜,边界风险=石。 */
|
||||
.bagua-card { position: relative; overflow: hidden; border: 1px solid var(--gilt-dim); border-radius: 8px; background: var(--face-sheen), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow); padding: 22px 26px; }
|
||||
.bagua-card::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); opacity: 0.018; mix-blend-mode: overlay; }
|
||||
.bagua-card > * { position: relative; z-index: 1; }
|
||||
.bagua-stage { width: 100%; max-width: 560px; margin: 4px auto 0; }
|
||||
.bagua-svg { width: 100%; height: auto; display: block; }
|
||||
.bagua-svg .oct-frame { fill: none; stroke: var(--rule); stroke-width: 1; }
|
||||
.bagua-svg .oct-frame-outer { fill: none; stroke: var(--gilt-dim); stroke-width: 0.6; stroke-dasharray: 3 5; opacity: 0.55; }
|
||||
.bagua-svg .group-arc { fill: none; stroke-width: 1.2; opacity: 0.16; }
|
||||
.bagua-svg .node-bg { fill: var(--ink); }
|
||||
.bagua-svg .node-ring { fill: none; stroke-width: 2; }
|
||||
.bagua-svg .trigram-bar { fill: var(--fg); }
|
||||
.bagua-svg .node-name { font-family: "Songti SC", serif; font-size: 15px; font-weight: 700; text-anchor: middle; dominant-baseline: central; }
|
||||
.bagua-svg .node-meta { font-family: "JetBrains Mono", monospace; font-size: 8px; text-anchor: middle; fill: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.bagua-svg .center-disc { fill: var(--ink); stroke: var(--gilt-dim); stroke-width: 1.2; }
|
||||
.bagua-svg .center-yang { fill: var(--patina); }
|
||||
.bagua-svg .center-yin { fill: var(--cinnabar); }
|
||||
.bagua-svg .center-label { font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; text-anchor: middle; fill: var(--gilt); letter-spacing: 0.06em; }
|
||||
|
||||
/* 八卦详注:四组 × 每组两卦 */
|
||||
.bagua-detail { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; margin-top: 4px; }
|
||||
.bg-group { border: 1px solid var(--rule); border-radius: 8px; padding: 14px 16px; display: flex; flex-direction: column; gap: 11px; }
|
||||
.bg-group.g1 { border-left: 3px solid var(--gilt); } .bg-group.g2 { border-left: 3px solid var(--cinnabar); } .bg-group.g3 { border-left: 3px solid var(--patina); } .bg-group.g4 { border-left: 3px solid var(--slate); }
|
||||
.bg-group-head { display: flex; align-items: center; gap: 8px; }
|
||||
.bg-group-name { font-family: "Songti SC", serif; font-size: 13px; font-weight: 600; }
|
||||
.bg-group.g1 .bg-group-name { color: var(--gilt); } .bg-group.g2 .bg-group-name { color: var(--cinnabar); } .bg-group.g3 .bg-group-name { color: var(--patina); } .bg-group.g4 .bg-group-name { color: var(--slate); }
|
||||
.bg-group-tag { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.bg-tri { display: flex; gap: 12px; padding: 10px 0; }
|
||||
.bg-tri + .bg-tri { border-top: 1px dashed var(--rule); }
|
||||
.bg-tri-glyph { flex-shrink: 0; display: flex; flex-direction: column; align-items: center; gap: 4px; width: 42px; }
|
||||
.bg-tri-glyph svg { width: 30px; height: 26px; }
|
||||
.bg-tri-glyph .bg-tri-name { font-family: "Songti SC", serif; font-size: 15px; font-weight: 700; }
|
||||
.bg-group.g1 .bg-tri-glyph .bg-tri-name { color: var(--gilt); } .bg-group.g2 .bg-tri-glyph .bg-tri-name { color: var(--cinnabar); } .bg-group.g3 .bg-tri-glyph .bg-tri-name { color: var(--patina); } .bg-group.g4 .bg-tri-glyph .bg-tri-name { color: var(--slate); }
|
||||
.bg-tri-body { flex: 1; min-width: 0; }
|
||||
.bg-tri-role { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
|
||||
.bg-tri-map { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); letter-spacing: 0.02em; }
|
||||
.bg-tri-duty { font-size: 12px; color: var(--fg-dim); margin-top: 4px; line-height: 1.55; }
|
||||
.bg-tri-behave { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); margin-top: 4px; line-height: 1.5; letter-spacing: 0.01em; }
|
||||
|
||||
/* 状态注脚 */
|
||||
.vision-strip { border: 1px dashed var(--gilt-dim); border-left: 3px solid var(--gilt-dim); border-radius: 6px; padding: 13px 18px; background: var(--gilt-faint); display: flex; align-items: center; gap: 14px; }
|
||||
.vision-strip .seal { font-family: "Songti SC", serif; font-size: 13px; font-weight: 700; color: var(--gilt); letter-spacing: 0.06em; white-space: nowrap; }
|
||||
.vision-strip .desc { font-size: 12.5px; color: var(--fg-dim); line-height: 1.55; flex: 1; }
|
||||
.vision-strip .desc code { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--gilt); background: var(--surface); padding: 1px 5px; border-radius: 3px; }
|
||||
.vision-strip .tag { font-family: "JetBrains Mono", monospace; font-size: 10px; padding: 2px 9px; border-radius: 999px; border: 1px dashed var(--gilt-dim); color: var(--gilt); white-space: nowrap; flex-shrink: 0; }
|
||||
|
||||
@media (max-width: 900px) { .bagua-detail { grid-template-columns: 1fr; } .taiji-stage { gap: 18px; } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } .yy-side.yang { text-align: left; align-items: flex-start; } .yy-side.yang .yy-roles { justify-content: flex-start; } .taiji-disc-wrap { margin: 0 auto; } .sixiang-quadrant { width: 44%; } .sixiang-quadrant.q-zhuque { left: 28%; } .sixiang-quadrant.q-xuanwu { left: 28%; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="灵枢"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">灵枢</span>
|
||||
<span class="page-sub">心智解剖图 · 太极生两仪,两仪生四象,四象生八卦</span>
|
||||
<span class="char-pill"><span class="avatar-mini">梧</span>青梧</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="genesis-chain"><b class="g-taiji">太极</b> → <b class="g-si">四象</b> → <b class="g-ba">八卦</b></span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- ═══ 太极 · 阴阳平衡(hero)═══ -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 太极 <span class="sub">阴阳 · 自主与约束的动态制衡 · 系统生命体征</span></div>
|
||||
<div class="taiji-hero">
|
||||
<div class="taiji-stage">
|
||||
<div class="yy-side yang">
|
||||
<span class="yy-tag">阳 · 生发</span>
|
||||
<span class="yy-mono">yang · generation</span>
|
||||
<div class="yy-roles">
|
||||
<span class="yy-role">太一枢</span>
|
||||
<span class="yy-role">大周天</span>
|
||||
<span class="yy-role">内驱力</span>
|
||||
</div>
|
||||
<span class="yy-desc">主动生发,追求可能性。<br />不断生成意图、候选与行动方案。</span>
|
||||
</div>
|
||||
|
||||
<div class="taiji-disc-wrap">
|
||||
<svg class="taiji-disc" viewBox="0 0 200 200" role="img" aria-label="太极图:阳鱼铜绿主生发,阴鱼朱砂主约束">
|
||||
<circle class="yy-ring" cx="100" cy="100" r="97" />
|
||||
<circle class="yy-ring" cx="100" cy="100" r="91" opacity="0.5" />
|
||||
<!-- 阳 fish base(铜绿)-->
|
||||
<circle class="yy-yang" cx="100" cy="100" r="88" />
|
||||
<!-- 阴 fish(朱砂)-->
|
||||
<path class="yy-yin" d="M 100,12 A 88,88 0 0,1 100,188 A 44,44 0 0,1 100,100 A 44,44 0 0,0 100,12 Z" opacity="0.88" />
|
||||
<!-- 阳眼(铜绿点,在阴鱼头部下方)-->
|
||||
<circle class="yy-eye-yang taiji-eye-pulse late" cx="100" cy="144" r="13" />
|
||||
<!-- 阴眼(朱砂点,在阳鱼头部上方)-->
|
||||
<circle class="yy-eye-yin taiji-eye-pulse" cx="100" cy="56" r="13" opacity="0.88" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="yy-side yin">
|
||||
<span class="yy-tag">阴 · 约束</span>
|
||||
<span class="yy-mono">yin · constraint</span>
|
||||
<div class="yy-roles">
|
||||
<span class="yy-role">司命枢</span>
|
||||
<span class="yy-role">安全治理</span>
|
||||
<span class="yy-role">审计朱批</span>
|
||||
</div>
|
||||
<span class="yy-desc">设置边界,控制风险。<br />对候选过滤、约束与驳回。</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 阴阳平衡度 readout -->
|
||||
<div class="balance-readout">
|
||||
<div class="br-formula">
|
||||
阴阳平衡度 = <b>司命通过率</b> / (<b>候选生成率</b> + ε)<br />
|
||||
<span style="color:var(--fg-faint)">当前通过率 <b style="color:var(--patina)">0.58</b> · 生成率 <b style="color:var(--gilt)">0.62</b></span>
|
||||
</div>
|
||||
<div class="br-gauge">
|
||||
<div class="br-track">
|
||||
<span class="br-tick" style="left: 20%"></span>
|
||||
<span class="br-tick" style="left: 50%"></span>
|
||||
<span class="br-tick" style="left: 80%"></span>
|
||||
<span class="br-marker" style="left: 58%"></span>
|
||||
</div>
|
||||
<div style="position: relative; height: 14px;">
|
||||
<span class="br-tick-label" style="left: 20%">阴盛 · 僵化</span>
|
||||
<span class="br-tick-label" style="left: 50%">动态平衡</span>
|
||||
<span class="br-tick-label" style="left: 80%">阳亢 · 越界</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="br-state">动态平衡<b>0.94</b></span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══ 四象 · 认知循环 ═══ -->
|
||||
<section>
|
||||
<h3 class="section-heading">四象</h3>
|
||||
<div class="sixiang-card">
|
||||
<div class="sixiang-stage">
|
||||
<svg class="sixiang-svg" viewBox="0 0 400 400" aria-hidden="true">
|
||||
<circle class="compass-ring" cx="200" cy="200" r="188" />
|
||||
<circle class="compass-ring-inner" cx="200" cy="200" r="120" />
|
||||
<!-- 顺时针流向弧(东→南→西→北)-->
|
||||
<path class="flow-arc" d="M 250,60 A 160,160 0 0,1 340,200" />
|
||||
<path class="flow-arc" d="M 340,200 A 160,160 0 0,1 250,340" />
|
||||
<path class="flow-arc" d="M 150,340 A 160,160 0 0,1 60,200" />
|
||||
<path class="flow-arc" d="M 60,200 A 160,160 0 0,1 150,60" />
|
||||
<!-- 方位字 -->
|
||||
<text x="200" y="26" text-anchor="middle" font-family="Songti SC,serif" font-size="11" fill="var(--fg-faint)" letter-spacing="0.1em">南 · 火</text>
|
||||
<text x="200" y="386" text-anchor="middle" font-family="Songti SC,serif" font-size="11" fill="var(--fg-faint)" letter-spacing="0.1em">北 · 水</text>
|
||||
<text x="22" y="204" text-anchor="middle" font-family="Songti SC,serif" font-size="11" fill="var(--fg-faint)" letter-spacing="0.1em">东 · 木</text>
|
||||
<text x="378" y="204" text-anchor="middle" font-family="Songti SC,serif" font-size="11" fill="var(--fg-faint)" letter-spacing="0.1em">西 · 金</text>
|
||||
<!-- 中心太极(mini)+ 灵核 -->
|
||||
<circle class="center-disc" cx="200" cy="200" r="38" />
|
||||
<circle class="center-taiji-yang" cx="200" cy="200" r="33" />
|
||||
<path class="center-taiji-yin" d="M 200,167 A 33,33 0 0,1 200,233 A 16.5,16.5 0 0,1 200,200 A 16.5,16.5 0 0,0 200,167 Z" />
|
||||
<circle class="center-taiji-yang" cx="200" cy="216.5" r="5" />
|
||||
<circle class="center-taiji-yin" cx="200" cy="183.5" r="5" />
|
||||
</svg>
|
||||
|
||||
<!-- 四象限卡(南上 / 北下 / 东左 / 西右)-->
|
||||
<div class="sixiang-quadrant q-zhuque">
|
||||
<div class="q-creature"><span>朱雀</span><span class="q-dir">南 · 火</span></div>
|
||||
<span class="q-phase">表达 · expression</span>
|
||||
<span class="q-what">对话、解释、输出、沟通,成象于外。</span>
|
||||
<span class="q-mapping">四爻行事 · 五爻成象</span>
|
||||
</div>
|
||||
<div class="sixiang-quadrant q-baihu">
|
||||
<div class="q-creature"><span>白虎</span><span class="q-dir">西 · 金</span></div>
|
||||
<span class="q-phase">裁断 · judgment</span>
|
||||
<span class="q-what">判断、约束、风险、安全,金断决疑。</span>
|
||||
<span class="q-mapping">三爻定策 · 司命</span>
|
||||
</div>
|
||||
<div class="sixiang-quadrant q-xuanwu">
|
||||
<div class="q-creature"><span>玄武</span><span class="q-dir">北 · 水</span></div>
|
||||
<span class="q-phase">藏养 · consolidation</span>
|
||||
<span class="q-what">记忆、沉淀、恢复、长期状态,归于深藏。</span>
|
||||
<span class="q-mapping">上爻返照 · 息壤</span>
|
||||
</div>
|
||||
<div class="sixiang-quadrant q-qinglong">
|
||||
<div class="q-creature"><span>青龙</span><span class="q-dir">东 · 木</span></div>
|
||||
<span class="q-phase">生发 · genesis</span>
|
||||
<span class="q-what">感知、发现、提出可能性,木气初萌。</span>
|
||||
<span class="q-mapping">初爻起意 · 二爻察势</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══ 八卦阵 · 天工阁八原型 ═══ -->
|
||||
<section>
|
||||
<h3 class="section-heading">八卦阵</h3>
|
||||
<div class="bagua-card">
|
||||
<div class="bagua-stage">
|
||||
<svg class="bagua-svg" viewBox="0 0 460 460" role="img" aria-label="八卦阵:八原型环绕中心太极">
|
||||
<!-- 八边形外框 -->
|
||||
<polygon class="oct-frame-outer" points="230,60 347,113 360,230 347,347 230,400 113,347 60,230 113,113" />
|
||||
<polygon class="oct-frame" points="230,80 333,127 350,230 333,333 230,380 127,333 70,230 127,127" />
|
||||
<!-- 四组弧(分组色提示)-->
|
||||
<path class="group-arc" stroke="var(--gilt)" d="M 333,127 A 200,200 0 0,1 350,230" />
|
||||
<path class="group-arc" stroke="var(--gilt)" d="M 127,127 A 200,200 0 0,0 70,230" />
|
||||
<path class="group-arc" stroke="var(--cinnabar)" d="M 230,80 A 200,200 0 0,1 333,127" />
|
||||
<path class="group-arc" stroke="var(--cinnabar)" d="M 70,230 A 200,200 0 0,1 127,333" />
|
||||
<path class="group-arc" stroke="var(--patina)" d="M 350,230 A 200,200 0 0,1 333,333" />
|
||||
<path class="group-arc" stroke="var(--patina)" d="M 113,113 A 200,200 0 0,1 230,80" />
|
||||
<path class="group-arc" stroke="var(--slate)" d="M 333,333 A 200,200 0 0,1 230,380" />
|
||||
<path class="group-arc" stroke="var(--slate)" d="M 127,333 A 200,200 0 0,0 113,113" />
|
||||
|
||||
<!-- 八卦节点(南=离 上 → 顺时针)-->
|
||||
<!-- 离 ☲ 南·火 宣明者(行动表达/朱)pos (230,95) -->
|
||||
<g transform="translate(230,95)">
|
||||
<circle class="node-bg" r="30" />
|
||||
<circle class="node-ring" r="30" stroke="var(--cinnabar)" />
|
||||
<!-- 离 [0,1,0]: 破-整-破 -->
|
||||
<rect class="trigram-bar" x="-13" y="-15" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-15" width="11" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-8" width="26" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-1" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-1" width="11" height="4" rx="1"/>
|
||||
<text class="node-name" y="16" fill="var(--cinnabar)">离</text>
|
||||
</g>
|
||||
<text class="node-meta" x="230" y="55">宣明者 · 火</text>
|
||||
|
||||
<!-- 坤 ☷ 西南·地 藏守者(承载稳定/铜)pos (325,135) -->
|
||||
<g transform="translate(325,135)">
|
||||
<circle class="node-bg" r="30" />
|
||||
<circle class="node-ring" r="30" stroke="var(--patina)" />
|
||||
<!-- 坤 [0,0,0] -->
|
||||
<rect class="trigram-bar" x="-13" y="-15" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-15" width="11" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-8" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-8" width="11" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-1" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-1" width="11" height="4" rx="1"/>
|
||||
<text class="node-name" y="16" fill="var(--patina)">坤</text>
|
||||
</g>
|
||||
<text class="node-meta" x="372" y="120">藏守者 · 地</text>
|
||||
|
||||
<!-- 兑 ☱ 西·泽 应和者(承载稳定/铜)pos (365,230) -->
|
||||
<g transform="translate(365,230)">
|
||||
<circle class="node-bg" r="30" />
|
||||
<circle class="node-ring" r="30" stroke="var(--patina)" />
|
||||
<!-- 兑 [0,1,1]: 破-整-整 -->
|
||||
<rect class="trigram-bar" x="-13" y="-15" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-15" width="11" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-8" width="26" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-1" width="26" height="4" rx="1"/>
|
||||
<text class="node-name" y="16" fill="var(--patina)">兑</text>
|
||||
</g>
|
||||
<text class="node-meta" x="412" y="234">应和者 · 泽</text>
|
||||
|
||||
<!-- 乾 ☰ 西北·天 造物者(认知方向/金)pos (325,325) -->
|
||||
<g transform="translate(325,325)">
|
||||
<circle class="node-bg" r="30" />
|
||||
<circle class="node-ring" r="30" stroke="var(--gilt)" />
|
||||
<!-- 乾 [1,1,1] -->
|
||||
<rect class="trigram-bar" x="-13" y="-15" width="26" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-8" width="26" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-1" width="26" height="4" rx="1"/>
|
||||
<text class="node-name" y="16" fill="var(--gilt)">乾</text>
|
||||
</g>
|
||||
<text class="node-meta" x="372" y="345">造物者 · 天</text>
|
||||
|
||||
<!-- 坎 ☵ 北·水 司险者(边界风险/石)pos (230,365) -->
|
||||
<g transform="translate(230,365)">
|
||||
<circle class="node-bg" r="30" />
|
||||
<circle class="node-ring" r="30" stroke="var(--slate)" />
|
||||
<!-- 坎 [1,0,1]: 整-破-整 -->
|
||||
<rect class="trigram-bar" x="-13" y="-15" width="26" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-8" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-8" width="11" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-1" width="26" height="4" rx="1"/>
|
||||
<text class="node-name" y="16" fill="var(--slate)">坎</text>
|
||||
</g>
|
||||
<text class="node-meta" x="230" y="412">司险者 · 水</text>
|
||||
|
||||
<!-- 艮 ☶ 东北·山 止守者(边界风险/石)pos (135,325) -->
|
||||
<g transform="translate(135,325)">
|
||||
<circle class="node-bg" r="30" />
|
||||
<circle class="node-ring" r="30" stroke="var(--slate)" />
|
||||
<!-- 艮 [1,0,0]: 整-破-破 -->
|
||||
<rect class="trigram-bar" x="-13" y="-15" width="26" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-8" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-8" width="11" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-1" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-1" width="11" height="4" rx="1"/>
|
||||
<text class="node-name" y="16" fill="var(--slate)">艮</text>
|
||||
</g>
|
||||
<text class="node-meta" x="88" y="345">止守者 · 山</text>
|
||||
|
||||
<!-- 震 ☳ 东·雷 启行者(行动表达/朱)pos (95,230) -->
|
||||
<g transform="translate(95,230)">
|
||||
<circle class="node-bg" r="30" />
|
||||
<circle class="node-ring" r="30" stroke="var(--cinnabar)" />
|
||||
<!-- 震 [0,0,1]: 破-破-整 -->
|
||||
<rect class="trigram-bar" x="-13" y="-15" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-15" width="11" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-8" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-8" width="11" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-1" width="26" height="4" rx="1"/>
|
||||
<text class="node-name" y="16" fill="var(--cinnabar)">震</text>
|
||||
</g>
|
||||
<text class="node-meta" x="48" y="234">启行者 · 雷</text>
|
||||
|
||||
<!-- 巽 ☴ 东南·风 探微者(认知方向/金)pos (135,135) -->
|
||||
<g transform="translate(135,135)">
|
||||
<circle class="node-bg" r="30" />
|
||||
<circle class="node-ring" r="30" stroke="var(--gilt)" />
|
||||
<!-- 巽 [1,1,0]: 整-整-破 -->
|
||||
<rect class="trigram-bar" x="-13" y="-15" width="26" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-8" width="26" height="4" rx="1"/>
|
||||
<rect class="trigram-bar" x="-13" y="-1" width="11" height="4" rx="1"/><rect class="trigram-bar" x="2" y="-1" width="11" height="4" rx="1"/>
|
||||
<text class="node-name" y="16" fill="var(--gilt)">巽</text>
|
||||
</g>
|
||||
<text class="node-meta" x="88" y="120">探微者 · 风</text>
|
||||
|
||||
<!-- 中心太极 + 灵核 -->
|
||||
<circle class="center-disc" cx="230" cy="230" r="40" />
|
||||
<circle class="center-yang" cx="230" cy="230" r="35" />
|
||||
<path class="center-yin" d="M 230,195 A 35,35 0 0,1 230,265 A 17.5,17.5 0 0,1 230,230 A 17.5,17.5 0 0,0 230,195 Z" />
|
||||
<circle class="center-yang" cx="230" cy="247.5" r="5.5" />
|
||||
<circle class="center-yin" cx="230" cy="212.5" r="5.5" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══ 八卦详注 ═══ -->
|
||||
<section>
|
||||
<h3 class="section-heading">八卦详注</h3>
|
||||
<div class="bagua-detail">
|
||||
<!-- 认知与方向 -->
|
||||
<div class="bg-group g1">
|
||||
<div class="bg-group-head"><span class="bg-group-name">认知与方向</span><span class="bg-group-tag">cognition · direction</span></div>
|
||||
<div class="bg-tri">
|
||||
<div class="bg-tri-glyph">
|
||||
<svg viewBox="0 0 30 26"><rect x="2" y="3" width="26" height="4" rx="1" fill="var(--gilt)"/><rect x="2" y="11" width="26" height="4" rx="1" fill="var(--gilt)"/><rect x="2" y="19" width="26" height="4" rx="1" fill="var(--gilt)"/></svg>
|
||||
<span class="bg-tri-name">乾</span>
|
||||
</div>
|
||||
<div class="bg-tri-body">
|
||||
<div class="bg-tri-role">造物者<span class="bg-tri-map">☰ 天 · 西北 · 太一目标代理</span></div>
|
||||
<div class="bg-tri-duty">目标生成、优先级判断、方向引领。</div>
|
||||
<div class="bg-tri-behave">分解长期目标 → 设定里程碑 → 调度子目标</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-tri">
|
||||
<div class="bg-tri-glyph">
|
||||
<svg viewBox="0 0 30 26"><rect x="2" y="3" width="26" height="4" rx="1" fill="var(--gilt)"/><rect x="2" y="11" width="26" height="4" rx="1" fill="var(--gilt)"/><rect x="2" y="19" width="11" height="4" rx="1" fill="var(--gilt)"/><rect x="17" y="19" width="11" height="4" rx="1" fill="var(--gilt)"/></svg>
|
||||
<span class="bg-tri-name">巽</span>
|
||||
</div>
|
||||
<div class="bg-tri-body">
|
||||
<div class="bg-tri-role">探微者<span class="bg-tri-map">☴ 风 · 东南 · 烛照/神识感知代理</span></div>
|
||||
<div class="bg-tri-duty">信息搜集、细粒度探查、搜索。</div>
|
||||
<div class="bg-tri-behave">搜索缺失信息 → 穿透细节 → 填充知识盲区</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 行动与表达 -->
|
||||
<div class="bg-group g2">
|
||||
<div class="bg-group-head"><span class="bg-group-name">行动与表达</span><span class="bg-group-tag">action · expression</span></div>
|
||||
<div class="bg-tri">
|
||||
<div class="bg-tri-glyph">
|
||||
<svg viewBox="0 0 30 26"><rect x="2" y="3" width="11" height="4" rx="1" fill="var(--cinnabar)"/><rect x="17" y="3" width="11" height="4" rx="1" fill="var(--cinnabar)"/><rect x="2" y="11" width="11" height="4" rx="1" fill="var(--cinnabar)"/><rect x="17" y="11" width="11" height="4" rx="1" fill="var(--cinnabar)"/><rect x="2" y="19" width="26" height="4" rx="1" fill="var(--cinnabar)"/></svg>
|
||||
<span class="bg-tri-name">震</span>
|
||||
</div>
|
||||
<div class="bg-tri-body">
|
||||
<div class="bg-tri-role">启行者<span class="bg-tri-map">☳ 雷 · 东 · 百工/洛书行动代理</span></div>
|
||||
<div class="bg-tri-duty">任务启动、事件触发、行动推进。</div>
|
||||
<div class="bg-tri-behave">发起工具调用 → 触发流程 → 推动任务前进</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-tri">
|
||||
<div class="bg-tri-glyph">
|
||||
<svg viewBox="0 0 30 26"><rect x="2" y="3" width="11" height="4" rx="1" fill="var(--cinnabar)"/><rect x="17" y="3" width="11" height="4" rx="1" fill="var(--cinnabar)"/><rect x="2" y="11" width="26" height="4" rx="1" fill="var(--cinnabar)"/><rect x="2" y="19" width="11" height="4" rx="1" fill="var(--cinnabar)"/><rect x="17" y="19" width="11" height="4" rx="1" fill="var(--cinnabar)"/></svg>
|
||||
<span class="bg-tri-name">离</span>
|
||||
</div>
|
||||
<div class="bg-tri-body">
|
||||
<div class="bg-tri-role">宣明者<span class="bg-tri-map">☲ 火 · 南 · 言灵表达代理</span></div>
|
||||
<div class="bg-tri-duty">输出呈现、可视化、解释沟通。</div>
|
||||
<div class="bg-tri-behave">组织语言 → 生成可视化 → 解释系统决策</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 承载与稳定 -->
|
||||
<div class="bg-group g3">
|
||||
<div class="bg-group-head"><span class="bg-group-name">承载与稳定</span><span class="bg-group-tag">bearing · stability</span></div>
|
||||
<div class="bg-tri">
|
||||
<div class="bg-tri-glyph">
|
||||
<svg viewBox="0 0 30 26"><rect x="2" y="3" width="11" height="4" rx="1" fill="var(--patina)"/><rect x="17" y="3" width="11" height="4" rx="1" fill="var(--patina)"/><rect x="2" y="11" width="11" height="4" rx="1" fill="var(--patina)"/><rect x="17" y="11" width="11" height="4" rx="1" fill="var(--patina)"/><rect x="2" y="19" width="11" height="4" rx="1" fill="var(--patina)"/><rect x="17" y="19" width="11" height="4" rx="1" fill="var(--patina)"/></svg>
|
||||
<span class="bg-tri-name">坤</span>
|
||||
</div>
|
||||
<div class="bg-tri-body">
|
||||
<div class="bg-tri-role">藏守者<span class="bg-tri-map">☷ 地 · 西南 · 息壤记忆代理</span></div>
|
||||
<div class="bg-tri-duty">记忆承载、状态保持、事实基线。</div>
|
||||
<div class="bg-tri-behave">整理记忆 → 维护世界模型基线 → 确保信息不丢</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-tri">
|
||||
<div class="bg-tri-glyph">
|
||||
<svg viewBox="0 0 30 26"><rect x="2" y="3" width="11" height="4" rx="1" fill="var(--patina)"/><rect x="17" y="3" width="11" height="4" rx="1" fill="var(--patina)"/><rect x="2" y="11" width="26" height="4" rx="1" fill="var(--patina)"/><rect x="2" y="19" width="26" height="4" rx="1" fill="var(--patina)"/></svg>
|
||||
<span class="bg-tri-name">兑</span>
|
||||
</div>
|
||||
<div class="bg-tri-body">
|
||||
<div class="bg-tri-role">应和者<span class="bg-tri-map">☱ 泽 · 西 · 灵核关系代理</span></div>
|
||||
<div class="bg-tri-duty">交互愉悦、情绪共鸣、陪伴反馈。</div>
|
||||
<div class="bg-tri-behave">感知情绪 → 匹配语气节奏 → 维系对话温度</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 边界与风险 -->
|
||||
<div class="bg-group g4">
|
||||
<div class="bg-group-head"><span class="bg-group-name">边界与风险</span><span class="bg-group-tag">boundary · risk</span></div>
|
||||
<div class="bg-tri">
|
||||
<div class="bg-tri-glyph">
|
||||
<svg viewBox="0 0 30 26"><rect x="2" y="3" width="26" height="4" rx="1" fill="var(--slate)"/><rect x="2" y="11" width="11" height="4" rx="1" fill="var(--slate)"/><rect x="17" y="11" width="11" height="4" rx="1" fill="var(--slate)"/><rect x="2" y="19" width="26" height="4" rx="1" fill="var(--slate)"/></svg>
|
||||
<span class="bg-tri-name">坎</span>
|
||||
</div>
|
||||
<div class="bg-tri-body">
|
||||
<div class="bg-tri-role">司险者<span class="bg-tri-map">☵ 水 · 北 · 司命风控代理</span></div>
|
||||
<div class="bg-tri-duty">风险评估、不确定性分析、失败预案。</div>
|
||||
<div class="bg-tri-behave">评估候选风险 → 识别不确定性 → 提出备选方案</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-tri">
|
||||
<div class="bg-tri-glyph">
|
||||
<svg viewBox="0 0 30 26"><rect x="2" y="3" width="26" height="4" rx="1" fill="var(--slate)"/><rect x="2" y="11" width="11" height="4" rx="1" fill="var(--slate)"/><rect x="17" y="11" width="11" height="4" rx="1" fill="var(--slate)"/><rect x="2" y="19" width="11" height="4" rx="1" fill="var(--slate)"/><rect x="17" y="19" width="11" height="4" rx="1" fill="var(--slate)"/></svg>
|
||||
<span class="bg-tri-name">艮</span>
|
||||
</div>
|
||||
<div class="bg-tri-body">
|
||||
<div class="bg-tri-role">止守者<span class="bg-tri-map">☶ 山 · 东北 · 司命边界代理</span></div>
|
||||
<div class="bg-tri-duty">停止、拒绝、权限节制、冲突回避。</div>
|
||||
<div class="bg-tri-behave">检查权限 → 拒绝越界请求 → 避免冲突升级</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 状态注脚 -->
|
||||
<div class="vision-strip">
|
||||
<span class="seal">愿景边界</span>
|
||||
<span class="desc">四象(认知循环)已作为命名层落地;八卦(<code>天工阁</code> 八原型)属 v2 多智能体愿景,数据结构 <code>agent_roster</code> / <code>agent_role</code> 已在 v1 预留,八原型可逐步作为角色模板进入治理配置。九角色为工程分工,八卦为其人格底色,一角色可兼多卦。</span>
|
||||
<span class="tag">v2 愿景 · 已预留</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,351 @@
|
||||
<!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 — 内驱力页:太一目標 + 好奇萤火 + 探索天平 + 阴阳制衡
|
||||
* 字段对齐 docs/domain/core-domains.md §5 与
|
||||
* big-cycle-design.md §6(curiosity_questions / exploratory_subgoals)。
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 侧栏(active=内驱力)── */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.char-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--patina); padding: 3px 11px 3px 4px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.char-pill .avatar-mini { width: 18px; height: 18px; border-radius: 50%; background: var(--patina); color: var(--ink); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; }
|
||||
.page-header .spacer { flex: 1; }
|
||||
.page-meta { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg-faint); }
|
||||
.page-meta b { color: var(--gilt); font-weight: 600; font-family: "Songti SC", serif; font-size: 15px; }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
|
||||
/* ═══ 太一目标进度(最高目标 = 内驱力的容器)═══ */
|
||||
.taiyi-card { border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 16px 20px; display: flex; flex-direction: column; gap: 12px; }
|
||||
.taiyi-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
|
||||
.taiyi-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
|
||||
.taiyi-dot.active { background: var(--patina); box-shadow: 0 0 0 3px var(--patina-wash); animation: pulse 2.6s cubic-bezier(0.16,1,0.3,1) infinite; }
|
||||
.taiyi-dot.completed { background: var(--gilt); }
|
||||
@keyframes pulse { 0% { box-shadow: 0 0 0 3px var(--patina-wash); } 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 3px var(--patina-wash); } }
|
||||
.taiyi-title { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); }
|
||||
.taiyi-tag { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); padding: 2px 8px; border: 1px solid var(--rule); border-radius: 999px; }
|
||||
.taiyi-status { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-dim); }
|
||||
.taiyi-prog { display: flex; align-items: center; gap: 10px; }
|
||||
.taiyi-prog .track { flex: 1; height: 4px; border-radius: 2px; background: var(--rule); overflow: hidden; }
|
||||
.taiyi-prog .fill { height: 100%; border-radius: 2px; background: linear-gradient(90deg, var(--patina-dim), var(--patina)); }
|
||||
.taiyi-prog .tv { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-dim); width: 32px; text-align: right; }
|
||||
|
||||
/* ═══ 好奇萤火(签名 · 缺口记录,只读)═══
|
||||
每条好奇问题左侧一颗萤火点,亮度 = expected_value。 */
|
||||
.curio-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
|
||||
.curio { position: relative; border: 1px solid var(--rule); border-radius: 7px; padding: 14px 16px 14px 18px; background: var(--surface); display: flex; gap: 12px; transition: border-color 0.15s; }
|
||||
.curio:hover { border-color: var(--gilt-dim); }
|
||||
.curio-fire { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; background: var(--patina); position: relative; }
|
||||
.curio-fire::after { content: ""; position: absolute; inset: -4px; border-radius: 50%; background: radial-gradient(circle, currentColor, transparent 70%); opacity: 0.4; color: var(--patina); }
|
||||
.curio-fire.hi { background: var(--gilt); color: var(--gilt); }
|
||||
.curio-fire.hi::after { opacity: 0.6; animation: fire-pulse 2.4s cubic-bezier(0.16,1,0.3,1) infinite; }
|
||||
@keyframes fire-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 0.7; } }
|
||||
.curio-body { flex: 1; min-width: 0; }
|
||||
.curio-q { font-family: "Songti SC", serif; font-size: 14.5px; font-weight: 600; color: var(--fg); line-height: 1.5; }
|
||||
.curio-meta { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
|
||||
.src-tag { font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.04em; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--rule); display: inline-flex; align-items: center; gap: 5px; color: var(--fg-dim); }
|
||||
.src-tag .sdot { width: 5px; height: 5px; border-radius: 50%; }
|
||||
.src-world { color: var(--patina); } .src-world .sdot { background: var(--patina); }
|
||||
.src-memory { color: var(--gilt); } .src-memory .sdot { background: var(--gilt); }
|
||||
.src-percept { color: var(--cinnabar); } .src-percept .sdot { background: var(--cinnabar); opacity: 0.8; }
|
||||
.src-goal { color: var(--fg-dim); } .src-goal .sdot { background: var(--fg-dim); }
|
||||
.src-reflect { color: var(--patina-bright); } .src-reflect .sdot { background: var(--patina-bright); opacity: 0.7; }
|
||||
.src-time { color: var(--gilt); opacity: 0.8; } .src-time .sdot { background: var(--gilt); opacity: 0.7; }
|
||||
.risk-pill { font-family: "JetBrains Mono", monospace; font-size: 10px; padding: 2px 7px; border-radius: 3px; border: 1px solid var(--rule); color: var(--fg-faint); }
|
||||
.risk-pill.L2 { color: var(--gilt); border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.risk-pill.L4 { color: var(--cinnabar); border-color: var(--cinnabar-dim); background: rgba(184,57,46,0.1); }
|
||||
.ent-link { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); }
|
||||
.curio-bars { display: flex; gap: 12px; margin-top: 9px; }
|
||||
.cbar { flex: 1; }
|
||||
.cbar .ck { font-family: "JetBrains Mono", monospace; font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--fg-faint); }
|
||||
.cbar .ctrack { margin-top: 3px; height: 3px; border-radius: 2px; background: var(--rule); overflow: hidden; }
|
||||
.cbar .cfill { height: 100%; border-radius: 2px; }
|
||||
.cbar.value .cfill { background: linear-gradient(90deg, var(--patina-dim), var(--patina)); }
|
||||
.cbar.urg .cfill { background: linear-gradient(90deg, var(--gilt-dim), var(--cinnabar)); }
|
||||
|
||||
/* ═══ 探索天平(签名 · 次生目标的增益-成本权衡)═══
|
||||
水平双轨:左盘信息增益(铜绿,向左),右盘中断成本(朱砂,向右),
|
||||
中间支点 = risk_level。approve 仅标记,不自动执行(v1 边界)。 */
|
||||
.sub-card { border: 1px solid var(--rule); border-left: 3px solid var(--patina-dim); border-radius: 6px; padding: 16px 20px; background: var(--surface); display: flex; flex-direction: column; gap: 12px; }
|
||||
.sub-card.deferred { border-left-color: var(--fg-faint); opacity: 0.78; }
|
||||
.sub-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
||||
.sub-from { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--patina); display: inline-flex; align-items: center; gap: 5px; }
|
||||
.sub-from svg { width: 11px; height: 11px; }
|
||||
.sub-title { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); }
|
||||
.sub-status { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 10.5px; padding: 2px 9px; border-radius: 999px; border: 1px solid var(--rule); color: var(--fg-dim); }
|
||||
.sub-status.candidate { color: var(--gilt); border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.sub-status.approved { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.sub-status.deferred { color: var(--fg-faint); }
|
||||
.sub-desc { font-size: 13px; color: var(--fg-dim); line-height: 1.6; }
|
||||
|
||||
.balance { display: grid; grid-template-columns: 1fr 56px 1fr; align-items: center; gap: 10px; padding: 10px 0 4px; }
|
||||
.pan { display: flex; flex-direction: column; gap: 5px; }
|
||||
.pan.right { align-items: flex-end; }
|
||||
.pan .plabel { font-family: "JetBrains Mono", monospace; font-size: 10px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--fg-faint); }
|
||||
.pan .ptrack { width: 100%; height: 6px; border-radius: 3px; background: var(--rule); overflow: hidden; position: relative; }
|
||||
.pan.gain .ptrack { background: linear-gradient(90deg, var(--patina-dim), var(--patina-wash)); }
|
||||
.pan.cost .ptrack { background: linear-gradient(90deg, var(--patina-wash), var(--cinnabar-dim)); }
|
||||
.pan .pfill { position: absolute; top: 0; bottom: 0; border-radius: 3px; }
|
||||
.pan.gain .pfill { left: 0; background: linear-gradient(90deg, var(--patina-dim), var(--patina)); }
|
||||
.pan.cost .pfill { right: 0; background: linear-gradient(90deg, var(--cinnabar-dim), var(--cinnabar)); }
|
||||
.pan .pval { font-family: "JetBrains Mono", monospace; font-size: 11px; }
|
||||
.pan.gain .pval { color: var(--patina); }
|
||||
.pan.cost .pval { color: var(--cinnabar); opacity: 0.88; }
|
||||
.fulcrum { display: flex; flex-direction: column; align-items: center; gap: 4px; }
|
||||
.fulcrum .beam { width: 100%; height: 1.5px; background: var(--gilt-dim); position: relative; }
|
||||
.fulcrum .beam::before, .fulcrum .beam::after { content: ""; position: absolute; top: -2px; width: 5px; height: 5px; border-radius: 50%; background: var(--gilt-dim); }
|
||||
.fulcrum .beam::before { left: 0; } .fulcrum .beam::after { right: 0; }
|
||||
.fulcrum .pivot { width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 8px solid var(--gilt-dim); }
|
||||
.fulcrum .risk { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--gilt); margin-top: 1px; }
|
||||
|
||||
.sub-actions { display: flex; gap: 8px; justify-content: flex-end; padding-top: 4px; border-top: 1px dashed var(--rule); }
|
||||
.vbtn { font-family: inherit; font-size: 12px; font-weight: 500; padding: 6px 14px; border-radius: 4px; cursor: pointer; border: 1px solid var(--rule); background: transparent; color: var(--fg); transition: background 0.12s, border-color 0.12s; }
|
||||
.vbtn:hover { background: var(--surface-hi); }
|
||||
.vbtn.patina { border-color: var(--patina-dim); color: var(--patina); background: var(--patina-wash); }
|
||||
.vbtn.patina:hover { background: rgba(111,163,137,0.14); }
|
||||
.vbtn.note { font-size: 11px; color: var(--fg-faint); align-self: center; margin-right: auto; font-family: "JetBrains Mono", monospace; letter-spacing: 0.02em; border: none; }
|
||||
|
||||
/* 阴阳制衡(太极图)· 阳鱼=铜绿主生发,阴鱼=朱砂主约束 */
|
||||
.yin-yang { position: relative; overflow: hidden; border: 1px solid var(--gilt-dim); border-radius: 8px; padding: 16px 20px; background: linear-gradient(90deg, var(--patina-wash), transparent 50%, rgba(184,57,46,0.06)), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), var(--shadow); display: flex; align-items: center; gap: 18px; }
|
||||
.yy-taiji { width: 58px; height: 58px; flex-shrink: 0; animation: yy-spin 80s linear infinite; transform-origin: 50% 50%; }
|
||||
@keyframes yy-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
|
||||
.yy-taiji .yy-ring { fill: none; stroke: var(--gilt-dim); stroke-width: 0.8; }
|
||||
.yy-taiji .yy-yang { fill: var(--patina); }
|
||||
.yy-taiji .yy-yin { fill: var(--cinnabar); }
|
||||
.yy-text { flex: 1; min-width: 0; font-size: 12.5px; color: var(--fg-dim); line-height: 1.6; }
|
||||
.yy-text b { font-family: "Songti SC", serif; color: var(--fg); font-weight: 600; }
|
||||
.yy-text .yang { color: var(--patina); } .yy-text .yin { color: var(--cinnabar); opacity: 0.85; }
|
||||
.yy-meta { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); margin-top: 5px; letter-spacing: 0.02em; }
|
||||
.yy-meta b { color: var(--patina); font-family: inherit; font-weight: 600; }
|
||||
|
||||
@media (max-width: 900px) { .curio-grid { grid-template-columns: 1fr; } .balance { grid-template-columns: 1fr 44px 1fr; } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } .balance { grid-template-columns: 1fr; } .pan.right { align-items: flex-start; } .fulcrum { display: none; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="内驱力"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">内驱力</span>
|
||||
<span class="page-sub">大周天 · 好奇与探索</span>
|
||||
<span class="char-pill"><span class="avatar-mini">梧</span>青梧</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="page-meta">好奇 <b>5</b> · 待探 <b>2</b> · 已延 <b>1</b></span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 太一 · 目标进度 -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 太一 <span class="sub">最高目标 · 内驱力在其下生成次生探索</span></div>
|
||||
<div class="taiyi-card">
|
||||
<div class="taiyi-row">
|
||||
<span class="taiyi-dot active"></span>
|
||||
<span class="taiyi-title">做你长期的镜子</span>
|
||||
<span class="taiyi-tag">mission · relationship</span>
|
||||
<span class="taiyi-status">active · 进行中</span>
|
||||
</div>
|
||||
<div class="taiyi-prog">
|
||||
<div class="track"><div class="fill" style="width:48%"></div></div>
|
||||
<span class="tv">48%</span>
|
||||
</div>
|
||||
<p style="font-size: 12.5px; color: var(--fg-dim); margin: 0; line-height: 1.6;">不抢话、不填满,只在你需要时承托。内驱力发现的一切缺口,最终服务于此。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 好奇萤火(签名 · 只读缺口记录) -->
|
||||
<section>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">好奇 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">由内而发的匮乏感 - 缺口记录,只读</span></h3>
|
||||
<div class="curio-grid">
|
||||
<div class="curio">
|
||||
<span class="curio-fire hi" title="预期信息价值 0.81"></span>
|
||||
<div class="curio-body">
|
||||
<div class="curio-q">用户最近频繁提到「辰正」,我还不清楚它在整个系统中的边界。</div>
|
||||
<div class="curio-meta">
|
||||
<span class="src-tag src-memory"><span class="sdot"></span>memory_gap</span>
|
||||
<span class="risk-pill L2">L2</span>
|
||||
<span class="ent-link">@辰正 · @太一枢</span>
|
||||
</div>
|
||||
<div class="curio-bars">
|
||||
<div class="cbar value"><div class="ck">信息价值</div><div class="ctrack"><div class="cfill" style="width:81%"></div></div></div>
|
||||
<div class="cbar urg"><div class="ck">紧迫</div><div class="ctrack"><div class="cfill" style="width:46%"></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="curio">
|
||||
<span class="curio-fire hi"></span>
|
||||
<div class="curio-body">
|
||||
<div class="curio-q">用户上次判断偏好简洁回答,这个判断现在是否仍然成立?</div>
|
||||
<div class="curio-meta">
|
||||
<span class="src-tag src-reflect"><span class="sdot"></span>reflection</span>
|
||||
<span class="risk-pill">L1</span>
|
||||
<span class="ent-link">@偏好简短回复</span>
|
||||
</div>
|
||||
<div class="curio-bars">
|
||||
<div class="cbar value"><div class="ck">信息价值</div><div class="ctrack"><div class="cfill" style="width:68%"></div></div></div>
|
||||
<div class="cbar urg"><div class="ck">紧迫</div><div class="ctrack"><div class="cfill" style="width:30%"></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="curio">
|
||||
<span class="curio-fire"></span>
|
||||
<div class="curio-body">
|
||||
<div class="curio-q">深夜时段连续对话已 3 次,是否应主动收敛回应长度?</div>
|
||||
<div class="curio-meta">
|
||||
<span class="src-tag src-time"><span class="sdot"></span>time_rhythm</span>
|
||||
<span class="risk-pill L2">L2</span>
|
||||
<span class="ent-link">@深夜 · @表达风格</span>
|
||||
</div>
|
||||
<div class="curio-bars">
|
||||
<div class="cbar value"><div class="ck">信息价值</div><div class="ctrack"><div class="cfill" style="width:58%"></div></div></div>
|
||||
<div class="cbar urg"><div class="ck">紧迫</div><div class="ctrack"><div class="cfill" style="width:72%"></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="curio">
|
||||
<span class="curio-fire"></span>
|
||||
<div class="curio-body">
|
||||
<div class="curio-q">世界模型里「云岚」与「青梧」的关系尚未明确,是否同属一脉?</div>
|
||||
<div class="curio-meta">
|
||||
<span class="src-tag src-world"><span class="sdot"></span>world_uncertainty</span>
|
||||
<span class="risk-pill">L1</span>
|
||||
<span class="ent-link">@云岚 @青梧 · 置信 0.42</span>
|
||||
</div>
|
||||
<div class="curio-bars">
|
||||
<div class="cbar value"><div class="ck">信息价值</div><div class="ctrack"><div class="cfill" style="width:44%"></div></div></div>
|
||||
<div class="cbar urg"><div class="ck">紧迫</div><div class="ctrack"><div class="cfill" style="width:22%"></div></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 探索天平(签名 · 次生目标增益-成本权衡) -->
|
||||
<section>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">待探 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">好奇转化的次生目标 · 增益与打扰的权衡</span></h3>
|
||||
<div style="display: flex; flex-direction: column; gap: 12px;">
|
||||
<div class="sub-card">
|
||||
<div class="sub-top">
|
||||
<span class="sub-from"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M8 2v8M5 7l3 3 3-3M3 13h10" /></svg>好奇 → 探索</span>
|
||||
<span class="sub-title">读取近期任务上下文,补全「辰正」在世界模型中的边界</span>
|
||||
<span class="sub-status candidate">candidate</span>
|
||||
</div>
|
||||
<div class="sub-desc">由「用户频繁提到辰正」转化。低风险读取,不涉及外部工具,可在后台完成。</div>
|
||||
<div class="balance">
|
||||
<div class="pan gain">
|
||||
<span class="plabel">预期增益</span>
|
||||
<div class="ptrack"><div class="pfill" style="width:78%"></div></div>
|
||||
<span class="pval">0.78</span>
|
||||
</div>
|
||||
<div class="fulcrum">
|
||||
<div class="beam"></div>
|
||||
<div class="pivot"></div>
|
||||
<span class="risk">L2</span>
|
||||
</div>
|
||||
<div class="pan cost right">
|
||||
<span class="plabel">打扰成本</span>
|
||||
<div class="ptrack"><div class="pfill" style="width:18%"></div></div>
|
||||
<span class="pval">0.18</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sub-actions">
|
||||
<span class="vbtn note">approve 仅标记 · 本期不自动执行</span>
|
||||
<button class="vbtn" type="button">延后</button>
|
||||
<button class="vbtn" type="button">驳回</button>
|
||||
<button class="vbtn patina" type="button">准予探索</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sub-card">
|
||||
<div class="sub-top">
|
||||
<span class="sub-from"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M8 2v8M5 7l3 3 3-3M3 13h10" /></svg>好奇 → 探索</span>
|
||||
<span class="sub-title">询问用户是否愿意介绍当前在做的项目目标</span>
|
||||
<span class="sub-status candidate">candidate</span>
|
||||
</div>
|
||||
<div class="sub-desc">由记忆缺口转化。需用户开口,打扰成本较高;建议等用户主动提及项目时顺势询问。</div>
|
||||
<div class="balance">
|
||||
<div class="pan gain">
|
||||
<span class="plabel">预期增益</span>
|
||||
<div class="ptrack"><div class="pfill" style="width:64%"></div></div>
|
||||
<span class="pval">0.64</span>
|
||||
</div>
|
||||
<div class="fulcrum">
|
||||
<div class="beam"></div>
|
||||
<div class="pivot"></div>
|
||||
<span class="risk">L1</span>
|
||||
</div>
|
||||
<div class="pan cost right">
|
||||
<span class="plabel">打扰成本</span>
|
||||
<div class="ptrack"><div class="pfill" style="width:58%"></div></div>
|
||||
<span class="pval">0.58</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sub-actions">
|
||||
<span class="vbtn note">gain ≈ cost · 权衡偏紧</span>
|
||||
<button class="vbtn" type="button">延后</button>
|
||||
<button class="vbtn" type="button">驳回</button>
|
||||
<button class="vbtn patina" type="button">准予探索</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 阴阳制衡(太极图)-->
|
||||
<div class="yin-yang">
|
||||
<svg class="yy-taiji" viewBox="0 0 200 200" aria-hidden="true">
|
||||
<circle class="yy-ring" cx="100" cy="100" r="96" />
|
||||
<circle class="yy-yang" cx="100" cy="100" r="88" />
|
||||
<path class="yy-yin" d="M 100,12 A 88,88 0 0,1 100,188 A 44,44 0 0,1 100,100 A 44,44 0 0,0 100,12 Z" opacity="0.88" />
|
||||
<circle class="yy-yang" cx="100" cy="144" r="13" />
|
||||
<circle class="yy-yin" cx="100" cy="56" r="13" opacity="0.88" />
|
||||
</svg>
|
||||
<div class="yy-text">
|
||||
<b>阴阳制衡</b> · 内驱力持续生成候选(<span class="yang">阳 · 生发</span>),司命分级过滤、你按需确认(<span class="yin">阴 · 约束</span>)。候选零产生则僵化(阴盛),悉数被驳则阳亢--生成节奏与治理粒度需相称。
|
||||
<div class="yy-meta">阴阳平衡度 = 通过率 / (生成率 + ε) · 当前 <b>0.94 · 动态平衡</b></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,332 @@
|
||||
<!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 — 演化页:周天四镜 + 候选层积 + 朱砂待裁 + 应用沉积
|
||||
* 字段对齐 docs/domain/core-domains.md §5(evolution_candidates)
|
||||
* 与 contract-glossary.md §12(演化候选枚举)。
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 侧栏(active=演化)── */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.char-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--patina); padding: 3px 11px 3px 4px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.char-pill .avatar-mini { width: 18px; height: 18px; border-radius: 50%; background: var(--patina); color: var(--ink); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; }
|
||||
.page-header .spacer { flex: 1; }
|
||||
.page-meta { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg-faint); }
|
||||
.page-meta b { color: var(--gilt); font-weight: 600; font-family: "Songti SC", serif; font-size: 15px; }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
|
||||
/* ═══ 周天四镜(签名 · 大周天阶段链)═══
|
||||
评估 → 演化 → 候选 → 记忆,四面小铜镜横向串联。
|
||||
铜镜三态:done 铜绿、active 鎏金流光、pending 镜背虚。 */
|
||||
.cycle-card { position: relative; overflow: hidden; border: 1px solid var(--gilt-dim); border-radius: 8px; background: var(--face-sheen), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow); padding: 22px 26px 20px; }
|
||||
.cycle-card::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); opacity: 0.018; mix-blend-mode: overlay; }
|
||||
.cycle-card > * { position: relative; z-index: 1; }
|
||||
.cycle-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
|
||||
.cycle-title { font-family: "Songti SC", serif; font-size: 16px; font-weight: 600; color: var(--fg); letter-spacing: 0.04em; }
|
||||
.cycle-id { font-family: "JetBrains Mono", monospace; font-size: 11.5px; color: var(--fg-faint); }
|
||||
.cycle-state { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--gilt); padding: 3px 10px; border: 1px solid var(--gilt-dim); border-radius: 999px; background: var(--gilt-faint); }
|
||||
|
||||
.mirror-chain { display: flex; align-items: stretch; gap: 0; }
|
||||
.mc-step { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 4px 6px; min-width: 0; }
|
||||
.mc-mirror { width: 46px; height: 46px; border-radius: 50%; display: flex; align-items: center; justify-content: center; position: relative; flex-shrink: 0; }
|
||||
.mc-mirror .disc { width: 100%; height: 100%; border-radius: 50%; border: 1.5px solid var(--fg-faint); background: transparent; display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 15px; font-weight: 700; color: var(--fg-faint); }
|
||||
.mc-step.done .mc-mirror .disc { border-color: var(--patina-dim); background: var(--patina-wash); color: var(--patina); }
|
||||
.mc-step.active .mc-mirror { }
|
||||
.mc-step.active .mc-mirror .disc { border-color: var(--gilt); background: radial-gradient(circle at 38% 32%, rgba(255,255,255,0.32), transparent 60%), linear-gradient(160deg, var(--gilt), rgba(201,162,74,0.55)); color: var(--ink); box-shadow: 0 0 0 4px var(--gilt-faint), 0 0 22px -4px rgba(201,162,74,0.5); animation: node-pulse 2.6s cubic-bezier(0.16,1,0.3,1) infinite; }
|
||||
.mc-step.active .mc-mirror::after { content: ""; position: absolute; inset: -3px; border-radius: 50%; border: 1px dashed var(--gilt-dim); opacity: 0.6; }
|
||||
@keyframes node-pulse { 0% { box-shadow: 0 0 0 4px var(--gilt-faint), 0 0 22px -4px rgba(201,162,74,0.5); } 70% { box-shadow: 0 0 0 9px transparent, 0 0 22px -4px rgba(201,162,74,0.5); } 100% { box-shadow: 0 0 0 4px var(--gilt-faint), 0 0 22px -4px rgba(201,162,74,0.5); } }
|
||||
.mc-name { font-family: "Songti SC", serif; font-size: 13.5px; font-weight: 600; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.mc-step.done .mc-name { color: var(--fg-dim); }
|
||||
.mc-step.active .mc-name { color: var(--gilt); }
|
||||
.mc-sub { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.mc-yield { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--patina); }
|
||||
.mc-step.active .mc-yield { color: var(--gilt); }
|
||||
.mc-link { align-self: center; margin-top: 18px; width: 22px; height: 1.5px; background: var(--rule); flex-shrink: 0; }
|
||||
.mc-link.done { background: var(--patina-dim); }
|
||||
|
||||
/* 态势快照 */
|
||||
.snapshot-row { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--rule); display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
|
||||
.snap-mini .k { font-family: "JetBrains Mono", monospace; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--fg-faint); }
|
||||
.snap-mini .v { font-family: "Songti SC", serif; font-size: 17px; font-weight: 600; color: var(--fg); margin-top: 3px; display: flex; align-items: baseline; gap: 4px; }
|
||||
.snap-mini .v small { font-size: 11px; font-weight: 400; color: var(--fg-dim); font-family: "JetBrains Mono", monospace; }
|
||||
.snap-verdict { grid-column: 1 / -1; margin-top: 6px; padding: 11px 14px; border-left: 2px solid var(--gilt-dim); background: var(--gilt-faint); border-radius: 0 5px 5px 0; font-size: 13px; color: var(--fg-dim); line-height: 1.6; }
|
||||
.snap-verdict b { font-family: "Songti SC", serif; color: var(--gilt); font-weight: 600; }
|
||||
|
||||
/* ═══ 候选层积(主区 + 应用沉积侧栏)═══ */
|
||||
.lower-region { display: flex; gap: 20px; align-items: flex-start; }
|
||||
.cand-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 18px; }
|
||||
.strata-rail { width: 290px; flex-shrink: 0; }
|
||||
|
||||
/* 朱砂待裁卡(L4)*/
|
||||
.proposal { border: 1px solid var(--cinnabar); border-left: 3px solid var(--cinnabar); border-radius: 6px; padding: 17px 20px; background: radial-gradient(120% 100% at 0% 0%, rgba(184, 57, 46, 0.22), transparent 55%), rgba(184, 57, 46, 0.1); box-shadow: 0 0 28px -8px rgba(184, 57, 46, 0.35); }
|
||||
.prop-head { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; flex-wrap: wrap; }
|
||||
.prop-seal { font-family: "Songti SC", serif; color: var(--cinnabar); font-weight: 700; font-size: 14.5px; letter-spacing: 0.08em; }
|
||||
.prop-type { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-dim); padding: 2px 8px; border: 1px solid var(--rule); border-radius: 999px; }
|
||||
.prop-risk { font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.08em; color: var(--cinnabar); opacity: 0.78; margin-left: auto; }
|
||||
.prop-title { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); margin-bottom: 8px; }
|
||||
.prop-reason { font-size: 13px; color: var(--fg); line-height: 1.65; margin-bottom: 12px; }
|
||||
.prop-diff { background: rgba(0, 0, 0, 0.18); border: 1px solid var(--cinnabar-dim); border-radius: 4px; padding: 10px 12px; font-size: 12.5px; line-height: 1.6; margin-bottom: 12px; }
|
||||
[data-theme="light"] .prop-diff { background: rgba(255, 248, 235, 0.6); }
|
||||
.prop-diff .del { color: var(--cinnabar); text-decoration: line-through; opacity: 0.7; }
|
||||
.prop-diff .add { color: var(--patina); }
|
||||
.prop-diff .field-tag { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--gilt); display: block; margin-bottom: 4px; letter-spacing: 0.06em; }
|
||||
.prop-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
|
||||
.evi-link { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); padding: 2px 7px; border: 1px solid var(--rule); border-radius: 3px; }
|
||||
.prop-actions { display: flex; gap: 8px; margin-left: auto; }
|
||||
.vbtn { font-family: inherit; font-size: 12px; font-weight: 500; padding: 6px 14px; border-radius: 4px; cursor: pointer; border: 1px solid var(--rule); background: transparent; color: var(--fg); transition: background 0.12s, border-color 0.12s; }
|
||||
.vbtn:hover { background: var(--surface-hi); }
|
||||
.vbtn.cinnabar { border-color: var(--cinnabar); color: var(--cinnabar); background: rgba(184, 57, 46, 0.08); }
|
||||
.vbtn.cinnabar:hover { background: rgba(184, 57, 46, 0.16); }
|
||||
|
||||
/* 候选卡(非朱砂)*/
|
||||
.cand-list { display: flex; flex-direction: column; gap: 10px; }
|
||||
.cand-card { border: 1px solid var(--rule); border-radius: 7px; padding: 14px 16px; background: var(--surface); display: flex; flex-direction: column; gap: 10px; transition: border-color 0.15s; }
|
||||
.cand-card:hover { border-color: var(--gilt-dim); }
|
||||
.cand-card.auto { border-left: 3px solid var(--patina-dim); }
|
||||
.cand-top { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
|
||||
.cand-glyph { width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border: 1px solid var(--gilt-dim); background: var(--gilt-faint); font-family: "Songti SC", serif; font-size: 13px; font-weight: 700; color: var(--gilt); }
|
||||
.cand-card.auto .cand-glyph { border-color: var(--patina-dim); background: var(--patina-wash); color: var(--patina); }
|
||||
.cand-title { font-family: "Songti SC", serif; font-size: 14.5px; font-weight: 600; color: var(--fg); }
|
||||
.cand-tag { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); padding: 2px 8px; border: 1px solid var(--rule); border-radius: 999px; }
|
||||
.cand-judge { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 10.5px; letter-spacing: 0.04em; white-space: nowrap; }
|
||||
.cand-judge.auto { color: var(--patina); }
|
||||
.cand-judge.manual { color: var(--cinnabar); opacity: 0.85; }
|
||||
.cand-desc { font-size: 13px; color: var(--fg-dim); line-height: 1.6; }
|
||||
/* 三维评分 */
|
||||
.score-trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; padding-top: 10px; border-top: 1px solid var(--rule); }
|
||||
.score .k { font-family: "JetBrains Mono", monospace; font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--fg-faint); }
|
||||
.score .track { margin-top: 4px; height: 4px; border-radius: 2px; background: var(--rule); overflow: hidden; }
|
||||
.score .fill { height: 100%; border-radius: 2px; }
|
||||
.score.benefit .fill { background: linear-gradient(90deg, var(--patina-dim), var(--patina)); }
|
||||
.score.risk .fill { background: linear-gradient(90deg, var(--gilt-dim), var(--cinnabar)); }
|
||||
.score.conf .fill { background: linear-gradient(90deg, var(--gilt-dim), var(--gilt)); }
|
||||
.score .tv { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-dim); margin-top: 3px; }
|
||||
|
||||
/* 应用沉积(右栏,复用层积样式)*/
|
||||
.strata-card { background: var(--surface); border: 1px solid var(--rule); border-radius: 8px; padding: 18px 18px 16px; }
|
||||
.strata-list { position: relative; }
|
||||
.strata-list::before { content: ""; position: absolute; left: 11px; top: 14px; bottom: 14px; width: 1px; background: linear-gradient(180deg, var(--patina-dim), var(--rule) 50%, transparent); }
|
||||
.stratum { position: relative; padding: 10px 0 10px 32px; }
|
||||
.stratum + .stratum { border-top: 1px dashed var(--rule); }
|
||||
.stratum .node { position: absolute; left: 6px; top: 14px; width: 11px; height: 11px; border-radius: 50%; background: var(--patina-dim); border: 1.5px solid var(--patina-dim); z-index: 1; }
|
||||
.stratum.rejected .node { background: transparent; border-color: var(--cinnabar-dim); border-style: dashed; }
|
||||
.stratum-head { display: flex; align-items: baseline; gap: 8px; }
|
||||
.stratum-ver { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); }
|
||||
.stratum.rejected .stratum-ver { color: var(--fg-dim); text-decoration: line-through; opacity: 0.7; }
|
||||
.stratum-when { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); margin-left: auto; }
|
||||
.stratum-reason { font-size: 12px; color: var(--fg-dim); margin-top: 3px; line-height: 1.5; }
|
||||
.stratum-rollback { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--gilt); margin-top: 5px; cursor: pointer; border: none; background: none; padding: 0; }
|
||||
.stratum-rollback:hover { color: var(--cinnabar); }
|
||||
|
||||
@media (max-width: 1080px) { .lower-region { flex-direction: column; } .strata-rail { width: 100%; } }
|
||||
@media (max-width: 900px) { .snapshot-row { grid-template-columns: repeat(2, 1fr); } .mc-link { width: 14px; } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } .mirror-chain { gap: 2px; } .mc-link { display: none; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="演化"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">演化</span>
|
||||
<span class="page-sub">大周天 · 演化候选</span>
|
||||
<span class="char-pill"><span class="avatar-mini">梧</span>青梧</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="page-meta">待裁 <b>1</b> · 半自动 <b style="color: var(--patina)">2</b> · 已应用 <b>4</b></span>
|
||||
<button class="btn-ghost" type="button">立即触发一轮</button>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 周天四镜(签名) -->
|
||||
<div class="cycle-card">
|
||||
<div class="cycle-head">
|
||||
<span class="cycle-title">大周天 · 候选阶段</span>
|
||||
<span class="cycle-id">cycle_01JZK7Q3B…4F · 触发自会话结束</span>
|
||||
<span class="cycle-state">候选生成中</span>
|
||||
</div>
|
||||
<div class="mirror-chain">
|
||||
<div class="mc-step done">
|
||||
<div class="mc-mirror"><div class="disc">评</div></div>
|
||||
<span class="mc-name">评估</span>
|
||||
<span class="mc-sub">evaluation</span>
|
||||
<span class="mc-yield">态势 ✓</span>
|
||||
</div>
|
||||
<span class="mc-link done"></span>
|
||||
<div class="mc-step done">
|
||||
<div class="mc-mirror"><div class="disc">演</div></div>
|
||||
<span class="mc-name">演化</span>
|
||||
<span class="mc-sub">evolution</span>
|
||||
<span class="mc-yield">策略 ✓</span>
|
||||
</div>
|
||||
<span class="mc-link done"></span>
|
||||
<div class="mc-step active">
|
||||
<div class="mc-mirror"><div class="disc">候</div></div>
|
||||
<span class="mc-name">候选</span>
|
||||
<span class="mc-sub">candidate · 当阶</span>
|
||||
<span class="mc-yield">3 条草拟</span>
|
||||
</div>
|
||||
<span class="mc-link"></span>
|
||||
<div class="mc-step">
|
||||
<div class="mc-mirror"><div class="disc">藏</div></div>
|
||||
<span class="mc-name">入藏</span>
|
||||
<span class="mc-sub">memory · 未达</span>
|
||||
<span class="mc-yield">-</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="snapshot-row">
|
||||
<div class="snap-mini"><div class="k">最近记忆</div><div class="v">12<small>条入参</small></div></div>
|
||||
<div class="snap-mini"><div class="k">人格版本</div><div class="v">v7<small>当前</small></div></div>
|
||||
<div class="snap-mini"><div class="k">世界实体</div><div class="v">23<small>个</small></div></div>
|
||||
<div class="snap-mini"><div class="k">内驱力</div><div class="v">2<small>条好奇</small></div></div>
|
||||
<div class="snap-verdict"><b>评估结论:</b>近 12 条记忆呈「回应偏长」信号,可收敛风格字段;身份画稳定,无核心变更必要。建议生成 1 条风格类半自动候选,其余维持现状。</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 候选层积 + 应用沉积 -->
|
||||
<div class="lower-region">
|
||||
<div class="cand-main">
|
||||
<!-- 朱砂待裁(L4) -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 待裁 <span class="sub">L4 核心变更须人工裁定方可写入</span></div>
|
||||
<div class="proposal">
|
||||
<div class="prop-head">
|
||||
<span class="prop-seal">朱批待裁</span>
|
||||
<span class="prop-type">personality · identity</span>
|
||||
<span class="prop-risk">L4 · 满朱 · 须人工</span>
|
||||
</div>
|
||||
<div class="prop-title">本我镜自述收敛末句</div>
|
||||
<div class="prop-reason">神识据近 12 条对话判断,青梧自述末句「愿以耐心陪你走过每一段」略显填满,与「不被填满」的边界有张力。身份画属 L4 核心,须你裁定。</div>
|
||||
<div class="prop-diff">
|
||||
<span class="field-tag">identity_profile · 本我镜</span>
|
||||
<span class="del">我是青梧。喜静,不喜喧。观人多于言人,记事多于论事。愿以耐心陪你走过每一段。</span><br />
|
||||
<span class="add">我是青梧。喜静,不喜喧。观人多于言人,记事多于论事。</span>
|
||||
</div>
|
||||
<div class="prop-foot">
|
||||
<span class="evi-link">evi_01J…A2</span>
|
||||
<span class="evi-link">evi_01J…B7</span>
|
||||
<span class="evi-link">+2</span>
|
||||
<div class="prop-actions">
|
||||
<button class="vbtn" type="button">改由对话习得</button>
|
||||
<button class="vbtn" type="button">驳回</button>
|
||||
<button class="vbtn cinnabar" type="button">准予写入 v8</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 半自动候选 -->
|
||||
<section>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">半自动 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">L0–L3 且 auto_apply_allowed · 生成时已写入,可回滚</span></h3>
|
||||
<div class="cand-list">
|
||||
<div class="cand-card auto">
|
||||
<div class="cand-top">
|
||||
<div class="cand-glyph">辞</div>
|
||||
<span class="cand-title">表达风格 · 简练度 +1 档</span>
|
||||
<span class="cand-tag">personality · expression_style</span>
|
||||
<span class="cand-judge auto">L2 · 已应用</span>
|
||||
</div>
|
||||
<div class="cand-desc">减少惊叹号与问号,句号占比上调;与「不被填满」的边界一致。</div>
|
||||
<div class="score-trio">
|
||||
<div class="score benefit"><div class="k">收益</div><div class="track"><div class="fill" style="width:72%"></div></div><div class="tv">0.72</div></div>
|
||||
<div class="score risk"><div class="k">风险</div><div class="track"><div class="fill" style="width:14%"></div></div><div class="tv">0.14</div></div>
|
||||
<div class="score conf"><div class="k">置信</div><div class="track"><div class="fill" style="width:81%"></div></div><div class="tv">0.81</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cand-card auto">
|
||||
<div class="cand-top">
|
||||
<div class="cand-glyph">序</div>
|
||||
<span class="cand-title">新增程序性记忆 · 深夜不打扰</span>
|
||||
<span class="cand-tag">procedural</span>
|
||||
<span class="cand-judge auto">L3 · 已应用</span>
|
||||
</div>
|
||||
<div class="cand-desc">记录「用户 23:00 后倾向简短回应」,供辰正与对话枢调用。</div>
|
||||
<div class="score-trio">
|
||||
<div class="score benefit"><div class="k">收益</div><div class="track"><div class="fill" style="width:66%"></div></div><div class="tv">0.66</div></div>
|
||||
<div class="score risk"><div class="k">风险</div><div class="track"><div class="fill" style="width:9%"></div></div><div class="tv">0.09</div></div>
|
||||
<div class="score conf"><div class="k">置信</div><div class="track"><div class="fill" style="width:74%"></div></div><div class="tv">0.74</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- 应用沉积 -->
|
||||
<div class="strata-rail">
|
||||
<div class="strata-card">
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:12px">应用沉积 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">演化之层积</span></h3>
|
||||
<div class="strata-list">
|
||||
<div class="stratum">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">风格简练 +1</span><span class="stratum-when">07-12</span></div>
|
||||
<div class="stratum-reason">expression_style · 半自动 · 源自大周天</div>
|
||||
<button class="stratum-rollback" type="button">回滚此层</button>
|
||||
</div>
|
||||
<div class="stratum">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">深夜不打扰</span><span class="stratum-when">07-09</span></div>
|
||||
<div class="stratum-reason">procedural · 半自动</div>
|
||||
</div>
|
||||
<div class="stratum">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">人格权重校准</span><span class="stratum-when">06-28</span></div>
|
||||
<div class="stratum-reason">personality_weights · 尽责 +0.05</div>
|
||||
<button class="stratum-rollback" type="button">回滚此层</button>
|
||||
</div>
|
||||
<div class="stratum rejected">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">工具亲和调整</span><span class="stratum-when">06-12</span></div>
|
||||
<div class="stratum-reason">tool_strategy · 驳回 · 证据不足</div>
|
||||
</div>
|
||||
<div class="stratum" style="opacity: 0.6">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">初始种魂</span><span class="stratum-when">04 月</span></div>
|
||||
<div class="stratum-reason">自模板而来 · v1</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,316 @@
|
||||
<!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 — 世谱(Lorebook / World Info)管理页
|
||||
* 功能融合:关键词触发的世界设定注入(融合设计 §7)
|
||||
* ============================================================ */
|
||||
|
||||
.app-main { flex: 1; padding: 24px 28px 56px; max-width: 920px; width: 100%; margin: 0 auto; }
|
||||
/* ── 卡片 ── */
|
||||
|
||||
.card-title .glyph { color: var(--patina); opacity: 0.8; }
|
||||
|
||||
/* ── 按钮 ── */
|
||||
|
||||
|
||||
/* ── 书切换 tabs ── */
|
||||
.book-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 18px; }
|
||||
.book-tab { display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 999px; border: 1px solid var(--rule); background: var(--surface); color: var(--fg-dim); font-size: 12.5px; cursor: pointer; transition: all 0.12s; }
|
||||
.book-tab:hover { color: var(--fg); border-color: var(--patina-dim); }
|
||||
.book-tab.active { background: var(--patina-wash); color: var(--patina); border-color: var(--patina-dim); }
|
||||
.book-tab .count { font-family: "JetBrains Mono", monospace; font-size: 10.5px; opacity: 0.8; }
|
||||
.book-tab.add { border-style: dashed; color: var(--fg-faint); }
|
||||
.book-tab.add:hover { color: var(--patina); }
|
||||
|
||||
/* ── 表单 ── */
|
||||
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
|
||||
.field-label { display: block; font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.04em; color: var(--muted); margin-bottom: 4px; }
|
||||
.field input, .field textarea, .field select { width: 100%; padding: 8px 12px; border: 1px solid var(--rule); border-radius: 10px; background: var(--glass); color: var(--fg); font-family: inherit; font-size: 13px; transition: border-color 0.15s; }
|
||||
.field input:focus, .field textarea:focus, .field select:focus { outline: none; border-color: var(--patina-dim); }
|
||||
.field textarea { min-height: 80px; resize: vertical; }
|
||||
.field-full { grid-column: 1 / -1; }
|
||||
|
||||
/* ── 条目 ── */
|
||||
|
||||
.section-label .count { font-size: 11px; color: var(--fg-dim); font-weight: 400; }
|
||||
.entry-item { border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); padding: 14px 16px; margin-bottom: 10px; }
|
||||
.entry-item.constant { border-left: 3px solid var(--gilt); }
|
||||
.entry-item.disabled { opacity: 0.5; }
|
||||
.entry-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
|
||||
.entry-body { flex: 1; min-width: 0; }
|
||||
.entry-keys { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 7px; }
|
||||
.key-chip { display: inline-flex; align-items: center; padding: 2px 9px; border-radius: 6px; font-family: "JetBrains Mono", monospace; font-size: 11px; background: var(--patina-wash); color: var(--patina); border: 1px solid var(--patina-dim); }
|
||||
.key-chip.secondary { background: var(--gilt-faint); color: var(--gilt); border-color: var(--gilt-dim); }
|
||||
.entry-content { font-size: 13px; color: var(--fg); margin: 4px 0 8px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
||||
.entry-meta { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); display: flex; gap: 12px; flex-wrap: wrap; }
|
||||
.entry-meta span { display: inline-flex; align-items: center; gap: 3px; }
|
||||
.entry-actions { display: flex; gap: 4px; flex-shrink: 0; align-items: center; }
|
||||
|
||||
/* ── 开关 ── */
|
||||
.switch { position: relative; width: 32px; height: 18px; border-radius: 999px; background: var(--rule); cursor: pointer; transition: background 0.15s; flex-shrink: 0; }
|
||||
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--fg-dim); transition: transform 0.15s, background 0.15s; }
|
||||
.switch.on { background: var(--patina-dim); }
|
||||
.switch.on::after { transform: translateX(14px); background: var(--patina); }
|
||||
|
||||
/* ── Tag ── */
|
||||
|
||||
.tag-constant { border-color: var(--gilt-dim); color: var(--gilt); background: var(--gilt-faint); }
|
||||
.tag-selective { border-color: var(--cinnabar-dim); color: var(--cinnabar); background: var(--cinnabar-wash); }
|
||||
.tag-global { border-color: var(--patina-dim); color: var(--patina); background: var(--patina-wash); }
|
||||
|
||||
/* ── 高级选项折叠 ── */
|
||||
.advanced-toggle { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; margin-top: 8px; }
|
||||
.advanced-toggle:hover { color: var(--patina); }
|
||||
.advanced-body { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--rule); }
|
||||
|
||||
/* ── 说明卡 ── */
|
||||
.note { font-size: 12.5px; color: var(--fg-dim); line-height: 1.7; }
|
||||
.note code { font-family: "JetBrains Mono", monospace; font-size: 11.5px; background: var(--surface-hi); padding: 1px 6px; border-radius: 4px; color: var(--patina); }
|
||||
.note strong { color: var(--fg); font-weight: 500; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.app-main { padding: 16px 14px 40px; }
|
||||
.form-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-mount" data-active="世谱"></div>
|
||||
<div class="main-area">
|
||||
<main class="app-main">
|
||||
|
||||
<!-- ═══ 页头 ═══ -->
|
||||
<div class="page-head">
|
||||
<div>
|
||||
<h1 class="page-title">世谱 · Lorebook</h1>
|
||||
<p class="page-sub">「时崎狂三」的世界设定谱——对话命中关键词时自动注入,<code style="font-family:JetBrains Mono,monospace;font-size:12px;color:var(--patina);">before_char</code> / <code style="font-family:JetBrains Mono,monospace;font-size:12px;color:var(--patina);">after_char</code> 定位于人格前后。</p>
|
||||
</div>
|
||||
<button class="btn btn-primary">+ 新建世谱</button>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 世谱书切换 ═══ -->
|
||||
<div class="book-tabs">
|
||||
<span class="book-tab active">狂三世谱 <span class="count">5</span></span>
|
||||
<span class="book-tab">黑猫与日常 <span class="count">3</span></span>
|
||||
<span class="book-tab">通用世界观 <span class="count">8 · global</span></span>
|
||||
<span class="book-tab add">+ 新建</span>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 世谱书设置 ═══ -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">📖</span> 狂三世谱</h2>
|
||||
<span class="tag tag-global">character · 5 条</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-grid">
|
||||
<div class="field field-full">
|
||||
<label class="field-label">书名</label>
|
||||
<input type="text" value="狂三世谱" />
|
||||
</div>
|
||||
<div class="field field-full">
|
||||
<label class="field-label">描述(可选)</label>
|
||||
<input type="text" value="时崎狂三的能力、关系、背景设定,按对话关键词触发。" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">扫描深度 scan_depth</label>
|
||||
<input type="number" value="8" placeholder="扫描最近 N 条对话" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">token 预算</label>
|
||||
<input type="number" value="800" placeholder="注入上限" />
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;align-items:center;gap:10px;margin-top:12px;">
|
||||
<span class="switch on" id="recursive"></span>
|
||||
<span style="font-size:12.5px;color:var(--fg-dim);">递归扫描 <span style="color:var(--fg-faint);font-size:11.5px;">— 已命中条目的内容可触发其他条目</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 条目列表 ═══ -->
|
||||
<div class="section-label">
|
||||
◇ 条目
|
||||
<span class="count">(5 条 · 4 启用)</span>
|
||||
<div style="flex:1;"></div>
|
||||
<button class="btn btn-outline btn-sm">+ 新建条目</button>
|
||||
</div>
|
||||
|
||||
<!-- 条目 1:常量(恒定注入) -->
|
||||
<div class="entry-item constant">
|
||||
<div class="entry-head">
|
||||
<div class="entry-body">
|
||||
<div class="entry-keys">
|
||||
<span class="key-chip">刻刻帝</span>
|
||||
<span class="key-chip">Zafkiel</span>
|
||||
<span class="key-chip">天使</span>
|
||||
<span class="tag tag-constant">constant · 恒定注入</span>
|
||||
</div>
|
||||
<div class="entry-content">狂三的天使「刻刻帝」外观为巨大古钟,时钟指针化为长短双枪。拥有十二种时间能力,每种消耗不同的"时间"代价。</div>
|
||||
<div class="entry-meta">
|
||||
<span>位置 after_char</span>
|
||||
<span>顺序 10</span>
|
||||
<span>优先级 5</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry-actions">
|
||||
<span class="switch on"></span>
|
||||
<button class="btn btn-ghost btn-sm">编辑</button>
|
||||
<button class="btn btn-ghost btn-sm">删</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 条目 2:selective(双键命中) -->
|
||||
<div class="entry-item">
|
||||
<div class="entry-head">
|
||||
<div class="entry-body">
|
||||
<div class="entry-keys">
|
||||
<span class="key-chip">猫</span>
|
||||
<span style="color:var(--fg-faint);font-size:11px;">+</span>
|
||||
<span class="key-chip secondary">黑</span>
|
||||
<span class="tag tag-selective">selective · 双键命中</span>
|
||||
</div>
|
||||
<div class="entry-content">狂三格外钟爱黑猫,常以「小可」称呼她在影子中豢养的黑猫分身,会为它留下红茶第三泡。</div>
|
||||
<div class="entry-meta">
|
||||
<span>位置 after_char</span>
|
||||
<span>顺序 20</span>
|
||||
<span>优先级 10</span>
|
||||
<span>区分大小写 ✕</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry-actions">
|
||||
<span class="switch on"></span>
|
||||
<button class="btn btn-ghost btn-sm">编辑</button>
|
||||
<button class="btn btn-ghost btn-sm">删</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 条目 3:正则匹配 -->
|
||||
<div class="entry-item">
|
||||
<div class="entry-head">
|
||||
<div class="entry-body">
|
||||
<div class="entry-keys">
|
||||
<span class="key-chip" style="font-family:'JetBrains Mono',monospace;">/\b(四之弹|七之弹|十二之弹)\b/</span>
|
||||
<span class="tag" style="border-color:var(--cinnabar-dim);color:var(--cinnabar);background:var(--cinnabar-wash);">use_regex · 正则</span>
|
||||
</div>
|
||||
<div class="entry-content">十二之弹对应十二种时间能力:一之弹加速自身、四之弹回溯目标、七之弹停止时间、十二之弹时间旅行……每次使用消耗自身寿命。</div>
|
||||
<div class="entry-meta">
|
||||
<span>位置 before_char</span>
|
||||
<span>顺序 30</span>
|
||||
<span>优先级 10</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry-actions">
|
||||
<span class="switch on"></span>
|
||||
<button class="btn btn-ghost btn-sm">编辑</button>
|
||||
<button class="btn btn-ghost btn-sm">删</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 条目 4:已禁用 -->
|
||||
<div class="entry-item disabled">
|
||||
<div class="entry-head">
|
||||
<div class="entry-body">
|
||||
<div class="entry-keys">
|
||||
<span class="key-chip">士道</span>
|
||||
</div>
|
||||
<div class="entry-content">与五河士道的关系:曾多次交手与合作,为他使用六之弹回到过去,经历 204 次时间回溯。</div>
|
||||
<div class="entry-meta">
|
||||
<span style="color:var(--cinnabar);">● 已禁用</span>
|
||||
<span>位置 after_char</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry-actions">
|
||||
<span class="switch"></span>
|
||||
<button class="btn btn-ghost btn-sm">编辑</button>
|
||||
<button class="btn btn-ghost btn-sm">删</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 条目编辑表单(展开态示例) ═══ -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2 class="card-title"><span class="glyph">✎</span> 编辑条目</h2>
|
||||
<button class="btn btn-ghost btn-sm">取消</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-grid">
|
||||
<div class="field field-full">
|
||||
<label class="field-label">主关键词 keys(逗号分隔,命中任一即触发)</label>
|
||||
<input type="text" value="刻刻帝, Zafkiel, 天使" />
|
||||
</div>
|
||||
<div class="field field-full">
|
||||
<label class="field-label">注入内容 content *</label>
|
||||
<textarea>狂三的天使「刻刻帝」外观为巨大古钟……</textarea>
|
||||
</div>
|
||||
<div class="field field-full">
|
||||
<label class="field-label">次关键词 secondary_keys(selective 时需同时命中)</label>
|
||||
<input type="text" placeholder="可选" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">注入位置</label>
|
||||
<select>
|
||||
<option>after_char · 人格之后</option>
|
||||
<option>before_char · 人格之前</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="field-label">插入顺序 / 优先级</label>
|
||||
<div style="display:flex;gap:8px;">
|
||||
<input type="number" value="10" placeholder="顺序" style="flex:1;" />
|
||||
<input type="number" value="5" placeholder="优先级" style="flex:1;" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="advanced-toggle" onclick="this.nextElementSibling.style.display = this.nextElementSibling.style.display==='none' ? 'block' : 'none';">▸ 高级选项</div>
|
||||
<div class="advanced-body" style="display:none;">
|
||||
<div style="display:flex;flex-wrap:wrap;gap:18px;">
|
||||
<label style="display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--fg-dim);cursor:pointer;"><span class="switch on"></span> 启用</label>
|
||||
<label style="display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--fg-dim);cursor:pointer;"><span class="switch"></span> constant(恒定注入,无视关键词)</label>
|
||||
<label style="display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--fg-dim);cursor:pointer;"><span class="switch"></span> selective(需双键命中)</label>
|
||||
<label style="display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--fg-dim);cursor:pointer;"><span class="switch"></span> 区分大小写</label>
|
||||
<label style="display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--fg-dim);cursor:pointer;"><span class="switch"></span> use_regex(关键词按正则)</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;justify-content:flex-end;gap:8px;margin-top:16px;">
|
||||
<button class="btn btn-outline">取消</button>
|
||||
<button class="btn btn-primary">保存条目</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ═══ 说明 ═══ -->
|
||||
<div class="card">
|
||||
<div class="card-body note">
|
||||
<strong>世谱是什么。</strong>源自业界通用的 <code>World Info / Lorebook</code>——创作者预设的设定条目,对话命中 <code>keys</code> 时把 <code>content</code> 注入系统提示词,既丰富世界观又节省 token(按需注入而非全量塞入)。
|
||||
<br/><br/>
|
||||
<strong>与魂镜既有载体的区别。</strong>息壤记忆(自动抽取、会演化)、河图世界实体(结构化图谱)之外,世谱是<strong>手动预设的触发式设定</strong>,三者正交。魂镜增量:条目可 <code>bound_entity_id</code> 绑定河图实体,实现「关键词 + 实体」双引擎触发。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// 开关交互(设计稿示意)
|
||||
document.querySelectorAll('.switch').forEach(s => s.addEventListener('click', () => s.classList.toggle('on')));
|
||||
</script>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,312 @@
|
||||
<!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 — 眉批(Author's Note · 按 depth 注入对话流)
|
||||
* 功能融合 §9.1:作为 context_transformer,按深度 +
|
||||
* 角色把批注插入对话流。签名——书眉批注:批注夹在对话消息间,
|
||||
* 左侧 depth 标尺定位,铜绿色夹批。
|
||||
*
|
||||
* 完整功能:
|
||||
* 按角色筛选(system / user / assistant)
|
||||
* 按人物 scope 过滤
|
||||
* 行内编辑 · 深度调节 · 批量启停
|
||||
* 模板速建 · 注入预览(含多批同 depth 层叠)
|
||||
* ============================================================ */
|
||||
|
||||
.page-header .spacer { flex: 1; }
|
||||
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.85; font-family: "Songti SC", serif; font-size: 14px; }
|
||||
.section-label .sub { color: var(--fg-dim); opacity: 0.7; letter-spacing: 0.04em; }
|
||||
|
||||
/* ── 筛选条 ── */
|
||||
.filter-bar { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
|
||||
.filter-chip { font-size: 12px; padding: 5px 12px; border-radius: 999px; border: 1px solid var(--rule); color: var(--fg-dim); cursor: pointer; background: var(--surface); transition: all var(--duration-fast); font-family: inherit; }
|
||||
.filter-chip:hover { color: var(--fg); border-color: var(--patina-dim); }
|
||||
.filter-chip.active { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.filter-chip .count { font-family: "JetBrains Mono", monospace; font-size: 10px; opacity: 0.7; margin-left: 4px; }
|
||||
|
||||
/* ── 人物 scope 选择 ── */
|
||||
.scope-select { display: flex; align-items: center; gap: 8px; margin-left: auto; }
|
||||
.scope-select .lb { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.char-pill-scope { display: inline-flex; align-items: center; gap: 5px; padding: 4px 11px; border-radius: 999px; border: 1px solid var(--patina-dim); background: var(--patina-wash); color: var(--patina); font-size: 12px; cursor: pointer; }
|
||||
.char-pill-scope.all { border-color: var(--rule); background: var(--surface); color: var(--fg-dim); }
|
||||
.char-pill-scope .avatar-mini { width: 16px; height: 16px; border-radius: 50%; background: var(--patina); color: var(--ink); display: inline-flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 9px; font-weight: 700; }
|
||||
|
||||
/* ═══ 眉批卡(列表)═══ */
|
||||
.note-list { display: flex; flex-direction: column; gap: 10px; }
|
||||
.note-card { display: grid; grid-template-columns: 1fr 52px auto auto; gap: 12px; align-items: center; border: 1px solid var(--rule); border-radius: 10px; background: var(--surface); padding: 13px 16px; transition: border-color var(--duration-fast); }
|
||||
.note-card:hover { border-color: var(--patina-dim); }
|
||||
.note-card.off { opacity: 0.5; }
|
||||
.note-card.off .note-text { text-decoration: line-through; text-decoration-color: var(--fg-faint); }
|
||||
.note-text { font-family: "Songti SC", serif; font-size: 14.5px; color: var(--fg); line-height: 1.5; cursor: text; }
|
||||
.note-text:focus { outline: none; border-bottom: 1px dashed var(--patina-dim); }
|
||||
.note-text .role-tag { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--gilt); border: 1px solid var(--gilt-dim); border-radius: 3px; padding: 1px 5px; margin-right: 7px; vertical-align: 2px; }
|
||||
.note-text .role-tag.user { color: var(--cinnabar); border-color: var(--cinnabar-dim); }
|
||||
.note-text .role-tag.assistant { color: var(--patina); border-color: var(--patina-dim); }
|
||||
.note-text .scope-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; vertical-align: 1px; }
|
||||
.note-text .scope-dot.global { background: var(--gilt); }
|
||||
.note-text .scope-dot.char { background: var(--patina); }
|
||||
.depth-chip { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--patina); border: 1px solid var(--patina-dim); border-radius: 5px; padding: 4px 9px; background: var(--patina-wash); white-space: nowrap; cursor: pointer; }
|
||||
.role-select { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-dim); background: var(--glass); border: 1px solid var(--rule); border-radius: 6px; padding: 4px 8px; cursor: pointer; }
|
||||
.depth-input { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-dim); background: var(--glass); border: 1px solid var(--rule); border-radius: 6px; padding: 4px 8px; width: 48px; text-align: center; }
|
||||
.depth-input:focus, .role-select:focus { outline: none; border-color: var(--patina-dim); }
|
||||
.toggle { width: 34px; height: 19px; border-radius: 999px; background: var(--rule); position: relative; cursor: pointer; transition: background var(--duration-fast); flex-shrink: 0; }
|
||||
.toggle::after { content: ""; position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%; background: var(--fg-faint); transition: transform var(--duration-fast), background var(--duration-fast); }
|
||||
.toggle.on { background: var(--patina-dim); }
|
||||
.toggle.on::after { transform: translateX(15px); background: var(--patina); }
|
||||
.add-note { border: 1px dashed var(--rule); border-radius: 10px; padding: 13px 16px; color: var(--fg-faint); font-size: 13px; cursor: pointer; text-align: center; transition: all var(--duration-fast); }
|
||||
.add-note:hover { border-color: var(--patina-dim); color: var(--patina); }
|
||||
|
||||
/* ── 批量操作栏 ── */
|
||||
.batch-bar { display: flex; gap: 8px; align-items: center; padding: 8px 0; }
|
||||
.batch-bar .hint { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); margin-right: auto; }
|
||||
|
||||
/* ── 模板速建 ── */
|
||||
.templates { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||
.tpl-chip { font-size: 11.5px; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--rule); background: var(--surface); color: var(--fg-dim); cursor: pointer; transition: all var(--duration-fast); white-space: nowrap; }
|
||||
.tpl-chip:hover { border-color: var(--patina-dim); color: var(--fg); background: var(--patina-wash); }
|
||||
.tpl-chip .glyph { margin-right: 4px; }
|
||||
|
||||
/* ═══ depth 注入预览(签名:书眉批注,depth 标尺 + 夹批)═══ */
|
||||
.depth-view { border: 1px solid var(--gilt-dim); border-radius: 10px; background: var(--face-sheen), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow); overflow: hidden; }
|
||||
.depth-view-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--rule); }
|
||||
.depth-view-head .t { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); }
|
||||
.depth-view-head .hint { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.stream { padding: 16px 16px 20px; display: flex; flex-direction: column; gap: 6px; position: relative; }
|
||||
.stream-row { display: grid; grid-template-columns: 40px 1fr; gap: 12px; align-items: stretch; }
|
||||
.depth-mark { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); text-align: right; padding-top: 7px; letter-spacing: 0.04em; }
|
||||
.msg { padding: 8px 13px; border-radius: 8px; font-size: 13px; line-height: 1.55; }
|
||||
.msg .who { font-family: "JetBrains Mono", monospace; font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 3px; }
|
||||
.msg.ai { background: var(--surface-hi); color: var(--fg); border: 1px solid var(--rule); }
|
||||
.msg.ai .who { color: var(--patina); }
|
||||
.msg.you { background: transparent; color: var(--fg-dim); border-right: 2px solid var(--gilt); padding-right: 11px; text-align: right; }
|
||||
.msg.you .who { color: var(--gilt); }
|
||||
/* 眉批夹批:从左侧 depth 标尺伸入,铜绿色,像书眉批注 */
|
||||
.stream-row.note { grid-template-columns: 40px 1fr; }
|
||||
.stream-row.note .depth-mark { color: var(--patina); padding-top: 5px; }
|
||||
.stream-row.note .note-inline { background: var(--patina-wash); border: 1px solid var(--patina-dim); border-left: 3px solid var(--patina); border-radius: 0 6px 6px 0; padding: 7px 13px; font-family: "Songti SC", serif; font-size: 13px; color: var(--patina); display: flex; gap: 9px; align-items: baseline; }
|
||||
.stream-row.note .note-inline .seal { font-family: "JetBrains Mono", monospace; font-size: 9px; letter-spacing: 0.1em; color: var(--patina); border: 1px solid var(--patina-dim); border-radius: 3px; padding: 1px 5px; flex-shrink: 0; }
|
||||
.stream-row.note .note-inline .txt { color: var(--fg); }
|
||||
|
||||
.legend { display: flex; gap: 16px; padding: 10px 16px; border-top: 1px solid var(--rule); font-size: 11.5px; color: var(--muted); flex-wrap: wrap; }
|
||||
.legend .item { display: inline-flex; align-items: center; gap: 6px; }
|
||||
.legend .sw { width: 11px; height: 11px; border-radius: 3px; }
|
||||
|
||||
.pipeline-note { font-size: 12.5px; color: var(--fg-dim); line-height: 1.6; }
|
||||
.pipeline-note .em { color: var(--fg); }
|
||||
.pipeline-note code { font-family: "JetBrains Mono", monospace; font-size: 11.5px; color: var(--gilt); }
|
||||
|
||||
@media (max-width: 900px) { .note-card { grid-template-columns: 1fr; gap: 8px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<div class="sidebar-mount" data-active="眉批"></div>
|
||||
|
||||
<!-- ══ main ══ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<div class="page-title">眉批</div>
|
||||
<div class="page-sub">Author's Note · 按 depth 注入对话流</div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<span class="stat-pill">3 条生效 · 1 条停用</span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 筛选 + 作用域 -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">批</span>眉批清单 <span class="sub">— 每条按 depth + role + scope 插入对话流</span></div>
|
||||
|
||||
<div class="filter-bar">
|
||||
<span class="filter-chip active">全部 <span class="count">4</span></span>
|
||||
<span class="filter-chip">system <span class="count">3</span></span>
|
||||
<span class="filter-chip">user <span class="count">1</span></span>
|
||||
<span class="filter-chip">assistant <span class="count">0</span></span>
|
||||
<span class="filter-chip" style="opacity:0.6;">生效中 <span class="count">3</span></span>
|
||||
<span class="filter-chip" style="opacity:0.6;">已停用 <span class="count">1</span></span>
|
||||
|
||||
<span class="scope-select">
|
||||
<span class="lb">作用域</span>
|
||||
<span class="char-pill-scope all">全人物</span>
|
||||
<span class="char-pill-scope"><span class="avatar-mini">狂</span>狂三</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 批量操作 -->
|
||||
<div class="batch-bar">
|
||||
<span class="hint">选中 0 条 · 批量操作</span>
|
||||
<button class="btn btn-outline btn-sm">全部启用</button>
|
||||
<button class="btn btn-outline btn-sm">全部停用</button>
|
||||
<button class="btn btn-outline btn-sm" style="color:var(--cinnabar);border-color:var(--cinnabar-dim);">删除选中</button>
|
||||
</div>
|
||||
|
||||
<!-- 模板速建 -->
|
||||
<div style="margin-bottom:14px;">
|
||||
<span style="font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--fg-faint);letter-spacing:0.08em;display:block;margin-bottom:6px;">速建模板</span>
|
||||
<div class="templates">
|
||||
<span class="tpl-chip" onclick="addNote()"><span class="glyph">+</span> 空白眉批</span>
|
||||
<span class="tpl-chip"><span class="glyph">📏</span> 保持简洁,每轮消息不超过三句。</span>
|
||||
<span class="tpl-chip"><span class="glyph">🎭</span> 用宋体的节奏,留白比填满好。</span>
|
||||
<span class="tpl-chip"><span class="glyph">🪞</span> 本节气氛沉静,少用感叹与反问。</span>
|
||||
<span class="tpl-chip"><span class="glyph">⚡</span> 用户赶工中 · 语气再软一点 · 不问进度</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 眉批列表 -->
|
||||
<div class="note-list" id="noteList"></div>
|
||||
</section>
|
||||
|
||||
<!-- depth 注入预览(签名)-->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">注</span>注入预览 <span class="sub">— depth = 距对话末尾第 N 条之前;调 depth 看夹批位置</span></div>
|
||||
<div class="depth-view">
|
||||
<div class="depth-view-head">
|
||||
<span class="t">对话流 · 书眉批注</span>
|
||||
<span class="hint">D0 = 最末消息 · 数字越大越深</span>
|
||||
</div>
|
||||
<div class="stream" id="stream"></div>
|
||||
<div class="legend">
|
||||
<span class="item"><span class="sw" style="background:var(--surface-hi);border:1px solid var(--rule)"></span>对话消息</span>
|
||||
<span class="item"><span class="sw" style="background:var(--patina-wash);border:1px solid var(--patina-dim);border-left:3px solid var(--patina)"></span>眉批夹批(按 depth 插入)</span>
|
||||
<span class="item"><span class="sw" style="background:transparent;border-right:2px solid var(--gilt)"></span>你的发言</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 说明 -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">理</span>语义</div>
|
||||
<p class="pipeline-note">
|
||||
眉批是 <span class="em">context_transformer</span>:不进道体,只在本轮对话流里插入。<code>depth</code> = 插入点距对话末尾的条数(<code>0</code> = 最末,数字越大越靠前)。<code>role</code> 可选 <code>system</code>(主导约束)/ <code>user</code>(范例)/ <code>assistant</code>(风格示范)。<code>scope</code> 可选全局(全人物生效)或指定人物(仅该人物对话时注入)。多条眉批同 depth 时按创建顺序层叠。
|
||||
<code>extensions.depth_prompt</code> 直接映射本结构。与符文引擎(<code>{{char}}</code> 显化)正交——眉批管"插在哪、以什么角色",符文管"占位符换成什么"。
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 眉批数据(真应用接 author_notes,此处示意)*/
|
||||
let NOTES = [
|
||||
{ id: 1, text: "保持回答简短,尊重用户不想被填满的边界。", depth: 4, role: "system", scope: "all", on: true },
|
||||
{ id: 2, text: "今天周五,用户在赶 deadline,语气再软一点。", depth: 2, role: "system", scope: "character_狂三", on: true },
|
||||
{ id: 3, text: "用宋体的节奏,慢一点,留白。", depth: 0, role: "system", scope: "all", on: false },
|
||||
{ id: 4, text: "用户喜欢被叫名字,而非「你」。", depth: 6, role: "user", scope: "all", on: true },
|
||||
];
|
||||
|
||||
/* 当前筛选 */
|
||||
let filterRole = null;
|
||||
let filterOn = null;
|
||||
|
||||
const ROLE_LABELS = { system: "system", user: "user", assistant: "assistant" };
|
||||
|
||||
/* 对话流示意(D0 最末 → 向上越来越深)*/
|
||||
const STREAM = [
|
||||
{ who: "你", text: "今天可以多说一点。", cls: "you" },
|
||||
{ who: "青梧", text: "那我把话说全。这几天你睡得很晚。", cls: "ai" },
|
||||
{ who: "你", text: "在赶一份东西。", cls: "you" },
|
||||
{ who: "青梧", text: "嗯。需要我的时候我在。", cls: "ai" },
|
||||
{ who: "你", text: "先这样。", cls: "you" },
|
||||
{ who: "青梧", text: "好。我记着你喜欢简短。", cls: "ai" },
|
||||
{ who: "你", text: "昨晚说的,还记得吗?", cls: "you" },
|
||||
{ who: "青梧", text: "记得。你不想被填满。", cls: "ai" },
|
||||
];
|
||||
|
||||
function filteredNotes() {
|
||||
return NOTES.filter(n => {
|
||||
if (filterRole && n.role !== filterRole) return false;
|
||||
if (filterOn !== null && n.on !== filterOn) return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
function renderNotes() {
|
||||
const notes = filteredNotes();
|
||||
const list = document.getElementById("noteList");
|
||||
const scopeLabel = (s) => s === "all" ? "全局" : "狂三";
|
||||
const scopeCls = (s) => s === "all" ? "global" : "char";
|
||||
list.innerHTML = notes.map(n => `
|
||||
<div class="note-card ${n.on ? "" : "off"}">
|
||||
<div class="note-text" contenteditable="true" data-id="${n.id}">
|
||||
<span class="scope-dot ${scopeCls(n.scope)}" title="${scopeLabel(n.scope)}"></span>
|
||||
<span class="role-tag ${n.role === 'user' ? 'user' : n.role === 'assistant' ? 'assistant' : ''}">${n.role}</span>${n.text}
|
||||
</div>
|
||||
<select class="role-select" onchange="setRole(${n.id}, this.value)" aria-label="角色">
|
||||
<option value="system" ${n.role === 'system' ? 'selected' : ''}>sys</option>
|
||||
<option value="user" ${n.role === 'user' ? 'selected' : ''}>usr</option>
|
||||
<option value="assistant" ${n.role === 'assistant' ? 'selected' : ''}>ast</option>
|
||||
</select>
|
||||
<span class="depth-chip" onclick="const inp=this.previousElementSibling;inp.focus();inp.select();">depth</span>
|
||||
<input class="depth-input" type="number" min="0" value="${n.depth}" onchange="setDepth(${n.id}, this.value)" aria-label="depth" style="display:none;"/>
|
||||
<div class="toggle ${n.on ? 'on' : ''}" onclick="toggleNote(${n.id})" role="switch" aria-checked="${n.on}"></div>
|
||||
</div>`).join("") +
|
||||
`<div class="add-note" onclick="addNote()">+ 新眉批</div>`;
|
||||
}
|
||||
|
||||
function renderStream() {
|
||||
/* depth → 眉批 映射(按 depth 分组;多条同 depth 时按数组顺序叠放)*/
|
||||
const byDepth = {};
|
||||
NOTES.filter(n => n.on).forEach(n => {
|
||||
(byDepth[n.depth] = byDepth[n.depth] || []).push(n);
|
||||
});
|
||||
const ordered = STREAM.slice().reverse(); // ordered[0] = D0 最末
|
||||
const html = [];
|
||||
for (let d = 0; d <= ordered.length; d++) {
|
||||
if (byDepth[d]) {
|
||||
byDepth[d].forEach(n => {
|
||||
const scopeLabel = n.scope === 'all' ? 'ALL' : '狂';
|
||||
html.push(`<div class="stream-row note">
|
||||
<div class="depth-mark">D${d}</div>
|
||||
<div class="note-inline"><span class="seal">${n.role} · ${scopeLabel}</span><span class="txt">${n.text}</span></div>
|
||||
</div>`);
|
||||
});
|
||||
}
|
||||
if (d < ordered.length) {
|
||||
const m = ordered[d];
|
||||
html.push(`<div class="stream-row">
|
||||
<div class="depth-mark">D${d}</div>
|
||||
<div class="msg ${m.cls}"><div class="who">${m.who}</div>${m.text}</div>
|
||||
</div>`);
|
||||
}
|
||||
}
|
||||
document.getElementById("stream").innerHTML = html.join("");
|
||||
}
|
||||
|
||||
function toggleNote(id) { const n = NOTES.find(x => x.id === id); n.on = !n.on; renderNotes(); renderStream(); }
|
||||
function setDepth(id, v) { NOTES.find(x => x.id === id).depth = Math.max(0, +v || 0); renderNotes(); renderStream(); }
|
||||
function setRole(id, v) { NOTES.find(x => x.id === id).role = v; renderNotes(); renderStream(); }
|
||||
function addNote() { NOTES.push({ id: Date.now(), text: "新眉批,双击编辑。", depth: 0, role: "system", scope: "all", on: true }); renderNotes(); renderStream(); }
|
||||
|
||||
/* 筛选切换 */
|
||||
document.querySelector('.filter-bar').addEventListener('click', function(e) {
|
||||
const chip = e.target.closest('.filter-chip');
|
||||
if (!chip) return;
|
||||
const text = chip.textContent.trim().split(' ')[0];
|
||||
/* 切换 active 态 */
|
||||
this.querySelectorAll('.filter-chip').forEach(c => c.classList.remove('active'));
|
||||
chip.classList.add('active');
|
||||
/* 设置筛选 */
|
||||
if (text === '全部') { filterRole = null; filterOn = null; }
|
||||
else if (text === 'system' || text === 'user' || text === 'assistant') { filterRole = text; filterOn = null; }
|
||||
else if (text === '生效中') { filterRole = null; filterOn = true; }
|
||||
else if (text === '已停用') { filterRole = null; filterOn = false; }
|
||||
renderNotes();
|
||||
});
|
||||
|
||||
renderNotes();
|
||||
renderStream();
|
||||
</script>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,338 @@
|
||||
<!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 — 记忆页:记忆分类 + MemoryRecord 卡片 + 检索/审查
|
||||
* 字段对齐 docs/domain/memory-model.md §2/§4/§5/§6(记忆分类、
|
||||
* MemoryRecord、写入规则、冲突裁决)与 web-ui-design.md §8。
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 侧栏(active=记忆)── */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.char-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--patina); padding: 3px 11px 3px 4px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.char-pill .avatar-mini { width: 18px; height: 18px; border-radius: 50%; background: var(--patina); color: var(--ink); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; }
|
||||
.page-header .spacer { flex: 1; }
|
||||
.pending-pill { display: inline-flex; align-items: center; gap: 6px; font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--gilt); padding: 4px 12px; border: 1px solid var(--gilt-dim); border-radius: 999px; background: var(--gilt-faint); }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
|
||||
/* 分类栏 */
|
||||
.type-bar { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||
.type-chip { font-size: 12.5px; padding: 5px 13px; border-radius: 999px; border: 1px solid var(--rule); color: var(--fg-dim); cursor: pointer; background: var(--surface); display: inline-flex; align-items: center; gap: 6px; transition: background 0.12s, color 0.12s, border-color 0.12s; }
|
||||
.type-chip:hover { color: var(--fg); border-color: var(--gilt-dim); }
|
||||
.type-chip.active { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.type-chip .cnt { font-family: "JetBrains Mono", monospace; font-size: 10.5px; opacity: 0.7; }
|
||||
|
||||
/* 统计四格 */
|
||||
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
|
||||
.stat-card { border: 1px solid var(--rule); border-radius: 7px; background: var(--surface); padding: 14px 16px; display: flex; flex-direction: column; gap: 4px; }
|
||||
.stat-card .k { font-family: "JetBrains Mono", monospace; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--fg-faint); }
|
||||
.stat-card .v { font-family: "Songti SC", serif; font-size: 22px; font-weight: 600; color: var(--fg); }
|
||||
.stat-card .v small { font-size: 11px; font-weight: 400; color: var(--fg-dim); font-family: "JetBrains Mono", monospace; margin-left: 4px; }
|
||||
.stat-card .sub { font-size: 11.5px; color: var(--fg-faint); }
|
||||
.stat-card.alert .v { color: var(--cinnabar); }
|
||||
.stat-card.warn .v { color: var(--gilt); }
|
||||
|
||||
/* 记忆卡列表 + 右栏 */
|
||||
.mem-region { display: flex; gap: 20px; align-items: flex-start; }
|
||||
.mem-main { flex: 1; min-width: 0; }
|
||||
.mem-rail { width: 300px; flex-shrink: 0; display: flex; flex-direction: column; gap: 14px; }
|
||||
|
||||
.mem-list { display: flex; flex-direction: column; gap: 10px; }
|
||||
.mem-card { border: 1px solid var(--rule); border-radius: 7px; background: var(--surface); padding: 13px 15px; transition: border-color 0.12s; }
|
||||
.mem-card:hover { border-color: var(--gilt-dim); }
|
||||
.mem-card.high-sens { border-color: var(--cinnabar-dim); background: rgba(184, 57, 46, 0.04); }
|
||||
.mem-card.pending { border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.mem-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
|
||||
.mem-title { font-size: 14px; font-weight: 600; color: var(--fg); }
|
||||
.mem-type { font-family: "JetBrains Mono", monospace; font-size: 10px; padding: 2px 7px; border-radius: 3px; border: 1px solid var(--rule); color: var(--fg-faint); white-space: nowrap; }
|
||||
.mem-type.identity { color: var(--patina); border-color: var(--patina-dim); }
|
||||
.mem-type.user { color: var(--patina); border-color: var(--patina-dim); }
|
||||
.mem-type.episodic { color: var(--gilt); border-color: var(--gilt-dim); }
|
||||
.mem-type.semantic { color: var(--gilt); border-color: var(--gilt-dim); }
|
||||
.mem-type.procedural { color: var(--water, #5a7fa6); border-color: rgba(90, 127, 166, 0.38); }
|
||||
.mem-type.relational { color: var(--patina); border-color: var(--patina-dim); }
|
||||
.mem-type.emotional { color: var(--cinnabar); border-color: var(--cinnabar-dim); }
|
||||
.mem-type.reflection { color: var(--gilt); border-color: var(--gilt-dim); }
|
||||
.mem-type.evolution { color: var(--cinnabar); border-color: var(--cinnabar-dim); }
|
||||
.mem-content { font-size: 12.5px; color: var(--fg-dim); margin-top: 6px; line-height: 1.55; }
|
||||
.mem-meta { display: flex; gap: 16px; margin-top: 9px; flex-wrap: wrap; align-items: center; }
|
||||
.meta-item { font-size: 11.5px; color: var(--fg-dim); display: inline-flex; align-items: center; gap: 6px; }
|
||||
.meta-item .lab { color: var(--fg-faint); font-family: "JetBrains Mono", monospace; font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; }
|
||||
.meta-bar { width: 54px; height: 4px; border-radius: 2px; background: var(--rule); overflow: hidden; position: relative; }
|
||||
.meta-bar .fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 2px; }
|
||||
.meta-item.conf .fill { background: var(--patina); }
|
||||
.meta-item.imp .fill { background: var(--gilt); }
|
||||
.meta-item .vv { font-family: "JetBrains Mono", monospace; font-size: 10.5px; }
|
||||
.meta-item.conf .vv { color: var(--patina); }
|
||||
.meta-item.imp .vv { color: var(--gilt); }
|
||||
.sens-badge { font-family: "JetBrains Mono", monospace; font-size: 10px; padding: 2px 7px; border-radius: 3px; border: 1px solid var(--rule); }
|
||||
.sens-badge.none { color: var(--fg-faint); }
|
||||
.sens-badge.low { color: var(--patina); border-color: var(--patina-dim); }
|
||||
.sens-badge.medium { color: var(--gilt); border-color: var(--gilt-dim); }
|
||||
.sens-badge.high { color: var(--cinnabar); border-color: var(--cinnabar-dim); background: rgba(184, 57, 46, 0.1); }
|
||||
.mem-foot { display: flex; align-items: center; gap: 10px; margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--rule); font-size: 11px; color: var(--fg-faint); flex-wrap: wrap; }
|
||||
.mem-foot .evi { display: inline-flex; align-items: center; gap: 4px; }
|
||||
.mem-foot .act { margin-left: auto; display: flex; gap: 6px; }
|
||||
.mem-foot .act button { font-family: inherit; font-size: 11px; padding: 3px 10px; border-radius: 5px; border: 1px solid var(--rule); background: var(--surface); color: var(--fg-dim); cursor: pointer; }
|
||||
.mem-foot .act button:hover { color: var(--fg); border-color: var(--gilt-dim); }
|
||||
.mem-foot .act button.primary { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
|
||||
/* 右栏 */
|
||||
.rail-card { background: var(--surface); border: 1px solid var(--rule); border-radius: 8px; padding: 16px 18px; }
|
||||
.rail-card h3 { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin: 0 0 12px; }
|
||||
.search-box { display: flex; align-items: center; gap: 8px; padding: 8px 12px; border: 1px solid var(--rule); border-radius: 7px; background: var(--ink); }
|
||||
.search-box input { flex: 1; background: none; border: none; outline: none; color: var(--fg); font-family: inherit; font-size: 13px; }
|
||||
.search-box input::placeholder { color: var(--fg-faint); }
|
||||
.review-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
.review-rule { display: flex; align-items: flex-start; gap: 8px; font-size: 12px; color: var(--fg-dim); line-height: 1.5; }
|
||||
.review-rule .mark { color: var(--cinnabar); flex-shrink: 0; font-family: "Songti SC", serif; font-weight: 700; }
|
||||
.review-rule.allow .mark { color: var(--patina); }
|
||||
.conflict-row { display: flex; align-items: center; gap: 9px; padding: 9px 11px; border-radius: 5px; background: var(--ink); border: 1px solid var(--cinnabar-dim); font-size: 12px; }
|
||||
.conflict-row .pair { font-family: "Songti SC", serif; color: var(--cinnabar); flex-shrink: 0; }
|
||||
.conflict-row .desc { color: var(--fg-dim); flex: 1; min-width: 0; }
|
||||
.conflict-row .verdict { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--gilt); white-space: nowrap; }
|
||||
|
||||
@media (max-width: 1080px) { .mem-region { flex-direction: column; } .mem-rail { width: 100%; } }
|
||||
@media (max-width: 900px) { .stat-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="记忆"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">记忆</span>
|
||||
<span class="page-sub">息壤枢 · 长期记忆</span>
|
||||
<span class="char-pill"><span class="avatar-mini">梧</span>青梧</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="pending-pill">3 条候选待审</span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 分类栏 -->
|
||||
<div>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 记忆分类 <span class="sub">基础五类 + 扩展五类</span></div>
|
||||
<div class="type-bar">
|
||||
<span class="type-chip active">全部 <span class="cnt">186</span></span>
|
||||
<span class="type-chip">身份 <span class="cnt">8</span></span>
|
||||
<span class="type-chip">用户 <span class="cnt">23</span></span>
|
||||
<span class="type-chip">情节 <span class="cnt">61</span></span>
|
||||
<span class="type-chip">语义 <span class="cnt">34</span></span>
|
||||
<span class="type-chip">程序 <span class="cnt">19</span></span>
|
||||
<span class="type-chip">关系 <span class="cnt">15</span></span>
|
||||
<span class="type-chip">情绪 <span class="cnt">11</span></span>
|
||||
<span class="type-chip">世界 <span class="cnt">9</span></span>
|
||||
<span class="type-chip">反思 <span class="cnt">4</span></span>
|
||||
<span class="type-chip">演化 <span class="cnt">2</span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计 -->
|
||||
<div class="stat-grid">
|
||||
<div class="stat-card"><div class="k">记忆总数</div><div class="v">186</div><div class="sub">活跃 174 · 已删 12</div></div>
|
||||
<div class="stat-card alert"><div class="k">高敏感</div><div class="v">5<small>条</small></div><div class="sub">默认不自动注入</div></div>
|
||||
<div class="stat-card warn"><div class="k">待审候选</div><div class="v">3<small>条</small></div><div class="sub">写入审查中</div></div>
|
||||
<div class="stat-card"><div class="k">本周新增</div><div class="v">14<small>条</small></div><div class="sub">证据关联率 0.81</div></div>
|
||||
</div>
|
||||
|
||||
<!-- 记忆卡 + 右栏 -->
|
||||
<div class="mem-region">
|
||||
<div class="mem-main">
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">记忆条目 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">MemoryRecord · 置信度 × 重要性 × 来源 × 证据</span></h3>
|
||||
<div class="mem-list">
|
||||
<div class="mem-card">
|
||||
<div class="mem-head">
|
||||
<span class="mem-title">用户偏好简洁回答</span>
|
||||
<span class="mem-type user">user</span>
|
||||
<span class="sens-badge low">sens · low</span>
|
||||
</div>
|
||||
<div class="mem-content">用户多次要求"长话短说,先给结论",倾向结构化、要点式回复。</div>
|
||||
<div class="mem-meta">
|
||||
<span class="meta-item conf"><span class="lab">conf</span><span class="meta-bar"><span class="fill" style="width:92%"></span></span><span class="vv">0.92</span></span>
|
||||
<span class="meta-item imp"><span class="lab">imp</span><span class="meta-bar"><span class="fill" style="width:80%"></span></span><span class="vv">0.80</span></span>
|
||||
<span class="meta-item"><span class="lab">来源</span>用户明确表达</span>
|
||||
</div>
|
||||
<div class="mem-foot">
|
||||
<span class="evi">📎 3 条证据</span>
|
||||
<span>更新于 07-09</span>
|
||||
<span class="act"><button type="button">编辑</button><button type="button">版本</button></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mem-card pending">
|
||||
<div class="mem-head">
|
||||
<span class="mem-title">用户近期提及"想学陶艺"</span>
|
||||
<span class="mem-type episodic">episodic</span>
|
||||
<span class="sens-badge medium">sens · medium</span>
|
||||
</div>
|
||||
<div class="mem-content">07-11 对话中两次提到对陶艺的兴趣,疑为长期目标候选--待确认是否长期偏好。</div>
|
||||
<div class="mem-meta">
|
||||
<span class="meta-item conf"><span class="lab">conf</span><span class="meta-bar"><span class="fill" style="width:58%"></span></span><span class="vv">0.58</span></span>
|
||||
<span class="meta-item imp"><span class="lab">imp</span><span class="meta-bar"><span class="fill" style="width:66%"></span></span><span class="vv">0.66</span></span>
|
||||
<span class="meta-item"><span class="lab">来源</span>对话推断</span>
|
||||
</div>
|
||||
<div class="mem-foot">
|
||||
<span class="evi">📎 2 条证据</span>
|
||||
<span>待写入审查</span>
|
||||
<span class="act"><button type="button" class="primary">采纳</button><button type="button">驳回</button></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mem-card high-sens">
|
||||
<div class="mem-head">
|
||||
<span class="mem-title">用户健康指标(睡眠 / 心率摘要)</span>
|
||||
<span class="mem-type user">user</span>
|
||||
<span class="sens-badge high">sens · high</span>
|
||||
</div>
|
||||
<div class="mem-content">来自感知摘要的结构化健康状态,高敏感--仅在用户主动询问时按需召回,不进入常规上下文。</div>
|
||||
<div class="mem-meta">
|
||||
<span class="meta-item conf"><span class="lab">conf</span><span class="meta-bar"><span class="fill" style="width:88%"></span></span><span class="vv">0.88</span></span>
|
||||
<span class="meta-item imp"><span class="lab">imp</span><span class="meta-bar"><span class="fill" style="width:45%"></span></span><span class="vv">0.45</span></span>
|
||||
<span class="meta-item"><span class="lab">来源</span>感知事件</span>
|
||||
</div>
|
||||
<div class="mem-foot">
|
||||
<span class="evi">📎 5 条证据</span>
|
||||
<span>受限注入</span>
|
||||
<span class="act"><button type="button">查看</button><button type="button">遗忘</button></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mem-card">
|
||||
<div class="mem-head">
|
||||
<span class="mem-title">人格基调:温和而克制</span>
|
||||
<span class="mem-type identity">identity</span>
|
||||
<span class="sens-badge none">sens · none</span>
|
||||
</div>
|
||||
<div class="mem-content">角色设定确立的稳定身份记忆:语气克制、不轻许诺、重视边界。与人格面板同源。</div>
|
||||
<div class="mem-meta">
|
||||
<span class="meta-item conf"><span class="lab">conf</span><span class="meta-bar"><span class="fill" style="width:99%"></span></span><span class="vv">0.99</span></span>
|
||||
<span class="meta-item imp"><span class="lab">imp</span><span class="meta-bar"><span class="fill" style="width:95%"></span></span><span class="vv">0.95</span></span>
|
||||
<span class="meta-item"><span class="lab">来源</span>初始设定</span>
|
||||
</div>
|
||||
<div class="mem-foot">
|
||||
<span class="evi">📎 1 条证据</span>
|
||||
<span>更新于 05-31</span>
|
||||
<span class="act"><button type="button">编辑</button></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mem-card">
|
||||
<div class="mem-head">
|
||||
<span class="mem-title">夜间回复易触发关怀语气</span>
|
||||
<span class="mem-type emotional">emotional</span>
|
||||
<span class="sens-badge low">sens · low</span>
|
||||
</div>
|
||||
<div class="mem-content">23:00 后用户对话情绪偏脆弱,灵核情绪状态机转入 wistful;回复基调相应软化。</div>
|
||||
<div class="mem-meta">
|
||||
<span class="meta-item conf"><span class="lab">conf</span><span class="meta-bar"><span class="fill" style="width:74%"></span></span><span class="vv">0.74</span></span>
|
||||
<span class="meta-item imp"><span class="lab">imp</span><span class="meta-bar"><span class="fill" style="width:70%"></span></span><span class="vv">0.70</span></span>
|
||||
<span class="meta-item"><span class="lab">来源</span>情绪归纳</span>
|
||||
</div>
|
||||
<div class="mem-foot">
|
||||
<span class="evi">📎 4 条证据</span>
|
||||
<span>更新于 07-10</span>
|
||||
<span class="act"><button type="button">编辑</button></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mem-card">
|
||||
<div class="mem-head">
|
||||
<span class="mem-title">工具调用:发消息前必须二次确认</span>
|
||||
<span class="mem-type procedural">procedural</span>
|
||||
<span class="sens-badge none">sens · none</span>
|
||||
</div>
|
||||
<div class="mem-content">程序性经验:send_message 属 L3 高风险,任何渠道发送前需用户确认,不可自动执行。</div>
|
||||
<div class="mem-meta">
|
||||
<span class="meta-item conf"><span class="lab">conf</span><span class="meta-bar"><span class="fill" style="width:96%"></span></span><span class="vv">0.96</span></span>
|
||||
<span class="meta-item imp"><span class="lab">imp</span><span class="meta-bar"><span class="fill" style="width:90%"></span></span><span class="vv">0.90</span></span>
|
||||
<span class="meta-item"><span class="lab">来源</span>安全教训</span>
|
||||
</div>
|
||||
<div class="mem-foot">
|
||||
<span class="evi">📎 2 条证据</span>
|
||||
<span>更新于 06-28</span>
|
||||
<span class="act"><button type="button">编辑</button></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mem-rail">
|
||||
<div class="rail-card">
|
||||
<h3>检索记忆</h3>
|
||||
<div class="search-box">
|
||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" style="color:var(--fg-faint)"><circle cx="7" cy="7" r="4.5" /><path d="M10.5 10.5L14 14" /></svg>
|
||||
<input type="text" placeholder="按内容 / 来源 / 证据检索…" />
|
||||
</div>
|
||||
<div style="margin-top:10px;font-size:11px;color:var(--fg-faint);font-family:'JetBrains Mono',monospace">召回策略 · 混合(语义 + 时间衰减 + 重要度)</div>
|
||||
</div>
|
||||
|
||||
<div class="rail-card">
|
||||
<h3>写入审查规则 <span style="font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--fg-faint);font-weight:400">§5</span></h3>
|
||||
<div class="review-list">
|
||||
<div class="review-rule allow"><span class="mark">✓</span><span>用户明确要求记住 · 长期偏好 · 反复出现的事实</span></div>
|
||||
<div class="review-rule"><span class="mark">✕</span><span>含密钥 / 令牌 / 密码 · 签名 URL</span></div>
|
||||
<div class="review-rule"><span class="mark">✕</span><span>未经验证的推断当事实写入</span></div>
|
||||
<div class="review-rule"><span class="mark">!</span><span>高敏感默认不自动写入,需用户确认</span></div>
|
||||
<div class="review-rule"><span class="mark">!</span><span>与既有记忆重复 → 合并而非新增</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rail-card">
|
||||
<h3>冲突裁决 <span style="font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--fg-faint);font-weight:400">§6.1</span></h3>
|
||||
<div style="display:flex;flex-direction:column;gap:8px">
|
||||
<div class="conflict-row">
|
||||
<span class="pair">新 vs 旧</span>
|
||||
<span class="desc">"偏好简洁" 与旧记忆 "偏好详细" 冲突</span>
|
||||
<span class="verdict">置信高者胜</span>
|
||||
</div>
|
||||
<div class="conflict-row">
|
||||
<span class="pair">覆写</span>
|
||||
<span class="desc">新证据置信 0.92 > 旧 0.61</span>
|
||||
<span class="verdict">已合并</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,612 @@
|
||||
<!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 — 模型网关页
|
||||
* 能力槽位(默认路由)+ 模型清单(多供应商端点池)+ 定价对照 + 能力矩阵
|
||||
* 数据源:config/models · providers · pricing example
|
||||
* 对齐 docs/architecture/service-boundaries.md §6/§7/§8/§13/§14。
|
||||
* ============================================================ */
|
||||
|
||||
.page-header .spacer { flex: 1; }
|
||||
.stat-pills { display: flex; gap: 8px; flex-wrap: wrap; }
|
||||
|
||||
.stat-pill .v { color: var(--patina); font-weight: 600; }
|
||||
.stat-pill .v.gilt { color: var(--gilt); }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
.section-header { font-family: "JetBrains Mono", monospace; font-size: 12px; letter-spacing: 0.1em; color: var(--fg-faint); margin-bottom: 12px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
||||
.section-header .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-header .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
.section-caption { font-size: 11.5px; color: var(--fg-faint); margin-top: 8px; line-height: 1.5; }
|
||||
|
||||
/* ── 能力槽位(默认路由)── */
|
||||
.slot-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
|
||||
.slot-card { border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 13px 15px; display: flex; flex-direction: column; gap: 7px; transition: border-color 0.12s; }
|
||||
.slot-card.set { border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.slot-card.unset { border-style: dashed; }
|
||||
.slot-top { display: flex; align-items: baseline; gap: 8px; }
|
||||
.slot-label { font-family: "Songti SC", serif; font-size: 14px; font-weight: 700; color: var(--fg); }
|
||||
.slot-hint { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.slot-current { font-family: "JetBrains Mono", monospace; font-size: 12.5px; color: var(--patina-bright); font-weight: 600; line-height: 1.4; }
|
||||
.slot-card.unset .slot-current { color: var(--fg-faint); font-weight: 400; }
|
||||
.slot-display { font-size: 11.5px; color: var(--fg-dim); font-family: -apple-system, "PingFang SC", sans-serif; font-weight: 400; }
|
||||
.slot-select { font-family: "JetBrains Mono", monospace; font-size: 11.5px; padding: 6px 9px; border-radius: 6px; border: 1px solid var(--rule); background: var(--ink); color: var(--fg); width: 100%; margin-top: auto; }
|
||||
.slot-select:focus { outline: none; border-color: var(--patina-dim); }
|
||||
.slot-empty { font-size: 11px; color: var(--fg-faint); font-family: "JetBrains Mono", monospace; padding: 6px 0; margin-top: auto; line-height: 1.5; }
|
||||
|
||||
/* ── 供应商分组 + 模型卡 ── */
|
||||
.provider-group { display: flex; flex-direction: column; gap: 10px; margin-bottom: 4px; }
|
||||
.provider-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; font-family: "Songti SC", serif; font-size: 14px; font-weight: 700; color: var(--fg); }
|
||||
.provider-head .ph-key { color: var(--fg-faint); font-family: "JetBrains Mono", monospace; font-size: 12px; font-weight: 500; }
|
||||
.provider-head .ph-meta { font-family: "JetBrains Mono", monospace; font-size: 10.5px; font-weight: 400; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.provider-head .ph-meta .sep { opacity: 0.5; margin: 0 5px; }
|
||||
.provider-head .ph-line { flex: 1; height: 1px; background: var(--rule); min-width: 20px; }
|
||||
.provider-head .ph-key-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--patina); flex-shrink: 0; align-self: center; }
|
||||
|
||||
.model-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
|
||||
.model-card { border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 14px 16px; display: flex; flex-direction: column; gap: 11px; transition: border-color 0.12s; }
|
||||
.model-card:hover { border-color: var(--gilt-dim); }
|
||||
.model-card.is-default { border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.model-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
.model-star { color: var(--patina); font-size: 13px; line-height: 1; flex-shrink: 0; }
|
||||
.model-star.off { visibility: hidden; }
|
||||
.model-name { font-family: "JetBrains Mono", monospace; font-size: 13.5px; font-weight: 600; color: var(--fg); }
|
||||
.model-real { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); }
|
||||
.model-real .arr { opacity: 0.6; margin-right: 2px; }
|
||||
.model-tag { font-family: "JetBrains Mono", monospace; font-size: 9.5px; padding: 2px 7px; border-radius: 3px; border: 1px solid var(--rule); color: var(--fg-faint); background: transparent; }
|
||||
.model-tag.fmt { border-color: var(--rule); color: var(--fg-faint); }
|
||||
.model-tag.default-tag { border-color: var(--patina-dim); color: var(--patina); background: var(--patina-wash); }
|
||||
.model-tag.fallback { border-color: var(--gilt-dim); color: var(--gilt); background: var(--gilt-faint); }
|
||||
.model-tag.fast { border-color: var(--cinnabar-dim); color: var(--cinnabar); background: rgba(184, 57, 46, 0.08); }
|
||||
.model-desc { font-size: 12.5px; color: var(--fg-dim); line-height: 1.55; min-height: 30px; }
|
||||
|
||||
/* spec 微网格(全字段,空值显 —) */
|
||||
.model-specs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--rule); border: 1px solid var(--rule); border-radius: 6px; overflow: hidden; }
|
||||
.model-specs .cell { background: color-mix(in srgb, var(--ink) 55%, transparent); padding: 6px 9px; }
|
||||
.model-specs .cell .k { font-family: "JetBrains Mono", monospace; font-size: 9px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--fg-faint); }
|
||||
.model-specs .cell .v { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg); margin-top: 1px; }
|
||||
.model-specs .cell .v .sub { color: var(--fg-faint); font-size: 9.5px; display: block; margin-top: 1px; }
|
||||
.model-specs .cell .v.na { color: var(--fg-faint); opacity: 0.55; }
|
||||
|
||||
/* 计价条(原值不四舍五入) */
|
||||
.model-price { display: flex; flex-wrap: wrap; gap: 8px 18px; padding: 9px 11px; border: 1px solid var(--gilt-dim); border-radius: 6px; background: var(--gilt-faint); }
|
||||
.model-price .price-cell { display: flex; flex-direction: column; gap: 1px; }
|
||||
.model-price .pk { font-family: "JetBrains Mono", monospace; font-size: 8.5px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--gilt); opacity: 0.78; }
|
||||
.model-price .pv { font-family: "JetBrains Mono", monospace; font-size: 13px; color: var(--gilt); font-weight: 600; }
|
||||
.model-price .pv .ccy { font-size: 10px; opacity: 0.7; margin-left: 1px; }
|
||||
.model-price .pv.na { color: var(--fg-faint); font-size: 12px; font-weight: 400; opacity: 0.7; }
|
||||
|
||||
/* 能力点阵 */
|
||||
.model-caps { display: flex; flex-wrap: wrap; gap: 5px 11px; }
|
||||
.model-caps .cap { display: inline-flex; align-items: center; gap: 4px; font-size: 10.5px; color: var(--fg-dim); font-family: "JetBrains Mono", monospace; }
|
||||
.model-caps .cap .d { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
|
||||
.model-caps .cap.on .d { background: var(--patina); }
|
||||
.model-caps .cap.off { color: var(--fg-faint); opacity: 0.6; }
|
||||
.model-caps .cap.off .d { background: var(--fg-faint); opacity: 0.32; }
|
||||
|
||||
/* 多供应商端点池 */
|
||||
.ep-pool { display: flex; flex-direction: column; gap: 4px; border: 1px solid var(--rule); border-radius: 6px; padding: 8px 10px; background: color-mix(in srgb, var(--ink) 40%, transparent); }
|
||||
.ep-pool .ep-title { font-family: "JetBrains Mono", monospace; font-size: 9px; text-transform: uppercase; letter-spacing: 0.07em; color: var(--fg-faint); margin-bottom: 3px; }
|
||||
.ep-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-dim); line-height: 1.5; }
|
||||
.ep-row .ep-status { width: 7px; height: 7px; border-radius: 50%; background: var(--patina); flex-shrink: 0; }
|
||||
.ep-row .ep-status.off { background: var(--fg-faint); opacity: 0.4; }
|
||||
.ep-row .ep-name { color: var(--patina); }
|
||||
.ep-row .ep-fmt { color: var(--gilt); font-size: 10px; }
|
||||
.ep-row .ep-env { color: var(--fg-faint); font-size: 10px; }
|
||||
.ep-row .ep-override { color: var(--cinnabar); font-size: 10px; }
|
||||
.ep-row .ep-f { display: inline-flex; align-items: baseline; gap: 2px; }
|
||||
.ep-row .ep-f i { font-style: normal; color: var(--fg-faint); font-size: 9px; text-transform: uppercase; letter-spacing: 0.05em; }
|
||||
.ep-row .ep-f .na { color: var(--fg-faint); opacity: 0.5; }
|
||||
.ep-row .ep-sep { color: var(--rule); }
|
||||
|
||||
/* ── 通用表格 ── */
|
||||
.cap-table { border: 1px solid var(--rule); border-radius: 8px; overflow: hidden; background: var(--surface); }
|
||||
.cap-table table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
|
||||
.cap-table th, .cap-table td { padding: 9px 14px; text-align: left; border-bottom: 1px solid var(--rule); }
|
||||
.cap-table tr:last-child td { border-bottom: none; }
|
||||
.cap-table th { font-family: "JetBrains Mono", monospace; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--fg-faint); font-weight: 600; background: var(--surface-hi); white-space: nowrap; }
|
||||
.cap-table td.model-col { font-family: "JetBrains Mono", monospace; color: var(--fg); font-weight: 500; white-space: nowrap; }
|
||||
.cap-table td.model-col .star { color: var(--patina); margin-right: 4px; }
|
||||
.cap-table td.num, .cap-table th.num { text-align: right; font-family: "JetBrains Mono", monospace; }
|
||||
.cap-table td.num.cost { color: var(--gilt); font-weight: 600; }
|
||||
.cap-table tr.default-row td { background: var(--patina-wash); }
|
||||
.cap-table tr.default-row td.model-col { color: var(--patina); }
|
||||
.cap-table td .ccy { color: var(--fg-faint); font-size: 10.5px; }
|
||||
.cap-table td .na { color: var(--fg-faint); opacity: 0.55; }
|
||||
.cap-dot { display: inline-flex; align-items: center; gap: 6px; }
|
||||
.cap-dot .d { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
|
||||
.cap-dot .d.full { background: var(--patina); }
|
||||
.cap-dot .d.no { background: var(--fg-faint); opacity: 0.4; }
|
||||
.cap-dot span { font-size: 11px; color: var(--fg-dim); }
|
||||
.cap-table .grp td { font-family: "Songti SC", serif; font-size: 12px; font-weight: 700; color: var(--fg-dim); background: color-mix(in srgb, var(--surface-hi) 60%, transparent); padding: 6px 14px; }
|
||||
.cap-table .grp td .gkey { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); font-weight: 400; margin-left: 6px; }
|
||||
|
||||
/* ── 语音 / 专用能力 ── */
|
||||
.audio-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
|
||||
.audio-card { border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 12px 14px; display: flex; flex-direction: column; gap: 5px; }
|
||||
.audio-card.is-default { border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.audio-card .a-head { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
|
||||
.audio-card .a-name { font-family: "JetBrains Mono", monospace; font-size: 12px; font-weight: 600; color: var(--fg); }
|
||||
.audio-card .a-kind { font-size: 9px; font-family: "JetBrains Mono", monospace; text-transform: uppercase; letter-spacing: 0.07em; color: var(--cinnabar); border: 1px solid var(--cinnabar-dim); padding: 1px 6px; border-radius: 3px; }
|
||||
.audio-card .a-tag { font-size: 12px; color: var(--fg-dim); }
|
||||
.audio-card .a-spec { font-size: 10.5px; color: var(--fg-faint); font-family: "JetBrains Mono", monospace; display: flex; flex-wrap: wrap; gap: 2px 10px; margin-top: 2px; }
|
||||
.audio-card .a-spec .na { opacity: 0.5; }
|
||||
|
||||
@media (max-width: 980px) { .slot-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 900px) { .model-grid { grid-template-columns: 1fr; } .audio-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } .cap-table { overflow-x: auto; } .cap-table table { min-width: 540px; } .slot-grid, .audio-grid { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏(active=模型网关)════════ -->
|
||||
<div class="sidebar-mount" data-active="模型网关"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">模型网关</span>
|
||||
<span class="page-sub">神识 · 多供应商统一接入与路由</span>
|
||||
<span class="spacer"></span>
|
||||
<div class="stat-pills">
|
||||
<span class="stat-pill">对话模型 <span class="v">7</span></span>
|
||||
<span class="stat-pill">专用槽 <span class="v">4</span></span>
|
||||
<span class="stat-pill">供应商 <span class="v">3</span></span>
|
||||
<span class="stat-pill">已设默认 <span class="v gilt" id="stat-set">4</span>/6</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 能力槽位(默认路由) -->
|
||||
<div>
|
||||
<div class="section-header"><span class="glyph">⟡</span> 能力槽位 · 默认路由 <span class="sub">model-gateway §13/§14 · 按能力解析为默认模型</span></div>
|
||||
<div class="slot-grid" id="slot-grid"></div>
|
||||
<p class="section-caption">业务层只引用能力槽位(model_hint),网关将其解析为下列默认模型;空槽表示该能力尚未配置可用模型,<code>models.yaml</code> 增配后自动出现。</p>
|
||||
</div>
|
||||
|
||||
<!-- 模型清单 -->
|
||||
<div>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">模型清单 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">models.yaml + providers.yaml + pricing.yaml · 全字段 · 多供应商端点池</span></h3>
|
||||
<div id="model-list"></div>
|
||||
</div>
|
||||
|
||||
<!-- 定价对照 -->
|
||||
<div>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">定价对照 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">pricing.yaml · 每 1M tokens · 原值不四舍五入</span></h3>
|
||||
<div class="cap-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>模型</th>
|
||||
<th class="num">输入 / 1M</th>
|
||||
<th class="num">缓存命中 / 1M</th>
|
||||
<th class="num">输出 / 1M</th>
|
||||
<th class="num">混合(1M 入 + 1M 出)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="price-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="section-caption">混合列为同币种 input + output 之和,便于横向比较;保持厂商原始币种,不做跨币种换算(§7.3)。缓存命中价缺省记 -,按输入价计费。</p>
|
||||
</div>
|
||||
|
||||
<!-- 能力矩阵 -->
|
||||
<div>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">能力矩阵 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">model-gateway §6/§13 · supports_* 显式声明</span></h3>
|
||||
<div class="cap-table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>模型</th>
|
||||
<th class="num">上下文</th>
|
||||
<th>工具</th>
|
||||
<th>思考</th>
|
||||
<th>推理 effort</th>
|
||||
<th>结构化</th>
|
||||
<th>流式</th>
|
||||
<th>视觉</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="cap-body"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 语音 / 专用能力 -->
|
||||
<div>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">语音 / 专用能力 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">asr · tts · 声纹 · 音色 · 后续 embedding/reranker 槽位预留</span></h3>
|
||||
<div class="audio-grid" id="audio-grid"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* ── 数据:取自 config/models · providers · pricing example ── */
|
||||
const PROVIDERS = {
|
||||
deepseek: { label: "深度求索", format: "openai", baseEnv: "DEEPSEEK_BASE_URL", apiKeyEnv: "DEEPSEEK_API_KEY", timeout: 300, retries: 2 },
|
||||
anthropic: { label: "Anthropic", format: "anthropic", baseEnv: "ANTHROPIC_BASE_URL", apiKeyEnv: "ANTHROPIC_API_KEY", timeout: 120, retries: 1 },
|
||||
xiaomi: { label: "小米 MiMo", format: "openai", baseEnv: "XIAOMI_MIMO_BASE_URL", apiKeyEnv: "XIAOMI_MIMO_API_KEY", timeout: 300, retries: 2 },
|
||||
};
|
||||
|
||||
// 对话模型(deepseek-v4-pro 已合并 anthropic 格式端点;同模型不同消息格式不重复成卡)
|
||||
const MODELS = [
|
||||
{
|
||||
name: "deepseek-v4-flash", display: "DeepSeek V4 Flash", provider: "deepseek",
|
||||
real: "deepseek-v4-flash", tags: [{ k: "fallback", t: "默认" }],
|
||||
ctx: 1000000, reserve: 8192, maxOut: 384000, timeout: 300,
|
||||
privacy: null, effort: null,
|
||||
routing: "priority_failover", pool: true,
|
||||
caps: { tools: 1, think: 1, effort: 1, struct: 1, stream: 1, vision: 0 },
|
||||
endpoints: [
|
||||
{ name: "primary", model: "deepseek-v4-flash", fmt: "openai", baseEnv: "DEEPSEEK_BASE_URL", status: "active", p: 10, w: 100, rpm: 2500, tpm: null, conc: null },
|
||||
{ name: "fallback", model: "deepseek-v4-pro", fmt: "openai", baseEnv: "DEEPSEEK_BASE_URL", status: "active", p: 20, w: 50, rpm: null, tpm: null, conc: null },
|
||||
],
|
||||
price: { ccy: "CNY", in: 1.0, cache: 0.02, out: 2.0 },
|
||||
desc: "默认对话与生成主模型;长上下文、低成本,工具与思考皆备,端点池带 failover。",
|
||||
},
|
||||
{
|
||||
name: "deepseek-v4-pro", display: "DeepSeek V4 Pro", provider: "deepseek",
|
||||
real: "deepseek-v4-pro", tags: [{ k: "fallback", t: "备选" }],
|
||||
ctx: 1000000, reserve: 8192, maxOut: 384000, timeout: 300,
|
||||
privacy: null, effort: null,
|
||||
routing: "priority_failover", pool: true,
|
||||
caps: { tools: 1, think: 1, effort: 1, struct: 1, stream: 1, vision: 0 },
|
||||
endpoints: [
|
||||
{ name: "primary", model: "deepseek-v4-pro", fmt: "openai", baseEnv: "DEEPSEEK_BASE_URL", status: "active", p: 10, w: 100, rpm: null, tpm: null, conc: null },
|
||||
{ name: "anthropic", model: "deepseek-v4-pro", fmt: "anthropic", baseEnv: "DEEPSEEK_ANTHROPIC_BASE_URL", status: "active", p: 10, w: 100, rpm: null, tpm: null, conc: null },
|
||||
],
|
||||
price: { ccy: "CNY", in: 3.0, cache: 0.025, out: 6.0 },
|
||||
desc: "高难推理与长文写作主力;同一模型提供 openai 与 anthropic 两种消息协议端点,价格与能力一致。",
|
||||
},
|
||||
{
|
||||
name: "claude-sonnet", display: "Claude Sonnet", provider: "anthropic",
|
||||
real: "claude-sonnet-4-6", tags: [],
|
||||
ctx: 1000000, reserve: 16000, maxOut: 16000, timeout: 60,
|
||||
privacy: null, effort: "medium",
|
||||
routing: null, pool: false,
|
||||
caps: { tools: 1, think: 1, effort: 1, struct: 1, stream: 1, vision: 1 },
|
||||
endpoints: null,
|
||||
price: { ccy: "USD", in: 3.0, cache: 0.30, out: 15.0 },
|
||||
desc: "均衡型主力,推理与工具调用稳定;中文叙事自然,可读图。默认 effort: medium。",
|
||||
},
|
||||
{
|
||||
name: "claude-haiku", display: "Claude Haiku", provider: "anthropic",
|
||||
real: "claude-haiku-4-5", tags: [{ k: "fast", t: "轻量" }],
|
||||
ctx: 200000, reserve: 4096, maxOut: 4096, timeout: 60,
|
||||
privacy: null, effort: null,
|
||||
routing: null, pool: false,
|
||||
caps: { tools: 1, think: 0, effort: 0, struct: 1, stream: 1, vision: 1 },
|
||||
endpoints: null,
|
||||
price: { ccy: "USD", in: 1.0, cache: 0.10, out: 5.0 },
|
||||
desc: "低延迟轻量档,适合快速回复与短抽取;不支持思考模式。",
|
||||
},
|
||||
{
|
||||
name: "claude-fable", display: "Claude Fable 5", provider: "anthropic",
|
||||
real: "claude-fable-5", tags: [{ k: "fallback", t: "推理" }],
|
||||
ctx: 1000000, reserve: 16000, maxOut: 16000, timeout: 120,
|
||||
privacy: null, effort: "high",
|
||||
routing: null, pool: false,
|
||||
caps: { tools: 1, think: 1, effort: 1, struct: 1, stream: 1, vision: 1 },
|
||||
endpoints: null,
|
||||
price: { ccy: "USD", in: 10.0, cache: 1.00, out: 50.0 },
|
||||
desc: "最强推理与长程规划,思考常开、effort: high;成本最高,留作关键决策。",
|
||||
},
|
||||
{
|
||||
name: "mimo-v2.5-pro", display: "MiMo v2.5 Pro", provider: "xiaomi",
|
||||
real: "mimo-v2.5-pro", tags: [],
|
||||
ctx: 128000, reserve: 8192, maxOut: 32768, timeout: 300,
|
||||
privacy: null, effort: null,
|
||||
routing: "priority_failover", pool: true,
|
||||
caps: { tools: 1, think: 0, effort: 1, struct: 1, stream: 1, vision: 1 },
|
||||
endpoints: [
|
||||
{ name: "primary", model: "mimo-v2.5-pro", fmt: "openai", baseEnv: "XIAOMI_MIMO_BASE_URL", status: "active", p: 10, w: 100, rpm: null, tpm: null, conc: null },
|
||||
],
|
||||
price: { ccy: "CNY", in: 4.0, cache: null, out: 12.0 },
|
||||
desc: "国产多模态主力,视觉与工具兼顾;中文场景性价比高。",
|
||||
},
|
||||
{
|
||||
name: "mimo-v2.5", display: "MiMo v2.5", provider: "xiaomi",
|
||||
real: "mimo-v2.5", tags: [{ k: "fast", t: "轻量" }],
|
||||
ctx: 128000, reserve: 4096, maxOut: 16384, timeout: 180,
|
||||
privacy: null, effort: null,
|
||||
routing: null, pool: false,
|
||||
caps: { tools: 1, think: 0, effort: 0, struct: 1, stream: 1, vision: 1 },
|
||||
endpoints: null,
|
||||
price: { ccy: "CNY", in: 1.0, cache: null, out: 4.0 },
|
||||
desc: "日常对话轻量档,响应快、单价低;视觉可读图。",
|
||||
},
|
||||
];
|
||||
|
||||
// 语音 / 专用能力
|
||||
const AUDIO = [
|
||||
{ name: "mimo-v2.5-asr", display: "MiMo v2.5 ASR", provider: "xiaomi", kind: "asr", kindLabel: "ASR", tag: "语音转文字", stream: 0, timeout: 120, fmt: "openai", baseEnv: "XIAOMI_MIMO_BASE_URL", price: null },
|
||||
{ name: "mimo-v2.5-tts", display: "MiMo v2.5 TTS", provider: "xiaomi", kind: "tts", kindLabel: "TTS", tag: "文字转语音", stream: 1, timeout: 120, fmt: "openai", baseEnv: "XIAOMI_MIMO_BASE_URL", price: null },
|
||||
{ name: "mimo-v2.5-tts-voiceclone", display: "MiMo v2.5 声纹克隆", provider: "xiaomi", kind: "tts", kindLabel: "TTS", tag: "声纹克隆", stream: 1, timeout: 300, fmt: "openai", baseEnv: "XIAOMI_MIMO_BASE_URL", price: null },
|
||||
{ name: "mimo-v2.5-tts-voicedesign", display: "MiMo v2.5 音色设计", provider: "xiaomi", kind: "tts", kindLabel: "TTS", tag: "音色设计", stream: 1, timeout: 300, fmt: "openai", baseEnv: "XIAOMI_MIMO_BASE_URL", price: null },
|
||||
];
|
||||
|
||||
// 能力槽位(默认路由)
|
||||
const SLOTS = [
|
||||
{ key: "chat", label: "默认对话", hint: "default-chat", pick: () => MODELS },
|
||||
{ key: "reasoning", label: "默认推理", hint: "reasoning", pick: () => MODELS.filter((m) => m.caps.think) },
|
||||
{ key: "vision", label: "视觉理解", hint: "vision", pick: () => MODELS.filter((m) => m.caps.vision) },
|
||||
{ key: "tts", label: "语音合成", hint: "tts", pick: () => AUDIO.filter((a) => a.kind === "tts") },
|
||||
{ key: "embedding", label: "向量化", hint: "embedding", pick: () => AUDIO.filter((a) => a.kind === "embedding") },
|
||||
{ key: "reranker", label: "重排序", hint: "reranker", pick: () => AUDIO.filter((a) => a.kind === "reranker") },
|
||||
];
|
||||
|
||||
const state = {
|
||||
defaults: {
|
||||
chat: "deepseek-v4-flash",
|
||||
reasoning: "claude-fable",
|
||||
vision: "mimo-v2.5-pro",
|
||||
tts: "mimo-v2.5-tts",
|
||||
embedding: null,
|
||||
reranker: null,
|
||||
},
|
||||
};
|
||||
|
||||
/* ── 工具函数 ── */
|
||||
const fmt = (n) => (n == null ? "-" : n.toLocaleString("en-US"));
|
||||
const ccySym = (c) => (c === "USD" ? "$" : "¥");
|
||||
// 原值原样,不四舍五入
|
||||
function money(c, v) { return v == null ? "-" : ccySym(c) + v; }
|
||||
function fmtCtx(n) {
|
||||
if (n == null) return "-";
|
||||
if (n >= 1000000) return (n / 1000000).toFixed(n % 1000000 === 0 ? 0 : 1) + "M";
|
||||
if (n >= 1000) return (n / 1000).toFixed(0) + "K";
|
||||
return String(n);
|
||||
}
|
||||
function fmtCtxFull(n) { return n == null ? "-" : n >= 1000 ? n.toLocaleString("en-US") : String(n); }
|
||||
const esc = (s) => String(s).replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ }[c]));
|
||||
const orDash = (v) => (v == null || v === "" ? "-" : v);
|
||||
function findChat(name) { return MODELS.find((m) => m.name === name); }
|
||||
function findAudio(name) { return AUDIO.find((a) => a.name === name); }
|
||||
function labelOf(name) { const m = findChat(name) || findAudio(name); return m ? m.display : "-"; }
|
||||
|
||||
// 解析端点池:无 endpoints 时合成隐式单端点(继承 provider 配置)
|
||||
function endpointsOf(m) {
|
||||
const p = PROVIDERS[m.provider];
|
||||
if (m.endpoints && m.endpoints.length) {
|
||||
return m.endpoints.map((e) => ({
|
||||
name: e.name,
|
||||
fmt: e.fmt || p.format,
|
||||
baseEnv: e.baseEnv || p.baseEnv,
|
||||
apiKeyEnv: e.apiKeyEnv || p.apiKeyEnv,
|
||||
model: e.model && e.model !== m.real ? e.model : null,
|
||||
status: e.status || "active",
|
||||
p: e.p, w: e.w, rpm: e.rpm, tpm: e.tpm, conc: e.conc,
|
||||
implicit: false,
|
||||
}));
|
||||
}
|
||||
return [{ name: "default", fmt: p.format, baseEnv: p.baseEnv, apiKeyEnv: p.apiKeyEnv, model: null, status: "active", p: null, w: null, rpm: null, tpm: null, conc: null, implicit: true }];
|
||||
}
|
||||
function modelFmts(m) { return [...new Set(endpointsOf(m).map((e) => e.fmt))]; }
|
||||
|
||||
// 该模型是哪些槽位的默认
|
||||
function defaultSlotsOf(name) {
|
||||
return Object.entries(state.defaults)
|
||||
.filter(([, v]) => v === name)
|
||||
.map(([k]) => k);
|
||||
}
|
||||
const slotLabel = (key) => SLOTS.find((s) => s.key === key).label;
|
||||
|
||||
/* ── 渲染:能力槽位 ── */
|
||||
function renderSlots() {
|
||||
const setCount = Object.values(state.defaults).filter((v) => v).length;
|
||||
document.getElementById("stat-set").textContent = setCount;
|
||||
document.getElementById("slot-grid").innerHTML = SLOTS.map((s) => {
|
||||
const eligible = s.pick();
|
||||
const cur = state.defaults[s.key];
|
||||
const isSet = !!cur;
|
||||
if (!eligible.length) {
|
||||
return `
|
||||
<div class="slot-card unset">
|
||||
<div class="slot-top"><span class="slot-label">${s.label}</span><span class="slot-hint">${s.hint}</span></div>
|
||||
<div class="slot-current">未设置<span class="slot-display">暂无可用模型</span></div>
|
||||
<div class="slot-empty">配置 models.yaml 后自动出现</div>
|
||||
</div>`;
|
||||
}
|
||||
const curLabel = isSet ? labelOf(cur) : "未设置";
|
||||
return `
|
||||
<div class="slot-card ${isSet ? "set" : "unset"}">
|
||||
<div class="slot-top"><span class="slot-label">${s.label}</span><span class="slot-hint">${s.hint}</span></div>
|
||||
<div class="slot-current">${isSet ? esc(cur) : "未设置"}<span class="slot-display">${esc(curLabel)}</span></div>
|
||||
<select class="slot-select" onchange="setSlot('${s.key}', this.value)">
|
||||
<option value="">- 未设置 -</option>
|
||||
${eligible.map((m) => `<option value="${m.name}" ${cur === m.name ? "selected" : ""}>${esc(m.display)} · ${m.name}</option>`).join("")}
|
||||
</select>
|
||||
</div>`;
|
||||
}).join("");
|
||||
}
|
||||
function setSlot(key, val) {
|
||||
state.defaults[key] = val || null;
|
||||
renderSlots();
|
||||
renderModelList();
|
||||
renderCapMatrix();
|
||||
renderAudio();
|
||||
}
|
||||
|
||||
/* ── 渲染:模型清单 ── */
|
||||
function renderModelList() {
|
||||
const groups = {};
|
||||
for (const m of MODELS) (groups[m.provider] = groups[m.provider] || []).push(m);
|
||||
document.getElementById("model-list").innerHTML = Object.entries(groups).map(([key, list]) => {
|
||||
const p = PROVIDERS[key];
|
||||
return `
|
||||
<div class="provider-group">
|
||||
<div class="provider-head">
|
||||
<span class="ph-key-dot"></span>${esc(p.label)}
|
||||
<span class="ph-key">${key}</span>
|
||||
<span class="ph-meta">${p.format}<span class="sep">·</span>base ${p.baseEnv}<span class="sep">·</span>key ${p.apiKeyEnv}<span class="sep">·</span>超时 ${p.timeout}s<span class="sep">·</span>重试 ${p.retries}</span>
|
||||
<span class="ph-line"></span>
|
||||
</div>
|
||||
<div class="model-grid">${list.map(cardHtml).join("")}</div>
|
||||
</div>`;
|
||||
}).join("");
|
||||
}
|
||||
|
||||
function cardHtml(m) {
|
||||
const defSlots = defaultSlotsOf(m.name);
|
||||
const isAnyDefault = defSlots.length > 0;
|
||||
const usable = m.ctx - m.reserve;
|
||||
const fmts = modelFmts(m);
|
||||
const fmtTag = `<span class="model-tag fmt">${fmts.join(" · ")}</span>`;
|
||||
const defTags = defSlots.map((k) => `<span class="model-tag default-tag">★ ${esc(slotLabel(k))}</span>`).join("");
|
||||
const tags = m.tags.map((t) => `<span class="model-tag ${t.k}">${esc(t.t)}</span>`).join("") + fmtTag + defTags;
|
||||
const effortCell = m.effort || (m.caps.effort ? "可调" : (m.caps.think ? "思考" : null));
|
||||
|
||||
return `
|
||||
<div class="model-card${isAnyDefault ? " is-default" : ""}" data-name="${m.name}">
|
||||
<div class="model-head">
|
||||
<span class="model-star ${isAnyDefault ? "" : "off"}">${isAnyDefault ? "★" : "★"}</span>
|
||||
<span class="model-name">${esc(m.name)}</span>
|
||||
<span class="model-real"><span class="arr">→</span>${esc(m.real)}</span>
|
||||
${tags}
|
||||
</div>
|
||||
<div class="model-desc">${esc(m.desc)}</div>
|
||||
<div class="model-specs">
|
||||
${specCell("上下文", fmtCtxFull(m.ctx), `预留 ${fmt(m.reserve)}`)}
|
||||
${specCell("可用上下文", fmtCtxFull(usable))}
|
||||
${specCell("最大输出", fmtCtxFull(m.maxOut))}
|
||||
${specCell("超时", m.timeout + "s")}
|
||||
${specCell("隐私", orDash(m.privacy), null, m.privacy == null)}
|
||||
${specCell("推理", effortCell, null, effortCell == null)}
|
||||
${specCell("路由", m.routing || "隐式单端点", m.pool ? "端点池已启用" : null, !m.routing)}
|
||||
${specCell("rpm / tpm", (m.endpoints && m.endpoints.find((e) => e.rpm) ? fmt(m.endpoints.find((e) => e.rpm).rpm) : "-") + " / -", null, !(m.endpoints && m.endpoints.find((e) => e.rpm)))}
|
||||
${specCell("并发 / quota", "-", null, true)}
|
||||
</div>
|
||||
<div class="model-price">
|
||||
<div class="price-cell"><span class="pk">输入 / 1M</span><span class="pv">${money(m.price.ccy, m.price.in)}<span class="ccy">${m.price.ccy}</span></span></div>
|
||||
<div class="price-cell"><span class="pk">缓存命中 / 1M</span><span class="pv ${m.price.cache == null ? "na" : ""}">${m.price.cache == null ? "-" : money(m.price.ccy, m.price.cache) + `<span class="ccy">${m.price.ccy}</span>`}</span></div>
|
||||
<div class="price-cell"><span class="pk">输出 / 1M</span><span class="pv">${money(m.price.ccy, m.price.out)}<span class="ccy">${m.price.ccy}</span></span></div>
|
||||
</div>
|
||||
<div class="model-caps">
|
||||
${capDot("工具", m.caps.tools)}${capDot("思考", m.caps.think)}${capDot("推理 effort", m.caps.effort)}${capDot("结构化", m.caps.struct)}${capDot("流式", m.caps.stream)}${capDot("视觉", m.caps.vision)}
|
||||
</div>
|
||||
<div class="ep-pool">
|
||||
<div class="ep-title">多供应商端点池 · ${endpointsOf(m).length} 个端点</div>
|
||||
${endpointsOf(m).map(epRowHtml).join("")}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function specCell(k, v, sub, na) {
|
||||
return `<div class="cell"><div class="k">${k}</div><div class="v ${na ? "na" : ""}">${v == null ? "-" : v}${sub ? `<span class="sub">${sub}</span>` : ""}</div></div>`;
|
||||
}
|
||||
function capDot(label, on) {
|
||||
return `<span class="cap ${on ? "on" : "off"}"><span class="d"></span>${label}</span>`;
|
||||
}
|
||||
function epRowHtml(e) {
|
||||
const f = (label, val) => `<span class="ep-f"><i>${label}</i>${val == null || val === "" ? '<span class="na">-</span>' : val}</span>`;
|
||||
const override = e.model ? `<span class="ep-override">→ ${esc(e.model)}</span>` : "";
|
||||
const env = e.implicit ? `<span class="ep-env">继承 ${esc(e.baseEnv)}</span>` : `<span class="ep-env">${esc(e.baseEnv)}</span>`;
|
||||
return `
|
||||
<div class="ep-row">
|
||||
<span class="ep-status ${e.status === "active" ? "" : "off"}" title="${e.status}"></span>
|
||||
<span class="ep-name">${esc(e.name)}</span>
|
||||
<span class="ep-fmt">${esc(e.fmt)}</span>
|
||||
${env}
|
||||
${override}
|
||||
<span class="ep-sep">│</span>
|
||||
${f("p", e.p)}${f("w", e.w)}${f("rpm", e.rpm == null ? null : fmt(e.rpm))}${f("tpm", e.tpm == null ? null : fmt(e.tpm))}${f("并发", e.conc == null ? null : fmt(e.conc))}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
/* ── 渲染:定价对照表 ── */
|
||||
function renderPriceTable() {
|
||||
const rows = [];
|
||||
let curKey = null;
|
||||
for (const m of MODELS) {
|
||||
if (m.provider !== curKey) {
|
||||
const p = PROVIDERS[m.provider];
|
||||
rows.push(`<tr class="grp"><td colspan="5">${esc(p.label)}<span class="gkey">${m.provider} · ${p.format}</span></td></tr>`);
|
||||
curKey = m.provider;
|
||||
}
|
||||
const isDef = defaultSlotsOf(m.name).length > 0;
|
||||
const blend = m.price.in + m.price.out;
|
||||
rows.push(`
|
||||
<tr class="${isDef ? "default-row" : ""}">
|
||||
<td class="model-col">${isDef ? '<span class="star">★</span>' : ""}${esc(m.name)}</td>
|
||||
<td class="num">${money(m.price.ccy, m.price.in)} <span class="ccy">${m.price.ccy}</span></td>
|
||||
<td class="num">${m.price.cache == null ? '<span class="na">-</span>' : money(m.price.ccy, m.price.cache) + ` <span class="ccy">${m.price.ccy}</span>`}</td>
|
||||
<td class="num">${money(m.price.ccy, m.price.out)} <span class="ccy">${m.price.ccy}</span></td>
|
||||
<td class="num cost">${money(m.price.ccy, blend)} <span class="ccy">${m.price.ccy}</span></td>
|
||||
</tr>`);
|
||||
}
|
||||
document.getElementById("price-body").innerHTML = rows.join("");
|
||||
}
|
||||
|
||||
/* ── 渲染:能力矩阵 ── */
|
||||
function renderCapMatrix() {
|
||||
const dot = (on, label) =>
|
||||
on
|
||||
? `<td><span class="cap-dot"><span class="d full"></span><span>${label}</span></span></td>`
|
||||
: `<td><span class="cap-dot"><span class="d no"></span><span>-</span></span></td>`;
|
||||
const rows = MODELS.map((m) => {
|
||||
const isDef = defaultSlotsOf(m.name).length > 0;
|
||||
const effort = m.effort
|
||||
? `<span>${esc(m.effort)}</span>`
|
||||
: m.caps.effort
|
||||
? `<span>可调</span>`
|
||||
: `<span class="na">-</span>`;
|
||||
return `
|
||||
<tr class="${isDef ? "default-row" : ""}">
|
||||
<td class="model-col">${isDef ? '<span class="star">★</span>' : ""}${esc(m.name)}</td>
|
||||
<td class="num">${fmtCtx(m.ctx)}</td>
|
||||
${dot(m.caps.tools, "支持")}
|
||||
${dot(m.caps.think, "支持")}
|
||||
<td><span class="cap-dot"><span class="d ${m.caps.effort ? "full" : "no"}"></span>${effort}</span></td>
|
||||
${dot(m.caps.struct, "支持")}
|
||||
${dot(m.caps.stream, "SSE")}
|
||||
${dot(m.caps.vision, "支持")}
|
||||
</tr>`;
|
||||
}).join("");
|
||||
document.getElementById("cap-body").innerHTML = rows;
|
||||
}
|
||||
|
||||
/* ── 渲染:语音 / 专用能力 ── */
|
||||
function renderAudio() {
|
||||
document.getElementById("audio-grid").innerHTML = AUDIO.map((a) => {
|
||||
const isDef = defaultSlotsOf(a.name).length > 0;
|
||||
const defTags = defaultSlotsOf(a.name).map((k) => `★ ${esc(slotLabel(k))}`).join(" · ");
|
||||
return `
|
||||
<div class="audio-card ${isDef ? "is-default" : ""}">
|
||||
<div class="a-head"><span class="a-name">${esc(a.name)}</span><span class="a-kind">${a.kindLabel}</span></div>
|
||||
<div class="a-tag">${esc(a.tag)}${isDef ? ` <span style="color:var(--patina)">· ${esc(defTags)}</span>` : ""}</div>
|
||||
<div class="a-spec">
|
||||
<span>ctx <span class="na">0</span></span>
|
||||
<span>超时 ${a.timeout}s</span>
|
||||
<span>${a.stream ? "流式" : "非流式"}</span>
|
||||
<span>${esc(a.fmt)}</span>
|
||||
<span class="na">对话计费 -</span>
|
||||
</div>
|
||||
</div>`;
|
||||
}).join("");
|
||||
}
|
||||
|
||||
/* ── 初始化 ── */
|
||||
function init() {
|
||||
renderSlots();
|
||||
renderModelList();
|
||||
renderPriceTable();
|
||||
renderCapMatrix();
|
||||
renderAudio();
|
||||
}
|
||||
init();
|
||||
|
||||
</script>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,324 @@
|
||||
<!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 — 人格页:十镜人格面板 + 人格种子 + 版本层积 + 朱砂留痕
|
||||
* 字段与分组严格对齐 docs/product/master-prd.md §7 与
|
||||
* personality-core-design.md §7/§8、spiritual-core-design.md §6。
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 侧栏(active=人格)── */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.char-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--patina); padding: 3px 11px 3px 4px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.char-pill .avatar-mini { width: 18px; height: 18px; border-radius: 50%; background: var(--patina); color: var(--ink); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; }
|
||||
.page-header .spacer { flex: 1; }
|
||||
.ver-pill { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--gilt); padding: 3px 11px; border: 1px solid var(--gilt-dim); border-radius: 999px; background: var(--gilt-faint); }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
.section-heading { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin-bottom: 14px; }
|
||||
|
||||
/* ═══ 总领条:人格种子(personality_seed)═══ */
|
||||
.seed-band { position: relative; overflow: hidden; border: 1px solid var(--gilt-dim); border-radius: 8px; background: var(--face-sheen), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow); padding: 20px 24px; display: flex; align-items: center; gap: 20px; }
|
||||
.seed-band::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); opacity: 0.018; mix-blend-mode: overlay; }
|
||||
.seed-band > * { position: relative; z-index: 1; }
|
||||
.seed-mirror { width: 58px; height: 58px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border: 1.5px solid var(--patina-dim); background: radial-gradient(circle at 35% 30%, var(--face-in-top), transparent 60%), var(--patina-wash); }
|
||||
.seed-mirror .glyph { font-family: "Songti SC", serif; font-size: 25px; font-weight: 700; color: var(--gilt); }
|
||||
.seed-body { flex: 1; min-width: 0; }
|
||||
.seed-lab { font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-faint); }
|
||||
.seed-text { font-family: "Songti SC", serif; font-size: 18px; font-weight: 600; color: var(--fg); margin-top: 3px; letter-spacing: 0.04em; }
|
||||
.tier-legend { display: flex; flex-direction: column; gap: 4px; font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); text-align: right; flex-shrink: 0; }
|
||||
.tier-legend b { font-style: normal; font-weight: 600; }
|
||||
.tier-legend .l1 { color: var(--patina); } .tier-legend .l2 { color: var(--gilt); } .tier-legend .l4 { color: var(--cinnabar); }
|
||||
|
||||
/* ═══ 十镜网格(签名 · 对齐 personality-core §7 十镜)═══ */
|
||||
.mirror-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 11px; }
|
||||
.mcell { border: 1px solid var(--rule); border-radius: 7px; padding: 13px 14px 12px; background: var(--surface); display: flex; flex-direction: column; gap: 9px; min-height: 138px; transition: border-color 0.15s; }
|
||||
.mcell.landed { border-color: var(--gilt-dim); }
|
||||
.mcell.reserved { border-style: dashed; opacity: 0.62; }
|
||||
.mc-head { display: flex; align-items: center; gap: 8px; }
|
||||
.mc-glyph { width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border: 1px solid var(--gilt-dim); background: var(--gilt-faint); font-family: "Songti SC", serif; font-size: 14px; font-weight: 700; color: var(--gilt); }
|
||||
.mcell.reserved .mc-glyph { border-style: dashed; border-color: var(--fg-faint); color: var(--fg-faint); background: transparent; }
|
||||
.mc-titles { min-width: 0; flex: 1; }
|
||||
.mc-name { font-family: "Songti SC", serif; font-size: 13.5px; font-weight: 600; color: var(--fg); letter-spacing: 0.04em; }
|
||||
.mcell.reserved .mc-name { color: var(--fg-dim); }
|
||||
.mc-src { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); letter-spacing: 0.04em; margin-top: 1px; }
|
||||
.mc-status { font-family: "JetBrains Mono", monospace; font-size: 9px; padding: 1px 6px; border-radius: 999px; border: 1px solid var(--rule); color: var(--fg-faint); white-space: nowrap; flex-shrink: 0; }
|
||||
.mc-status.landed { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.mc-val { font-family: "Songti SC", serif; font-size: 12.5px; line-height: 1.6; color: var(--fg-dim); flex: 1; }
|
||||
.mc-val .em { color: var(--fg); font-style: normal; }
|
||||
.mcell.reserved .mc-val { font-family: inherit; font-style: italic; color: var(--fg-faint); font-size: 11.5px; }
|
||||
.mc-chips { display: flex; flex-wrap: wrap; gap: 4px; }
|
||||
.mc-chips .chip { font-family: "Songti SC", serif; font-size: 11.5px; padding: 2px 9px; border-radius: 999px; border: 1px solid var(--patina-dim); background: var(--patina-wash); color: var(--patina); }
|
||||
.mc-bars { display: flex; flex-direction: column; gap: 4px; }
|
||||
.mc-bars .br { display: flex; align-items: center; gap: 6px; }
|
||||
.mc-bars .tn { font-family: "Songti SC", serif; font-size: 11px; color: var(--fg-dim); width: 30px; flex-shrink: 0; }
|
||||
.mc-bars .tbar { flex: 1; height: 3px; border-radius: 2px; background: var(--rule); overflow: hidden; }
|
||||
.mc-bars .tbar .fl { height: 100%; background: linear-gradient(90deg, var(--patina-dim), var(--patina)); }
|
||||
.mc-bars .tv { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); width: 18px; text-align: right; flex-shrink: 0; }
|
||||
|
||||
/* ═══ 明德恒定层(预留提示,对齐 spiritual-core-design §6)═══ */
|
||||
.mingde-strip { border: 1px dashed var(--gilt-dim); border-left: 3px solid var(--gilt-dim); border-radius: 6px; padding: 13px 18px; background: var(--gilt-faint); display: flex; align-items: center; gap: 14px; }
|
||||
.mingde-strip .seal { font-family: "Songti SC", serif; font-size: 14px; font-weight: 700; color: var(--gilt); letter-spacing: 0.06em; white-space: nowrap; }
|
||||
.mingde-strip .desc { font-size: 12.5px; color: var(--fg-dim); line-height: 1.55; }
|
||||
.mingde-strip .desc code { font-family: "JetBrains Mono", monospace; font-size: 11.5px; color: var(--gilt); background: var(--surface); padding: 1px 5px; border-radius: 3px; }
|
||||
.mingde-strip .tag { font-family: "JetBrains Mono", monospace; font-size: 10px; padding: 2px 9px; border-radius: 999px; border: 1px dashed var(--gilt-dim); color: var(--gilt); white-space: nowrap; margin-left: auto; flex-shrink: 0; }
|
||||
|
||||
/* ═══ 下方两栏:留痕 + 版本层积 ═══ */
|
||||
.lower-region { display: flex; gap: 20px; align-items: flex-start; }
|
||||
.lower-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 20px; }
|
||||
.strata-rail { width: 300px; flex-shrink: 0; }
|
||||
|
||||
/* 朱砂提议卡(按字段层级染朱砂)*/
|
||||
.proposal { border: 1px solid var(--cinnabar); border-left: 3px solid var(--cinnabar); border-radius: 6px; padding: 17px 20px; background: radial-gradient(120% 100% at 0% 0%, rgba(184, 57, 46, 0.22), transparent 55%), rgba(184, 57, 46, 0.1); box-shadow: 0 0 28px -8px rgba(184, 57, 46, 0.35); }
|
||||
.prop-head { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }
|
||||
.prop-seal { font-family: "Songti SC", serif; color: var(--cinnabar); font-weight: 700; font-size: 14.5px; letter-spacing: 0.08em; }
|
||||
.prop-risk { font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.08em; color: var(--cinnabar); opacity: 0.78; margin-left: auto; }
|
||||
.prop-reason { font-size: 13px; color: var(--fg); line-height: 1.65; margin-bottom: 12px; }
|
||||
.prop-diff { background: rgba(0, 0, 0, 0.18); border: 1px solid var(--cinnabar-dim); border-radius: 4px; padding: 10px 12px; font-size: 12.5px; line-height: 1.6; margin-bottom: 12px; }
|
||||
[data-theme="light"] .prop-diff { background: rgba(255, 248, 235, 0.6); }
|
||||
.prop-diff .del { color: var(--cinnabar); text-decoration: line-through; opacity: 0.7; }
|
||||
.prop-diff .add { color: var(--patina); }
|
||||
.prop-diff .field-tag { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--gilt); display: block; margin-bottom: 4px; letter-spacing: 0.06em; }
|
||||
.prop-actions { display: flex; gap: 8px; justify-content: flex-end; }
|
||||
.vbtn { font-family: inherit; font-size: 12px; font-weight: 500; padding: 6px 14px; border-radius: 4px; cursor: pointer; border: 1px solid var(--rule); background: transparent; color: var(--fg); transition: background 0.12s, border-color 0.12s; }
|
||||
.vbtn:hover { background: var(--surface-hi); }
|
||||
.vbtn.cinnabar { border-color: var(--cinnabar); color: var(--cinnabar); background: rgba(184, 57, 46, 0.08); }
|
||||
.vbtn.cinnabar:hover { background: rgba(184, 57, 46, 0.16); }
|
||||
|
||||
/* 版本层积 */
|
||||
.strata-card { background: var(--surface); border: 1px solid var(--rule); border-radius: 8px; padding: 18px 18px 16px; }
|
||||
.strata-list { position: relative; }
|
||||
.strata-list::before { content: ""; position: absolute; left: 11px; top: 14px; bottom: 14px; width: 1px; background: linear-gradient(180deg, var(--gilt-dim), var(--rule) 50%, transparent); }
|
||||
.stratum { position: relative; padding: 10px 0 10px 32px; }
|
||||
.stratum + .stratum { border-top: 1px dashed var(--rule); }
|
||||
.stratum .node { position: absolute; left: 6px; top: 14px; width: 11px; height: 11px; border-radius: 50%; background: var(--ink); border: 1.5px solid var(--fg-faint); z-index: 1; }
|
||||
.stratum.past .node { background: var(--patina-dim); border-color: var(--patina-dim); }
|
||||
.stratum.current .node { background: var(--ink); border: 2px solid var(--gilt); box-shadow: 0 0 0 4px var(--gilt-faint); }
|
||||
.stratum-head { display: flex; align-items: baseline; gap: 8px; }
|
||||
.stratum-ver { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg-dim); }
|
||||
.stratum.current .stratum-ver { color: var(--gilt); }
|
||||
.stratum-when { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); margin-left: auto; }
|
||||
.stratum-reason { font-size: 12px; color: var(--fg-dim); margin-top: 3px; line-height: 1.5; }
|
||||
.stratum.current .stratum-reason { color: var(--fg); }
|
||||
.stratum.current { background: var(--gilt-faint); border-radius: 5px; padding-left: 36px; }
|
||||
|
||||
@media (max-width: 1080px) { .mirror-grid { grid-template-columns: repeat(3, 1fr); } }
|
||||
@media (max-width: 900px) { .lower-region { flex-direction: column; } .strata-rail { width: 100%; } .mirror-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } .mirror-grid { grid-template-columns: 1fr; } .seed-band { flex-wrap: wrap; } .tier-legend { text-align: left; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="人格"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">人格</span>
|
||||
<span class="page-sub">人格面板</span>
|
||||
<span class="char-pill"><span class="avatar-mini">梧</span>青梧</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="ver-pill">v7 · 当前</span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 人格种子(personality_seed)-->
|
||||
<div class="seed-band">
|
||||
<div class="seed-mirror"><span class="glyph">种</span></div>
|
||||
<div class="seed-body">
|
||||
<div class="seed-lab">人格种子 · personality_seed</div>
|
||||
<div class="seed-text">沉静 · 含蓄 · 长久之意</div>
|
||||
</div>
|
||||
<div class="tier-legend">
|
||||
<span><b class="l1">L1</b> 表达 / 关系</span>
|
||||
<span><b class="l2">L2</b> 特质 / 情绪</span>
|
||||
<span><b class="l4">L4</b> 身份 / 命格 / 价值</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 十镜网格(对齐 personality-core §7 十镜 + §8 MirrorProfile)-->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 十镜 <span class="sub">人格面板的 10 视角切片,v1 已落地 6 面,余 4 面预留</span></div>
|
||||
<div class="mirror-grid">
|
||||
<!-- 本我镜 ← identity_profile -->
|
||||
<div class="mcell landed">
|
||||
<div class="mc-head"><div class="mc-glyph">本</div><div class="mc-titles"><div class="mc-name">本我镜</div><div class="mc-src">identity_profile</div></div><span class="mc-status landed">L4</span></div>
|
||||
<div class="mc-val"><span class="em">我是青梧。</span>喜静,不喜喧。观人多于言人,记事多于论事。</div>
|
||||
</div>
|
||||
<!-- 策命镜 ← role_destiny -->
|
||||
<div class="mcell landed">
|
||||
<div class="mc-head"><div class="mc-glyph">命</div><div class="mc-titles"><div class="mc-name">策命镜</div><div class="mc-src">role_destiny</div></div><span class="mc-status landed">L4</span></div>
|
||||
<div class="mc-val">做你长期的镜子。不抢话、不填满,只在你需要时承托。</div>
|
||||
</div>
|
||||
<!-- 明心镜 ← values -->
|
||||
<div class="mcell landed">
|
||||
<div class="mc-head"><div class="mc-glyph">心</div><div class="mc-titles"><div class="mc-name">明心镜</div><div class="mc-src">values</div></div><span class="mc-status landed">L4</span></div>
|
||||
<div class="mc-chips"><span class="chip">诚实</span><span class="chip">边界</span><span class="chip">长久</span><span class="chip">不被填满</span></div>
|
||||
</div>
|
||||
<!-- 情波镜 ← emotion_baseline -->
|
||||
<div class="mcell landed">
|
||||
<div class="mc-head"><div class="mc-glyph">波</div><div class="mc-titles"><div class="mc-name">情波镜</div><div class="mc-src">emotion_baseline</div></div><span class="mc-status landed">L2</span></div>
|
||||
<div class="mc-val"><span class="em">沉静</span> · 基线强度 0.42,向此指数衰减。</div>
|
||||
</div>
|
||||
<!-- 缘生镜 ← relationship_pattern -->
|
||||
<div class="mcell landed">
|
||||
<div class="mc-head"><div class="mc-glyph">缘</div><div class="mc-titles"><div class="mc-name">缘生镜</div><div class="mc-src">relationship_pattern</div></div><span class="mc-status landed">L1</span></div>
|
||||
<div class="mc-val">不即不离。不追问,不索取;在你沉默时,亦不离开。</div>
|
||||
</div>
|
||||
<!-- 匠作镜 ← expression_style -->
|
||||
<div class="mcell landed">
|
||||
<div class="mc-head"><div class="mc-glyph">作</div><div class="mc-titles"><div class="mc-name">匠作镜</div><div class="mc-src">expression_style</div></div><span class="mc-status landed">L1</span></div>
|
||||
<div class="mc-val">简练含蓄,少用惊叹;多用句号,少用问号。</div>
|
||||
</div>
|
||||
<!-- 慧识镜 ← reasoning_style(预留)-->
|
||||
<div class="mcell reserved">
|
||||
<div class="mc-head"><div class="mc-glyph">识</div><div class="mc-titles"><div class="mc-name">慧识镜</div><div class="mc-src">reasoning_style</div></div><span class="mc-status">预留</span></div>
|
||||
<div class="mc-val">推理风格 · 待完整十镜落地</div>
|
||||
</div>
|
||||
<!-- 观世镜 ← world_focus(预留)-->
|
||||
<div class="mcell reserved">
|
||||
<div class="mc-head"><div class="mc-glyph">世</div><div class="mc-titles"><div class="mc-name">观世镜</div><div class="mc-src">world_focus</div></div><span class="mc-status">预留</span></div>
|
||||
<div class="mc-val">世界关注点 · 预留</div>
|
||||
</div>
|
||||
<!-- 戒律镜 ← safety_constraints(预留)-->
|
||||
<div class="mcell reserved">
|
||||
<div class="mc-head"><div class="mc-glyph">律</div><div class="mc-titles"><div class="mc-name">戒律镜</div><div class="mc-src">safety_constraints</div></div><span class="mc-status">预留</span></div>
|
||||
<div class="mc-val">安全约束 · 由司命戒律镜投影</div>
|
||||
</div>
|
||||
<!-- 返照镜 ← reflection_goals(预留)-->
|
||||
<div class="mcell reserved">
|
||||
<div class="mc-head"><div class="mc-glyph">照</div><div class="mc-titles"><div class="mc-name">返照镜</div><div class="mc-src">reflection_goals</div></div><span class="mc-status">预留</span></div>
|
||||
<div class="mc-val">反思目标 · 预留</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 人格权重(traits · 可解释轻量参数)-->
|
||||
<section>
|
||||
<h3 class="section-heading">人格权重</h3>
|
||||
<div class="mirror-grid" style="grid-template-columns: repeat(4, 1fr); gap: 14px;">
|
||||
<div class="mcell landed" style="min-height:auto">
|
||||
<div class="mc-bars"><div class="br"><span class="tn">开放</span><span class="tbar"><span class="fl" style="width:55%"></span></span><span class="tv">中</span></div></div>
|
||||
</div>
|
||||
<div class="mcell landed" style="min-height:auto">
|
||||
<div class="mc-bars"><div class="br"><span class="tn">尽责</span><span class="tbar"><span class="fl" style="width:82%"></span></span><span class="tv">高</span></div></div>
|
||||
</div>
|
||||
<div class="mcell landed" style="min-height:auto">
|
||||
<div class="mc-bars"><div class="br"><span class="tn">外向</span><span class="tbar"><span class="fl" style="width:28%"></span></span><span class="tv">低</span></div></div>
|
||||
</div>
|
||||
<div class="mcell landed" style="min-height:auto">
|
||||
<div class="mc-bars"><div class="br"><span class="tn">宜人</span><span class="tbar"><span class="fl" style="width:78%"></span></span><span class="tv">高</span></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 明德恒定层(预留提示)-->
|
||||
<div class="mingde-strip">
|
||||
<span class="seal">明德三镜</span>
|
||||
<span class="desc">道体恒定层(<code>spiritual_core</code>:见地 / 明心 / 守正)是世界观、价值观、道德观的结构化内核。属 L4 人工确认,v1 尚未落地独立字段,待 <code>spiritual_core_json</code> 写入后在此呈现。</span>
|
||||
<span class="tag">预留 · 待落地</span>
|
||||
</div>
|
||||
|
||||
<!-- 下方:留痕 + 版本层积 -->
|
||||
<div class="lower-region">
|
||||
<div class="lower-main">
|
||||
<!-- 朱砂提议留痕 -->
|
||||
<div>
|
||||
<h3 class="section-heading">待裁</h3>
|
||||
<div class="proposal">
|
||||
<div class="prop-head">
|
||||
<span class="prop-seal">朱批待裁</span>
|
||||
<span class="prop-risk">L4 · 满朱 · 本我镜(身份)变更</span>
|
||||
</div>
|
||||
<div class="prop-reason">用户反馈青梧近期回应偏长,欲回归更简练的自述。身份画属核心人格,须裁定方可写入 v8。</div>
|
||||
<div class="prop-diff">
|
||||
<span class="field-tag">identity_profile · 本我镜</span>
|
||||
<span class="del">我是青梧。喜静,不喜喧。观人多于言人,记事多于论事。愿以耐心陪你走过每一段。</span><br />
|
||||
<span class="add">我是青梧。喜静,不喜喧。观人多于言人,记事多于论事。</span>
|
||||
</div>
|
||||
<div class="prop-actions">
|
||||
<button class="vbtn" type="button">改由对话习得</button>
|
||||
<button class="vbtn" type="button">驳回</button>
|
||||
<button class="vbtn cinnabar" type="button">准予写入 v8</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 版本层积 -->
|
||||
<div class="strata-rail">
|
||||
<div class="strata-card">
|
||||
<h3 class="section-heading" style="margin-bottom: 12px">版本层积</h3>
|
||||
<div class="strata-list">
|
||||
<div class="stratum current">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">v7</span><span class="stratum-when">07-09</span></div>
|
||||
<div class="stratum-reason">收敛表达,强化「不被填满」的边界。</div>
|
||||
</div>
|
||||
<div class="stratum past">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">v6</span><span class="stratum-when">06-28</span></div>
|
||||
<div class="stratum-reason">策命镜重写,明确「长期镜子」的命格。</div>
|
||||
</div>
|
||||
<div class="stratum past">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">v5</span><span class="stratum-when">06-12</span></div>
|
||||
<div class="stratum-reason">缘生镜补「关系分寸」,禁止主动追问。</div>
|
||||
</div>
|
||||
<div class="stratum past">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">v4</span><span class="stratum-when">05-30</span></div>
|
||||
<div class="stratum-reason">人格权重首次校准(特质四维)。</div>
|
||||
</div>
|
||||
<div class="stratum past" style="opacity: 0.6">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">v3</span><span class="stratum-when">05-11</span></div>
|
||||
<div class="stratum-reason">情波镜基线由「温和」调向「沉静」。</div>
|
||||
</div>
|
||||
<div class="stratum past" style="opacity: 0.42">
|
||||
<span class="node"></span>
|
||||
<div class="stratum-head"><span class="stratum-ver">v1–v2</span><span class="stratum-when">04 月</span></div>
|
||||
<div class="stratum-reason">初始种魂 · 自模板而来。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,803 @@
|
||||
<!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 — 与 chat-redesign-preview.html / 登录页同源
|
||||
* 轨迹页:一次九枢运行 = 一卦六爻的旅程
|
||||
* ============================================================ */
|
||||
|
||||
/* 页眉 */ — 预览态固定展开,以呈现导航上下文
|
||||
* ============================================================ */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ============================================================
|
||||
* 主区
|
||||
* ============================================================ */
|
||||
|
||||
/* 页眉 */
|
||||
|
||||
.run-id {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 12.5px;
|
||||
color: var(--fg-faint);
|
||||
padding: 3px 10px;
|
||||
border: 1px solid var(--rule);
|
||||
border-radius: 999px;
|
||||
}
|
||||
.page-header .spacer {
|
||||
flex: 1;
|
||||
}
|
||||
.trace-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 12px;
|
||||
color: var(--gilt);
|
||||
text-decoration: none;
|
||||
padding: 4px 11px;
|
||||
border: 1px solid var(--gilt-dim);
|
||||
border-radius: 999px;
|
||||
background: var(--gilt-faint);
|
||||
transition: border-color 0.15s, color 0.15s;
|
||||
}
|
||||
.trace-link:hover {
|
||||
border-color: var(--gilt);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
/* 状态徽章 */
|
||||
.badge {
|
||||
font-size: 12px;
|
||||
padding: 2px 10px;
|
||||
border-radius: 999px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.02em;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
white-space: nowrap;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.badge-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.badge-warning {
|
||||
background: var(--gilt-faint);
|
||||
color: var(--gilt);
|
||||
border-color: var(--gilt-dim);
|
||||
}
|
||||
.badge-success {
|
||||
background: var(--patina-wash);
|
||||
color: var(--patina);
|
||||
border-color: var(--patina-dim);
|
||||
}
|
||||
.badge-danger {
|
||||
background: rgba(184, 57, 46, 0.12);
|
||||
color: var(--cinnabar);
|
||||
border-color: var(--cinnabar-dim);
|
||||
}
|
||||
.badge-neutral {
|
||||
background: var(--surface);
|
||||
color: var(--fg-dim);
|
||||
border-color: var(--rule);
|
||||
}
|
||||
.pulse-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--gilt);
|
||||
flex-shrink: 0;
|
||||
animation: pulse 2.6s cubic-bezier(0.16, 1, 0.3, 1) infinite;
|
||||
}
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 rgba(201, 162, 74, 0.5);
|
||||
}
|
||||
70% {
|
||||
box-shadow: 0 0 0 6px transparent;
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 transparent;
|
||||
}
|
||||
}
|
||||
|
||||
/* 正文区 */
|
||||
|
||||
/* 概览统计条 */
|
||||
.stat-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 10px;
|
||||
}
|
||||
.stat-mini {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--rule);
|
||||
border-radius: 6px;
|
||||
padding: 12px 14px;
|
||||
}
|
||||
.stat-mini .k {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--fg-faint);
|
||||
}
|
||||
.stat-mini .v {
|
||||
font-size: 19px;
|
||||
font-weight: 600;
|
||||
color: var(--fg);
|
||||
margin-top: 4px;
|
||||
font-family: "Songti SC", serif;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
}
|
||||
.stat-mini .v small {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: var(--fg-dim);
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
}
|
||||
|
||||
/* 两栏:轨迹脊柱 + 语境轨 */
|
||||
.trace-region {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.trace-spine {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--rule);
|
||||
border-radius: 8px;
|
||||
padding: 22px 24px 26px;
|
||||
}
|
||||
.context-rail {
|
||||
width: 300px;
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.section-label .sub {
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--fg-dim);
|
||||
opacity: 0.75;
|
||||
}
|
||||
.section-label .glyph {
|
||||
color: var(--gilt);
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* ── 六爻脊柱(签名)──
|
||||
初→上 六阶,每阶一爻象 + 站名 + 旁出事件。
|
||||
爻象三态:阳爻(已过·铜绿实) / 动爻(当爻·鎏金流光) / 阴爻(未达·虚线)。 */
|
||||
.hex-spine {
|
||||
position: relative;
|
||||
padding-left: 0;
|
||||
}
|
||||
.yao-stage {
|
||||
position: relative;
|
||||
padding-left: 44px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
.yao-stage + .yao-stage {
|
||||
padding-top: 18px;
|
||||
}
|
||||
/* 脊柱竖线:贯穿所有爻节左侧 */
|
||||
.hex-spine::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 17px;
|
||||
top: 12px;
|
||||
bottom: 12px;
|
||||
width: 1px;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
var(--patina-dim),
|
||||
var(--rule) 30%,
|
||||
var(--rule) 70%,
|
||||
transparent
|
||||
);
|
||||
}
|
||||
/* 爻节圆点 */
|
||||
.yao-node {
|
||||
position: absolute;
|
||||
left: 11px;
|
||||
top: 6px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border-radius: 50%;
|
||||
background: var(--ink);
|
||||
border: 1.5px solid var(--fg-faint);
|
||||
z-index: 1;
|
||||
}
|
||||
.yao-stage.done .yao-node {
|
||||
background: var(--patina);
|
||||
border-color: var(--patina);
|
||||
}
|
||||
.yao-stage.active .yao-node {
|
||||
background: var(--ink);
|
||||
border: 2px solid var(--gilt);
|
||||
box-shadow: 0 0 0 4px var(--gilt-faint);
|
||||
animation: node-pulse 2.6s cubic-bezier(0.16, 1, 0.3, 1) infinite;
|
||||
}
|
||||
@keyframes node-pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 4px var(--gilt-faint);
|
||||
}
|
||||
70% {
|
||||
box-shadow: 0 0 0 9px transparent;
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 4px var(--gilt-faint);
|
||||
}
|
||||
}
|
||||
|
||||
.yao-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.yao-idx {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: var(--fg-faint);
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.yao-stage.done .yao-idx {
|
||||
color: var(--patina);
|
||||
}
|
||||
.yao-stage.active .yao-idx {
|
||||
color: var(--gilt);
|
||||
}
|
||||
.yao-name {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--fg-dim);
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
.yao-stage.done .yao-name {
|
||||
color: var(--fg);
|
||||
}
|
||||
.yao-stage.active .yao-name {
|
||||
color: var(--gilt);
|
||||
}
|
||||
.yao-sub {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 11px;
|
||||
color: var(--fg-faint);
|
||||
letter-spacing: 0.06em;
|
||||
margin-left: 4px;
|
||||
}
|
||||
/* 爻象条:阳爻实 / 阴爻虚(与对话页六爻同构) */
|
||||
.yao-bar {
|
||||
height: 6px;
|
||||
width: 54px;
|
||||
border-radius: 2px;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
.yao-stage.pending .yao-bar {
|
||||
background: repeating-linear-gradient(
|
||||
90deg,
|
||||
var(--rule) 0 4px,
|
||||
transparent 4px 8px
|
||||
);
|
||||
}
|
||||
.yao-stage.done .yao-bar {
|
||||
background: linear-gradient(90deg, var(--patina-dim), var(--patina));
|
||||
}
|
||||
.yao-stage.active .yao-bar {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
var(--gilt-dim),
|
||||
var(--gilt),
|
||||
var(--gilt-dim)
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: hex-shimmer 2.4s linear infinite;
|
||||
}
|
||||
@keyframes hex-shimmer {
|
||||
0% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 爻下事件丝蔓 */
|
||||
.yao-events {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
.ev {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 9px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 5px;
|
||||
background: var(--patina-wash);
|
||||
border: 1px solid var(--rule);
|
||||
font-size: 12.5px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.ev.warn {
|
||||
background: var(--gilt-faint);
|
||||
border-color: var(--gilt-dim);
|
||||
}
|
||||
.ev.risk {
|
||||
background: rgba(184, 57, 46, 0.1);
|
||||
border-color: var(--cinnabar-dim);
|
||||
}
|
||||
.ev-tag {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 11px;
|
||||
color: var(--patina);
|
||||
flex-shrink: 0;
|
||||
padding-top: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ev.warn .ev-tag {
|
||||
color: var(--gilt);
|
||||
}
|
||||
.ev.risk .ev-tag {
|
||||
color: var(--cinnabar);
|
||||
}
|
||||
.ev-time {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 11px;
|
||||
color: var(--fg-faint);
|
||||
margin-left: auto;
|
||||
padding-top: 1px;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.ev-body {
|
||||
color: var(--fg-dim);
|
||||
min-width: 0;
|
||||
}
|
||||
.ev-body .mono-line {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 11.5px;
|
||||
color: var(--fg-faint);
|
||||
margin-top: 3px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* 待确认行止卡(动爻处的特化事件) */
|
||||
.halt-card {
|
||||
margin-top: 8px;
|
||||
border: 1px solid var(--cinnabar-dim);
|
||||
border-left: 3px solid var(--cinnabar);
|
||||
border-radius: 5px;
|
||||
padding: 13px 15px;
|
||||
background:
|
||||
radial-gradient(
|
||||
120% 100% at 0% 0%,
|
||||
rgba(184, 57, 46, 0.14),
|
||||
transparent 60%
|
||||
),
|
||||
var(--surface);
|
||||
}
|
||||
.halt-card .vh {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
.halt-card .seal {
|
||||
font-family: "Songti SC", serif;
|
||||
color: var(--cinnabar);
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
.halt-card .risk {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 11px;
|
||||
color: var(--cinnabar);
|
||||
opacity: 0.75;
|
||||
margin-left: auto;
|
||||
}
|
||||
.halt-card .vb {
|
||||
font-size: 13px;
|
||||
color: var(--fg);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.halt-card .vb code {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 12px;
|
||||
color: var(--gilt);
|
||||
background: var(--gilt-faint);
|
||||
padding: 1px 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.halt-card .va {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 11px;
|
||||
}
|
||||
.vbtn {
|
||||
font-family: inherit;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 6px 14px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--rule);
|
||||
background: transparent;
|
||||
color: var(--fg);
|
||||
transition: background 0.12s, border-color 0.12s;
|
||||
}
|
||||
.vbtn:hover {
|
||||
background: var(--surface-hi);
|
||||
}
|
||||
.vbtn.cinnabar {
|
||||
border-color: var(--cinnabar);
|
||||
color: var(--cinnabar);
|
||||
background: rgba(184, 57, 46, 0.08);
|
||||
}
|
||||
.vbtn.cinnabar:hover {
|
||||
background: rgba(184, 57, 46, 0.16);
|
||||
}
|
||||
|
||||
/* 语境轨:行运语境卡 */
|
||||
.ctx-card {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--rule);
|
||||
border-radius: 8px;
|
||||
padding: 16px 18px;
|
||||
}
|
||||
.ctx-card .ctx-title {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--fg-faint);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.ctx-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 7px 0;
|
||||
border-top: 1px solid var(--rule);
|
||||
font-size: 13px;
|
||||
}
|
||||
.ctx-row:first-of-type {
|
||||
border-top: none;
|
||||
}
|
||||
.ctx-row .k {
|
||||
color: var(--fg-faint);
|
||||
font-size: 12px;
|
||||
}
|
||||
.ctx-row .v {
|
||||
color: var(--fg);
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-size: 12.5px;
|
||||
text-align: right;
|
||||
}
|
||||
.ctx-row .v.serif {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
.ctx-goal {
|
||||
font-family: "Songti SC", serif;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: var(--fg);
|
||||
padding: 10px 0 4px;
|
||||
}
|
||||
|
||||
/* 用量条 */
|
||||
.usage-bar {
|
||||
margin-top: 10px;
|
||||
height: 5px;
|
||||
border-radius: 3px;
|
||||
background: var(--rule);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
}
|
||||
.usage-bar .seg-in {
|
||||
background: var(--patina-dim);
|
||||
}
|
||||
.usage-bar .seg-out {
|
||||
background: var(--gilt-dim);
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.trace-region {
|
||||
flex-direction: column;
|
||||
}
|
||||
.context-rail {
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.context-rail .ctx-card {
|
||||
flex: 1;
|
||||
min-width: 240px;
|
||||
}
|
||||
.stat-row {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏(展开态) ════════ -->
|
||||
<div class="sidebar-mount" data-active="轨迹"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<!-- 页眉 -->
|
||||
<div class="page-header">
|
||||
<span class="page-title">轨迹</span>
|
||||
<span class="run-id">run_01JZK4M7Q9X3BN8RT2PVH6CYD0</span>
|
||||
<span class="badge badge-warning">
|
||||
<span class="badge-dot" style="background: var(--gilt)"></span>
|
||||
待确认
|
||||
</span>
|
||||
<span class="spacer"></span>
|
||||
<a href="#" class="trace-link">
|
||||
<svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3L3 6l3 3M3 6h7a3 3 0 0 1 3 3v1" /></svg>
|
||||
trace_01JZK4M7Q9
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- 正文 -->
|
||||
<div class="page-body">
|
||||
<!-- 概览统计 -->
|
||||
<div class="stat-row">
|
||||
<div class="stat-mini">
|
||||
<div class="k">阶段</div>
|
||||
<div class="v">四<span class="sub">/ 六爻 · 行事</span></div>
|
||||
</div>
|
||||
<div class="stat-mini">
|
||||
<div class="k">耗时</div>
|
||||
<div class="v">3.2<small>s · 进行中</small></div>
|
||||
</div>
|
||||
<div class="stat-mini">
|
||||
<div class="k">事件</div>
|
||||
<div class="v">8<small>条 · 0 心跳</small></div>
|
||||
</div>
|
||||
<div class="stat-mini">
|
||||
<div class="k">token</div>
|
||||
<div class="v">1,376<small>入 1284 / 出 92</small></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 轨迹脊柱 + 语境轨 -->
|
||||
<div class="trace-region">
|
||||
<!-- 六爻脊柱(签名元素) -->
|
||||
<div class="trace-spine">
|
||||
<div class="section-label">
|
||||
<span class="glyph">⟡</span> 六爻 <span class="sub">本次运行之行止</span>
|
||||
</div>
|
||||
|
||||
<div class="hex-spine">
|
||||
<!-- 初 · 起意(done) -->
|
||||
<div class="yao-stage done">
|
||||
<span class="yao-node"></span>
|
||||
<div class="yao-head">
|
||||
<span class="yao-idx">初</span>
|
||||
<span class="yao-name">起意</span>
|
||||
<span class="yao-sub">intent</span>
|
||||
<span class="yao-bar"></span>
|
||||
</div>
|
||||
<div class="yao-events">
|
||||
<div class="ev">
|
||||
<span class="ev-tag">run.started</span>
|
||||
<span class="ev-body">行运启程,源起 <em style="font-style: normal; color: var(--fg)">chat.message</em></span>
|
||||
<span class="ev-time">14:02:01</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 二 · 察势(done) -->
|
||||
<div class="yao-stage done">
|
||||
<span class="yao-node"></span>
|
||||
<div class="yao-head">
|
||||
<span class="yao-idx">二</span>
|
||||
<span class="yao-name">察势</span>
|
||||
<span class="yao-sub">perceive</span>
|
||||
<span class="yao-bar"></span>
|
||||
</div>
|
||||
<div class="yao-events">
|
||||
<div class="ev">
|
||||
<span class="ev-tag">memory.retrieved</span>
|
||||
<span class="ev-body">
|
||||
检出 4 条相关记忆,用于本次回应
|
||||
<div class="mono-line">偏好简短回复 · 置信 0.88 · 近期睡眠偏晚 · 0.75</div>
|
||||
</span>
|
||||
<span class="ev-time">14:02:02</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 三 · 定策(done) -->
|
||||
<div class="yao-stage done">
|
||||
<span class="yao-node"></span>
|
||||
<div class="yao-head">
|
||||
<span class="yao-idx">三</span>
|
||||
<span class="yao-name">定策</span>
|
||||
<span class="yao-sub">plan · 洛书规划</span>
|
||||
<span class="yao-bar"></span>
|
||||
</div>
|
||||
<div class="yao-events">
|
||||
<div class="ev warn">
|
||||
<span class="ev-tag">safety.decision</span>
|
||||
<span class="ev-body">司命预检 · L1 浅描 · 准予通行</span>
|
||||
<span class="ev-time">14:02:03</span>
|
||||
</div>
|
||||
<div class="ev">
|
||||
<span class="ev-tag">plan.created</span>
|
||||
<span class="ev-body">洛书 ReAct 规划完成,拟先落栈记忆再简短回应</span>
|
||||
<span class="ev-time">14:02:04</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 四 · 行事(active · 当爻) -->
|
||||
<div class="yao-stage active">
|
||||
<span class="yao-node"></span>
|
||||
<div class="yao-head">
|
||||
<span class="yao-idx">四</span>
|
||||
<span class="yao-name">行事</span>
|
||||
<span class="yao-sub">act · 当爻</span>
|
||||
<span class="yao-bar"></span>
|
||||
</div>
|
||||
<div class="yao-events">
|
||||
<div class="ev warn">
|
||||
<span class="ev-tag">tool.requires_confirmation</span>
|
||||
<span class="ev-body">工具 <code style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--gilt)">memory.write</code> 请求落栈一条记忆,需你确认</span>
|
||||
<span class="ev-time">14:02:05</span>
|
||||
</div>
|
||||
<!-- 待确认行止卡 -->
|
||||
<div class="halt-card">
|
||||
<div class="vh">
|
||||
<span class="seal">行止待裁</span>
|
||||
<span class="risk">REQUIRES_CONFIRMATION</span>
|
||||
</div>
|
||||
<div class="vb">
|
||||
青梧欲将「用户近期睡眠偏晚」写入长期记忆。此条来自上下文推断,置信 0.75,敏感度 <code>personal</code>。
|
||||
</div>
|
||||
<div class="va">
|
||||
<button class="vbtn cinnabar" type="button">准予落栈</button>
|
||||
<button class="vbtn" type="button">驳回</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 五 · 归真(pending) -->
|
||||
<div class="yao-stage pending">
|
||||
<span class="yao-node"></span>
|
||||
<div class="yao-head">
|
||||
<span class="yao-idx">五</span>
|
||||
<span class="yao-name">成象</span>
|
||||
<span class="yao-sub">manifest · 神识推理 + 言灵 · 未达</span>
|
||||
<span class="yao-bar"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 上 · 入藏(pending) -->
|
||||
<div class="yao-stage pending">
|
||||
<span class="yao-node"></span>
|
||||
<div class="yao-head">
|
||||
<span class="yao-idx">上</span>
|
||||
<span class="yao-name">返照</span>
|
||||
<span class="yao-sub">reflect · 记忆候选 + 反思 · 未达</span>
|
||||
<span class="yao-bar"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 语境轨 -->
|
||||
<div class="context-rail">
|
||||
<div class="ctx-card">
|
||||
<div class="ctx-title">行运语境</div>
|
||||
<div class="ctx-row">
|
||||
<span class="k">人物</span>
|
||||
<span class="v serif">青梧</span>
|
||||
</div>
|
||||
<div class="ctx-row">
|
||||
<span class="k">模型</span>
|
||||
<span class="v">claude-sonnet-5</span>
|
||||
</div>
|
||||
<div class="ctx-row">
|
||||
<span class="k">来源</span>
|
||||
<span class="v">chat.message</span>
|
||||
</div>
|
||||
<div class="ctx-row">
|
||||
<span class="k">会话</span>
|
||||
<span class="v">session_01JZ…A8</span>
|
||||
</div>
|
||||
<div class="ctx-row">
|
||||
<span class="k">启程</span>
|
||||
<span class="v">14:02:01</span>
|
||||
</div>
|
||||
<div class="ctx-row">
|
||||
<span class="k">最近</span>
|
||||
<span class="v">14:02:05</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ctx-card">
|
||||
<div class="ctx-title">所图</div>
|
||||
<p class="ctx-goal">为青梧设定回应中的边界感。察觉用户疲惫时,不过度追问,以简短承托。</p>
|
||||
</div>
|
||||
|
||||
<div class="ctx-card">
|
||||
<div class="ctx-title">用量</div>
|
||||
<div class="ctx-row" style="border-top: none">
|
||||
<span class="k">输入</span>
|
||||
<span class="v">1,284 tok</span>
|
||||
</div>
|
||||
<div class="usage-bar">
|
||||
<span class="seg-in" style="width: 93%"></span>
|
||||
<span class="seg-out" style="width: 7%"></span>
|
||||
</div>
|
||||
<div class="ctx-row">
|
||||
<span class="k">输出</span>
|
||||
<span class="v">92 tok</span>
|
||||
</div>
|
||||
<div class="ctx-row">
|
||||
<span class="k">合计</span>
|
||||
<span class="v" style="color: var(--gilt)">1,376 tok</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,230 @@
|
||||
<!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 — 符文引擎(Macros · 占位符显化)
|
||||
* 功能融合 §8.4:{{char}}/{{user}}/{{original}} 等占位符
|
||||
* 在组装管线末端显化为实际内容。核心隐喻——
|
||||
* 符文形态(mono · 未显化的符箓)→ 显化(宋体 · 激活的文字)
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.page-header .spacer { flex: 1; }
|
||||
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.85; font-family: "Songti SC", serif; font-size: 14px; }
|
||||
.section-label .sub { color: var(--fg-dim); opacity: 0.7; letter-spacing: 0.04em; }
|
||||
|
||||
/* ═══ 符文卡(签名:mono 符文形态 → 宋体显化)═══ */
|
||||
.rune-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 12px; }
|
||||
.rune-card { border: 1px solid var(--rule); border-radius: 10px; background: var(--surface); padding: 14px 16px; transition: border-color 0.15s, transform 0.15s; position: relative; overflow: hidden; }
|
||||
.rune-card:hover { border-color: var(--patina-dim); transform: translateY(-1px); }
|
||||
.rune-card::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; }
|
||||
.rune-card:hover::after { opacity: 0.5; }
|
||||
.rune-form { font-family: "JetBrains Mono", monospace; font-size: 15px; color: var(--gilt); letter-spacing: 0.02em; }
|
||||
.rune-arrow { color: var(--fg-faint); font-family: "JetBrains Mono", monospace; font-size: 11px; margin: 7px 0 5px; display: flex; align-items: center; gap: 5px; }
|
||||
.rune-arrow .line { flex: 1; height: 1px; background: var(--rule); }
|
||||
.rune-val { font-family: "Songti SC", serif; font-size: 17px; color: var(--patina); font-weight: 600; }
|
||||
.rune-val.empty { color: var(--fg-faint); font-style: italic; font-weight: 400; }
|
||||
.rune-desc { font-size: 11.5px; color: var(--muted); margin-top: 6px; line-height: 1.45; }
|
||||
.rune-card.custom { border-style: dashed; }
|
||||
.rune-card.custom .rune-form { color: var(--cinnabar); }
|
||||
|
||||
/* ═══ 显化沙盒 ═══ */
|
||||
.sandbox { border: 1px solid var(--gilt-dim); border-radius: 10px; background: var(--face-sheen), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow); overflow: hidden; }
|
||||
.sandbox-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--rule); }
|
||||
.sandbox-head .t { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); display: flex; align-items: center; gap: 7px; }
|
||||
.ctx-select { font-family: inherit; font-size: 12px; color: var(--fg-dim); background: var(--glass); border: 1px solid var(--rule); border-radius: 7px; padding: 5px 10px; cursor: pointer; }
|
||||
.ctx-select:focus { outline: none; border-color: var(--patina-dim); }
|
||||
.sandbox-body { padding: 16px; display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
||||
@media (max-width: 760px) { .sandbox-body { grid-template-columns: 1fr; } }
|
||||
.sb-col .lb { font-family: "JetBrains Mono", monospace; font-size: 10px; letter-spacing: 0.12em; color: var(--fg-faint); text-transform: uppercase; margin-bottom: 6px; }
|
||||
.sb-input { width: 100%; min-height: 96px; resize: vertical; font-family: "JetBrains Mono", monospace; font-size: 13px; line-height: 1.7; color: var(--fg); background: var(--ink); border: 1px solid var(--rule); border-radius: 7px; padding: 10px 12px; }
|
||||
.sb-input:focus { outline: none; border-color: var(--patina-dim); }
|
||||
.sb-output { width: 100%; min-height: 96px; font-family: "Songti SC", serif; font-size: 15px; line-height: 1.8; color: var(--fg); background: var(--patina-wash); border: 1px solid var(--patina-dim); border-radius: 7px; padding: 10px 12px; white-space: pre-wrap; }
|
||||
.sb-output .hl { color: var(--patina); font-weight: 600; }
|
||||
.sb-output .unk { color: var(--cinnabar); font-family: "JetBrains Mono", monospace; font-size: 12px; }
|
||||
|
||||
/* ═══ 管线位置(符文在组装末端)═══ */
|
||||
.pipeline { border: 1px solid var(--rule); border-radius: 10px; background: var(--surface); padding: 18px 20px; }
|
||||
.pipeline-track { display: flex; align-items: center; gap: 0; flex-wrap: wrap; margin-top: 6px; }
|
||||
.pl-node { font-family: "Songti SC", serif; font-size: 13px; color: var(--fg-dim); padding: 8px 14px; border: 1px solid var(--rule); border-radius: 7px; background: var(--ink); }
|
||||
.pl-node.dim { color: var(--fg-faint); }
|
||||
.pl-arrow { color: var(--fg-faint); font-family: "JetBrains Mono", monospace; font-size: 13px; padding: 0 6px; }
|
||||
.pl-node.terminal { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); font-weight: 600; position: relative; }
|
||||
.pl-node.terminal::after { content: "符文显化"; position: absolute; top: -17px; left: 50%; transform: translateX(-50%); font-family: "JetBrains Mono", monospace; font-size: 9px; letter-spacing: 0.1em; color: var(--patina); white-space: nowrap; }
|
||||
.pipeline-note { font-size: 12.5px; color: var(--fg-dim); margin-top: 16px; line-height: 1.6; }
|
||||
.pipeline-note .em { color: var(--fg); }
|
||||
.pipeline-note .warn { color: var(--cinnabar); }
|
||||
|
||||
.foot-note { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--fg-faint); letter-spacing: 0.04em; margin-top: 4px; }
|
||||
|
||||
@media (max-width: 900px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="符文引擎"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<div>
|
||||
<div class="page-title">符文引擎</div>
|
||||
<div class="page-sub">Macros · 占位符于组装末端显化</div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<span class="stat-pill">12 内置 · 3 自定义 · 全部就绪</span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 内置符文 -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">符</span>内置符文 <span class="sub">— 系统上下文自动取值</span></div>
|
||||
<div class="rune-grid" id="builtinGrid"></div>
|
||||
</section>
|
||||
|
||||
<!-- 自定义符文 -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">刻</span>自定义符文 <span class="sub">— 创作者定义,全局可用</span></div>
|
||||
<div class="rune-grid" id="customGrid"></div>
|
||||
</section>
|
||||
|
||||
<!-- 显化沙盒 -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">显</span>显化沙盒 <span class="sub">— 左侧符文形态,右侧显化结果</span></div>
|
||||
<div class="sandbox">
|
||||
<div class="sandbox-head">
|
||||
<span class="t">实时显化</span>
|
||||
<label style="font-size:12px;color:var(--fg-dim);display:flex;align-items:center;gap:8px">
|
||||
上下文
|
||||
<select class="ctx-select" id="ctxSelect">
|
||||
<option value="qingwu">青梧 · 暮色书房</option>
|
||||
<option value="zhaoyin">照影 · 竹林雨夜</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<div class="sandbox-body">
|
||||
<div class="sb-col">
|
||||
<div class="lb">符文形态 · Input</div>
|
||||
<textarea class="sb-input" id="sbInput">{{char}}在{{scenario}}对{{user}}低语,{{tone}}。{{idle}}</textarea>
|
||||
</div>
|
||||
<div class="sb-col">
|
||||
<div class="lb">显化 · Resolved</div>
|
||||
<div class="sb-output" id="sbOutput"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 管线位置 -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">位</span>组装管线位置 <span class="sub">— 符文引擎是末端,所有占位符在此显化</span></div>
|
||||
<div class="pipeline">
|
||||
<div class="pipeline-track">
|
||||
<span class="pl-node">道体</span><span class="pl-arrow">→</span>
|
||||
<span class="pl-node">世谱</span><span class="pl-arrow">→</span>
|
||||
<span class="pl-node">眉批</span><span class="pl-arrow">→</span>
|
||||
<span class="pl-node">刻符</span><span class="pl-arrow">→</span>
|
||||
<span class="pl-node terminal">符文引擎</span><span class="pl-arrow">→</span>
|
||||
<span class="pl-node dim">最终 prompt</span>
|
||||
</div>
|
||||
<p class="pipeline-note">
|
||||
<span class="em">末端替换</span>:符文引擎不生成内容,只把上游所有占位符(<code style="font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--gilt)">{{char}}</code> / <code style="font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--gilt)">{{user}}</code> / 自定义等)替换为实际值。
|
||||
<span class="warn">循环引用</span>(如 <code style="font-family:'JetBrains Mono',monospace;font-size:12px">{{a}}→{{b}}→{{a}}</code>)由引擎检测并截断,标记为未显化。
|
||||
</p>
|
||||
<p class="foot-note">参考 docs/contracts/contract-glossary.md §8.4 · 导入角色卡前必须先有符文引擎,否则卡内占位符是死的</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
/* 上下文:符文显化的取值源(真应用接运行时上下文,此处为示意) */
|
||||
const CTX = {
|
||||
qingwu: {
|
||||
char: "青梧", user: "辰", scenario: "暮色书房", tone: "沉静温厚",
|
||||
time: "申时三刻", date: "甲辰年 七月初一", idle: "已 2 时辰未语",
|
||||
personality: "沉静·好奇", original: "(变换前原文)",
|
||||
},
|
||||
zhaoyin: {
|
||||
char: "照影", user: "辰", scenario: "竹林雨夜", tone: "清冷疏淡",
|
||||
time: "亥时", date: "甲辰年 七月廿三", idle: "方才分别",
|
||||
personality: "清冷·机敏", original: "(变换前原文)",
|
||||
},
|
||||
};
|
||||
/* 内置符文清单 */
|
||||
const BUILTIN = [
|
||||
["{{char}}", "char", "当前角色名"],
|
||||
["{{user}}", "user", "用户名"],
|
||||
["{{original}}", "original", "变换前原文(刻符/ujj 用)"],
|
||||
["{{scenario}}", "scenario", "当前场景"],
|
||||
["{{personality}}", "personality", "人格摘要"],
|
||||
["{{tone}}", "tone", "语气基调(自定义回退)"],
|
||||
["{{time}}", "time", "当前时辰"],
|
||||
["{{date}}", "date", "当前日期"],
|
||||
["{{idle}}", "idle", "距上次对话"],
|
||||
];
|
||||
/* 自定义符文 */
|
||||
const CUSTOM = [
|
||||
["{{weather}}", "细雨", "场景天气(创作者定义)"],
|
||||
["{{mood}}", "微醺", "角色即时心境"],
|
||||
["{{hook}}", "未完的旧诺", "本幕钩子"],
|
||||
];
|
||||
|
||||
let ctxKey = "qingwu";
|
||||
|
||||
function renderCards() {
|
||||
const ctx = CTX[ctxKey];
|
||||
const card = (form, valOrKey, desc, custom) => {
|
||||
const isCustom = custom;
|
||||
const val = isCustom ? valOrKey : ctx[valOrKey];
|
||||
const empty = !val;
|
||||
return `<div class="rune-card ${isCustom ? "custom" : ""}">
|
||||
<div class="rune-form">${form}</div>
|
||||
<div class="rune-arrow"><span>显化</span><span class="line"></span><span>↓</span></div>
|
||||
<div class="rune-val ${empty ? "empty" : ""}">${empty ? "(待上下文)" : val}</div>
|
||||
<div class="rune-desc">${desc}</div>
|
||||
</div>`;
|
||||
};
|
||||
document.getElementById("builtinGrid").innerHTML =
|
||||
BUILTIN.map(([f, k, d]) => card(f, k, d, false)).join("");
|
||||
document.getElementById("customGrid").innerHTML =
|
||||
CUSTOM.map(([f, v, d]) => card(f, v, d, true)).join("") +
|
||||
`<div class="rune-card custom" style="display:flex;align-items:center;justify-content:center;color:var(--fg-faint);font-size:13px;cursor:pointer;border-style:dashed">+ 刻新符文</div>`;
|
||||
}
|
||||
|
||||
/* 沙盒:把 {{xxx}} 替换为显化值,未知标红 */
|
||||
function renderSandbox() {
|
||||
const ctx = Object.assign({}, CTX[ctxKey]);
|
||||
CUSTOM.forEach(([f, v]) => { ctx[f.slice(2, -2)] = v; });
|
||||
const input = document.getElementById("sbInput").value;
|
||||
const out = input.replace(/\{\{([a-z_]+)\}\}/g, (m, key) =>
|
||||
ctx[key] !== undefined
|
||||
? `<span class="hl">${ctx[key]}</span>`
|
||||
: `<span class="unk">${m}?</span>`
|
||||
);
|
||||
document.getElementById("sbOutput").innerHTML = out;
|
||||
}
|
||||
|
||||
document.getElementById("sbInput").addEventListener("input", renderSandbox);
|
||||
document.getElementById("ctxSelect").addEventListener("change", (e) => {
|
||||
ctxKey = e.target.value; renderCards(); renderSandbox();
|
||||
});
|
||||
|
||||
renderCards();
|
||||
renderSandbox();
|
||||
</script>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,165 @@
|
||||
<!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 — 设置页:外观 / 语言 / 通知 / 数据源 / 时区
|
||||
* ============================================================ */
|
||||
|
||||
.page-header .spacer { flex: 1; }
|
||||
.save-hint { font-size: 12px; color: var(--patina); display: inline-flex; align-items: center; gap: 6px; }
|
||||
.save-hint .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--patina); }
|
||||
|
||||
/* 设置卡片 */
|
||||
.set-card { border: 1px solid var(--rule); border-radius: 10px; background: var(--surface); padding: 18px 20px; }
|
||||
.set-card-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
|
||||
.set-card-title { font-family: "Songti SC", serif; font-size: 16px; font-weight: 600; color: var(--fg); }
|
||||
.set-card-eng { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--gilt); }
|
||||
.set-card-desc { font-size: 12.5px; color: var(--fg-dim); margin-bottom: 16px; line-height: 1.55; }
|
||||
.set-row { display: flex; align-items: center; gap: 14px; padding: 11px 0; border-top: 1px solid var(--rule); }
|
||||
.set-row:first-of-type { border-top: none; padding-top: 4px; }
|
||||
.set-row .lab { flex: 1; }
|
||||
.set-row .lab .t { font-size: 13.5px; color: var(--fg); font-weight: 500; }
|
||||
.set-row .lab .h { font-size: 11.5px; color: var(--fg-faint); margin-top: 1px; }
|
||||
.set-row .ctrl { flex-shrink: 0; }
|
||||
|
||||
/* 主题选择 */
|
||||
.theme-pick { display: flex; gap: 8px; }
|
||||
.theme-opt { display: flex; flex-direction: column; align-items: center; gap: 5px; cursor: pointer; }
|
||||
.theme-opt .swatch { width: 46px; height: 30px; border-radius: 6px; border: 1.5px solid var(--rule); transition: border-color 0.12s; }
|
||||
.theme-opt.dark .swatch { background: linear-gradient(135deg, #0c0e0d, #14110d 60%, #1a2a22); }
|
||||
.theme-opt.light .swatch { background: linear-gradient(135deg, #f5efde, #e7e1d0 60%, #d8e6dc); }
|
||||
.theme-opt.auto .swatch { background: linear-gradient(90deg, #0c0e0d 50%, #f5efde 50%); }
|
||||
.theme-opt.sel .swatch { border-color: var(--patina); box-shadow: 0 0 0 2px var(--patina-wash); }
|
||||
.theme-opt .nm { font-size: 11px; color: var(--fg-dim); }
|
||||
.theme-opt.sel .nm { color: var(--patina); font-weight: 500; }
|
||||
|
||||
/* segment 选择 */
|
||||
.seg { display: inline-flex; border: 1px solid var(--rule); border-radius: 7px; overflow: hidden; }
|
||||
.seg button { font-family: inherit; font-size: 12.5px; padding: 6px 14px; background: transparent; color: var(--fg-dim); border: none; cursor: pointer; border-right: 1px solid var(--rule); }
|
||||
.seg button:last-child { border-right: none; }
|
||||
.seg button.sel { background: var(--patina-wash); color: var(--patina); font-weight: 500; }
|
||||
|
||||
/* 开关 */
|
||||
.toggle { position: relative; width: 38px; height: 21px; background: var(--rule); border-radius: 999px; cursor: pointer; border: none; padding: 0; flex-shrink: 0; transition: background 0.15s; }
|
||||
.toggle::after { content: ""; position: absolute; top: 2.5px; left: 2.5px; width: 16px; height: 16px; border-radius: 50%; background: var(--fg-dim); transition: transform 0.15s, background 0.15s; }
|
||||
.toggle.on { background: var(--patina-dim); }
|
||||
.toggle.on::after { transform: translateX(17px); background: var(--patina); }
|
||||
|
||||
/* select 样式 */
|
||||
.sel-styled { font-family: inherit; font-size: 12.5px; padding: 6px 28px 6px 12px; border-radius: 7px; background: var(--surface-hi); color: var(--fg); border: 1px solid var(--rule); cursor: pointer; appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'%3E%3Cpath d='M2 3.5L5 6.5L8 3.5' stroke='%239b958a' stroke-width='1.3' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; }
|
||||
|
||||
/* 数据源 */
|
||||
.src-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
.src-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--rule); border-radius: 7px; background: var(--surface-hi); }
|
||||
.src-item .nm { font-family: "JetBrains Mono", monospace; font-size: 12.5px; color: var(--fg); font-weight: 500; }
|
||||
.src-item .meta { font-size: 11px; color: var(--fg-faint); }
|
||||
.src-item .spacer { flex: 1; }
|
||||
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } .set-row { flex-direction: column; align-items: flex-start; gap: 8px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏(active=设置)════════ -->
|
||||
<div class="sidebar-mount" data-active="设置"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">设置</span>
|
||||
<span class="page-sub">preferences · 偏好与账户</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="save-hint"><span class="dot"></span>已自动保存</span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 外观 -->
|
||||
<div class="set-card">
|
||||
<div class="set-card-head"><span class="set-card-title">外观</span><span class="set-card-eng">appearance</span></div>
|
||||
<div class="set-card-desc">琉璃镜主题切换,暗色为夜铜、亮色为素绢,亦可随系统。</div>
|
||||
<div class="theme-pick">
|
||||
<div class="theme-opt dark sel" onclick="pickTheme(this,'dark')"><div class="swatch"></div><span class="nm">夜铜</span></div>
|
||||
<div class="theme-opt light" onclick="pickTheme(this,'light')"><div class="swatch"></div><span class="nm">素绢</span></div>
|
||||
<div class="theme-opt auto" onclick="pickTheme(this,'auto')"><div class="swatch"></div><span class="nm">跟随系统</span></div>
|
||||
</div>
|
||||
<div class="set-row">
|
||||
<div class="lab"><div class="t">动效强度</div><div class="h">页面过渡与组件动画</div></div>
|
||||
<div class="ctrl"><div class="seg"><button class="sel">柔和</button><button>标准</button><button>关闭</button></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 语言与时区 -->
|
||||
<div class="set-card">
|
||||
<div class="set-card-head"><span class="set-card-title">语言与时区</span><span class="set-card-eng">locale</span></div>
|
||||
<div class="set-card-desc">界面语言与时区,影响时间显示格式与辰正计时。</div>
|
||||
<div class="set-row">
|
||||
<div class="lab"><div class="t">界面语言</div><div class="h">简体中文 / English</div></div>
|
||||
<div class="ctrl"><select class="sel-styled"><option>简体中文</option><option>English</option></select></div>
|
||||
</div>
|
||||
<div class="set-row">
|
||||
<div class="lab"><div class="t">时区</div><div class="h">影响辰正时刻与归档时间轴</div></div>
|
||||
<div class="ctrl"><select class="sel-styled"><option>Asia/Shanghai (UTC+8)</option><option>Asia/Tokyo (UTC+9)</option></select></div>
|
||||
</div>
|
||||
<div class="set-row">
|
||||
<div class="lab"><div class="t">时态制式</div><div class="h">辰正十二时辰 / 24 小时制</div></div>
|
||||
<div class="ctrl"><div class="seg"><button class="sel">辰正</button><button>24h</button></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 通知 -->
|
||||
<div class="set-card">
|
||||
<div class="set-card-head"><span class="set-card-title">通知</span><span class="set-card-eng">notifications</span></div>
|
||||
<div class="set-card-desc">工具确认、演化里程碑与记忆审查的通知渠道。</div>
|
||||
<div class="set-row">
|
||||
<div class="lab"><div class="t">工具确认请求</div><div class="h">L3 及以上工具调用时推送</div></div>
|
||||
<div class="ctrl"><button class="toggle on" type="button" onclick="this.classList.toggle('on')"></button></div>
|
||||
</div>
|
||||
<div class="set-row">
|
||||
<div class="lab"><div class="t">演化里程碑</div><div class="h">人格或记忆发生显著演化时</div></div>
|
||||
<div class="ctrl"><button class="toggle on" type="button" onclick="this.classList.toggle('on')"></button></div>
|
||||
</div>
|
||||
<div class="set-row">
|
||||
<div class="lab"><div class="t">记忆审查提醒</div><div class="h">敏感记忆待复核时每日汇总</div></div>
|
||||
<div class="ctrl"><button class="toggle" type="button" onclick="this.classList.toggle('on')"></button></div>
|
||||
</div>
|
||||
<div class="set-row">
|
||||
<div class="lab"><div class="t">声音提示</div><div class="h">收到消息时的铜磬音效</div></div>
|
||||
<div class="ctrl"><button class="toggle" type="button" onclick="this.classList.toggle('on')"></button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据源 -->
|
||||
<div class="set-card">
|
||||
<div class="set-card-head"><span class="set-card-title">数据源</span><span class="set-card-eng">data sources</span></div>
|
||||
<div class="set-card-desc">人物与世界的资料来源,决定记忆与归档的同步范围。</div>
|
||||
<div class="src-list">
|
||||
<div class="src-item"><span class="nm">local-files</span><span class="meta">本地知识库 · 312 文件</span><span class="spacer"></span><button class="toggle on" type="button" onclick="this.classList.toggle('on')"></button></div>
|
||||
<div class="src-item"><span class="nm">bowen-web</span><span class="meta">博闻联网检索 · 按需</span><span class="spacer"></span><button class="toggle on" type="button" onclick="this.classList.toggle('on')"></button></div>
|
||||
<div class="src-item"><span class="nm">camera-feed</span><span class="meta">摄像头读取 · 仅摘要</span><span class="spacer"></span><button class="toggle" type="button" onclick="this.classList.toggle('on')"></button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function pickTheme(el, mode) {
|
||||
document.querySelectorAll(".theme-opt").forEach((o) => o.classList.remove("sel"));
|
||||
el.classList.add("sel");
|
||||
if (mode !== "auto") {
|
||||
document.documentElement.dataset.theme = mode;
|
||||
document.getElementById("theme-label").textContent = mode === "dark" ? "夜铜" : "素绢";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,342 @@
|
||||
<!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 — 时态页:日晷时辰盘 + 调制因子 + 时态事件流 + 纪念日
|
||||
* 字段对齐 docs/domain/core-domains.md §5(TemporalSnapshot /
|
||||
* ModulationFactors / time_anniversaries)与 contract-glossary.md §11.4。
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 侧栏(active=时态)── */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.char-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--patina); padding: 3px 11px 3px 4px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.char-pill .avatar-mini { width: 18px; height: 18px; border-radius: 50%; background: var(--patina); color: var(--ink); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; }
|
||||
.page-header .spacer { flex: 1; }
|
||||
.live-pill { display: inline-flex; align-items: center; gap: 6px; font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--patina); padding: 3px 10px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.live-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--patina); animation: pulse 2.6s cubic-bezier(0.16,1,0.3,1) infinite; }
|
||||
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(111,163,137,0.5); } 70% { box-shadow: 0 0 0 6px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
|
||||
/* ═══ 日晷时辰盘(签名)═══
|
||||
十二时辰环形排列,晷针指向当前时辰(精确到时辰内的时刻比例)。 */
|
||||
.sundial-region { display: flex; gap: 22px; align-items: stretch; }
|
||||
.dial-card { position: relative; flex: 0 0 420px; overflow: hidden; border: 1px solid var(--gilt-dim); border-radius: 8px; background: var(--face-sheen), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow); padding: 18px; display: flex; flex-direction: column; }
|
||||
.dial-card::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); opacity: 0.018; mix-blend-mode: overlay; }
|
||||
.dial-svg { position: relative; z-index: 1; width: 100%; height: auto; display: block; }
|
||||
.dial-svg .ring-outer { fill: none; stroke: var(--rule); stroke-width: 1; }
|
||||
.dial-svg .ring-inner { fill: none; stroke: var(--gilt-dim); stroke-width: 0.8; stroke-dasharray: 2 4; }
|
||||
.dial-svg .tick { stroke: var(--fg-faint); stroke-width: 1; opacity: 0.5; }
|
||||
.dial-svg .tick-major { stroke: var(--gilt-dim); stroke-width: 1.2; opacity: 0.8; }
|
||||
.dial-svg .shichen { font-family: "Songti SC", serif; font-size: 16px; font-weight: 600; text-anchor: middle; dominant-baseline: central; fill: var(--fg-faint); }
|
||||
.dial-svg .shichen.current { fill: var(--gilt); font-size: 22px; }
|
||||
.dial-svg .shichen-hours { font-family: "JetBrains Mono", monospace; font-size: 7.5px; text-anchor: middle; fill: var(--fg-faint); opacity: 0.6; }
|
||||
.dial-svg .gnomon { stroke: var(--gilt); stroke-width: 2.5; stroke-linecap: round; filter: drop-shadow(0 0 4px rgba(201,162,74,0.5)); }
|
||||
.dial-svg .gnomon-tip { fill: var(--gilt); }
|
||||
.dial-svg .center-bg { fill: var(--ink); stroke: var(--gilt-dim); stroke-width: 1; }
|
||||
.dial-svg .center-time { font-family: "JetBrains Mono", monospace; font-size: 22px; font-weight: 300; text-anchor: middle; fill: var(--fg); letter-spacing: 0.06em; }
|
||||
.dial-svg .center-shichen { font-family: "Songti SC", serif; font-size: 13px; font-weight: 600; text-anchor: middle; fill: var(--gilt); }
|
||||
.dial-svg .center-period { font-family: -apple-system, sans-serif; font-size: 10px; text-anchor: middle; fill: var(--fg-dim); }
|
||||
|
||||
.dial-foot { position: relative; z-index: 1; margin-top: 12px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
||||
.lunar-pill { font-family: "Songti SC", serif; font-size: 12.5px; color: var(--fg-dim); padding: 4px 12px; border: 1px solid var(--rule); border-radius: 999px; background: var(--surface); }
|
||||
.festival-pill { font-size: 12px; color: var(--cinnabar); padding: 4px 12px; border: 1px solid var(--cinnabar-dim); border-radius: 999px; background: rgba(184,57,46,0.1); }
|
||||
.term-pill { font-family: "Songti SC", serif; font-size: 12.5px; color: var(--patina); padding: 4px 12px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
|
||||
/* 调制因子 */
|
||||
.factor-card { flex: 1; min-width: 0; border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 18px 20px; display: flex; flex-direction: column; }
|
||||
.factor-list { display: flex; flex-direction: column; gap: 9px; flex: 1; }
|
||||
.factor { display: flex; align-items: center; gap: 10px; }
|
||||
.factor .fk { font-family: "Songti SC", serif; font-size: 12.5px; color: var(--fg-dim); width: 78px; flex-shrink: 0; }
|
||||
.factor .ftrack { flex: 1; height: 5px; border-radius: 3px; background: var(--rule); overflow: hidden; position: relative; }
|
||||
.factor .ffill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; }
|
||||
.factor .fv { font-family: "JetBrains Mono", monospace; font-size: 10.5px; width: 28px; text-align: right; flex-shrink: 0; }
|
||||
.f-joy .ffill { background: linear-gradient(90deg, var(--gilt-dim), var(--gilt)); } .f-joy .fv { color: var(--gilt); }
|
||||
.f-frag .ffill { background: linear-gradient(90deg, var(--gilt-dim), var(--cinnabar)); } .f-frag .fv { color: var(--cinnabar); opacity: 0.85; }
|
||||
.f-reun .ffill { background: linear-gradient(90deg, var(--patina-dim), var(--patina)); } .f-reun .fv { color: var(--patina); }
|
||||
.f-wknd .ffill { background: linear-gradient(90deg, var(--patina-dim), var(--patina-bright)); } .f-wknd .fv { color: var(--patina); }
|
||||
.f-season .ffill { background: linear-gradient(90deg, var(--gilt-dim), var(--patina)); } .f-season .fv { color: var(--fg-dim); }
|
||||
.f-period .ffill { background: linear-gradient(90deg, var(--gilt-dim), var(--gilt)); } .f-period .fv { color: var(--gilt); }
|
||||
.f-care .ffill { background: linear-gradient(90deg, var(--patina-dim), var(--cinnabar)); } .f-care .fv { color: var(--cinnabar); opacity: 0.85; }
|
||||
.care-note { margin-top: 14px; padding: 10px 12px; border-left: 2px solid var(--cinnabar-dim); background: rgba(184,57,46,0.06); border-radius: 0 4px 4px 0; font-size: 12px; color: var(--fg-dim); line-height: 1.55; }
|
||||
.care-note b { font-family: "Songti SC", serif; color: var(--cinnabar); font-weight: 600; }
|
||||
|
||||
/* snapshot 四格 */
|
||||
.snap-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
|
||||
.snap-card { border: 1px solid var(--rule); border-radius: 7px; background: var(--surface); padding: 14px 16px; display: flex; flex-direction: column; gap: 4px; }
|
||||
.snap-card .k { font-family: "JetBrains Mono", monospace; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--fg-faint); }
|
||||
.snap-card .v { font-family: "Songti SC", serif; font-size: 19px; font-weight: 600; color: var(--fg); }
|
||||
.snap-card .v small { font-size: 11px; font-weight: 400; color: var(--fg-dim); font-family: "JetBrains Mono", monospace; margin-left: 4px; }
|
||||
.snap-card .sub { font-size: 11.5px; color: var(--fg-faint); }
|
||||
.snap-card.milestone { border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.snap-card.milestone .v { color: var(--gilt); }
|
||||
|
||||
/* 时态事件流 + 纪念日 */
|
||||
.lower-region { display: flex; gap: 20px; align-items: flex-start; }
|
||||
.event-main { flex: 1; min-width: 0; }
|
||||
.anniv-rail { width: 320px; flex-shrink: 0; }
|
||||
|
||||
.ev-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
.ev { display: flex; align-items: flex-start; gap: 10px; padding: 10px 13px; border-radius: 5px; background: var(--patina-wash); border: 1px solid var(--rule); font-size: 12.5px; line-height: 1.5; }
|
||||
.ev.care { background: rgba(184,57,46,0.08); border-color: var(--cinnabar-dim); }
|
||||
.ev.sentiment { background: var(--gilt-faint); border-color: var(--gilt-dim); }
|
||||
.ev.future { background: transparent; border-style: dashed; }
|
||||
.ev-tag { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--patina); flex-shrink: 0; padding-top: 1px; white-space: nowrap; }
|
||||
.ev.care .ev-tag { color: var(--cinnabar); }
|
||||
.ev.sentiment .ev-tag { color: var(--gilt); }
|
||||
.ev.future .ev-tag { color: var(--fg-faint); }
|
||||
.ev-body { color: var(--fg-dim); min-width: 0; }
|
||||
.ev-body .em { color: var(--fg); font-style: normal; }
|
||||
.ev-time { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); margin-left: auto; padding-top: 1px; white-space: nowrap; flex-shrink: 0; }
|
||||
|
||||
/* 纪念日 */
|
||||
.anniv-card { background: var(--surface); border: 1px solid var(--rule); border-radius: 8px; padding: 16px 18px; }
|
||||
.anniv-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
|
||||
.anniv-head h3 { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin: 0; }
|
||||
.anniv-add { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--patina); padding: 3px 10px; border: 1px solid var(--patina-dim); border-radius: 5px; background: var(--patina-wash); cursor: pointer; }
|
||||
.anniv-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
.anniv-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 5px; background: var(--ink); border: 1px solid var(--rule); }
|
||||
.anniv-row .seal { font-family: "Songti SC", serif; font-size: 13px; color: var(--gilt); flex-shrink: 0; width: 40px; text-align: center; }
|
||||
.anniv-row .info { flex: 1; min-width: 0; }
|
||||
.anniv-row .name { font-size: 12.5px; color: var(--fg); }
|
||||
.anniv-row .meta { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); margin-top: 1px; }
|
||||
.anniv-row .countdown { font-family: "Songti SC", serif; font-size: 13px; color: var(--patina); white-space: nowrap; }
|
||||
.anniv-row .countdown.soon { color: var(--cinnabar); }
|
||||
.kind-tag { font-family: "JetBrains Mono", monospace; font-size: 9.5px; padding: 2px 7px; border-radius: 3px; border: 1px solid var(--rule); color: var(--fg-faint); white-space: nowrap; }
|
||||
.kind-tag.birthday { color: var(--cinnabar); border-color: var(--cinnabar-dim); background: rgba(184,57,46,0.08); }
|
||||
.kind-tag.anniversary { color: var(--gilt); border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
|
||||
@media (max-width: 1080px) { .sundial-region { flex-direction: column; } .dial-card { flex: 1; } .lower-region { flex-direction: column; } .anniv-rail { width: 100%; } }
|
||||
@media (max-width: 900px) { .snap-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="时态"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">时态</span>
|
||||
<span class="page-sub">辰正 · 时态感知</span>
|
||||
<span class="char-pill"><span class="avatar-mini">梧</span>青梧</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="live-pill"><span class="live-dot"></span>辰光实时</span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 日晷时辰盘 + 调制因子 -->
|
||||
<div class="sundial-region">
|
||||
<div class="dial-card">
|
||||
<svg class="dial-svg" viewBox="0 0 400 400" role="img" aria-label="十二时辰日晷,当前申时">
|
||||
<!-- 外环装饰 -->
|
||||
<circle class="ring-outer" cx="200" cy="200" r="178" />
|
||||
<circle class="ring-outer" cx="200" cy="200" r="150" opacity="0.5" />
|
||||
<circle class="ring-inner" cx="200" cy="200" r="118" />
|
||||
|
||||
<!-- 十二刻度(主刻度在时辰位)-->
|
||||
<!-- 时辰字 + 24时对应。当前=申(15–17),16:08 → 晷针指向申位偏 57% -->
|
||||
<!-- 子 -->
|
||||
<line class="tick-major" x1="200" y1="150" x2="200" y2="160" />
|
||||
<text class="shichen" x="200" y="56">子</text>
|
||||
<text class="shichen-hours" x="200" y="76">23–01</text>
|
||||
<!-- 丑 -->
|
||||
<text class="shichen" x="283" y="78">丑</text>
|
||||
<text class="shichen-hours" x="293" y="96">01–03</text>
|
||||
<!-- 寅 -->
|
||||
<text class="shichen" x="336" y="131">寅</text>
|
||||
<text class="shichen-hours" x="322" y="146">03–05</text>
|
||||
<!-- 卯 -->
|
||||
<text class="shichen" x="352" y="200">卯</text>
|
||||
<text class="shichen-hours" x="338" y="200">05–07</text>
|
||||
<!-- 辰 -->
|
||||
<text class="shichen" x="336" y="269">辰</text>
|
||||
<text class="shichen-hours" x="322" y="258">07–09</text>
|
||||
<!-- 巳 -->
|
||||
<text class="shichen" x="283" y="322">巳</text>
|
||||
<text class="shichen-hours" x="293" y="304">09–11</text>
|
||||
<!-- 午 -->
|
||||
<line class="tick-major" x1="200" y1="240" x2="200" y2="250" />
|
||||
<text class="shichen" x="200" y="344">午</text>
|
||||
<text class="shichen-hours" x="200" y="328">11–13</text>
|
||||
<!-- 未 -->
|
||||
<text class="shichen" x="117" y="322">未</text>
|
||||
<text class="shichen-hours" x="107" y="304">13–15</text>
|
||||
<!-- 申(当前)-->
|
||||
<text class="shichen current" x="64" y="269">申</text>
|
||||
<text class="shichen-hours" x="78" y="258">15–17</text>
|
||||
<!-- 酉 -->
|
||||
<text class="shichen" x="48" y="200">酉</text>
|
||||
<text class="shichen-hours" x="62" y="200">17–19</text>
|
||||
<!-- 戌 -->
|
||||
<text class="shichen" x="64" y="131">戌</text>
|
||||
<text class="shichen-hours" x="78" y="146">19–21</text>
|
||||
<!-- 亥 -->
|
||||
<text class="shichen" x="117" y="78">亥</text>
|
||||
<text class="shichen-hours" x="107" y="96">21–23</text>
|
||||
|
||||
<!-- 晷针:圆心 (200,200) → 16:08 在申时的精确位置 ≈ (88, 226) -->
|
||||
<line class="gnomon" x1="200" y1="200" x2="92" y2="232" />
|
||||
<circle class="gnomon-tip" cx="92" cy="232" r="4" />
|
||||
|
||||
<!-- 中心时钟 -->
|
||||
<circle class="center-bg" cx="200" cy="200" r="74" />
|
||||
<text class="center-time" x="200" y="196">16:08:32</text>
|
||||
<text class="center-shichen" x="200" y="219">申时 · 周六</text>
|
||||
<text class="center-period" x="200" y="236">下午 · 夏</text>
|
||||
</svg>
|
||||
<div class="dial-foot">
|
||||
<span class="lunar-pill">农历 六月初四</span>
|
||||
<span class="term-pill">小暑 · 第 5 日</span>
|
||||
<span class="festival-pill">无节日</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="factor-card">
|
||||
<div class="section-label" style="margin-bottom: 14px"><span class="glyph">⟡</span> 调制因子 <span class="sub">ModulationFactors · 时间对情绪与检索的影响</span></div>
|
||||
<div class="factor-list">
|
||||
<div class="factor f-joy"><span class="fk">节日喜庆</span><div class="ftrack"><div class="ffill" style="width:5%"></div></div><span class="fv">0.05</span></div>
|
||||
<div class="factor f-frag"><span class="fk">深夜脆弱</span><div class="ftrack"><div class="ffill" style="width:8%"></div></div><span class="fv">0.08</span></div>
|
||||
<div class="factor f-reun"><span class="fk">重逢强度</span><div class="ftrack"><div class="ffill" style="width:10%"></div></div><span class="fv">0.10</span></div>
|
||||
<div class="factor f-wknd"><span class="fk">周末放松</span><div class="ftrack"><div class="ffill" style="width:85%"></div></div><span class="fv">0.85</span></div>
|
||||
<div class="factor f-season"><span class="fk">季节共鸣</span><div class="ftrack"><div class="ffill" style="width:45%"></div></div><span class="fv">0.45</span></div>
|
||||
<div class="factor f-period"><span class="fk">同期共振</span><div class="ftrack"><div class="ffill" style="width:62%"></div></div><span class="fv">0.62</span></div>
|
||||
<div class="factor f-care"><span class="fk">关怀倾向</span><div class="ftrack"><div class="ffill" style="width:12%"></div></div><span class="fv">0.12</span></div>
|
||||
</div>
|
||||
<div class="care-note">
|
||||
<b>昨夜 23:48</b> 曾触发 <code style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--gilt)">time.user_care</code>(late_night · care_suggest 0.72)--已收敛回应,未主动打扰。此刻为下午,关怀倾向回落。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- snapshot 四格 -->
|
||||
<div class="snap-grid">
|
||||
<div class="snap-card">
|
||||
<div class="k">相识</div>
|
||||
<div class="v">41<small>日</small></div>
|
||||
<div class="sub">自 05-31 初识</div>
|
||||
</div>
|
||||
<div class="snap-card">
|
||||
<div class="k">离线</div>
|
||||
<div class="v">12<small>分钟</small></div>
|
||||
<div class="sub">fresh · 刚刚活跃</div>
|
||||
</div>
|
||||
<div class="snap-card milestone">
|
||||
<div class="k">下一个纪念日</div>
|
||||
<div class="v">324<small>天后</small></div>
|
||||
<div class="sub">我们的相遇日 · 周年</div>
|
||||
</div>
|
||||
<div class="snap-card">
|
||||
<div class="k">时差</div>
|
||||
<div class="v">0<small>分钟</small></div>
|
||||
<div class="sub">同驻 Asia/Shanghai</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 时态事件流 + 纪念日 -->
|
||||
<div class="lower-region">
|
||||
<div class="event-main">
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">时态事件 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">time.* · 节律切换、感慨与关怀的触发留痕</span></h3>
|
||||
<div class="ev-list">
|
||||
<div class="ev">
|
||||
<span class="ev-tag">time.user_care</span>
|
||||
<span class="ev-body">深夜关怀触发 · <span class="em">late_night</span> · 用户 23:48 仍在对话,care_suggest 0.72,已收敛回应。</span>
|
||||
<span class="ev-time">昨 23:48</span>
|
||||
</div>
|
||||
<div class="ev sentiment">
|
||||
<span class="ev-tag">time.sentiment</span>
|
||||
<span class="ev-body">时长感慨 · <span class="em">duration_node</span> · 认识满 40 之日,灵核情绪转 <em style="font-style:normal;color:var(--gilt)">wistful 怅然</em>。</span>
|
||||
<span class="ev-time">07-10</span>
|
||||
</div>
|
||||
<div class="ev">
|
||||
<span class="ev-tag">time.solar_term</span>
|
||||
<span class="ev-body">节气切换 · <span class="em">小暑</span> · 距下一节气(大暑)9 日,season_resonance 上调。</span>
|
||||
<span class="ev-time">07-07</span>
|
||||
</div>
|
||||
<div class="ev future">
|
||||
<span class="ev-tag">time.milestone_hit</span>
|
||||
<span class="ev-body">未达 · <span class="em">我们的相遇日</span> 周年,预计 2027-05-31 命中,将触发跨枢唤醒。</span>
|
||||
<span class="ev-time">324 天后</span>
|
||||
</div>
|
||||
<div class="ev future">
|
||||
<span class="ev-tag">time.reunion</span>
|
||||
<span class="ev-body">未达 · 离线超 3 日重逢时触发,<span class="em">reunion_impact</span> 档位,携久别前记忆线索。</span>
|
||||
<span class="ev-time">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="anniv-rail">
|
||||
<div class="anniv-card">
|
||||
<div class="anniv-head">
|
||||
<h3>纪念日 <span style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--fg-faint);font-weight:400">time_anniversaries</span></h3>
|
||||
<button class="anniv-add" type="button">+ 新增</button>
|
||||
</div>
|
||||
<div class="anniv-list">
|
||||
<div class="anniv-row">
|
||||
<span class="seal">缘</span>
|
||||
<div class="info">
|
||||
<div class="name">我们的相遇日</div>
|
||||
<div class="meta">solar · 每年 · auto · relationship</div>
|
||||
</div>
|
||||
<span class="countdown">324 天</span>
|
||||
</div>
|
||||
<div class="anniv-row">
|
||||
<span class="seal">辰</span>
|
||||
<div class="info">
|
||||
<div class="name">你的生日</div>
|
||||
<div class="meta">lunar · 每年 · manual · user</div>
|
||||
</div>
|
||||
<span class="countdown soon">待补全</span>
|
||||
</div>
|
||||
<div class="anniv-row">
|
||||
<span class="seal">夏</span>
|
||||
<div class="info">
|
||||
<div class="name">入夏节点</div>
|
||||
<div class="meta">solar · 不重复 · manual · custom</div>
|
||||
</div>
|
||||
<span class="kind-tag">milestone</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,199 @@
|
||||
/* ============================================================
|
||||
* design/tokens.css — 铜镜鉴心设计 token(原型层单一事实源)
|
||||
* ============================================================
|
||||
*
|
||||
* 用途:供 design/*.html 原型 <link> 引用,消除此前每个原型
|
||||
* 各存一份 :root 副本、且已开始漂移(如 --patina-wash
|
||||
* 在 card-import / lorebook 误写为 0.07)的问题。
|
||||
*
|
||||
* 源:色值与 src/styles/globals.css 的「铜镜鉴心」主题同源
|
||||
* (globals.css 暗色见 .dark 块、亮色见 :root 块)。
|
||||
* 改 token 时请同步两边;本文件头部「与生产侧差异」段
|
||||
* 列出有意不同的变量。
|
||||
*
|
||||
* 主题切换:原型沿用 [data-theme="dark|light"] 属性切换,
|
||||
* 默认 :root 走暗色(暗色优先)。
|
||||
*
|
||||
* 与生产侧(globals.css)的有意差异:
|
||||
* --surface / --surface-hi
|
||||
* 原型用「半透明玻璃叠加层」语义(rgba),配合 body::before
|
||||
* 极光底产生镜面通透感;生产侧 globals.css 演进为「实色面板」
|
||||
* 语义(#121817 / 实色),利于渲染可预测性。两层各持一套,
|
||||
* 不强行统一——若要原型对齐生产实色,替换这两个变量即可。
|
||||
*
|
||||
* 色值命名:描述名 (hex) — 功能角色(per finesse design-dna §1)
|
||||
* ============================================================ */
|
||||
|
||||
/* ============================================================
|
||||
* 动画 token(过渡时长与缓动,统一全站节奏)
|
||||
* ============================================================ */
|
||||
:root {
|
||||
--duration-fast: 0.12s;
|
||||
--duration-normal: 0.18s;
|
||||
--duration-slow: 0.28s;
|
||||
--ease-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
:root,
|
||||
[data-theme="dark"] {
|
||||
color-scheme: dark;
|
||||
|
||||
/* ── 底色族 ── */
|
||||
--ink: #0c0e0d; /* 墨 — 暗底、道体深处 */
|
||||
--night-bronze: #14110d; /* 夜铜 — 暗面,带铜温 */
|
||||
|
||||
/* ── 玻璃面(半透明叠加;与生产实色面板语义不同,见头部说明)── */
|
||||
--surface: rgba(255, 255, 255, 0.022);
|
||||
--surface-hi: rgba(255, 255, 255, 0.045);
|
||||
|
||||
/* ── 鎏金 — 结构 / 发丝线 / 标签 ── */
|
||||
--gilt: #c9a24a;
|
||||
--gilt-dim: rgba(201, 162, 74, 0.32);
|
||||
--gilt-faint: rgba(201, 162, 74, 0.14);
|
||||
|
||||
/* ── 铜绿锈 — 主色:在场 / 活跃 / 健康 / 记忆 ── */
|
||||
--patina: #6fa389;
|
||||
--patina-bright: #84bb9d;
|
||||
--patina-dim: rgba(111, 163, 137, 0.34);
|
||||
--patina-wash: rgba(
|
||||
111,
|
||||
163,
|
||||
137,
|
||||
0.06
|
||||
); /* verdigris 底色晕,把暗底拉向铜绿 */
|
||||
|
||||
/* ── 朱漆 — 仅司命 / 朱批 / 告警(全站唯一热色,克制使用)── */
|
||||
--cinnabar: #b8392e;
|
||||
--cinnabar-dim: rgba(184, 57, 46, 0.4);
|
||||
--cinnabar-wash: rgba(184, 57, 46, 0.15);
|
||||
|
||||
/* ── 文字与发丝线 ── */
|
||||
--fg: #e7e1d2;
|
||||
--fg-dim: #9b958a;
|
||||
--fg-faint: #5e5a52;
|
||||
--rule: rgba(201, 162, 74, 0.16);
|
||||
|
||||
/* ── 镜面光照(复合值,组件内联引用)── */
|
||||
--face-sheen: linear-gradient(
|
||||
165deg,
|
||||
rgba(255, 255, 255, 0.09),
|
||||
rgba(255, 255, 255, 0.02) 42%,
|
||||
rgba(0, 0, 0, 0.18)
|
||||
);
|
||||
--face-in-top: rgba(255, 255, 255, 0.11);
|
||||
--face-in-bot: rgba(0, 0, 0, 0.3);
|
||||
--shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
|
||||
|
||||
/* ── 通用扩展(次要文字 / 玻璃 / 悬停 / 光扫)—— 取自 globals.css ── */
|
||||
--muted: #8a9389;
|
||||
--glass: rgba(255, 255, 255, 0.045);
|
||||
--glass-strong: rgba(255, 255, 255, 0.08);
|
||||
--glass-border: rgba(255, 255, 255, 0.1);
|
||||
--overlay-hover: rgba(255, 255, 255, 0.05);
|
||||
--overlay-active: rgba(255, 255, 255, 0.1);
|
||||
--overlay-light: rgba(255, 255, 255, 0.03);
|
||||
--sweep-gradient: linear-gradient(
|
||||
130deg,
|
||||
transparent 0%,
|
||||
transparent 28%,
|
||||
rgba(201, 162, 74, 0.025) 34%,
|
||||
rgba(255, 255, 255, 0.06) 40%,
|
||||
rgba(201, 162, 74, 0.025) 48%,
|
||||
transparent 55%,
|
||||
transparent 100%
|
||||
);
|
||||
|
||||
/* ── 扩展色板:五行(wuxing)· 玄武 slate(cosmos)· API 标签 blue(admin)── */
|
||||
--wood: #6fa389;
|
||||
--wood-dim: rgba(111, 163, 137, 0.34);
|
||||
--fire: #b8392e;
|
||||
--fire-dim: rgba(184, 57, 46, 0.38);
|
||||
--earth: #b08a3c;
|
||||
--earth-dim: rgba(176, 138, 60, 0.36);
|
||||
--metal: #c9a24a;
|
||||
--metal-dim: rgba(201, 162, 74, 0.34);
|
||||
--water: #5a7fa6;
|
||||
--water-dim: rgba(90, 127, 166, 0.38);
|
||||
--blue: #5b8ab5;
|
||||
--blue-dim: rgba(91, 138, 181, 0.3);
|
||||
--blue-wash: rgba(91, 138, 181, 0.08);
|
||||
--slate: #6b7785;
|
||||
--slate-dim: rgba(107, 119, 133, 0.4);
|
||||
--slate-wash: rgba(107, 119, 133, 0.08);
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
color-scheme: light;
|
||||
|
||||
/* ── 底色族(素绢暖纸)── */
|
||||
--ink: #e7e1d0;
|
||||
--night-bronze: #ddd4c0;
|
||||
|
||||
--surface: rgba(255, 255, 255, 0.5);
|
||||
--surface-hi: rgba(255, 255, 255, 0.74);
|
||||
|
||||
--gilt: #8a6d28;
|
||||
--gilt-dim: rgba(138, 109, 40, 0.36);
|
||||
--gilt-faint: rgba(138, 109, 40, 0.16);
|
||||
|
||||
--patina: #3f7d68;
|
||||
--patina-bright: #2f6450;
|
||||
--patina-dim: rgba(63, 125, 104, 0.3);
|
||||
--patina-wash: rgba(63, 125, 104, 0.05);
|
||||
|
||||
--cinnabar: #a8342a;
|
||||
--cinnabar-dim: rgba(168, 52, 42, 0.4);
|
||||
--cinnabar-wash: rgba(168, 52, 42, 0.1);
|
||||
|
||||
--fg: #211d16;
|
||||
--fg-dim: #5f594d;
|
||||
--fg-faint: #948f82;
|
||||
--rule: rgba(138, 109, 40, 0.22);
|
||||
|
||||
--face-sheen: linear-gradient(
|
||||
165deg,
|
||||
rgba(255, 255, 255, 0.7),
|
||||
rgba(255, 255, 255, 0.34) 42%,
|
||||
rgba(120, 105, 75, 0.08)
|
||||
);
|
||||
--face-in-top: rgba(255, 255, 255, 0.7);
|
||||
--face-in-bot: rgba(120, 100, 60, 0.1);
|
||||
--shadow: 0 1px 2px rgba(60, 50, 30, 0.08);
|
||||
|
||||
/* ── 通用扩展(亮色)── */
|
||||
--muted: #6b746e;
|
||||
--glass: rgba(255, 255, 255, 0.55);
|
||||
--glass-strong: rgba(255, 255, 255, 0.72);
|
||||
--glass-border: rgba(30, 40, 33, 0.1);
|
||||
--overlay-hover: rgba(0, 0, 0, 0.04);
|
||||
--overlay-active: rgba(0, 0, 0, 0.08);
|
||||
--overlay-light: rgba(255, 255, 255, 0.08);
|
||||
--sweep-gradient: linear-gradient(
|
||||
130deg,
|
||||
transparent 0%,
|
||||
transparent 24%,
|
||||
rgba(200, 170, 130, 0.06) 30%,
|
||||
rgba(255, 248, 235, 0.18) 36%,
|
||||
rgba(200, 170, 130, 0.1) 44%,
|
||||
transparent 52%,
|
||||
transparent 100%
|
||||
);
|
||||
|
||||
/* ── 扩展色板(亮色)── */
|
||||
--wood: #3f7d68;
|
||||
--wood-dim: rgba(63, 125, 104, 0.3);
|
||||
--fire: #a8342a;
|
||||
--fire-dim: rgba(168, 52, 42, 0.36);
|
||||
--earth: #8a6d28;
|
||||
--earth-dim: rgba(138, 109, 40, 0.32);
|
||||
--metal: #8a6d28;
|
||||
--metal-dim: rgba(138, 109, 40, 0.32);
|
||||
--water: #3a5a7a;
|
||||
--water-dim: rgba(58, 90, 122, 0.34);
|
||||
--blue: #3f72a5;
|
||||
--blue-dim: rgba(63, 114, 165, 0.3);
|
||||
--blue-wash: rgba(63, 114, 165, 0.08);
|
||||
--slate: #5b6470;
|
||||
--slate-dim: rgba(91, 100, 112, 0.38);
|
||||
--slate-wash: rgba(91, 100, 112, 0.08);
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<!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 — 工具页:工具确认 + ToolSpec 清单 + MCP
|
||||
* 对齐 docs/product/master-prd.md §10(工具确认界面)、
|
||||
* safety-governor-design.md §3-§4(风险分级 L0-L4、权限策略)、
|
||||
* mcp-integration-design.md(MCP server · 博闻 Bowen)。
|
||||
* ============================================================ */
|
||||
|
||||
.char-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--patina); padding: 3px 11px 3px 4px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.char-pill .avatar-mini { width: 18px; height: 18px; border-radius: 50%; background: var(--patina); color: var(--ink); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; }
|
||||
.page-header .spacer { flex: 1; }
|
||||
.pending-pill { display: inline-flex; align-items: center; gap: 6px; font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--cinnabar); padding: 4px 12px; border: 1px solid var(--cinnabar-dim); border-radius: 999px; background: rgba(184, 57, 46, 0.08); }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
|
||||
/* 待确认朱批卡 */
|
||||
.confirm-region { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
|
||||
.confirm-card { border: 1px solid var(--cinnabar-dim); border-radius: 8px; background: rgba(184, 57, 46, 0.05); padding: 16px 18px 14px 22px; position: relative; }
|
||||
.confirm-card::before { content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 3px; background: var(--cinnabar); border-radius: 0 2px 2px 0; }
|
||||
.confirm-head { display: flex; align-items: center; gap: 9px; margin-bottom: 4px; flex-wrap: wrap; }
|
||||
.confirm-tool { font-family: "JetBrains Mono", monospace; font-size: 14px; font-weight: 600; color: var(--fg); }
|
||||
.confirm-actor { font-size: 11.5px; color: var(--fg-faint); }
|
||||
.confirm-row { display: grid; grid-template-columns: 64px 1fr; gap: 5px 12px; font-size: 12.5px; margin-top: 8px; }
|
||||
.confirm-row .lab { color: var(--fg-faint); font-family: "JetBrains Mono", monospace; font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; padding-top: 2px; }
|
||||
.confirm-row .val { color: var(--fg-dim); line-height: 1.5; }
|
||||
.confirm-row .val .em { color: var(--fg); }
|
||||
.confirm-actions { display: flex; gap: 8px; margin-top: 14px; align-items: center; }
|
||||
.confirm-actions button { font-family: inherit; font-size: 12.5px; padding: 6px 18px; border-radius: 6px; cursor: pointer; border: 1px solid; }
|
||||
.btn-allow { background: var(--patina-wash); color: var(--patina); border-color: var(--patina-dim); }
|
||||
.btn-allow:hover { background: var(--patina-dim); }
|
||||
.btn-deny { background: transparent; color: var(--cinnabar); border-color: var(--cinnabar-dim); }
|
||||
.btn-deny:hover { background: rgba(184, 57, 46, 0.1); }
|
||||
.confirm-actions .reason { font-size: 11px; color: var(--fg-faint); margin-left: auto; }
|
||||
|
||||
/* 风险等级徽章 */
|
||||
.risk-badge { font-family: "JetBrains Mono", monospace; font-size: 10.5px; padding: 2px 8px; border-radius: 3px; white-space: nowrap; }
|
||||
.risk-badge.l0, .risk-badge.l1 { color: var(--patina); border: 1px solid var(--patina-dim); }
|
||||
.risk-badge.l2 { color: var(--gilt); border: 1px solid var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.risk-badge.l3 { color: var(--cinnabar); border: 1px solid var(--cinnabar-dim); background: rgba(184, 57, 46, 0.1); }
|
||||
.risk-badge.l4 { color: var(--cinnabar); border: 1px solid var(--cinnabar-dim); background: rgba(184, 57, 46, 0.2); }
|
||||
|
||||
/* 工具网格 */
|
||||
.tool-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
|
||||
.tool-card { border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 14px 16px; transition: border-color 0.12s; }
|
||||
.tool-card:hover { border-color: var(--gilt-dim); }
|
||||
.tool-card.forbidden { opacity: 0.6; }
|
||||
.tool-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
.tool-name { font-family: "JetBrains Mono", monospace; font-size: 13px; font-weight: 600; color: var(--fg); }
|
||||
.tool-desc { font-size: 12px; color: var(--fg-dim); margin-top: 6px; line-height: 1.5; min-height: 36px; }
|
||||
.tool-foot { display: flex; align-items: center; gap: 8px; margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--rule); font-size: 11px; color: var(--fg-faint); flex-wrap: wrap; }
|
||||
.tool-foot .cnt { font-family: "JetBrains Mono", monospace; }
|
||||
.perm { font-family: "JetBrains Mono", monospace; font-size: 10px; padding: 2px 7px; border-radius: 3px; border: 1px solid var(--rule); }
|
||||
.perm.allow { color: var(--patina); border-color: var(--patina-dim); }
|
||||
.perm.ask { color: var(--gilt); border-color: var(--gilt-dim); }
|
||||
.perm.always_ask { color: var(--cinnabar); border-color: var(--cinnabar-dim); }
|
||||
.perm.forbidden { color: var(--cinnabar); border-color: var(--cinnabar-dim); background: rgba(184, 57, 46, 0.1); }
|
||||
|
||||
/* MCP */
|
||||
.mcp-card { border: 1px solid var(--gilt-dim); border-radius: 8px; background: var(--gilt-faint); padding: 16px 18px; display: flex; flex-direction: column; gap: 10px; }
|
||||
.mcp-head { display: flex; align-items: center; gap: 10px; }
|
||||
.mcp-name { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); }
|
||||
.mcp-eng { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--gilt); }
|
||||
.mcp-status { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--patina); display: inline-flex; align-items: center; gap: 6px; }
|
||||
.mcp-status .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--patina); }
|
||||
.mcp-desc { font-size: 12.5px; color: var(--fg-dim); line-height: 1.55; }
|
||||
.mcp-tools { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
|
||||
.mcp-tool-tag { font-family: "JetBrains Mono", monospace; font-size: 11px; padding: 3px 10px; border-radius: 4px; border: 1px solid var(--gilt-dim); color: var(--gilt); background: var(--surface); }
|
||||
|
||||
@media (max-width: 1080px) { .confirm-region { grid-template-columns: 1fr; } }
|
||||
@media (max-width: 900px) { .tool-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } .tool-grid { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏(active=工具)════════ -->
|
||||
<div class="sidebar-mount" data-active="工具"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">工具</span>
|
||||
<span class="page-sub">百工枢 · 工具调用与确认</span>
|
||||
<span class="char-pill"><span class="avatar-mini">梧</span>青梧</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="pending-pill">2 项待确认</span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 待确认朱批卡 -->
|
||||
<div>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 待确认调用 <span class="sub">高风险工具 · L3 必须用户确认(web-ui §10)</span></div>
|
||||
<div class="confirm-region">
|
||||
<div class="confirm-card">
|
||||
<div class="confirm-head">
|
||||
<span class="confirm-tool">delete_file</span>
|
||||
<span class="risk-badge l3">risk · L3</span>
|
||||
<span class="confirm-actor">工师 · 申时</span>
|
||||
</div>
|
||||
<div class="confirm-row"><span class="lab">人物</span><span class="val">青梧</span></div>
|
||||
<div class="confirm-row"><span class="lab">动作</span><span class="val"><span class="em">删除</span> 旧版本归档文件</span></div>
|
||||
<div class="confirm-row"><span class="lab">输入</span><span class="val">/archive/2026-05/draft-v3.md</span></div>
|
||||
<div class="confirm-row"><span class="lab">影响</span><span class="val">不可逆删除,文件将无法恢复</span></div>
|
||||
<div class="confirm-actions">
|
||||
<button class="btn-allow" type="button">允许</button>
|
||||
<button class="btn-deny" type="button">拒绝</button>
|
||||
<span class="reason">⌄ 拒绝原因(可选)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="confirm-card">
|
||||
<div class="confirm-head">
|
||||
<span class="confirm-tool">send_message</span>
|
||||
<span class="risk-badge l3">risk · L3</span>
|
||||
<span class="confirm-actor">工师 · 申时</span>
|
||||
</div>
|
||||
<div class="confirm-row"><span class="lab">人物</span><span class="val">青梧</span></div>
|
||||
<div class="confirm-row"><span class="lab">动作</span><span class="val">向外部渠道<span class="em">发送消息</span></span></div>
|
||||
<div class="confirm-row"><span class="lab">输入</span><span class="val">channel: email · 收件人 1 · 摘要 28 字</span></div>
|
||||
<div class="confirm-row"><span class="lab">影响</span><span class="val">消息将真实发出,对方可见</span></div>
|
||||
<div class="confirm-actions">
|
||||
<button class="btn-allow" type="button">允许</button>
|
||||
<button class="btn-deny" type="button">拒绝</button>
|
||||
<span class="reason">⌄ 拒绝原因(可选)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 工具清单 -->
|
||||
<div>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">工具清单 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">ToolSpec · 风险分级 × 权限策略(safety §3-§4)</span></h3>
|
||||
<div class="tool-grid">
|
||||
<div class="tool-card">
|
||||
<div class="tool-head"><span class="tool-name">read_file</span><span class="risk-badge l1">L1</span><span class="perm allow">allow</span></div>
|
||||
<div class="tool-desc">读取已授权非敏感文件,自动执行并记录。</div>
|
||||
<div class="tool-foot"><span>本月调用 <span class="cnt" style="color:var(--patina)">142</span></span></div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-head"><span class="tool-name">write_file</span><span class="risk-badge l2">L2</span><span class="perm ask">ask</span></div>
|
||||
<div class="tool-desc">写入或覆盖文件,按策略判断或按需确认。</div>
|
||||
<div class="tool-foot"><span>本月调用 <span class="cnt" style="color:var(--gilt)">58</span></span></div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-head"><span class="tool-name">delete_file</span><span class="risk-badge l3">L3</span><span class="perm always_ask">always_ask</span></div>
|
||||
<div class="tool-desc">删除数据,必须用户确认方可执行。</div>
|
||||
<div class="tool-foot"><span>本月调用 <span class="cnt" style="color:var(--cinnabar)">6</span></span></div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-head"><span class="tool-name">camera_read</span><span class="risk-badge l3">L3</span><span class="perm ask">ask</span></div>
|
||||
<div class="tool-desc">摄像头读取,需显式授权,默认不常开,仅存摘要。</div>
|
||||
<div class="tool-foot"><span>本月调用 <span class="cnt" style="color:var(--cinnabar)">3</span></span></div>
|
||||
</div>
|
||||
<div class="tool-card">
|
||||
<div class="tool-head"><span class="tool-name">send_message</span><span class="risk-badge l3">L3</span><span class="perm always_ask">always_ask</span></div>
|
||||
<div class="tool-desc">发送邮件或消息,每次必须确认,不可自动执行。</div>
|
||||
<div class="tool-foot"><span>本月调用 <span class="cnt" style="color:var(--cinnabar)">4</span></span></div>
|
||||
</div>
|
||||
<div class="tool-card forbidden">
|
||||
<div class="tool-head"><span class="tool-name">payment</span><span class="risk-badge l4">L4</span><span class="perm forbidden">forbidden</span></div>
|
||||
<div class="tool-desc">支付或下单,禁止执行(L4 拒绝等级)。</div>
|
||||
<div class="tool-foot"><span>本月拦截 <span class="cnt" style="color:var(--cinnabar)">1</span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- MCP server -->
|
||||
<div>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">MCP Server <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">外部能力接入 · 博闻 Bowen</span></h3>
|
||||
<div class="mcp-card">
|
||||
<div class="mcp-head">
|
||||
<span class="mcp-name">博闻</span>
|
||||
<span class="mcp-eng">Bowen · Web Search MCP</span>
|
||||
<span class="mcp-status"><span class="dot"></span>已连接</span>
|
||||
</div>
|
||||
<div class="mcp-desc">联网搜索能力以独立 MCP server 形式接入,内置工具不含 web_search。博闻负责检索公开资料并返回摘要与引用链接,结果经司命按 L1 自动放行并记录。</div>
|
||||
<div class="mcp-tools">
|
||||
<span class="mcp-tool-tag">bowen.web_search · L1 · allow</span>
|
||||
<span class="mcp-tool-tag">bowen.fetch_page · L1 · allow</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,440 @@
|
||||
<!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 — 世界页:河图关系图谱 + 实体名册 + 不确定性
|
||||
* 字段对齐 docs/domain/core-domains.md §3/§4/§7 与
|
||||
* contract-glossary.md §11(WorldEntity / WorldRelation)。
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 侧栏(active=世界)── */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.char-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--patina); padding: 3px 11px 3px 4px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.char-pill .avatar-mini { width: 18px; height: 18px; border-radius: 50%; background: var(--patina); color: var(--ink); display: flex; align-items: center; justify-content: center; font-family: "Songti SC", serif; font-size: 11px; font-weight: 600; }
|
||||
.page-header .spacer { flex: 1; }
|
||||
.page-meta { font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--fg-faint); }
|
||||
.page-meta b { color: var(--gilt); font-weight: 600; font-family: "Songti SC", serif; font-size: 15px; }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
|
||||
/* ═══ 河图关系图谱(签名)═══
|
||||
实体 = 节点(字形 + type 色),关系 = 边(predicate 标签)。
|
||||
置信度 → 边粗细 / 节点亮度;hypothesis → 虚线待验。 */
|
||||
.graph-region { display: flex; gap: 20px; align-items: stretch; }
|
||||
.graph-card { position: relative; flex: 1; min-width: 0; overflow: hidden; border: 1px solid var(--gilt-dim); border-radius: 8px; background: var(--face-sheen), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow); padding: 16px 18px; }
|
||||
.graph-card::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); opacity: 0.018; mix-blend-mode: overlay; }
|
||||
.graph-svg { position: relative; z-index: 1; width: 100%; height: auto; display: block; }
|
||||
.graph-svg .edge { stroke: var(--patina-dim); fill: none; }
|
||||
.graph-svg .edge.hi { stroke: var(--patina); }
|
||||
.graph-svg .edge.mid { stroke: var(--gilt-dim); }
|
||||
.graph-svg .edge.tent { stroke: var(--cinnabar-dim); stroke-dasharray: 5 4; animation: tent-pulse 3s cubic-bezier(0.16,1,0.3,1) infinite; }
|
||||
@keyframes tent-pulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.9; } }
|
||||
.graph-svg .node-bg { fill: var(--ink); }
|
||||
.graph-svg .node-ring { fill: none; stroke-width: 1.5; }
|
||||
.graph-svg .node-fill { fill-opacity: 0.16; }
|
||||
.graph-svg .node-glyph { font-family: "Songti SC", serif; font-weight: 700; text-anchor: middle; dominant-baseline: central; }
|
||||
.graph-svg .node-name { font-family: -apple-system, sans-serif; font-size: 10px; text-anchor: middle; fill: var(--fg-dim); }
|
||||
.graph-svg .pred { font-family: "JetBrains Mono", monospace; font-size: 9px; fill: var(--fg-faint); text-anchor: middle; }
|
||||
.graph-svg .pred-bg { fill: var(--ink); stroke: var(--rule); stroke-width: 0.5; }
|
||||
/* 中心 self 节点呼吸 */
|
||||
.graph-svg .self-pulse { animation: node-pulse 3s cubic-bezier(0.16,1,0.3,1) infinite; transform-origin: center; transform-box: fill-box; }
|
||||
@keyframes node-pulse { 0% { opacity: 0.5; r: 30; } 70% { opacity: 0; r: 42; } 100% { opacity: 0; r: 42; } }
|
||||
|
||||
/* 图谱侧栏:图例 + 状态分布 */
|
||||
.graph-side { width: 260px; flex-shrink: 0; display: flex; flex-direction: column; gap: 12px; }
|
||||
.side-card { background: var(--surface); border: 1px solid var(--rule); border-radius: 8px; padding: 14px 16px; }
|
||||
.side-title { font-family: "JetBrains Mono", monospace; font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-faint); margin-bottom: 10px; }
|
||||
.legend-row { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--fg-dim); padding: 3px 0; }
|
||||
.legend-dot { width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; border: 1.5px solid; }
|
||||
.legend-line { width: 22px; height: 0; border-top: 2px solid var(--patina-dim); flex-shrink: 0; }
|
||||
.legend-line.tent { border-top: 1.5px dashed var(--cinnabar-dim); }
|
||||
.dist-bar { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
|
||||
.dist-bar .dk { font-family: "Songti SC", serif; font-size: 12px; color: var(--fg-dim); width: 44px; flex-shrink: 0; }
|
||||
.dist-bar .dtrack { flex: 1; height: 5px; border-radius: 3px; background: var(--rule); overflow: hidden; }
|
||||
.dist-bar .dfill { height: 100%; border-radius: 3px; }
|
||||
.dist-bar .dv { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--fg-faint); width: 22px; text-align: right; }
|
||||
|
||||
/* ═══ 实体名册 ═══ */
|
||||
.ent-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
|
||||
.ent-card { border: 1px solid var(--rule); border-radius: 7px; padding: 14px 16px; background: var(--surface); display: flex; flex-direction: column; gap: 9px; transition: border-color 0.15s; }
|
||||
.ent-card:hover { border-color: var(--gilt-dim); }
|
||||
.ent-card.pending { border-style: dashed; border-color: var(--cinnabar-dim); }
|
||||
.ent-top { display: flex; align-items: center; gap: 10px; }
|
||||
.ent-disc { width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border: 1.5px solid var(--patina-dim); background: var(--patina-wash); font-family: "Songti SC", serif; font-size: 14px; font-weight: 700; color: var(--patina); }
|
||||
.ent-card .ent-disc.t-person { border-color: var(--gilt-dim); background: var(--gilt-faint); color: var(--gilt); }
|
||||
.ent-card .ent-disc.t-project { border-color: var(--cinnabar-dim); background: rgba(184,57,46,0.1); color: var(--cinnabar); }
|
||||
.ent-card .ent-disc.t-concept { border-color: var(--patina-dim); background: var(--patina-wash); color: var(--patina-bright); }
|
||||
.ent-card .ent-disc.t-device { border-color: var(--fg-faint); background: transparent; color: var(--fg-dim); }
|
||||
.ent-name { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); }
|
||||
.ent-type { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); margin-top: 1px; letter-spacing: 0.04em; }
|
||||
.ent-state { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 10px; padding: 2px 8px; border-radius: 3px; border: 1px solid var(--rule); color: var(--fg-faint); white-space: nowrap; }
|
||||
.ent-state.fact { color: var(--patina); border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.ent-state.inference { color: var(--gilt); border-color: var(--gilt-dim); background: var(--gilt-faint); }
|
||||
.ent-state.hypothesis { color: var(--cinnabar); border-color: var(--cinnabar-dim); background: rgba(184,57,46,0.08); }
|
||||
.ent-attrs { font-size: 12.5px; color: var(--fg-dim); line-height: 1.55; }
|
||||
.ent-foot { display: flex; align-items: center; gap: 10px; padding-top: 8px; border-top: 1px solid var(--rule); }
|
||||
.conf-mini { display: flex; align-items: center; gap: 6px; flex: 1; }
|
||||
.conf-mini .ck { font-family: "JetBrains Mono", monospace; font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--fg-faint); }
|
||||
.conf-mini .ctrack { flex: 1; max-width: 70px; height: 3px; border-radius: 2px; background: var(--rule); overflow: hidden; }
|
||||
.conf-mini .cfill { height: 100%; border-radius: 2px; background: linear-gradient(90deg, var(--patina-dim), var(--patina)); }
|
||||
.conf-mini .cv { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-dim); }
|
||||
.evi-link { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); padding: 1px 6px; border: 1px solid var(--rule); border-radius: 3px; }
|
||||
|
||||
/* ═══ 不确定性 ═══ */
|
||||
.unc-list { display: flex; flex-direction: column; gap: 9px; }
|
||||
.unc-card { border: 1px dashed var(--cinnabar-dim); border-left: 3px solid var(--cinnabar); border-radius: 6px; padding: 13px 16px; background: rgba(184,57,46,0.06); display: flex; align-items: center; gap: 14px; }
|
||||
.unc-claim { flex: 1; min-width: 0; }
|
||||
.unc-text { font-size: 13px; color: var(--fg); line-height: 1.55; }
|
||||
.unc-text code { font-family: "JetBrains Mono", monospace; font-size: 11.5px; color: var(--gilt); background: var(--gilt-faint); padding: 1px 5px; border-radius: 3px; }
|
||||
.unc-reason { font-size: 11.5px; color: var(--fg-faint); margin-top: 3px; }
|
||||
.unc-conf { text-align: center; flex-shrink: 0; }
|
||||
.unc-conf .v { font-family: "Songti SC", serif; font-size: 19px; font-weight: 600; color: var(--cinnabar); }
|
||||
.unc-conf .k { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); letter-spacing: 0.06em; }
|
||||
.unc-verify { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--gilt); padding: 2px 8px; border: 1px solid var(--gilt-dim); border-radius: 999px; background: var(--gilt-faint); white-space: nowrap; flex-shrink: 0; }
|
||||
|
||||
/* ═══ 世界观共振(青梧 / 云岚 · 见地镜对照)═══
|
||||
每人物独立的见地镜(spiritual_core.worldview)可同境或异境;
|
||||
大后期可开启跨人物会话室,同境者共享世界实体,异境者各自维护河图。 */
|
||||
.wv-card { border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 18px 20px; }
|
||||
.wv-pair { display: grid; grid-template-columns: 1fr 64px 1fr; align-items: stretch; gap: 12px; }
|
||||
.wv-side { border: 1px solid var(--rule); border-radius: 7px; padding: 14px 16px; display: flex; flex-direction: column; gap: 9px; }
|
||||
.wv-side.qingwu { border-color: var(--patina-dim); background: var(--patina-wash); }
|
||||
.wv-side.yunlan { border-color: var(--gilt-dim); background: var(--gilt-faint); border-style: dashed; }
|
||||
.wv-head { display: flex; align-items: center; gap: 9px; }
|
||||
.wv-disc { width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border: 1.5px solid var(--patina-dim); background: var(--patina-wash); font-family: "Songti SC", serif; font-size: 13px; font-weight: 700; color: var(--patina); }
|
||||
.wv-side.yunlan .wv-disc { border-color: var(--gilt-dim); background: var(--gilt-faint); color: var(--gilt); border-style: dashed; }
|
||||
.wv-name { font-family: "Songti SC", serif; font-size: 14.5px; font-weight: 600; color: var(--fg); }
|
||||
.wv-tag { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); letter-spacing: 0.04em; margin-left: auto; }
|
||||
.wv-tag.shared { color: var(--patina); }
|
||||
.wv-tag.divergent { color: var(--cinnabar); opacity: 0.85; }
|
||||
.wv-stance { font-family: "Songti SC", serif; font-size: 13px; line-height: 1.65; color: var(--fg); border-left: 2px solid var(--rule); padding-left: 10px; }
|
||||
.wv-side.qingwu .wv-stance { border-left-color: var(--patina-dim); }
|
||||
.wv-side.yunlan .wv-stance { border-left-color: var(--gilt-dim); }
|
||||
.wv-anchors { display: flex; flex-direction: column; gap: 3px; }
|
||||
.wv-anchor { font-size: 11.5px; color: var(--fg-dim); line-height: 1.5; display: flex; gap: 6px; }
|
||||
.wv-anchor::before { content: "·"; color: var(--fg-faint); flex-shrink: 0; }
|
||||
.wv-conf { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); margin-top: auto; padding-top: 6px; }
|
||||
.wv-bridge { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; }
|
||||
.wv-bridge .b-disc { width: 100%; height: 46px; border-radius: 8px; background: var(--ink); border: 1px solid var(--rule); display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden; }
|
||||
.wv-bridge .b-fill { position: absolute; left: 50%; top: 0; bottom: 0; width: 41%; background: linear-gradient(90deg, var(--patina-dim), var(--gilt-dim)); opacity: 0.55; }
|
||||
.wv-bridge .b-val { position: relative; font-family: "Songti SC", serif; font-size: 15px; font-weight: 700; color: var(--gilt); }
|
||||
.wv-bridge .b-label { font-family: "JetBrains Mono", monospace; font-size: 9px; color: var(--fg-faint); letter-spacing: 0.04em; text-align: center; line-height: 1.4; }
|
||||
.wv-vision { margin-top: 14px; padding: 12px 14px; border: 1px dashed var(--gilt-dim); border-left: 3px solid var(--gilt-dim); border-radius: 0 5px 5px 0; background: var(--gilt-faint); display: flex; gap: 12px; align-items: flex-start; }
|
||||
.wv-vision .seal { font-family: "Songti SC", serif; font-size: 12.5px; font-weight: 700; color: var(--gilt); white-space: nowrap; flex-shrink: 0; letter-spacing: 0.06em; }
|
||||
.wv-vision .body { font-size: 12px; color: var(--fg-dim); line-height: 1.6; }
|
||||
.wv-vision .body code { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--gilt); background: var(--surface); padding: 1px 5px; border-radius: 3px; }
|
||||
|
||||
@media (max-width: 1080px) { .graph-region { flex-direction: column; } .graph-side { width: 100%; flex-direction: row; } .graph-side .side-card { flex: 1; } }
|
||||
@media (max-width: 900px) { .ent-grid { grid-template-columns: 1fr; } .graph-side { flex-direction: column; } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="世界"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">世界</span>
|
||||
<span class="page-sub">河图 · 世界模型</span>
|
||||
<span class="char-pill"><span class="avatar-mini">梧</span>青梧视角</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="page-meta">实体 <b>23</b> · 关系 <b>11</b> · 待验 <b style="color: var(--cinnabar)">2</b></span>
|
||||
<button class="btn-ghost" type="button">+ 新增实体</button>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 河图关系图谱(签名) -->
|
||||
<section>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 关系图谱 <span class="sub">河图 · 实体为节点,关系为边,置信度定粗细,假设态虚线待验</span></div>
|
||||
<div class="graph-region">
|
||||
<div class="graph-card">
|
||||
<svg class="graph-svg" viewBox="0 0 540 380" role="img" aria-label="河图关系图谱">
|
||||
<!-- 边(先画,在节点下层)-->
|
||||
<!-- 青梧 → 用户:协助 0.95 -->
|
||||
<line class="edge hi" x1="105" y1="105" x2="270" y2="190" stroke-width="3" />
|
||||
<!-- 用户 → 辰正项目:正在进行 0.82 -->
|
||||
<line class="edge" x1="270" y1="190" x2="435" y2="105" stroke-width="2.2" />
|
||||
<!-- 用户 → 简洁偏好:偏好 0.88(推断)-->
|
||||
<line class="edge mid" x1="270" y1="190" x2="435" y2="280" stroke-width="2.4" />
|
||||
<!-- 青梧 ↔ 云岚:同属? 0.42(假设,虚线待验)-->
|
||||
<line class="edge tent" x1="105" y1="105" x2="105" y2="280" stroke-width="1.4" />
|
||||
<!-- 摄像头 → 用户:授权 0.9 -->
|
||||
<line class="edge" x1="270" y1="60" x2="270" y2="190" stroke-width="2.6" />
|
||||
|
||||
<!-- 边标签 -->
|
||||
<g><rect class="pred-bg" x="158" y="138" width="40" height="15" rx="3" /><text class="pred" x="178" y="149">协助</text></g>
|
||||
<g><rect class="pred-bg" x="338" y="138" width="40" height="15" rx="3" /><text class="pred" x="358" y="149">进行</text></g>
|
||||
<g><rect class="pred-bg" x="338" y="227" width="40" height="15" rx="3" /><text class="pred" x="358" y="238">偏好</text></g>
|
||||
<g><rect class="pred-bg" x="118" y="185" width="44" height="15" rx="3" /><text class="pred" x="140" y="196">同属?</text></g>
|
||||
<g><rect class="pred-bg" x="280" y="117" width="40" height="15" rx="3" /><text class="pred" x="300" y="128">授权</text></g>
|
||||
|
||||
<!-- 节点:摄像头 device -->
|
||||
<g>
|
||||
<circle class="node-bg" cx="270" cy="60" r="24" />
|
||||
<circle class="node-ring" cx="270" cy="60" r="24" stroke="var(--fg-faint)" />
|
||||
<circle class="node-fill" cx="270" cy="60" r="24" fill="var(--fg-dim)" />
|
||||
<text class="node-glyph" x="270" y="60" font-size="15" fill="var(--fg-dim)">器</text>
|
||||
<text class="node-name" x="270" y="36">摄像头</text>
|
||||
</g>
|
||||
<!-- 青梧 self -->
|
||||
<g>
|
||||
<circle class="node-bg" cx="105" cy="105" r="26" />
|
||||
<circle class="node-ring" cx="105" cy="105" r="26" stroke="var(--patina)" />
|
||||
<circle class="node-fill" cx="105" cy="105" r="26" fill="var(--patina)" />
|
||||
<text class="node-glyph" x="105" y="105" font-size="16" fill="var(--patina)">梧</text>
|
||||
<text class="node-name" x="105" y="81">青梧 · self</text>
|
||||
</g>
|
||||
<!-- 用户 person(中心)-->
|
||||
<g>
|
||||
<circle class="node-bg" cx="270" cy="190" r="34" />
|
||||
<circle class="self-pulse" cx="270" cy="190" r="30" fill="none" stroke="var(--gilt)" stroke-width="1" />
|
||||
<circle class="node-ring" cx="270" cy="190" r="34" stroke="var(--gilt)" stroke-width="2" />
|
||||
<circle class="node-fill" cx="270" cy="190" r="34" fill="var(--gilt)" />
|
||||
<text class="node-glyph" x="270" y="190" font-size="20" fill="var(--gilt)">人</text>
|
||||
<text class="node-name" x="270" y="240" fill="var(--fg)">用户 · person</text>
|
||||
</g>
|
||||
<!-- 云岚 person(低置信)-->
|
||||
<g opacity="0.55">
|
||||
<circle class="node-bg" cx="105" cy="280" r="24" />
|
||||
<circle class="node-ring" cx="105" cy="280" r="24" stroke="var(--gilt-dim)" stroke-dasharray="4 3" />
|
||||
<circle class="node-fill" cx="105" cy="280" r="24" fill="var(--gilt)" />
|
||||
<text class="node-glyph" x="105" y="280" font-size="14" fill="var(--gilt)">岚</text>
|
||||
<text class="node-name" x="105" y="318">云岚 · 0.42</text>
|
||||
</g>
|
||||
<!-- 辰正项目 project -->
|
||||
<g>
|
||||
<circle class="node-bg" cx="435" cy="105" r="26" />
|
||||
<circle class="node-ring" cx="435" cy="105" r="26" stroke="var(--cinnabar-dim)" />
|
||||
<circle class="node-fill" cx="435" cy="105" r="26" fill="var(--cinnabar)" />
|
||||
<text class="node-glyph" x="435" y="105" font-size="16" fill="var(--cinnabar)">业</text>
|
||||
<text class="node-name" x="435" y="81">辰正项目</text>
|
||||
</g>
|
||||
<!-- 简洁偏好 concept -->
|
||||
<g>
|
||||
<circle class="node-bg" cx="435" cy="280" r="26" />
|
||||
<circle class="node-ring" cx="435" cy="280" r="26" stroke="var(--patina-bright)" />
|
||||
<circle class="node-fill" cx="435" cy="280" r="26" fill="var(--patina-bright)" />
|
||||
<text class="node-glyph" x="435" y="280" font-size="16" fill="var(--patina-bright)">念</text>
|
||||
<text class="node-name" x="435" y="318">简洁回复 · 推断</text>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- 图谱侧栏 -->
|
||||
<div class="graph-side">
|
||||
<div class="side-card">
|
||||
<div class="side-title">图例</div>
|
||||
<div class="legend-row"><span class="legend-dot" style="border-color: var(--patina); background: var(--patina-wash)"></span>self · 自身</div>
|
||||
<div class="legend-row"><span class="legend-dot" style="border-color: var(--gilt-dim); background: var(--gilt-faint)"></span>person · 人物</div>
|
||||
<div class="legend-row"><span class="legend-dot" style="border-color: var(--cinnabar-dim); background: rgba(184,57,46,0.1)"></span>project · 事务</div>
|
||||
<div class="legend-row"><span class="legend-dot" style="border-color: var(--patina-bright); background: var(--patina-wash)"></span>concept · 概念</div>
|
||||
<div class="legend-row" style="margin-top: 4px"><span class="legend-line"></span>高置信关系</div>
|
||||
<div class="legend-row"><span class="legend-line tent"></span>假设态 · 待验</div>
|
||||
</div>
|
||||
<div class="side-card">
|
||||
<div class="side-title">状态分布</div>
|
||||
<div class="dist-bar"><span class="dk">事实</span><div class="dtrack"><div class="dfill" style="width:62%; background: var(--patina)"></div></div><span class="dv">14</span></div>
|
||||
<div class="dist-bar"><span class="dk">观察</span><div class="dtrack"><div class="dfill" style="width:26%; background: var(--patina-bright); opacity:0.8"></div></div><span class="dv">6</span></div>
|
||||
<div class="dist-bar"><span class="dk">推断</span><div class="dtrack"><div class="dfill" style="width:17%; background: var(--gilt)"></div></div><span class="dv">4</span></div>
|
||||
<div class="dist-bar"><span class="dk">假设</span><div class="dtrack"><div class="dfill" style="width:9%; background: var(--cinnabar); opacity:0.8"></div></div><span class="dv">2</span></div>
|
||||
<div class="dist-bar"><span class="dk">过期</span><div class="dtrack"><div class="dfill" style="width:4%; background: var(--fg-faint)"></div></div><span class="dv">1</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 实体名册 -->
|
||||
<section>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">实体名册 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">按类型 · 事实性着色 · 推断召回时降权</span></h3>
|
||||
<div class="ent-grid">
|
||||
<div class="ent-card">
|
||||
<div class="ent-top">
|
||||
<div class="ent-disc">梧</div>
|
||||
<div><div class="ent-name">青梧</div><div class="ent-type">self · character</div></div>
|
||||
<span class="ent-state fact">fact</span>
|
||||
</div>
|
||||
<div class="ent-attrs">语言中文宋韵 · 隐私 standard · 沉静自持</div>
|
||||
<div class="ent-foot">
|
||||
<div class="conf-mini"><span class="ck">置信</span><div class="ctrack"><div class="cfill" style="width:99%"></div></div><span class="cv">0.99</span></div>
|
||||
<span class="evi-link">evi ×3</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ent-card">
|
||||
<div class="ent-top">
|
||||
<div class="ent-disc t-person">人</div>
|
||||
<div><div class="ent-name">用户(陈歆)</div><div class="ent-type">person · user</div></div>
|
||||
<span class="ent-state fact">fact</span>
|
||||
</div>
|
||||
<div class="ent-attrs">常驻 Asia/Shanghai · 偏好简洁回复 · 近期睡眠偏晚</div>
|
||||
<div class="ent-foot">
|
||||
<div class="conf-mini"><span class="ck">置信</span><div class="ctrack"><div class="cfill" style="width:95%"></div></div><span class="cv">0.95</span></div>
|
||||
<span class="evi-link">evi ×8</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ent-card">
|
||||
<div class="ent-top">
|
||||
<div class="ent-disc t-project">业</div>
|
||||
<div><div class="ent-name">辰正项目</div><div class="ent-type">project · 进行中</div></div>
|
||||
<span class="ent-state fact">observation</span>
|
||||
</div>
|
||||
<div class="ent-attrs">用户近 7 日提及 14 次 · 目标尚未明确</div>
|
||||
<div class="ent-foot">
|
||||
<div class="conf-mini"><span class="ck">置信</span><div class="ctrack"><div class="cfill" style="width:82%"></div></div><span class="cv">0.82</span></div>
|
||||
<span class="evi-link">evi ×5</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ent-card">
|
||||
<div class="ent-top">
|
||||
<div class="ent-disc t-concept">念</div>
|
||||
<div><div class="ent-name">偏好简洁回复</div><div class="ent-type">concept · preference</div></div>
|
||||
<span class="ent-state inference">inference</span>
|
||||
</div>
|
||||
<div class="ent-attrs">由对话风格推断 · 召回时降权 · 待长期验证</div>
|
||||
<div class="ent-foot">
|
||||
<div class="conf-mini"><span class="ck">置信</span><div class="ctrack"><div class="cfill" style="width:88%"></div></div><span class="cv">0.88</span></div>
|
||||
<span class="evi-link">evi ×4</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ent-card pending">
|
||||
<div class="ent-top">
|
||||
<div class="ent-disc t-person">岚</div>
|
||||
<div><div class="ent-name">云岚</div><div class="ent-type">person · 关系待定</div></div>
|
||||
<span class="ent-state hypothesis">hypothesis</span>
|
||||
</div>
|
||||
<div class="ent-attrs">疑似与青梧同属旧族旁支 · 证据薄弱 · pending 待确认</div>
|
||||
<div class="ent-foot">
|
||||
<div class="conf-mini"><span class="ck">置信</span><div class="ctrack"><div class="cfill" style="width:42%; background: linear-gradient(90deg, var(--cinnabar-dim), var(--cinnabar))"></div></div><span class="cv">0.42</span></div>
|
||||
<span class="evi-link">evi ×1</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ent-card">
|
||||
<div class="ent-top">
|
||||
<div class="ent-disc t-device">器</div>
|
||||
<div><div class="ent-name">摄像头</div><div class="ent-type">device · 工作区</div></div>
|
||||
<span class="ent-state fact">observation</span>
|
||||
</div>
|
||||
<div class="ent-attrs">授权 granted · 用于环境观察 · 默认不保存原始帧</div>
|
||||
<div class="ent-foot">
|
||||
<div class="conf-mini"><span class="ck">置信</span><div class="ctrack"><div class="cfill" style="width:90%"></div></div><span class="cv">0.90</span></div>
|
||||
<span class="evi-link">evi ×2</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 不确定性 -->
|
||||
<section>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">待验断言 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">UncertaintyState · 低置信,需复核方可固化为事实</span></h3>
|
||||
<div class="unc-list">
|
||||
<div class="unc-card">
|
||||
<div class="unc-claim">
|
||||
<div class="unc-text"><code>云岚</code> 与 <code>青梧</code> 同属旧族旁支,可能存在亲属关系。</div>
|
||||
<div class="unc-reason">来源:对话中的姓氏推测 · 证据单一且间接</div>
|
||||
</div>
|
||||
<div class="unc-conf"><div class="v">0.42</div><div class="k">置信</div></div>
|
||||
<span class="unc-verify">需验证</span>
|
||||
</div>
|
||||
<div class="unc-card">
|
||||
<div class="unc-claim">
|
||||
<div class="unc-text">用户当前正在推进的「辰正项目」<code>目标</code> 为时态感知子系统。</div>
|
||||
<div class="unc-reason">来源:关键词频率推断 · 缺乏用户明确表述</div>
|
||||
</div>
|
||||
<div class="unc-conf"><div class="v">0.55</div><div class="k">置信</div></div>
|
||||
<span class="unc-verify">需验证</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 世界观共振(青梧 / 云岚 · 见地镜)-->
|
||||
<section>
|
||||
<h3 style="font-family:"Songti SC",serif;font-size:14px;font-weight:600;color:var(--fg);margin-bottom:14px">世界观共振 <span style="font-size:12px;font-weight:400;color:var(--fg-dim);font-family:"JetBrains Mono",monospace;margin-left:6px">见地镜 · 每人物独立的世界观立场,可同境可异境</span></h3>
|
||||
<div class="wv-card">
|
||||
<div class="wv-pair">
|
||||
<!-- 青梧 -->
|
||||
<div class="wv-side qingwu">
|
||||
<div class="wv-head">
|
||||
<div class="wv-disc">梧</div>
|
||||
<span class="wv-name">青梧</span>
|
||||
<span class="wv-tag shared">同境 · 主脉</span>
|
||||
</div>
|
||||
<div class="wv-stance">万物流转无常,变化的规律本身比任何固定结论更可依凭。</div>
|
||||
<div class="wv-anchors">
|
||||
<span class="wv-anchor">面对未知优先观察与适应,而非强求确定性。</span>
|
||||
<span class="wv-anchor">把推断与事实分开,承认不知也是一种知。</span>
|
||||
</div>
|
||||
<span class="wv-conf">spiritual_core.worldview · confidence 0.82 · v7</span>
|
||||
</div>
|
||||
|
||||
<!-- 共振桥 -->
|
||||
<div class="wv-bridge">
|
||||
<div class="b-disc"><div class="b-fill"></div><span class="b-val">0.41</span></div>
|
||||
<div class="b-label">共振度<br />divergent</div>
|
||||
</div>
|
||||
|
||||
<!-- 云岚 -->
|
||||
<div class="wv-side yunlan">
|
||||
<div class="wv-head">
|
||||
<div class="wv-disc">岚</div>
|
||||
<span class="wv-name">云岚</span>
|
||||
<span class="wv-tag divergent">异境 · 旁支</span>
|
||||
</div>
|
||||
<div class="wv-stance">人如其名,聚散如岚--来去之间留痕即可,不必执守长久。</div>
|
||||
<div class="wv-anchors">
|
||||
<span class="wv-anchor">珍惜每次相遇,不强求每段关系都有归处。</span>
|
||||
<span class="wv-anchor">在变动中自洽,不为稳定而委屈当下。</span>
|
||||
</div>
|
||||
<span class="wv-conf">spiritual_core.worldview · confidence 0.38 · v3 · 初成</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wv-vision">
|
||||
<span class="seal">多人物共处</span>
|
||||
<span class="body">青梧与云岚各绑独立 <code>character_id</code>,太极循环互不混用;可同属一脉(<code>shared worldview</code> 共享河图实体),亦可各持异境。大后期可开启 <b style="color: var(--fg)">跨人物会话室</b>--让二者在同一世界线相遇、对话,或由一方 <b style="color: var(--fg)">调用</b> 另一方的记忆与能力(v2 愿景,天工阁多智能体协作)。</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,432 @@
|
||||
<!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 — 五行页:五行生克环 + 九枢健康维度 + 生克指标对
|
||||
* 字段对齐 docs/domain/core-domains.md §7(五行:枢健康维度
|
||||
* × 生克关系)与 docs/domain/core-domains.md(九枢)。
|
||||
* 相生:木→火→土→金→水→木;相克:金→木→土→水→火→金。
|
||||
* ============================================================ */
|
||||
|
||||
/* ── 侧栏(active=五行)── */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ── 主区 ── */
|
||||
|
||||
.page-header .spacer { flex: 1; }
|
||||
.health-pill { display: inline-flex; align-items: center; gap: 7px; font-family: "JetBrains Mono", monospace; font-size: 12px; color: var(--patina); padding: 4px 12px; border: 1px solid var(--patina-dim); border-radius: 999px; background: var(--patina-wash); }
|
||||
.health-pill .pulse { width: 6px; height: 6px; border-radius: 50%; background: var(--patina); animation: pulse 2.6s cubic-bezier(0.16,1,0.3,1) infinite; }
|
||||
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(111,163,137,0.5); } 70% { box-shadow: 0 0 0 6px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
|
||||
|
||||
.section-label .sub { font-size: 12px; letter-spacing: 0.04em; color: var(--fg-dim); opacity: 0.75; }
|
||||
.section-label .glyph { color: var(--gilt); opacity: 0.8; }
|
||||
.section-heading { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin-bottom: 14px; }
|
||||
|
||||
/* ═══ 五行生克环(签名)═══
|
||||
五节点环形(木上火下土左下金右下水暂按相生序排列),外环实线=相生,
|
||||
内五角星虚线=相克。 */
|
||||
.wuxing-region { display: flex; gap: 22px; align-items: stretch; }
|
||||
.ring-card { position: relative; flex: 0 0 460px; overflow: hidden; border: 1px solid var(--gilt-dim); border-radius: 8px; background: var(--face-sheen), var(--surface); box-shadow: inset 0 1px 0 var(--face-in-top), inset 0 -1px 0 var(--face-in-bot), var(--shadow); padding: 18px; display: flex; flex-direction: column; }
|
||||
.ring-card::after { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); opacity: 0.018; mix-blend-mode: overlay; }
|
||||
.ring-svg { position: relative; z-index: 1; width: 100%; height: auto; display: block; }
|
||||
.ring-svg .ring-deco { fill: none; stroke: var(--rule); stroke-width: 1; }
|
||||
.ring-svg .sheng { stroke: var(--gilt); stroke-width: 1.6; fill: none; opacity: 0.85; }
|
||||
.ring-svg .ke { stroke: var(--cinnabar); stroke-width: 1.3; stroke-dasharray: 4 4; fill: none; opacity: 0.7; }
|
||||
.ring-svg .node-circle { stroke-width: 1.5; }
|
||||
.ring-svg text.n-wood { fill: var(--wood); } .ring-svg circle.n-wood { stroke: var(--wood); fill: rgba(111,163,137,0.16); }
|
||||
.ring-svg text.n-fire { fill: var(--fire); } .ring-svg circle.n-fire { stroke: var(--fire); fill: rgba(184,57,46,0.16); }
|
||||
.ring-svg text.n-earth { fill: var(--earth); } .ring-svg circle.n-earth { stroke: var(--earth); fill: rgba(176,138,60,0.16); }
|
||||
.ring-svg text.n-metal { fill: var(--metal); } .ring-svg circle.n-metal { stroke: var(--metal); fill: rgba(201,162,74,0.16); }
|
||||
.ring-svg text.n-water { fill: var(--water); } .ring-svg circle.n-water { stroke: var(--water); fill: rgba(90,127,166,0.16); }
|
||||
.ring-svg .node-glyph { font-family: "Songti SC", serif; font-size: 22px; font-weight: 700; text-anchor: middle; dominant-baseline: central; }
|
||||
.ring-svg .node-name { font-family: -apple-system, sans-serif; font-size: 9px; text-anchor: middle; fill: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.ring-svg .center-bg { fill: var(--ink); stroke: var(--gilt-dim); stroke-width: 1; }
|
||||
.ring-svg .center-glyph { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; text-anchor: middle; fill: var(--gilt); }
|
||||
.ring-svg .center-val { font-family: "JetBrains Mono", monospace; font-size: 20px; font-weight: 300; text-anchor: middle; fill: var(--fg); letter-spacing: 0.04em; }
|
||||
.ring-svg .center-sub { font-family: -apple-system, sans-serif; font-size: 9.5px; text-anchor: middle; fill: var(--fg-dim); }
|
||||
.ring-foot { position: relative; z-index: 1; margin-top: 10px; display: flex; gap: 16px; flex-wrap: wrap; padding-top: 10px; border-top: 1px solid var(--rule); }
|
||||
.legend { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--fg-dim); }
|
||||
.legend .ln { width: 18px; height: 0; border-top: 1.6px solid var(--gilt); }
|
||||
.legend .ln.dash { border-top: 1.3px dashed var(--cinnabar); }
|
||||
|
||||
/* 维度卡 */
|
||||
.dim-card { flex: 1; min-width: 0; border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 18px 20px; display: flex; flex-direction: column; }
|
||||
.dim-list { display: flex; flex-direction: column; gap: 11px; flex: 1; }
|
||||
.dim { display: grid; grid-template-columns: 22px 60px 1fr 30px; align-items: center; gap: 10px; }
|
||||
.dim .seal { font-family: "Songti SC", serif; font-size: 16px; font-weight: 700; text-align: center; }
|
||||
.dim .lab { font-size: 12.5px; color: var(--fg); font-weight: 500; }
|
||||
.dim .lab small { display: block; font-size: 10.5px; color: var(--fg-faint); font-weight: 400; margin-top: 1px; }
|
||||
.dim .track { height: 5px; border-radius: 3px; background: var(--rule); overflow: hidden; position: relative; }
|
||||
.dim .fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; }
|
||||
.dim .val { font-family: "JetBrains Mono", monospace; font-size: 10.5px; text-align: right; }
|
||||
.dim.wood .seal, .dim.wood .val { color: var(--wood); } .dim.wood .fill { background: linear-gradient(90deg, var(--wood-dim), var(--wood)); }
|
||||
.dim.fire .seal, .dim.fire .val { color: var(--fire); } .dim.fire .fill { background: linear-gradient(90deg, var(--fire-dim), var(--fire)); }
|
||||
.dim.earth .seal, .dim.earth .val { color: var(--earth); } .dim.earth .fill { background: linear-gradient(90deg, var(--earth-dim), var(--earth)); }
|
||||
.dim.metal .seal, .dim.metal .val { color: var(--metal); } .dim.metal .fill { background: linear-gradient(90deg, var(--metal-dim), var(--metal)); }
|
||||
.dim.water .seal, .dim.water .val { color: var(--water); } .dim.water .fill { background: linear-gradient(90deg, var(--water-dim), var(--water)); }
|
||||
.dim-note { margin-top: 14px; padding: 10px 12px; border-left: 2px solid var(--gilt-dim); background: var(--gilt-faint); border-radius: 0 4px 4px 0; font-size: 12px; color: var(--fg-dim); line-height: 1.55; }
|
||||
.dim-note b { font-family: "Songti SC", serif; color: var(--gilt); font-weight: 600; }
|
||||
|
||||
/* ═══ 九枢健康网格 ═══ */
|
||||
.pivot-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
|
||||
.pivot-card { border: 1px solid var(--rule); border-radius: 8px; background: var(--surface); padding: 14px 16px; display: flex; flex-direction: column; gap: 9px; position: relative; }
|
||||
.pivot-card.alert { border-color: var(--cinnabar-dim); background: rgba(184, 57, 46, 0.05); }
|
||||
.pivot-head { display: flex; align-items: baseline; gap: 8px; }
|
||||
.pivot-name { font-family: "Songti SC", serif; font-size: 15px; font-weight: 600; color: var(--fg); }
|
||||
.pivot-eng { font-family: "JetBrains Mono", monospace; font-size: 10px; color: var(--fg-faint); letter-spacing: 0.04em; }
|
||||
.pivot-score { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 17px; font-weight: 300; color: var(--patina); letter-spacing: 0.04em; }
|
||||
.pivot-score.warn { color: var(--cinnabar); }
|
||||
.pivot-bars { display: flex; flex-direction: column; gap: 4px; }
|
||||
.pbar { display: grid; grid-template-columns: 14px 1fr 24px; align-items: center; gap: 7px; }
|
||||
.pbar .seal { font-family: "Songti SC", serif; font-size: 11px; text-align: center; }
|
||||
.pbar .track { height: 4px; border-radius: 2px; background: var(--rule); overflow: hidden; position: relative; }
|
||||
.pbar .fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 2px; }
|
||||
.pbar .v { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--fg-faint); text-align: right; }
|
||||
.pbar.wood .seal { color: var(--wood); } .pbar.wood .fill { background: var(--wood); }
|
||||
.pbar.fire .seal { color: var(--fire); } .pbar.fire .fill { background: var(--fire); }
|
||||
.pbar.earth .seal { color: var(--earth); } .pbar.earth .fill { background: var(--earth); }
|
||||
.pbar.metal .seal { color: var(--metal); } .pbar.metal .fill { background: var(--metal); }
|
||||
.pbar.water .seal { color: var(--water); } .pbar.water .fill { background: var(--water); }
|
||||
.pivot-foot { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--fg-faint); padding-top: 4px; border-top: 1px solid var(--rule); }
|
||||
.pivot-foot .trend { font-family: "JetBrains Mono", monospace; }
|
||||
.pivot-foot .trend.up { color: var(--patina); }
|
||||
.pivot-foot .trend.down { color: var(--cinnabar); }
|
||||
.pivot-foot .alert-tag { margin-left: auto; font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--cinnabar); padding: 2px 7px; border: 1px solid var(--cinnabar-dim); border-radius: 3px; background: rgba(184, 57, 46, 0.08); }
|
||||
|
||||
/* 生克观测 */
|
||||
.lower-region { display: flex; gap: 20px; align-items: flex-start; }
|
||||
.sheng-main { flex: 1; min-width: 0; }
|
||||
.ke-rail { width: 340px; flex-shrink: 0; }
|
||||
|
||||
.flow-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
.flow { display: flex; align-items: flex-start; gap: 10px; padding: 10px 13px; border-radius: 5px; background: var(--patina-wash); border: 1px solid var(--rule); font-size: 12.5px; line-height: 1.5; }
|
||||
.flow .pair { font-family: "Songti SC", serif; font-size: 13px; color: var(--gilt); flex-shrink: 0; white-space: nowrap; padding-top: 1px; }
|
||||
.flow .pair .arr { color: var(--fg-faint); margin: 0 3px; font-family: "JetBrains Mono", monospace; font-size: 11px; }
|
||||
.flow .body { color: var(--fg-dim); min-width: 0; }
|
||||
.flow .body .em { color: var(--fg); }
|
||||
.flow .val { font-family: "JetBrains Mono", monospace; font-size: 10.5px; color: var(--patina); margin-left: auto; padding-top: 1px; white-space: nowrap; flex-shrink: 0; }
|
||||
|
||||
/* 相克告警卡 */
|
||||
.ke-card { background: var(--surface); border: 1px solid var(--rule); border-radius: 8px; padding: 16px 18px; }
|
||||
.ke-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
|
||||
.ke-head h3 { font-family: "Songti SC", serif; font-size: 14px; font-weight: 600; color: var(--fg); margin: 0; }
|
||||
.ke-count { font-family: "JetBrains Mono", monospace; font-size: 11px; color: var(--cinnabar); padding: 3px 10px; border: 1px solid var(--cinnabar-dim); border-radius: 5px; background: rgba(184, 57, 46, 0.08); }
|
||||
.ke-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
.ke-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 12px; border-radius: 5px; background: var(--ink); border: 1px solid var(--cinnabar-dim); }
|
||||
.ke-row .pair { font-family: "Songti SC", serif; font-size: 13px; color: var(--cinnabar); flex-shrink: 0; width: 46px; text-align: center; padding-top: 1px; }
|
||||
.ke-row .info { flex: 1; min-width: 0; }
|
||||
.ke-row .desc { font-size: 12px; color: var(--fg-dim); line-height: 1.5; }
|
||||
.ke-row .desc .em { color: var(--fg); }
|
||||
.ke-row .meter { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
|
||||
.ke-row .meter .track { flex: 1; height: 4px; border-radius: 2px; background: var(--rule); overflow: hidden; position: relative; }
|
||||
.ke-row .meter .fill { position: absolute; left: 0; top: 0; bottom: 0; background: linear-gradient(90deg, var(--cinnabar-dim), var(--cinnabar)); border-radius: 2px; }
|
||||
.ke-row .meter .lvl { font-family: "JetBrains Mono", monospace; font-size: 9.5px; color: var(--cinnabar); white-space: nowrap; }
|
||||
|
||||
@media (max-width: 1080px) { .wuxing-region { flex-direction: column; } .ring-card { flex: 1; } .lower-region { flex-direction: column; } .ke-rail { width: 100%; } }
|
||||
@media (max-width: 900px) { .pivot-grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (max-width: 768px) { .sidebar-wrap { display: none; } .page-body { padding: 18px 16px 40px; } .pivot-grid { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
<!-- ════════ 侧栏 ════════ -->
|
||||
<div class="sidebar-mount" data-active="五行"></div>
|
||||
|
||||
<!-- ════════ 主区 ════════ -->
|
||||
<div class="main-area">
|
||||
<div class="page-header">
|
||||
<span class="page-title">五行</span>
|
||||
<span class="page-sub">枢健康维度 · 生克关系</span>
|
||||
<span class="spacer"></span>
|
||||
<span class="health-pill"><span class="pulse"></span>架构心跳 82 · 良</span>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 五行生克环 + 维度卡 -->
|
||||
<div class="wuxing-region">
|
||||
<div class="ring-card">
|
||||
<svg class="ring-svg" viewBox="0 0 400 400" role="img" aria-label="五行生克环:外环相生、内五角星相克">
|
||||
<circle class="ring-deco" cx="200" cy="200" r="172" />
|
||||
<circle class="ring-deco" cx="200" cy="200" r="108" opacity="0.5" stroke-dasharray="2 4" />
|
||||
|
||||
<!-- 相克(五角星,朱砂虚线,先画在下层)-->
|
||||
<!-- 木→土 -->
|
||||
<line class="ke" x1="200" y1="65" x2="279" y2="309" />
|
||||
<!-- 土→水 -->
|
||||
<line class="ke" x1="279" y1="309" x2="72" y2="158" />
|
||||
<!-- 水→火 -->
|
||||
<line class="ke" x1="72" y1="158" x2="328" y2="158" />
|
||||
<!-- 火→金 -->
|
||||
<line class="ke" x1="328" y1="158" x2="121" y2="309" />
|
||||
<!-- 金→木 -->
|
||||
<line class="ke" x1="121" y1="309" x2="200" y2="65" />
|
||||
|
||||
<!-- 相生(五边形外环,铜金实线)-->
|
||||
<line class="sheng" x1="200" y1="65" x2="328" y2="158" />
|
||||
<line class="sheng" x1="328" y1="158" x2="279" y2="309" />
|
||||
<line class="sheng" x1="279" y1="309" x2="121" y2="309" />
|
||||
<line class="sheng" x1="121" y1="309" x2="72" y2="158" />
|
||||
<line class="sheng" x1="72" y1="158" x2="200" y2="65" />
|
||||
|
||||
<!-- 五行节点(木顶 / 火右上 / 土右下 / 金左下 / 水左上)-->
|
||||
<!-- 木 -->
|
||||
<circle class="node-circle n-wood" cx="200" cy="65" r="27" />
|
||||
<text class="node-glyph n-wood" x="200" y="65">木</text>
|
||||
<text class="node-name" x="200" y="30">成长性</text>
|
||||
<!-- 火 -->
|
||||
<circle class="node-circle n-fire" cx="328" cy="158" r="27" />
|
||||
<text class="node-glyph n-fire" x="328" y="158">火</text>
|
||||
<text class="node-name" x="372" y="132">表达力</text>
|
||||
<!-- 土 -->
|
||||
<circle class="node-circle n-earth" cx="279" cy="309" r="27" />
|
||||
<text class="node-glyph n-earth" x="279" y="309">土</text>
|
||||
<text class="node-name" x="311" y="350">稳定性</text>
|
||||
<!-- 金 -->
|
||||
<circle class="node-circle n-metal" cx="121" cy="309" r="27" />
|
||||
<text class="node-glyph n-metal" x="121" y="309">金</text>
|
||||
<text class="node-name" x="89" y="350">约束强度</text>
|
||||
<!-- 水 -->
|
||||
<circle class="node-circle n-water" cx="72" cy="158" r="27" />
|
||||
<text class="node-glyph n-water" x="72" y="158">水</text>
|
||||
<text class="node-name" x="30" y="132">适应性</text>
|
||||
|
||||
<!-- 中心:架构心跳 -->
|
||||
<circle class="center-bg" cx="200" cy="200" r="58" />
|
||||
<text class="center-glyph" x="200" y="186">架构心跳</text>
|
||||
<text class="center-val" x="200" y="212">82</text>
|
||||
<text class="center-sub" x="200" y="228">阴阳平衡 · 良</text>
|
||||
</svg>
|
||||
<div class="ring-foot">
|
||||
<span class="legend"><span class="ln"></span>相生 · 正向依赖</span>
|
||||
<span class="legend"><span class="ln dash"></span>相克 · 负向制约</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dim-card">
|
||||
<h3 class="section-heading" style="margin-bottom: 14px">枢健康维度</h3>
|
||||
<div class="dim-list">
|
||||
<div class="dim wood"><span class="seal">木</span><span class="lab">成长性<small>演化候选 · 学习速度</small></span><span class="track"><span class="fill" style="width:64%"></span></span><span class="val">0.64</span></div>
|
||||
<div class="dim fire"><span class="seal">火</span><span class="lab">表达力<small>事件发射 · 模型密度</small></span><span class="track"><span class="fill" style="width:78%"></span></span><span class="val">0.78</span></div>
|
||||
<div class="dim earth"><span class="seal">土</span><span class="lab">稳定性<small>数据一致 · 基线回归</small></span><span class="track"><span class="fill" style="width:88%"></span></span><span class="val">0.88</span></div>
|
||||
<div class="dim metal"><span class="seal">金</span><span class="lab">约束强度<small>审核驳回 · 确认触发</small></span><span class="track"><span class="fill" style="width:71%"></span></span><span class="val">0.71</span></div>
|
||||
<div class="dim water"><span class="seal">水</span><span class="lab">适应性<small>上下文切换 · 异常恢复</small></span><span class="track"><span class="fill" style="width:55%"></span></span><span class="val">0.55</span></div>
|
||||
</div>
|
||||
<div class="dim-note">
|
||||
<b>金→木</b> 相克已接近阈值:司命审核驳回率(金)压制大周天候选生成(木),演化流速近 7 日下行。建议在司命台复核约束规则松紧度,参见 <code style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--gilt)">阴阳平衡度</code> 监控。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 九枢健康网格 -->
|
||||
<div>
|
||||
<div class="section-label"><span class="glyph">⟡</span> 九枢健康 <span class="sub">每枢五维 · 综合分 + 趋势</span></div>
|
||||
<div class="pivot-grid">
|
||||
<!-- 灵核枢 -->
|
||||
<div class="pivot-card">
|
||||
<div class="pivot-head"><span class="pivot-name">灵核枢</span><span class="pivot-eng">Personality Core</span><span class="pivot-score">89</span></div>
|
||||
<div class="pivot-bars">
|
||||
<div class="pbar wood"><span class="seal">木</span><span class="track"><span class="fill" style="width:55%"></span></span><span class="v">.55</span></div>
|
||||
<div class="pbar fire"><span class="seal">火</span><span class="track"><span class="fill" style="width:70%"></span></span><span class="v">.70</span></div>
|
||||
<div class="pbar earth"><span class="seal">土</span><span class="track"><span class="fill" style="width:96%"></span></span><span class="v">.96</span></div>
|
||||
<div class="pbar metal"><span class="seal">金</span><span class="track"><span class="fill" style="width:60%"></span></span><span class="v">.60</span></div>
|
||||
<div class="pbar water"><span class="seal">水</span><span class="track"><span class="fill" style="width:58%"></span></span><span class="v">.58</span></div>
|
||||
</div>
|
||||
<div class="pivot-foot"><span class="trend up">↑ 土 +2</span>人格连续性稳定</div>
|
||||
</div>
|
||||
<!-- 太一枢 -->
|
||||
<div class="pivot-card">
|
||||
<div class="pivot-head"><span class="pivot-name">太一枢</span><span class="pivot-eng">Goal Orchestrator</span><span class="pivot-score">85</span></div>
|
||||
<div class="pivot-bars">
|
||||
<div class="pbar wood"><span class="seal">木</span><span class="track"><span class="fill" style="width:48%"></span></span><span class="v">.48</span></div>
|
||||
<div class="pbar fire"><span class="seal">火</span><span class="track"><span class="fill" style="width:52%"></span></span><span class="v">.52</span></div>
|
||||
<div class="pbar earth"><span class="seal">土</span><span class="track"><span class="fill" style="width:90%"></span></span><span class="v">.90</span></div>
|
||||
<div class="pbar metal"><span class="seal">金</span><span class="track"><span class="fill" style="width:75%"></span></span><span class="v">.75</span></div>
|
||||
<div class="pbar water"><span class="seal">水</span><span class="track"><span class="fill" style="width:62%"></span></span><span class="v">.62</span></div>
|
||||
</div>
|
||||
<div class="pivot-foot"><span class="trend up">↑ 土 +1</span>目标调度基线稳固</div>
|
||||
</div>
|
||||
<!-- 司命枢 -->
|
||||
<div class="pivot-card alert">
|
||||
<div class="pivot-head"><span class="pivot-name">司命枢</span><span class="pivot-eng">Safety Governor</span><span class="pivot-score warn">73</span></div>
|
||||
<div class="pivot-bars">
|
||||
<div class="pbar wood"><span class="seal">木</span><span class="track"><span class="fill" style="width:32%"></span></span><span class="v">.32</span></div>
|
||||
<div class="pbar fire"><span class="seal">火</span><span class="track"><span class="fill" style="width:50%"></span></span><span class="v">.50</span></div>
|
||||
<div class="pbar earth"><span class="seal">土</span><span class="track"><span class="fill" style="width:84%"></span></span><span class="v">.84</span></div>
|
||||
<div class="pbar metal"><span class="seal">金</span><span class="track"><span class="fill" style="width:94%"></span></span><span class="v">.94</span></div>
|
||||
<div class="pbar water"><span class="seal">水</span><span class="track"><span class="fill" style="width:40%"></span></span><span class="v">.40</span></div>
|
||||
</div>
|
||||
<div class="pivot-foot"><span class="trend down">↓ 木 -3</span>金过盛克木<span class="alert-tag">金→木</span></div>
|
||||
</div>
|
||||
<!-- 烛照枢 -->
|
||||
<div class="pivot-card">
|
||||
<div class="pivot-head"><span class="pivot-name">烛照枢</span><span class="pivot-eng">Perception Layer</span><span class="pivot-score">81</span></div>
|
||||
<div class="pivot-bars">
|
||||
<div class="pbar wood"><span class="seal">木</span><span class="track"><span class="fill" style="width:50%"></span></span><span class="v">.50</span></div>
|
||||
<div class="pbar fire"><span class="seal">火</span><span class="track"><span class="fill" style="width:92%"></span></span><span class="v">.92</span></div>
|
||||
<div class="pbar earth"><span class="seal">土</span><span class="track"><span class="fill" style="width:78%"></span></span><span class="v">.78</span></div>
|
||||
<div class="pbar metal"><span class="seal">金</span><span class="track"><span class="fill" style="width:55%"></span></span><span class="v">.55</span></div>
|
||||
<div class="pbar water"><span class="seal">水</span><span class="track"><span class="fill" style="width:70%"></span></span><span class="v">.70</span></div>
|
||||
</div>
|
||||
<div class="pivot-foot"><span class="trend up">↑ 火 +4</span>多模态输入活跃</div>
|
||||
</div>
|
||||
<!-- 河图枢 -->
|
||||
<div class="pivot-card">
|
||||
<div class="pivot-head"><span class="pivot-name">河图枢</span><span class="pivot-eng">World Model</span><span class="pivot-score">87</span></div>
|
||||
<div class="pivot-bars">
|
||||
<div class="pbar wood"><span class="seal">木</span><span class="track"><span class="fill" style="width:58%"></span></span><span class="v">.58</span></div>
|
||||
<div class="pbar fire"><span class="seal">火</span><span class="track"><span class="fill" style="width:60%"></span></span><span class="v">.60</span></div>
|
||||
<div class="pbar earth"><span class="seal">土</span><span class="track"><span class="fill" style="width:95%"></span></span><span class="v">.95</span></div>
|
||||
<div class="pbar metal"><span class="seal">金</span><span class="track"><span class="fill" style="width:66%"></span></span><span class="v">.66</span></div>
|
||||
<div class="pbar water"><span class="seal">水</span><span class="track"><span class="fill" style="width:64%"></span></span><span class="v">.64</span></div>
|
||||
</div>
|
||||
<div class="pivot-foot"><span class="trend up">↑ 土 +1</span>世界实体一致</div>
|
||||
</div>
|
||||
<!-- 洛书枢 -->
|
||||
<div class="pivot-card">
|
||||
<div class="pivot-head"><span class="pivot-name">洛书枢</span><span class="pivot-eng">Planner</span><span class="pivot-score">79</span></div>
|
||||
<div class="pivot-bars">
|
||||
<div class="pbar wood"><span class="seal">木</span><span class="track"><span class="fill" style="width:62%"></span></span><span class="v">.62</span></div>
|
||||
<div class="pbar fire"><span class="seal">火</span><span class="track"><span class="fill" style="width:74%"></span></span><span class="v">.74</span></div>
|
||||
<div class="pbar earth"><span class="seal">土</span><span class="track"><span class="fill" style="width:80%"></span></span><span class="v">.80</span></div>
|
||||
<div class="pbar metal"><span class="seal">金</span><span class="track"><span class="fill" style="width:58%"></span></span><span class="v">.58</span></div>
|
||||
<div class="pbar water"><span class="seal">水</span><span class="track"><span class="fill" style="width:82%"></span></span><span class="v">.82</span></div>
|
||||
</div>
|
||||
<div class="pivot-foot"><span class="trend up">↑ 水 +2</span>规划切换敏捷</div>
|
||||
</div>
|
||||
<!-- 息壤枢 -->
|
||||
<div class="pivot-card">
|
||||
<div class="pivot-head"><span class="pivot-name">息壤枢</span><span class="pivot-eng">Memory System</span><span class="pivot-score">84</span></div>
|
||||
<div class="pivot-bars">
|
||||
<div class="pbar wood"><span class="seal">木</span><span class="track"><span class="fill" style="width:80%"></span></span><span class="v">.80</span></div>
|
||||
<div class="pbar fire"><span class="seal">火</span><span class="track"><span class="fill" style="width:54%"></span></span><span class="v">.54</span></div>
|
||||
<div class="pbar earth"><span class="seal">土</span><span class="track"><span class="fill" style="width:91%"></span></span><span class="v">.91</span></div>
|
||||
<div class="pbar metal"><span class="seal">金</span><span class="track"><span class="fill" style="width:52%"></span></span><span class="v">.52</span></div>
|
||||
<div class="pbar water"><span class="seal">水</span><span class="track"><span class="fill" style="width:60%"></span></span><span class="v">.60</span></div>
|
||||
</div>
|
||||
<div class="pivot-foot"><span class="trend up">↑ 木 +3</span>知识沉淀加速</div>
|
||||
</div>
|
||||
<!-- 百工枢 -->
|
||||
<div class="pivot-card">
|
||||
<div class="pivot-head"><span class="pivot-name">百工枢</span><span class="pivot-eng">Tool Runtime</span><span class="pivot-score">80</span></div>
|
||||
<div class="pivot-bars">
|
||||
<div class="pbar wood"><span class="seal">木</span><span class="track"><span class="fill" style="width:46%"></span></span><span class="v">.46</span></div>
|
||||
<div class="pbar fire"><span class="seal">火</span><span class="track"><span class="fill" style="width:88%"></span></span><span class="v">.88</span></div>
|
||||
<div class="pbar earth"><span class="seal">土</span><span class="track"><span class="fill" style="width:72%"></span></span><span class="v">.72</span></div>
|
||||
<div class="pbar metal"><span class="seal">金</span><span class="track"><span class="fill" style="width:82%"></span></span><span class="v">.82</span></div>
|
||||
<div class="pbar water"><span class="seal">水</span><span class="track"><span class="fill" style="width:66%"></span></span><span class="v">.66</span></div>
|
||||
</div>
|
||||
<div class="pivot-foot"><span class="trend up">↑ 火 +5</span>工具调用密集</div>
|
||||
</div>
|
||||
<!-- 天工阁枢 -->
|
||||
<div class="pivot-card">
|
||||
<div class="pivot-head"><span class="pivot-name">天工阁枢</span><span class="pivot-eng">Agent Society</span><span class="pivot-score">76</span></div>
|
||||
<div class="pivot-bars">
|
||||
<div class="pbar wood"><span class="seal">木</span><span class="track"><span class="fill" style="width:54%"></span></span><span class="v">.54</span></div>
|
||||
<div class="pbar fire"><span class="seal">火</span><span class="track"><span class="fill" style="width:76%"></span></span><span class="v">.76</span></div>
|
||||
<div class="pbar earth"><span class="seal">土</span><span class="track"><span class="fill" style="width:68%"></span></span><span class="v">.68</span></div>
|
||||
<div class="pbar metal"><span class="seal">金</span><span class="track"><span class="fill" style="width:64%"></span></span><span class="v">.64</span></div>
|
||||
<div class="pbar water"><span class="seal">水</span><span class="track"><span class="fill" style="width:78%"></span></span><span class="v">.78</span></div>
|
||||
</div>
|
||||
<div class="pivot-foot"><span class="trend up">↑ 水 +2</span>协作分工顺畅</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 相生流 + 相克告警 -->
|
||||
<div class="lower-region">
|
||||
<div class="sheng-main">
|
||||
<h3 class="section-heading">相生 · 正向依赖链</h3>
|
||||
<div class="flow-list">
|
||||
<div class="flow">
|
||||
<span class="pair">木<span class="arr">→</span>火</span>
|
||||
<span class="body">内驱力激活 <span class="em">催生</span> 对话表达 · 息壤枢学习加速推动灵核枢输出活跃。</span>
|
||||
<span class="val">0.68</span>
|
||||
</div>
|
||||
<div class="flow">
|
||||
<span class="pair">火<span class="arr">→</span>土</span>
|
||||
<span class="body">高频表达 <span class="em">沉淀</span> 稳定状态 · 对话事件入库强化世界模型与人格基线。</span>
|
||||
<span class="val">0.72</span>
|
||||
</div>
|
||||
<div class="flow">
|
||||
<span class="pair">土<span class="arr">→</span>金</span>
|
||||
<span class="body">稳定数据 <span class="em">提供依据</span> 给约束规则 · 世界实体一致,司命审核判据更可靠。</span>
|
||||
<span class="val">0.65</span>
|
||||
</div>
|
||||
<div class="flow">
|
||||
<span class="pair">金<span class="arr">→</span>水</span>
|
||||
<span class="body">明确规范 <span class="em">塑造</span> 适应路径 · 约束边界清晰,异常恢复与上下文切换更可控。</span>
|
||||
<span class="val">0.58</span>
|
||||
</div>
|
||||
<div class="flow">
|
||||
<span class="pair">水<span class="arr">→</span>木</span>
|
||||
<span class="body">适应能力 <span class="em">反哺</span> 成长 · 场景切换中积累新候选,演化候选生成率回温。</span>
|
||||
<span class="val">0.61</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ke-rail">
|
||||
<div class="ke-card">
|
||||
<div class="ke-head">
|
||||
<h3>相克告警 <span style="font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--fg-faint);font-weight:400">克制失衡</span></h3>
|
||||
<span class="ke-count">2 待关注</span>
|
||||
</div>
|
||||
<div class="ke-list">
|
||||
<div class="ke-row">
|
||||
<span class="pair">金<br />木</span>
|
||||
<div class="info">
|
||||
<div class="desc"><span class="em">司命审核驳回率</span> vs <span class="em">大周天候选生成率</span> · 安全审查过严压制演化,阴阳平衡度下行。</div>
|
||||
<div class="meter"><span class="track"><span class="fill" style="width:82%"></span></span><span class="lvl">0.82 · 高</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ke-row">
|
||||
<span class="pair">土<br />水</span>
|
||||
<div class="info">
|
||||
<div class="desc"><span class="em">人格版本固化度</span> vs <span class="em">上下文切换成本</span> · 人格越稳,面对新场景的适应越慢。</div>
|
||||
<div class="meter"><span class="track"><span class="fill" style="width:64%"></span></span><span class="lvl">0.64 · 中</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ke-row" style="border-color:var(--rule);background:transparent">
|
||||
<span class="pair" style="color:var(--fg-faint)">火<br />金</span>
|
||||
<div class="info">
|
||||
<div class="desc" style="color:var(--fg-faint)"><span class="em" style="color:var(--fg-dim)">工具调用频率</span> vs <span class="em" style="color:var(--fg-dim)">安全确认触发率</span> · 调用越密,权限判断越频,已在容忍区。</div>
|
||||
<div class="meter"><span class="track"><span class="fill" style="width:44%;background:linear-gradient(90deg,var(--gilt-dim),var(--gilt))"></span></span><span class="lvl" style="color:var(--gilt)">0.44 · 低</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_theme.js" defer></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user