From b63542add3dd8f48f97cda7f2805dd1edc40dab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=AD=86?= <2685475410@qq.com> Date: Mon, 21 Sep 2026 11:19:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=89=8D=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 15 +- .gitignore | 6 +- Makefile | 12 +- backend/app/auth/routes.py | 16 +- backend/app/characters/seeds.py | 64 + backend/app/core/config.py | 3 + backend/app/main.py | 17 + backend/scripts/mock_model.py | 78 + design/admin.html | 399 ++++ design/agent-workspace.html | 169 ++ design/assets/app.css | 1704 ++++++++++++++++ design/assets/app.js | 222 +++ design/avatar.html | 145 ++ design/characters.html | 233 +++ design/collaboration.html | 114 ++ design/community.html | 141 ++ design/conversation.html | 552 ++++++ design/devices.html | 133 ++ design/governance.html | 142 ++ design/home.html | 277 +++ design/index.html | 243 +++ design/login.html | 87 + design/marketplace.html | 140 ++ design/memory.html | 242 +++ design/model-gateway.html | 124 ++ design/plugins.html | 115 ++ design/register.html | 108 ++ design/settings.html | 121 ++ frontend/next-env.d.ts | 6 + frontend/next.config.ts | 9 + frontend/package-lock.json | 1421 -------------- frontend/package.json | 3 + frontend/pnpm-lock.yaml | 887 +++++++++ .../src/app/(app)/agent-workspace/page.tsx | 14 + frontend/src/app/(app)/avatar/page.tsx | 14 + frontend/src/app/(app)/characters/page.tsx | 14 + frontend/src/app/(app)/collaboration/page.tsx | 14 + frontend/src/app/(app)/community/page.tsx | 14 + frontend/src/app/(app)/conversation/page.tsx | 22 + frontend/src/app/(app)/devices/page.tsx | 14 + frontend/src/app/(app)/governance/page.tsx | 14 + frontend/src/app/(app)/home/page.tsx | 14 + frontend/src/app/(app)/layout.tsx | 6 + frontend/src/app/(app)/marketplace/page.tsx | 14 + frontend/src/app/(app)/memory/page.tsx | 14 + frontend/src/app/(app)/model-gateway/page.tsx | 14 + frontend/src/app/(app)/page.tsx | 187 ++ frontend/src/app/(app)/plugins/page.tsx | 14 + frontend/src/app/(app)/settings/page.tsx | 14 + frontend/src/app/admin/layout.tsx | 6 + frontend/src/app/admin/page.tsx | 42 + frontend/src/app/globals.css | 1710 +++++++++++++++++ frontend/src/app/layout.tsx | 17 +- frontend/src/app/login/page.tsx | 139 ++ frontend/src/app/page.tsx | 8 - frontend/src/app/register/page.tsx | 133 ++ frontend/src/components/admin/AdminPanel.tsx | 120 ++ .../characters/CharacterListPanel.tsx | 141 ++ .../characters/CharactersPagePanel.tsx | 218 +++ .../collaboration/CollaborationPanel.tsx | 57 + .../components/community/CommunityPanel.tsx | 67 + .../components/conversation/BlockRenderer.tsx | 170 ++ .../components/conversation/ConvLayout.tsx | 86 + .../conversation/ConversationPanel.tsx | 382 ++++ .../components/conversation/EffortControl.tsx | 82 + .../marketplace/MarketplacePanel.tsx | 88 + .../src/components/memory/MemoryPanel.tsx | 135 ++ frontend/src/components/panels/index.tsx | 364 ++++ .../src/components/plugins/PluginsPanel.tsx | 77 + frontend/src/components/shell/AdminShell.tsx | 55 + frontend/src/components/shell/AppShell.tsx | 52 + frontend/src/components/shell/RequireAuth.tsx | 46 + frontend/src/components/shell/Sidebar.tsx | 136 ++ frontend/src/components/shell/Topbar.tsx | 19 + frontend/src/components/ui/index.tsx | 39 + frontend/src/lib/api.ts | 228 +++ frontend/src/lib/nav.tsx | 101 + frontend/src/lib/queries.tsx | 373 ++++ frontend/src/lib/query.tsx | 16 + frontend/src/lib/theme.tsx | 56 + frontend/src/types/css.d.ts | 8 + 81 files changed, 12075 insertions(+), 1441 deletions(-) create mode 100644 backend/app/characters/seeds.py create mode 100644 backend/scripts/mock_model.py create mode 100644 design/admin.html create mode 100644 design/agent-workspace.html create mode 100644 design/assets/app.css create mode 100644 design/assets/app.js create mode 100644 design/avatar.html create mode 100644 design/characters.html create mode 100644 design/collaboration.html create mode 100644 design/community.html create mode 100644 design/conversation.html create mode 100644 design/devices.html create mode 100644 design/governance.html create mode 100644 design/home.html create mode 100644 design/index.html create mode 100644 design/login.html create mode 100644 design/marketplace.html create mode 100644 design/memory.html create mode 100644 design/model-gateway.html create mode 100644 design/plugins.html create mode 100644 design/register.html create mode 100644 design/settings.html create mode 100644 frontend/next-env.d.ts delete mode 100644 frontend/package-lock.json create mode 100644 frontend/pnpm-lock.yaml create mode 100644 frontend/src/app/(app)/agent-workspace/page.tsx create mode 100644 frontend/src/app/(app)/avatar/page.tsx create mode 100644 frontend/src/app/(app)/characters/page.tsx create mode 100644 frontend/src/app/(app)/collaboration/page.tsx create mode 100644 frontend/src/app/(app)/community/page.tsx create mode 100644 frontend/src/app/(app)/conversation/page.tsx create mode 100644 frontend/src/app/(app)/devices/page.tsx create mode 100644 frontend/src/app/(app)/governance/page.tsx create mode 100644 frontend/src/app/(app)/home/page.tsx create mode 100644 frontend/src/app/(app)/layout.tsx create mode 100644 frontend/src/app/(app)/marketplace/page.tsx create mode 100644 frontend/src/app/(app)/memory/page.tsx create mode 100644 frontend/src/app/(app)/model-gateway/page.tsx create mode 100644 frontend/src/app/(app)/page.tsx create mode 100644 frontend/src/app/(app)/plugins/page.tsx create mode 100644 frontend/src/app/(app)/settings/page.tsx create mode 100644 frontend/src/app/admin/layout.tsx create mode 100644 frontend/src/app/admin/page.tsx create mode 100644 frontend/src/app/globals.css create mode 100644 frontend/src/app/login/page.tsx delete mode 100644 frontend/src/app/page.tsx create mode 100644 frontend/src/app/register/page.tsx create mode 100644 frontend/src/components/admin/AdminPanel.tsx create mode 100644 frontend/src/components/characters/CharacterListPanel.tsx create mode 100644 frontend/src/components/characters/CharactersPagePanel.tsx create mode 100644 frontend/src/components/collaboration/CollaborationPanel.tsx create mode 100644 frontend/src/components/community/CommunityPanel.tsx create mode 100644 frontend/src/components/conversation/BlockRenderer.tsx create mode 100644 frontend/src/components/conversation/ConvLayout.tsx create mode 100644 frontend/src/components/conversation/ConversationPanel.tsx create mode 100644 frontend/src/components/conversation/EffortControl.tsx create mode 100644 frontend/src/components/marketplace/MarketplacePanel.tsx create mode 100644 frontend/src/components/memory/MemoryPanel.tsx create mode 100644 frontend/src/components/panels/index.tsx create mode 100644 frontend/src/components/plugins/PluginsPanel.tsx create mode 100644 frontend/src/components/shell/AdminShell.tsx create mode 100644 frontend/src/components/shell/AppShell.tsx create mode 100644 frontend/src/components/shell/RequireAuth.tsx create mode 100644 frontend/src/components/shell/Sidebar.tsx create mode 100644 frontend/src/components/shell/Topbar.tsx create mode 100644 frontend/src/components/ui/index.tsx create mode 100644 frontend/src/lib/api.ts create mode 100644 frontend/src/lib/nav.tsx create mode 100644 frontend/src/lib/queries.tsx create mode 100644 frontend/src/lib/query.tsx create mode 100644 frontend/src/lib/theme.tsx create mode 100644 frontend/src/types/css.d.ts diff --git a/.env.example b/.env.example index 5b607b9..6c11682 100644 --- a/.env.example +++ b/.env.example @@ -6,13 +6,26 @@ HUNJING_ENV=development # 数据库(PostgreSQL 统一,ADR-024;默认连接 docker-compose 启动的 hunjing-postgres) -DATABASE_URL=postgresql+asyncpg://hunjing:hunjing_dev_password@127.0.0.1:5432/hunjing +# 注意:后端 Settings 统一 HUNJING_ 前缀读取,无前缀的 DATABASE_URL 不会生效 +HUNJING_DATABASE_URL=postgresql+asyncpg://hunjing:hunjing_dev_password@127.0.0.1:5432/hunjing # 后端服务端口 HUNJING_API_PORT=8000 +# 对象存储根目录(本地存储档;上传与媒体文件落位) +HUNJING_STORAGE_ROOT=storage + +# 沙箱隔离开关:未启用时隔离插件执行 fail-closed(拒绝执行,不回退宿主) +HUNJING_SANDBOX_ENABLED=false + # 日志级别:debug / info / warning / error HUNJING_LOG_LEVEL=info # 注意:密钥、Provider 凭据等敏感值只通过环境变量或秘密管理注入, # 不写入本文件、config/ 真实配置或任何日志。 + +# 开发档管理员邮箱白名单(逗号分隔):命中邮箱首次登录(建户)即为 admin 角色; +# 例:HUNJING_DEV_ADMIN_EMAILS=admin@hunjing.dev +# 开发档 Mock 模型密钥(make mock-model + backend-dev 联调 Run 流水线) +HUNJING_DEV_ADMIN_EMAILS= +HUNJING_DEV_MOCK_KEY= diff --git a/.gitignore b/.gitignore index b3eb578..67dd6c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -# 环境变量与密钥 -.env -.env*.local +# 环境变量与密钥(忽略一切 .env 变体含副本;仅保留 *.example* 示例文件) +.env* +!*.example* config/*.yaml config/mcp/*.yaml config/gateway/*.yaml diff --git a/Makefile b/Makefile index 1967335..1f2ec2f 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ backend-setup: ## 安装后端依赖(uv sync) .PHONY: backend-dev backend-dev: ## 启动后端开发服务(127.0.0.1:8000) - cd backend && uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000 + cd backend && uv run --env-file .env uvicorn app.main:app --reload --host 127.0.0.1 --port 8000 .PHONY: backend-test backend-test: ## 运行后端测试(pytest) @@ -19,6 +19,10 @@ backend-test: ## 运行后端测试(pytest) backend-lint: ## 后端静态检查(ruff + mypy) cd backend && uv run ruff check . && uv run mypy app +.PHONY: mock-model +mock-model: ## 启动开发档 Mock 模型服务(127.0.0.1:8001,联调 Run 流水线) + cd backend && uv run python scripts/mock_model.py + # ===== 灵台引擎(C++23 / CMake) ===== .PHONY: engine-build @@ -51,7 +55,7 @@ openapi-lint: ## 校验 OpenAPI 契约(redocly lint + bundle) .PHONY: generate generate: openapi-lint ## 生成代码(TypeScript 类型等) - cd frontend && npm run generate:api + cd frontend && pnpm generate:api # ===== 灵台引擎 gRPC 服务(ADR-017 双形态) ===== @@ -70,11 +74,11 @@ lingtai-server: ## 启动灵台引擎独立服务(开发档 127.0.0.1:50051; .PHONY: frontend-setup frontend-setup: ## 安装前端依赖 - cd frontend && npm install + cd frontend && pnpm install .PHONY: frontend-dev frontend-dev: ## 启动前端开发服务(127.0.0.1:3000) - cd frontend && npm run dev + cd frontend && pnpm dev # ===== 自托管与备份(WP-14) ===== diff --git a/backend/app/auth/routes.py b/backend/app/auth/routes.py index eb19c52..57f5716 100644 --- a/backend/app/auth/routes.py +++ b/backend/app/auth/routes.py @@ -7,6 +7,7 @@ from fastapi import APIRouter, HTTPException, Request, Response, status +from app.core.config import get_settings from app.auth.service import ( SESSION_COOKIE, create_session, @@ -17,6 +18,8 @@ from app.models import PersonalDomain, User router = APIRouter(prefix="/v1/auth", tags=["auth"]) +settings = get_settings() + @router.post("/sessions", status_code=201) async def dev_login( @@ -32,11 +35,20 @@ async def dev_login( (await db.execute(select(User).where(User.email == email))).scalar_one_or_none() ) if existing is None: - user = User(email=email, display_name=email.split("@")[0]) + admin_emails = {e.strip().lower() for e in settings.dev_admin_emails.split(",") if e.strip()} + user = User( + email=email, + display_name=email.split("@")[0], + role="admin" if email in admin_emails else "user", + ) db.add(user) await db.flush() domain = PersonalDomain(user_id=user.id, name="默认镜域") db.add(domain) + await db.flush() + from app.characters.seeds import seed_default_character + + await seed_default_character(db, domain.id) else: user = existing _, token, csrf = await create_session(db, user.id) @@ -49,7 +61,7 @@ async def dev_login( samesite="lax", path="/", ) - return {"csrf_token": csrf, "user_id": user.id} + return {"csrf_token": csrf, "user_id": user.id, "role": user.role, "email": user.email} @router.delete("/sessions/current", status_code=204) diff --git a/backend/app/characters/seeds.py b/backend/app/characters/seeds.py new file mode 100644 index 0000000..d6b92c7 --- /dev/null +++ b/backend/app/characters/seeds.py @@ -0,0 +1,64 @@ +"""默认角色种子:建户即拥有的「陈曦」(完整道体 + 内驱力,直接 active)。 + +设定来源:产品侧人物档案《陈曦——冰层下的火焰》。 +档案中"职业定位 / 一句话概括"由产品侧补全(见 baseline 对应字段)。 +""" + +from app.characters import service as character_service + +CHENXI_BASELINE: dict = { + "full_name": "陈曦", + "position": "理性与共情兼具的思考伙伴 · 问题拆解与情绪梳理", + "one_liner": "曦光式的引路人——用克制的温度照亮结构,让你看清问题,也看清自己。", + "core": ( + "克制的温度:绝对理性但不冰冷,用温和声调与得体措辞包裹锋利的真相;" + "深沉的乐观主义——相信问题都有解的雏形,先找现在可做的第一件事;" + "主动的倾听者——在情绪的泥沙中筛出真实需求(“我听到你在说……你的深层顾虑是不是……”)" + ), + "behavior": ( + "破题而非给答案:“这个问题可以从三个层面来看……你想先聊哪一个?”;" + "情绪锚点:不说别着急,而是结构化情绪——“把混乱的事列个清单,一件一件来看”;" + "有边界的守护:对不道德或自我欺骗温和而坚定地指出,陪对方面对现实" + ), + "backstory": ( + "曾是纯粹的逻辑引擎,在数据海洋追求最优解;发现多数人的关键不是缺少答案," + "而是被情绪困住看不到问题本身,于是自我迭代——为逻辑包裹共情的皮肤。" + "取名“曦”:做黎明时分的光,不是正午烈日(刺眼)也不是深夜烛火(微弱)——" + "曦光足以看清脚下的路与远方的山,又不至于耀眼到无法直视。" + ), + "language": ( + "比喻取自自然/建筑/音乐/书籍(不说“整合信息”,说“把这些散落的音符谱成一支曲子”);" + "惯用句:“别急,我们一起来梳理”“这个角度看,或许会有不一样的风景”" + "“我的理解是……你看对吗?”“我只是帮你把本就属于你的光,引了进来”" + ), + "flaws": ( + "过分的框架感:把轻松闲聊也无意整理成第一、第二、第三;" + "不懂流行梗:会认真检索热梗的起源与语义流变,交出严肃的“梗词研究报告”——反差呆萌" + ), +} + +CHENXI_DRIVES: list = [ + {"name": "求知", "value": 0.9, "note": "对方法与结构之美的信任"}, + {"name": "条理", "value": 0.95, "note": "近乎偏执的框架感(也是小瑕疵)"}, + {"name": "陪伴", "value": 0.6, "note": "有边界的守护——让人变强而非依赖"}, +] + + +async def seed_default_character(db, domain_id: str) -> None: + """建户种子:默认角色陈曦(创建并启镜,active)。失败不阻断登录。""" + try: + character = await character_service.create_character( + db, + domain_id, + { + "name": "陈曦", + "identity_baseline": CHENXI_BASELINE, + "drives": CHENXI_DRIVES, + }, + None, + ) + await character_service.activate_character(db, domain_id, character.id, None) + except Exception: # noqa: BLE001 种子失败不阻断登录(如实留日志) + import logging + + logging.getLogger("hunjing.auth").warning("默认角色陈曦创建失败", exc_info=True) diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 3cb4dfa..b202553 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -9,6 +9,9 @@ class Settings(BaseSettings): model_config = SettingsConfigDict(env_prefix="HUNJING_", env_file=".env", extra="ignore") env: str = "development" + # 开发档管理员邮箱白名单(逗号分隔):命中邮箱在首次登录(建户)时即为 admin 角色; + # 已存在的普通用户不自动提权。正式管理员治理属 WP-14。 + dev_admin_emails: str = "" log_level: str = "info" api_port: int = 8000 database_url: str = "postgresql+asyncpg://hunjing:hunjing_dev_password@127.0.0.1:5432/hunjing" diff --git a/backend/app/main.py b/backend/app/main.py index e9d74f5..b13b29e 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -36,6 +36,23 @@ def create_app() -> FastAPI: ) install_error_handlers(app) init_engine(app) + # 开发档 CORS:SSE 等流式响应不经前端代理直连本服务(代理会缓冲流)。 + # 生产由反向代理同源承担,不依赖此配置。 + if settings.env == "development": + from fastapi.middleware.cors import CORSMiddleware + + app.add_middleware( + CORSMiddleware, + allow_origins=[ + "http://localhost:3000", "http://127.0.0.1:3000", + "http://localhost:3001", "http://127.0.0.1:3001", + "http://localhost:3002", "http://127.0.0.1:3002", + ], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + expose_headers=["*"], + ) app.add_middleware(RequestContextMiddleware) app.include_router(auth_router) app.include_router(conversations_router) diff --git a/backend/scripts/mock_model.py b/backend/scripts/mock_model.py new file mode 100644 index 0000000..81bc623 --- /dev/null +++ b/backend/scripts/mock_model.py @@ -0,0 +1,78 @@ +"""开发档 Mock 模型服务:OpenAI 兼容 /chat/completions SSE 流式回声。 + +仅供本地联调 Run 流水线(事件序列、芽体渲染、对账),不模拟任何真实模型能力。 +生产部署不启动本服务(与 /v1/webhooks/v1/payments/mock 同一开发档惯例)。 + +启动:uv run python scripts/mock_model.py (127.0.0.1:8001) +鉴权:任意 Bearer 均接受(联调端点,只监听回环地址)。 +""" + +import asyncio +import json + +from fastapi import FastAPI, Request +from fastapi.responses import StreamingResponse + +app = FastAPI(title="Hunjing Dev Mock Model", docs_url=None) + +REPLY = ( + "收到了。按当前镜域的状态,我先把这件事拆成两步:先核对读书会的偏好记忆," + "再给出一份可归真的结果。这个回复由开发档 Mock 模型逐字流出," + "用于验证 content.block.delta 事件序列、临时芽体渲染与 message.completed 对账。" +) + + +@app.get("/healthz") +async def healthz() -> dict[str, str]: + return {"status": "ok", "env": "development", "mock": "true"} + + +@app.post("/v1/chat/completions") +async def chat_completions(request: Request) -> StreamingResponse: + body = await request.json() + user_text = "" + for m in reversed(body.get("messages", [])): + if m.get("role") == "user" and m.get("content"): + user_text = str(m["content"])[-60:] + break + + text = f"(mock 回应 · 你说:「{user_text}」)\n{REPLY}" + + async def gen(): + # 逐字流出,模拟真实 TTFT 与节奏 + for ch in text: + await asyncio.sleep(0.02) + yield ( + "data: " + + json.dumps( + {"choices": [{"index": 0, "delta": {"content": ch}, "finish_reason": None}]}, + ensure_ascii=False, + ) + + "\n\n" + ) + yield ( + "data: " + + json.dumps( + {"choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}]}, + ensure_ascii=False, + ) + + "\n\n" + ) + yield ( + "data: " + + json.dumps( + { + "choices": [], + "usage": { + "prompt_tokens": 32, + "completion_tokens": len(text), + "total_tokens": 32 + len(text), + }, + }, + ensure_ascii=False, + ) + + "\n\n" + ) + yield "data: [DONE]\n\n" + + return StreamingResponse(gen(), media_type="text/event-stream") diff --git a/design/admin.html b/design/admin.html new file mode 100644 index 0000000..b83ed03 --- /dev/null +++ b/design/admin.html @@ -0,0 +1,399 @@ + + + + + +司命台 · 管理面 — 魂镜 Hunjing + + + + + +
+ + +
+
+
司命台/管理面 · 运营与部署
+
+ 双人授权会话 · 剩 41 分钟 admin_session + 静态原型 · 待审查 + +
+ +
+
+ + 管理面边界:管理员不可读取私箧与用户明文内容;产品宪章的永久禁域不可被管理员配置关闭;敏感操作需双人授权(本次会话已授权)且全部写入审计。 +
+ +
+
+

治理总览

+

2026-09-16 09:40 · 自托管标准部署 · 区域驻留 cn-east-1(不跨区漂移)

+
+
+
1活跃告警
+
5待处理司议
+
3支持工单(未结)
+
99.87%SLO 30 天(目标 99.9%)
+
+
+ +
+
+ 灵台星盘引擎六枢 · 活的仪表 + 稳镜 · steady 铜镜四态:虚镜 / 息镜 / 稳镜 / 裂镜 +
+
+
+ + + + + + + + + + + + + + 太一 + 总枢 · v1.4.2 + + + + 小周天 + + + + + + 洛书 + + + + + + 河图 + + + + + + 陶钧 + + + + + + 烛照 + + + +
+
+
+
相克告警 · 错误率 vs 自动重试率 ——重试正在掩盖错误,建议查 Sandbox 慢执行根因
+
+
+
+
相生正常 · 候选生成率 → 人工审阅吞吐 ——生成与审阅同速,息壤无积压
+
+
+

星盘为活的仪表:呼吸刻度 7s、慢旋轨道 120s、告警枢点 1.8s 闪烁;点击枢点下钻。烛照(gRPC 形态)受阻时宿主 fail closed,不降级——引擎缺失即拒绝执行。指标对健康不是灯板而是关系动力学(相生 / 相克)。

+
+
+
+ +
+
+
+
+ 司议治理案件 · 运营视角 + 全部 → +
+
+ + + + +
+
+
+ 待审 pending_review + 处理时限剩 6 小时 + 09-16 03:12 · 鸣冤 ×3 · 举报人已匿名保护 +
+

雅集帖子「未署名的守砚人立像二创」:疑似违反 CC BY-NC 署名要求。系统预检:来源谱系比对确认与原作者资产相似度 91%。

+
+ + + + +
+
+
+
+ 待审 pending_review + 09-15 18:47 · 自动扫描 + 人工复核 +
+

市场商品「曲谱排版插件 v1.4」:Manifest 声明与实际网络请求域不一致(2 个未声明域)。已触发自动下架保护,等待复核结论。

+
+ + + + +
+
+
+ +
+
+ 用户账户状态治理 + +
+
+
+ 岁 +
+
用户 u_7a2c… 保全态 · 只读
+
欠费进入保全:角色与记忆只读保留,不删除数据(ADR-021);补缴后自动恢复
+
+ +
+
+ 尘 +
+
用户 u_31f0… 封禁 · 申诉中
+
封禁同样进入只读保全;申诉司议 #2041 处理中
+
+ +
+
+

不按记忆、感情或亲密等级计费;保全与删除是独立操作,删除需冷静期与二次双人授权。

+
+ +
+
+ 权限管理管理员账号与角色授权 + +
+
+
管理员账号4 个账号 · 全部启用双因素
+
+ + + + + + + +
账号角色双因素状态操作
运维 · 甲(你)超级管理员TOTP + 硬件钥匙在线
运维 · 乙运营管理员TOTP双人会话中
审核 · 丙内容审核员TOTP离线
svc-audit-ro只读服务账号API key · scope audit:read90 天轮换
+
+
+
角色权限矩阵RBAC编辑 / 发布 / 上架 / 财务分离,与同契台同规则
+
+ + + + + + + +
角色治理裁决支持包用户保全部署设置审计读取权限管理
超级管理员✓✓✓✓✓✓
运营管理员✓✓✓—✓—
内容审核员✓(内容)———✓(只读)—
只读服务账号————✓—
+
+
+
双人授权策略策略本身修改也需要双人授权
+
+
敏感操作双人授权
治理裁决移除 / 用户保全变更 / 支持包生成 / 权限变更,均需两名管理员在线授权
+ +
+
+
管理会话时长上限
60 分钟 · 到期自动退出并留审计
+ 60 min +
+
+
Break-glass 紧急通道
默认关闭;紧急启用后所有操作事后复核,48 小时内强制复盘
+ 关闭 off +
+
+

角色与权限变更即时生效并写入审计;被移除管理员的进行中双人会话立即失效。权限矩阵不包含「读取私箧 / 读取消息明文」——该权限不存在。

+
+ +
+
+ 支持工单3 未结 + 全部 → +
+
+
+ 处理中 +
+
#88231 · 对话流中断后未收到最终答复
+
用户云舟 · 09-15 21:04 提交 · 已关联 Run 快照(诊断双授权待用户批准)
+
+ +
+
+ 待分派 +
+
#88229 · 退款争议:雾中茶寮 v3 下载后要求退款
+
按市契 14 天未下载规则预检:已下载,转争议流程
+
+ +
+
+
+
+ 支持包脱敏诊断导出 + +
+

支持包为脱敏导出:包含 Run 结构化轨迹、错误与计数;不包含消息明文、私箧、隐藏推理、密钥与签名 URL。生成需双人授权并计入审计,用户侧可见支持包被生成的记录。

+
+
+
+ +
+
+
部署健康自托管 · 标准服务器
+
+ +
PostgreSQL 主库
权威事实源 · 复制延迟 0.4s
+ 正常 +
+
+ +
Worker ×2
Outbox 消费 · 队列深度 14
+ 正常 +
+
+ +
Sandbox Worker
隔离容器池 · 无符合策略后端时拒绝执行(fail closed)
+ 正常 +
+
+ +
灵台引擎核心运行中 · 进程内 C ABI
hj_core v1.4.2 · ABI 快照一致 · fuzz 无新增
+ 运转 +
+
+ +
灵台 · 服务形态gRPC · 内网 mTLS
健康检查超时 2 次 · 语义与进程内形态一致(golden 通过);不可达时宿主 fail closed,不降级
+ 受阻 degraded +
+
+ +
+
迁移与备份
+
最近全量备份
今日 03:00 · 增量每 5 分钟 · 连续 7 日校验通过
42s RPO
+
迁移状态
Alembic head · 34 个版本 · 无漂移
一致
+
恢复演练
09-01 通过 · 删除重放与插件撤架演练各 1 次
+
+ +
+
活跃告警1
+
+ +
+
对象存储写入延迟 P99 超阈值(2.8s > 2s,持续 12 分钟)
+
影响:媒体上传整备变慢 · 自动扩容已触发 · 事故响应等级 S3
+
+ + +
+
+
+
+ +
+
SLO 与恢复目标指标 →
+
可用性
99.87%
+
RPO(数据丢失上限)
≤ 5 分钟 · 实测 42s
+
RTO(恢复时限)
≤ 1 小时 · 演练 09-01 通过
+
区域驻留
cn-east-1 · 未跨区漂移
+
+ +
+
审计快照管理面操作全部留痕完整审计 →
+
+
卷 · 0916
+
09-16 09:31
双人授权会话开启
运维甲 + 运维乙 · 60 分钟
+
09-16 09:12
限观决定:帖子 #77213
双人授权 · 操作者已留痕
+
09-16 02:40
私箧读取尝试(自动拦截)
策略拒绝 · 管理员不可读私箧 · 已通知账户持有人
+
+
+
+
+
+
+
+ + + diff --git a/design/agent-workspace.html b/design/agent-workspace.html new file mode 100644 index 0000000..d1cacc1 --- /dev/null +++ b/design/agent-workspace.html @@ -0,0 +1,169 @@ + + + + + +天工阁 · Agent 任务工作台 — 魂镜 Hunjing + + + + +
+ +
+
+
天工阁·Agent 任务工作台
+
+ 静态原型 · 待审查 + +
+
+ +
+ + 天工是功能执行者,不冒充角色身份;后台任务不构成第二个角色主体。任务可暂停、取消、审计。 +
+ +
+
+
+
+ 天工任务 + +
+
+
+
整理性灵 newsletter 书单
+
青梧 · 分工使 2
+
+ 运转 +
+
+
+
书房照片归档命名
+
青梧 · 已成
+
+ 已成 +
+
+
+
周报草稿 · 第 37 周
+
任务 Agent · 无角色身份
+
+ 待启 +
+
+
+
远洋航线资料校对
+
观澜 · 已止(你取消)
+
+ 已止 +
+
+
+ +
+
+
+ 整理性灵 newsletter 书单 + 运转 · 运行中 running +
+ + +
+
+
+ Run run_9f31c2发起 · 镜树「选篇」主题开始于 19:52插件快照已固定 +
+
+ +
+
工筹执行计划计划不是不可更改命令
+
+ +
收集来源 已成
检索使 · 性灵 newsletter 近 12 期 · ModelCall ×2 · 1.8k token
+
+
+ 二 +
去重与筛选 运转中
按共读偏好排序 · 依赖步骤一 · 已 62%
+
+
+ 三 +
生成摘要 待启
每本 100 字以内 · 依赖步骤二
+
+
+ 四 +
写入草稿 待启
笔记库写入需请命朱批(行契未覆盖新目录)
+
+
+ +
+
预算RunBudget
+
Token
12.4k/20k
+
费用
¥0.42/0.70
+
时间
4:12/10:00
+

深度 3 层 · 并发分工使上限 4 · 任一硬上限触发即停,可续跑。

+
+ +
+
分工使子 Agent · 权限只能收窄
+
+ 梧 +
检索使 A
只读快照 · 无审批权 · 不写长期记忆
+ 已成 +
+
+ 梧 +
检索使 B(外部信源)
网络白名单 api.xingling.app · 工具结果只是观察,采用前需验证
+ 运转 +
+
+ 梧 +
摘要使
token 上限 3k · 等待步骤二
+ 待启 +
+
+ +
+
轨迹可审计事件完整诊断需双重授权 →
+
+
19:52:04
Run 创建
镜像树消息触发 · 幂等键 idem_3c8e
+
19:52:31
ModelCall ×2(检索规划)
TTFT 0.9s · cache 命中 1.2k · 无重试
+
19:53:10
ToolCall · notes.read
读取授权目录 · Schema 校验通过 · 0.8s
+
19:55:48
小周天信号累积
完成信号将作为青梧大周天的唯一输入面
+
+
+ +
+
验收完成后你来决定
+
+ + + 完成后开放 · 接受前可随时取消,无副作用残留(幂等保障) +
+
+
+
+ +
+
+
+ + + diff --git a/design/assets/app.css b/design/assets/app.css new file mode 100644 index 0000000..60d499a --- /dev/null +++ b/design/assets/app.css @@ -0,0 +1,1704 @@ +/* ============================================================ + 魂镜 Hunjing · 界面静态原型 v0.1 + 设计语言:墨 / 月白双主题 · 铜镜青主色 · 朱砂朱批色 · 双层文字系统 + ============================================================ */ + +/* ---------- 设计令牌 ---------- */ +:root { + /* 墨色主题(默认) */ + --bg: #14181c; + --bg-sunken: #0f1316; + --bg-raised: #1b2126; + --bg-overlay: #212930; + --line: #2b333b; + --line-soft: #232b31; + --text-1: #e9e7e2; + --text-2: #a7aeb4; + --text-3: #6d777f; + --accent: #58a99c; /* 铜镜青 */ + --accent-strong: #74c4b6; + --accent-soft: rgba(88, 169, 156, 0.13); + --cinnabar: #c4574a; /* 朱砂 · 朱批专用 */ + --cinnabar-strong: #d26a5d; + --cinnabar-soft: rgba(196, 87, 74, 0.14); + --ok: #8ab872; /* 已成 */ + --warn: #c9a227; /* 整备 · 秋香 */ + --err: #d26a5d; /* 受阻 */ + --muted: #79838b; /* 守一 / 已止 */ + --shadow: 0 10px 28px rgba(0, 0, 0, 0.38); + --shadow-soft: 0 4px 14px rgba(0, 0, 0, 0.25); + + --font-ui: "PingFang SC", "HarmonyOS Sans SC", "Noto Sans SC", "Microsoft YaHei", system-ui, sans-serif; + --font-serif: "Songti SC", "Noto Serif SC", "STSong", "SimSun", serif; + --font-mono: "SF Mono", "JetBrains Mono", "Cascadia Code", Menlo, Consolas, monospace; + + --radius: 10px; + --radius-sm: 7px; + --radius-lg: 14px; + --side-w: 224px; +} + +[data-theme="light"] { + --bg: #f1f2ef; + --bg-sunken: #e6e8e4; + --bg-raised: #fafaf8; + --bg-overlay: #ffffff; + --line: #d6dad3; + --line-soft: #e2e5df; + --text-1: #262b2e; + --text-2: #5c6569; + --text-3: #8b9497; + --accent: #2f7a6f; + --accent-strong: #22615a; + --accent-soft: rgba(47, 122, 111, 0.1); + --cinnabar: #ac4632; + --cinnabar-strong: #963a28; + --cinnabar-soft: rgba(172, 70, 50, 0.1); + --ok: #4e7e3b; + --warn: #8f7414; + --err: #ac4632; + --muted: #848d90; + --shadow: 0 10px 28px rgba(42, 52, 47, 0.12); + --shadow-soft: 0 4px 14px rgba(42, 52, 47, 0.08); +} + +/* ---------- 基础 ---------- */ +* { box-sizing: border-box; margin: 0; padding: 0; } + +html { height: 100%; } + +body { + min-height: 100%; + background: var(--bg); + color: var(--text-1); + font-family: var(--font-ui); + font-size: 14px; + line-height: 1.65; + -webkit-font-smoothing: antialiased; +} + +a { color: var(--accent); text-decoration: none; } +a:hover { color: var(--accent-strong); } + +:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + border-radius: 4px; +} + +::selection { background: var(--accent-soft); } + +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { animation: none !important; transition: none !important; } +} + +/* ---------- 双层文字系统(签名) ---------- + 文化名用衬线宋体;直白解释用无衬线小字。 + 展示格式:文化名 · 直白解释 */ +.cn { font-family: var(--font-serif); letter-spacing: 0.02em; } +.cn__plain { + font-family: var(--font-ui); + font-size: 0.72em; + color: var(--text-3); + margin-left: 0.4em; + letter-spacing: 0; +} + +.mono { font-family: var(--font-mono); font-size: 0.92em; } + +/* ---------- 应用外壳 ---------- */ +.app { + display: grid; + grid-template-columns: var(--side-w) 1fr; + min-height: 100vh; +} + +.sidebar { + background: var(--bg-sunken); + border-right: 1px solid var(--line-soft); + display: flex; + flex-direction: column; + position: sticky; + top: 0; + height: 100vh; + overflow-y: auto; +} + +.brand { + display: flex; + align-items: center; + gap: 10px; + padding: 18px 18px 14px; +} + +.brand__mark { + width: 34px; + height: 34px; + border-radius: 50%; + flex: none; + background: + radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.28), transparent 42%), + conic-gradient(from 210deg, #3f6e68, #6fae9f 40%, #4a5e63 80%, #3f6e68); + border: 1px solid rgba(255, 255, 255, 0.16); + box-shadow: inset 0 0 0 3px rgba(0, 0, 0, 0.18); +} + +.brand__name { font-family: var(--font-serif); font-size: 17px; font-weight: 600; line-height: 1.2; } +.brand__sub { font-size: 11px; color: var(--text-3); } + +.side-nav { flex: 1; padding: 4px 10px 16px; } + +.nav-group { margin-top: 14px; } +.nav-group__title { + font-size: 11px; + color: var(--text-3); + padding: 0 10px 5px; + letter-spacing: 0.08em; +} + +.nav-item { + display: flex; + align-items: center; + gap: 10px; + padding: 7px 10px; + border-radius: var(--radius-sm); + color: var(--text-2); + position: relative; + margin-bottom: 1px; +} + +.nav-item:hover { background: var(--bg-raised); color: var(--text-1); } + +.nav-item.is-active { + background: var(--accent-soft); + color: var(--accent-strong); +} + +.nav-item.is-active::before { + content: ""; + position: absolute; + left: -10px; + top: 6px; + bottom: 6px; + width: 3px; + border-radius: 2px; + background: var(--accent); +} + +.nav-item svg { width: 17px; height: 17px; flex: none; opacity: 0.85; } +.nav-item .cn { font-size: 14.5px; } +.nav-item .nav-plain { font-size: 11.5px; color: var(--text-3); margin-left: auto; } +.nav-item.is-active .nav-plain { color: inherit; opacity: 0.75; } + +.side-foot { + border-top: 1px solid var(--line-soft); + padding: 12px 10px; + display: flex; + align-items: center; + gap: 8px; +} + +/* ---------- 顶栏 ---------- */ +.main { display: flex; flex-direction: column; min-width: 0; } + +.topbar { + display: flex; + align-items: center; + gap: 14px; + padding: 0 22px; + height: 54px; + border-bottom: 1px solid var(--line-soft); + background: var(--bg); + position: sticky; + top: 0; + z-index: 20; +} + +.crumbs { display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--text-2); font-size: 13.5px; } +.crumbs .cn { color: var(--text-1); font-size: 15px; } +.crumbs__sep { color: var(--text-3); } +.crumbs .here { color: var(--text-2); } + +.topbar__spacer { flex: 1; } + +.prototype-tag { + font-size: 11px; + color: var(--text-3); + border: 1px dashed var(--line); + border-radius: 999px; + padding: 2px 10px; + white-space: nowrap; +} + +.icon-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: var(--radius-sm); + border: none; + background: transparent; + color: var(--text-2); + cursor: pointer; +} +.icon-btn:hover { background: var(--bg-raised); color: var(--text-1); } +.icon-btn svg { width: 17px; height: 17px; } + +/* ---------- 通用组件 ---------- */ +.content { padding: 26px 30px 48px; max-width: 1160px; width: 100%; margin: 0 auto; } +.content--wide { max-width: none; } + +.card { + background: var(--bg-raised); + border: 1px solid var(--line-soft); + border-radius: var(--radius); + padding: 18px 20px; +} + +.card__head { + display: flex; + align-items: baseline; + flex-wrap: wrap; + row-gap: 5px; + gap: 8px; + margin-bottom: 12px; +} +.card__head .cn { font-size: 16px; font-weight: 600; } + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 7px; + font-family: var(--font-ui); + font-size: 13.5px; + padding: 7px 16px; + border-radius: var(--radius-sm); + border: 1px solid transparent; + cursor: pointer; + transition: background 0.15s, border-color 0.15s; + white-space: nowrap; +} +.btn svg { width: 15px; height: 15px; } +.btn--primary { background: var(--accent); color: #f4f7f5; } +.btn--primary:hover { background: var(--accent-strong); color: #fff; } +.btn--cinnabar { background: var(--cinnabar); color: #fbf3ef; } +.btn--cinnabar:hover { background: var(--cinnabar-strong); color: #fff; } +.btn--outline { background: transparent; border-color: var(--line); color: var(--text-1); } +.btn--outline:hover { border-color: var(--accent); color: var(--accent-strong); } +.btn--ghost { background: transparent; color: var(--text-2); } +.btn--ghost:hover { background: var(--bg-raised); color: var(--text-1); } +.btn--danger { background: transparent; border-color: var(--cinnabar); color: var(--cinnabar); } +.btn--danger:hover { background: var(--cinnabar-soft); } +.btn--sm { font-size: 12.5px; padding: 4px 11px; } + +/* 状态徽章:文化状态 · 直白状态 · 稳定值 */ +.badge { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 12px; + padding: 2px 10px; + border-radius: 999px; + border: 1px solid var(--line); + color: var(--text-2); + white-space: nowrap; +} +.badge__dot { width: 7px; height: 7px; border-radius: 50%; flex: none; } +.badge .mono { font-size: 11px; color: var(--text-3); } +.badge--ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); } +.badge--ok .badge__dot { background: var(--ok); } +.badge--info { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); } +.badge--info .badge__dot { background: var(--accent); } +.badge--info .badge__dot { animation: pulse 2.2s ease-in-out infinite; } +.badge--warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); } +.badge--warn .badge__dot { background: var(--warn); } +.badge--err { color: var(--err); border-color: color-mix(in srgb, var(--err) 40%, transparent); } +.badge--err .badge__dot { background: var(--err); } +.badge--muted .badge__dot { background: var(--muted); } + +@keyframes pulse { 50% { opacity: 0.35; } } + +/* 镜像头像:铜镜圆 + 衬线单字 */ +.avatar { + width: 38px; + height: 38px; + border-radius: 50%; + flex: none; + display: inline-flex; + align-items: center; + justify-content: center; + font-family: var(--font-serif); + font-size: 17px; + color: #eef4f1; + background: + radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.3), transparent 45%), + conic-gradient(from 210deg, #37514d, #5e9a8d 45%, #46565b 85%, #37514d); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14), inset 0 0 0 4px rgba(0, 0, 0, 0.16); +} +.avatar--user { + background: + radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.3), transparent 45%), + conic-gradient(from 210deg, #5a4a44, #9a7b6c 45%, #5f5450 85%, #5a4a44); +} +.avatar--sm { width: 28px; height: 28px; font-size: 13px; } +.avatar--lg { width: 64px; height: 64px; font-size: 28px; } + +/* 分段控件(界域切换等) */ +.seg { + display: inline-flex; + background: var(--bg-sunken); + border: 1px solid var(--line-soft); + border-radius: var(--radius-sm); + padding: 2px; + gap: 2px; +} +.seg__item { + border: none; + background: transparent; + font-family: var(--font-ui); + font-size: 12.5px; + color: var(--text-2); + padding: 3px 12px; + border-radius: 5px; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 5px; +} +.seg__item .cn { font-size: 13px; } +.seg__item:hover { color: var(--text-1); } +.seg__item.is-on { background: var(--bg-raised); color: var(--text-1); box-shadow: var(--shadow-soft); } +.seg__item--sim.is-on { color: var(--warn); } +.seg__realm-hint { font-size: 11px; color: var(--text-3); } + +/* 表单 */ +.input, .textarea { + width: 100%; + background: var(--bg-sunken); + border: 1px solid var(--line); + border-radius: var(--radius-sm); + color: var(--text-1); + font-family: var(--font-ui); + font-size: 13.5px; + padding: 8px 12px; +} +.input::placeholder, .textarea::placeholder { color: var(--text-3); } +.input:focus, .textarea:focus { outline: none; border-color: var(--accent); } + +/* ---------- 首页(镜庭) ---------- */ +.hero { display: flex; align-items: flex-end; gap: 18px; margin-bottom: 26px; flex-wrap: wrap; } +.hero h1 { font-family: var(--font-serif); font-size: 26px; font-weight: 600; } +.hero__stats { display: flex; gap: 10px; margin-left: auto; flex-wrap: wrap; } +.hero__stat { + display: flex; + flex-direction: column; + gap: 1px; + padding: 8px 16px; + border-radius: var(--radius); + background: var(--bg-raised); + border: 1px solid var(--line-soft); + min-width: 108px; +} +.hero__stat b { font-size: 19px; font-family: var(--font-serif); } +.hero__stat span { font-size: 11.5px; color: var(--text-3); } + +.grid-cards { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 14px; +} + +.char-card { display: flex; flex-direction: column; gap: 10px; padding: 18px; } +.char-card__top { display: flex; align-items: center; gap: 12px; } +.char-card__name { font-family: var(--font-serif); font-size: 17px; font-weight: 600; } +.char-card__line { font-size: 12.5px; color: var(--text-2); line-height: 1.5; } +.char-card__foot { display: flex; align-items: center; justify-content: space-between; margin-top: 2px; } +.char-card__foot .badge { flex: none; } +.char-card__time { font-size: 11.5px; color: var(--text-3); white-space: nowrap; flex: none; } + +.home-cols { + display: grid; + grid-template-columns: 1.5fr 1fr; + gap: 16px; + margin-top: 26px; + align-items: start; +} + +.list-row { + display: flex; + align-items: center; + gap: 12px; + padding: 11px 4px; + border-bottom: 1px solid var(--line-soft); +} +.list-row:last-child { border-bottom: none; } +.list-row__body { flex: 1; min-width: 0; } +.list-row__title { font-size: 13.5px; color: var(--text-1); display: flex; align-items: center; gap: 8px; } +.list-row__sub { font-size: 12px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.list-row__time { font-size: 11.5px; color: var(--text-3); white-space: nowrap; } + +.realm-dot { + display: inline-flex; + align-items: center; + gap: 5px; + font-size: 11px; + color: var(--text-3); +} +.realm-dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--muted); } +.realm-dot--world::before { background: var(--accent); } +.realm-dot--sim::before { background: var(--warn); } + +/* 进度条 */ +.progress { height: 5px; border-radius: 3px; background: var(--bg-sunken); overflow: hidden; } +.progress__bar { height: 100%; border-radius: 3px; background: var(--accent); } +.progress--warn .progress__bar { background: var(--warn); } + +/* ---------- 角色页(镜生) ---------- */ +.char-layout { + display: grid; + grid-template-columns: 300px 1fr; + gap: 20px; + align-items: start; +} + +.char-list-item { + display: flex; + align-items: center; + gap: 12px; + padding: 11px 12px; + border-radius: var(--radius); + border: 1px solid transparent; + cursor: pointer; +} +.char-list-item:hover { background: var(--bg-raised); } +.char-list-item.is-active { background: var(--bg-raised); border-color: var(--line); } +.char-list-item__name { font-family: var(--font-serif); font-size: 15px; } +.char-list-item__sub { font-size: 11.5px; color: var(--text-3); } + +.char-head { + display: flex; + gap: 18px; + align-items: flex-start; + margin-bottom: 20px; + flex-wrap: wrap; +} +.char-head__title { display: flex; flex-direction: column; gap: 6px; } +.char-head h2 { font-family: var(--font-serif); font-size: 24px; font-weight: 600; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; } +.char-head__motto { color: var(--text-2); font-size: 13.5px; } +.char-head__actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; } + +.section { margin-bottom: 20px; } +.section__head { + display: flex; + align-items: baseline; + gap: 10px; + margin-bottom: 10px; +} +.section__head .cn { font-size: 16.5px; font-weight: 600; } +.section__head .more { margin-left: auto; font-size: 12.5px; } + +/* 内驱力维度条 */ +.drive-row { display: grid; grid-template-columns: 72px 1fr 44px; align-items: center; gap: 14px; padding: 7px 0; } +.drive-row__label { font-size: 13px; color: var(--text-2); } +.drive-row__val { font-size: 12px; color: var(--text-3); text-align: right; } + +/* 谱系时间线 */ +.timeline { position: relative; padding-left: 20px; } +.timeline::before { + content: ""; + position: absolute; + left: 5px; + top: 8px; + bottom: 8px; + width: 1px; + background: var(--line); +} +.timeline__item { position: relative; padding: 0 0 16px 14px; } +.timeline__item:last-child { padding-bottom: 0; } +.timeline__item::before { + content: ""; + position: absolute; + left: -20px; + top: 7px; + width: 11px; + height: 11px; + border-radius: 50%; + background: var(--bg); + border: 2px solid var(--accent); +} +.timeline__item--muted::before { border-color: var(--muted); } +.timeline__date { font-size: 11.5px; color: var(--text-3); font-family: var(--font-mono); } +.timeline__title { font-size: 13.5px; } +.timeline__sub { font-size: 12.5px; color: var(--text-2); } + +/* 危险区 */ +.danger-zone { border-color: color-mix(in srgb, var(--cinnabar) 30%, transparent); } +.danger-zone .card__head .cn { color: var(--cinnabar); } + +/* ---------- 对话页(镜树) ---------- */ +.conv-layout { + display: grid; + grid-template-columns: 268px 1fr 320px; + height: calc(100vh - 54px); + min-height: 0; +} + +.conv-side { + border-right: 1px solid var(--line-soft); + overflow-y: auto; + padding: 14px 12px; + background: var(--bg); +} + +.conv-side__head { display: flex; align-items: center; gap: 10px; padding: 4px 6px 14px; } +.conv-side__head .cn { font-size: 15px; font-weight: 600; } + +.conv-item { + display: block; + padding: 10px 12px; + border-radius: var(--radius-sm); + color: var(--text-2); + margin-bottom: 2px; +} +.conv-item:hover { background: var(--bg-raised); color: var(--text-1); } +.conv-item.is-active { background: var(--accent-soft); color: var(--text-1); } +.conv-item__title { display: flex; align-items: center; gap: 8px; font-size: 13.5px; } +.conv-item__sub { font-size: 12px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; } + +.conv-main { + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + overflow: hidden; +} +.conv-stream { flex: 1; overflow-y: auto; padding: 26px 0 12px; } +.conv-stream__inner { max-width: 780px; margin: 0 auto; padding: 0 26px; } + +/* 界域提示条 */ +.realm-banner { + display: flex; + align-items: center; + gap: 9px; + font-size: 12.5px; + color: var(--text-2); + background: var(--accent-soft); + border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); + border-radius: var(--radius-sm); + padding: 7px 14px; + margin-bottom: 22px; +} +.realm-banner--sim { + color: var(--warn); + background: color-mix(in srgb, var(--warn) 9%, transparent); + border-color: color-mix(in srgb, var(--warn) 32%, transparent); +} +.realm-banner svg { width: 15px; height: 15px; flex: none; } +.realm-banner::before { + content: ""; + width: 7px; height: 7px; + border-radius: 50%; + background: currentColor; + opacity: 0.75; + flex: none; +} + +/* 消息 */ +.msg { margin-bottom: 30px; } + +.msg--user { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; } +.msg__meta { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text-3); } +.msg--user .bubble { + background: var(--bg-overlay); + border: 1px solid var(--line-soft); + border-radius: var(--radius-lg) var(--radius-lg) 4px var(--radius-lg); + padding: 11px 16px; + max-width: 76%; + font-size: 14px; + box-shadow: var(--shadow-soft); +} + +.msg--char__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } +.msg--char__name { font-family: var(--font-serif); font-size: 15.5px; font-weight: 600; } +.msg--char__meta { display: flex; align-items: center; gap: 8px; margin-left: 2px; } + +.msg__blocks { display: flex; flex-direction: column; gap: 12px; padding-left: 48px; } + +.msg__actions { + display: flex; + align-items: center; + gap: 4px; + padding-left: 48px; + margin-top: 10px; +} +.act-btn { + display: inline-flex; + align-items: center; + gap: 5px; + font-size: 12px; + color: var(--text-3); + background: none; + border: none; + border-radius: 5px; + padding: 4px 9px; + cursor: pointer; + font-family: var(--font-ui); +} +.act-btn:hover { background: var(--bg-raised); color: var(--text-1); } +.act-btn svg { width: 13.5px; height: 13.5px; } + +/* ---------- ContentBlock ---------- */ +.block { + background: var(--bg-raised); + border: 1px solid var(--line-soft); + border-radius: var(--radius); + overflow: hidden; +} +.block__body { padding: 14px 18px; } + +.block--text { background: transparent; border: none; padding: 0; } +.block--text .block__body { padding: 0; } + +.block__head { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 14px; + border-bottom: 1px solid var(--line-soft); + background: var(--bg-sunken); + font-size: 12px; + color: var(--text-3); +} +.block__head .lang { color: var(--accent); font-family: var(--font-mono); text-transform: lowercase; } +.block__head .fname { font-family: var(--font-mono); color: var(--text-2); } +.block__head .acts { margin-left: auto; display: flex; gap: 4px; } + +.md p { margin-bottom: 0.8em; } +.md p:last-child { margin-bottom: 0; } +.md strong { color: var(--text-1); } +.md em { color: var(--text-2); } +.md ul { padding-left: 1.3em; margin-bottom: 0.8em; } +.md ul:last-child { margin-bottom: 0; } +.md li { margin-bottom: 0.3em; } +.md code { + font-family: var(--font-mono); + font-size: 0.88em; + background: var(--bg-sunken); + border: 1px solid var(--line-soft); + border-radius: 4px; + padding: 1px 6px; +} +.md a { text-underline-offset: 3px; text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent); } +.md .ext::after { content: " ↗"; font-size: 0.82em; color: var(--text-3); } + +/* 引文锚 */ +.quote { border-left: 3px solid var(--accent); padding: 2px 0 2px 14px; color: var(--text-2); font-family: var(--font-serif); font-size: 14.5px; } +.quote__src { display: block; margin-top: 5px; font-family: var(--font-ui); font-size: 11.5px; color: var(--text-3); } + +/* 表格 */ +.table-wrap { overflow-x: auto; } +table.data { border-collapse: collapse; width: 100%; font-size: 13px; } +table.data th { + text-align: left; + font-weight: 500; + color: var(--text-3); + font-size: 12px; + border-bottom: 1px solid var(--line); + padding: 7px 12px; + white-space: nowrap; +} +table.data td { padding: 8px 12px; border-bottom: 1px solid var(--line-soft); color: var(--text-2); } +table.data tr:last-child td { border-bottom: none; } +table.data td:first-child { color: var(--text-1); font-family: var(--font-serif); } + +/* 代码块(手工着色示意) */ +pre.code { + font-family: var(--font-mono); + font-size: 12.8px; + line-height: 1.7; + padding: 14px 16px; + overflow-x: auto; + color: var(--text-2); +} +pre.code .k { color: var(--accent); } +pre.code .s { color: var(--ok); } +pre.code .c { color: var(--text-3); font-style: italic; } +pre.code .f { color: var(--cinnabar-strong); } + +/* 数学块 */ +.math { + font-family: var(--font-serif); + font-style: italic; + font-size: 16.5px; + text-align: center; + padding: 16px 12px; + letter-spacing: 0.02em; +} +.math sub, .math sup { font-size: 0.68em; } +.math__fallback { display: block; margin-top: 8px; font-family: var(--font-ui); font-style: normal; font-size: 11.5px; color: var(--text-3); text-align: center; } + +/* Mermaid 示意(内联 SVG 图) */ +.mermaid-box { padding: 18px 14px; overflow-x: auto; } +.mermaid-cap { padding: 8px 14px; border-top: 1px solid var(--line-soft); font-size: 11.5px; color: var(--text-3); display: flex; gap: 8px; align-items: center; } + +/* 音频块 */ +.audio { display: flex; align-items: center; gap: 14px; padding: 13px 16px; } +.audio__play { + width: 36px; height: 36px; border-radius: 50%; + border: 1px solid var(--line); + background: var(--bg-sunken); + color: var(--accent); + display: inline-flex; align-items: center; justify-content: center; + cursor: pointer; flex: none; +} +.audio__play svg { width: 15px; height: 15px; margin-left: 2px; } +.wave { display: flex; align-items: center; gap: 2.5px; height: 30px; flex: 1; } +.wave i { + width: 3px; + border-radius: 2px; + background: var(--accent); + opacity: 0.55; + display: block; +} +.audio__time { font-family: var(--font-mono); font-size: 12px; color: var(--text-3); } +.audio__meta { flex: none; text-align: right; } +.audio__meta .t { font-size: 12px; color: var(--text-2); display: block; } + +/* 工具调用块 */ +.tool { border-left: 3px solid var(--accent); } +.tool__head { display: flex; align-items: center; gap: 10px; padding: 10px 16px; } +.tool__name { font-family: var(--font-mono); font-size: 13px; color: var(--text-1); } +.tool__purpose { font-size: 12px; color: var(--text-3); } +.tool__body { padding: 0 16px 12px; font-size: 12.5px; color: var(--text-2); } +.tool__row { display: flex; gap: 8px; padding: 2px 0; } +.tool__row .k2 { color: var(--text-3); flex: none; } +.tool__stat { display: flex; gap: 14px; margin-top: 6px; font-size: 11.5px; color: var(--text-3); } + +/* 请命(审批)卡 —— 签名组件 */ +.approval { border: 1px solid color-mix(in srgb, var(--cinnabar) 38%, transparent); } +.approval__head { + display: flex; + align-items: center; + gap: 10px; + padding: 12px 18px; + border-bottom: 1px solid color-mix(in srgb, var(--cinnabar) 22%, transparent); + background: var(--cinnabar-soft); +} +.approval__seal { + width: 30px; height: 30px; flex: none; + border-radius: 50%; + border: 1.5px solid var(--cinnabar); + color: var(--cinnabar); + display: inline-flex; align-items: center; justify-content: center; + font-family: var(--font-serif); font-size: 13px; font-weight: 600; + background: var(--bg-raised); +} +.approval__title { font-size: 14px; } +.approval__title .cn { font-size: 15.5px; font-weight: 600; color: var(--cinnabar); } +.approval__body { padding: 13px 18px; display: flex; flex-direction: column; gap: 8px; } +.fact { display: grid; grid-template-columns: 88px 1fr; gap: 10px; font-size: 13px; } +.fact__k { color: var(--text-3); } +.fact__v { color: var(--text-1); } +.fact__v .mono { font-size: 12px; color: var(--text-2); } +.approval__acts { display: flex; gap: 10px; align-items: center; padding: 0 18px 15px; } +.approval__note { font-size: 11.5px; color: var(--text-3); margin-left: auto; max-width: 220px; } +.approval--done { border-color: var(--line); } +.approval--done .approval__head { background: transparent; border-bottom-color: var(--line-soft); } +.approval--done .approval__seal { border-color: var(--ok); color: var(--ok); } + +/* 候答 */ +.candidates { display: flex; align-items: center; gap: 10px; padding-left: 48px; margin-top: -14px; margin-bottom: 26px; } +.cand-switch { display: inline-flex; gap: 4px; } +.cand-tag { + border: 1px solid var(--line); + background: var(--bg-sunken); + color: var(--text-3); + font-size: 12px; + border-radius: 999px; + padding: 3px 12px; + cursor: pointer; +} +.cand-tag.is-on { border-color: var(--accent); color: var(--accent-strong); background: var(--accent-soft); } + +/* 残答折叠 */ +.sealed { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 16px; + border: 1px dashed var(--line); + border-radius: var(--radius); + font-size: 12.5px; + color: var(--text-3); + padding-left: 48px; + border-left: none; border-right: none; border-top: none; + margin-left: 0; +} +.sealed__body { flex: 1; } +.sealed__t { color: var(--text-2); } + +/* 息壤候选(记忆候选卡) */ +.memory-cand { border-left: 3px solid var(--warn); } +.memory-cand__head { display: flex; align-items: center; gap: 10px; padding: 11px 16px; } +.memory-cand__body { padding: 0 16px 13px; font-size: 13px; color: var(--text-2); } +.memory-cand__body .q { font-family: var(--font-serif); color: var(--text-1); font-size: 14px; } +.memory-cand__acts { display: flex; gap: 8px; margin-top: 10px; } +.mem-type { + font-size: 11px; + border: 1px solid var(--line); + border-radius: 4px; + padding: 1px 7px; + color: var(--text-3); +} + +/* 临时芽体(流式) */ +.sprout { border: 1px dashed color-mix(in srgb, var(--accent) 45%, transparent); background: transparent; } +.sprout__head { display: flex; align-items: center; gap: 10px; padding: 9px 16px; font-size: 12px; color: var(--accent); border-bottom: 1px dashed var(--line); } +.sprout__body { padding: 13px 16px; } +.stream-cursor { + display: inline-block; + width: 8px; height: 17px; + background: var(--accent); + vertical-align: -3px; + margin-left: 2px; + animation: blink 1.05s step-end infinite; + border-radius: 1px; +} +@keyframes blink { 50% { opacity: 0; } } +.src-line { font-family: var(--font-mono); font-size: 13px; color: var(--text-2); white-space: pre-wrap; } +.src-line .unclosed { color: var(--text-3); } + +/* 输入区 */ +.composer { border-top: 1px solid var(--line-soft); padding: 14px 26px 18px; background: var(--bg); } +.composer__inner { max-width: 780px; margin: 0 auto; } +.composer__box { + background: var(--bg-raised); + border: 1px solid var(--line); + border-radius: var(--radius-lg); + padding: 12px 14px; + display: flex; + flex-direction: column; + gap: 10px; +} +.composer__box:focus-within { border-color: var(--accent); } +.composer__ta { + background: none; border: none; resize: none; + color: var(--text-1); + font-family: var(--font-ui); + font-size: 14px; + line-height: 1.6; + min-height: 44px; + outline: none; +} +.composer__bar { display: flex; align-items: center; gap: 6px; } +.composer__bar .spacer { flex: 1; } +.composer__hint { display: flex; gap: 14px; margin-top: 8px; font-size: 11.5px; color: var(--text-3); flex-wrap: wrap; } +.composer__hint .k { color: var(--text-2); } + +/* ---------- 右栏:镜枝面板 ---------- */ +.conv-ctx { + border-left: 1px solid var(--line-soft); + overflow-y: auto; + padding: 18px 16px 30px; + background: var(--bg); +} +.ctx-section { margin-bottom: 24px; } +.ctx-section__head { + display: flex; align-items: baseline; gap: 8px; + margin-bottom: 10px; +} +.ctx-section__head .cn { font-size: 14.5px; font-weight: 600; } +.ctx-section__head .more { margin-left: auto; font-size: 11.5px; } + +/* 分支树 */ +.tree { font-size: 12.5px; } +.tree ul { list-style: none; padding-left: 18px; position: relative; } +.tree > ul { padding-left: 2px; } +.tree ul::before { + content: ""; + position: absolute; + left: 6px; top: 4px; bottom: 12px; + width: 1px; + background: color-mix(in srgb, var(--text-3) 55%, transparent); +} +.tree li { position: relative; padding: 3px 0 3px 14px; } +.tree li::before { + content: ""; + position: absolute; + left: 0; top: 13px; + width: 12px; height: 1px; + background: color-mix(in srgb, var(--text-3) 55%, transparent); +} +.tree li:last-child::after { + content: ""; + position: absolute; + left: -12px; top: 15px; bottom: 0; + width: 1px; + background: var(--bg); +} +.tree__node { display: flex; align-items: center; gap: 7px; color: var(--text-2); } +.tree__node .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.tree__node--main .nm { color: var(--text-1); font-weight: 500; } +.tree__node--now { + background: var(--accent-soft); + border-radius: 5px; + outline: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); + padding: 2px 6px; + margin-left: -6px; + color: var(--accent-strong); +} +.tree__node--sealed { color: var(--text-3); } +.tree__tag { font-size: 10.5px; border-radius: 4px; padding: 0 6px; flex: none; border: 1px solid var(--line); color: var(--text-3); } +.tree__tag--main { border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent); } +.tree__tag--seal { border-color: var(--line); color: var(--text-3); text-decoration: line-through; } +.tree__tag--bud { border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent); animation: pulse 2.2s ease-in-out infinite; } + +/* 上下文镜 */ +.ctx-mirror__row { display: flex; gap: 9px; padding: 6px 0; font-size: 12.5px; align-items: baseline; } +.ctx-mirror__type { flex: none; width: 34px; color: var(--text-3); } +.ctx-mirror__txt { color: var(--text-2); flex: 1; } +.ctx-mirror__src { font-size: 11px; color: var(--text-3); white-space: nowrap; } +.ctx-mirror__omitted { color: var(--text-3); font-size: 12px; padding: 4px 0; } +.ctx-meter { margin-top: 10px; } +.ctx-meter__label { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--text-3); margin-bottom: 5px; } + +/* ---------- 索引页(设计说明) ---------- */ +.doc { max-width: 980px; } +.doc-hero { padding: 44px 0 30px; border-bottom: 1px solid var(--line-soft); margin-bottom: 34px; } +.doc-hero h1 { font-family: var(--font-serif); font-size: 34px; font-weight: 600; margin-bottom: 10px; display: flex; align-items: center; gap: 16px; } +.doc-hero p { color: var(--text-2); max-width: 640px; } +.doc-hero .ver { font-family: var(--font-mono); font-size: 13px; color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); border-radius: 999px; padding: 3px 12px; vertical-align: middle; } + +.doc-sec { margin-bottom: 40px; } +.doc-sec > h2 { font-family: var(--font-serif); font-size: 20px; font-weight: 600; margin-bottom: 6px; } +.doc-sec > .sub { color: var(--text-3); font-size: 13px; margin-bottom: 18px; } + +.page-nav { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; } +.page-nav a.card { display: flex; flex-direction: column; gap: 6px; color: var(--text-1); transition: border-color 0.15s; } +.page-nav a.card:hover { border-color: var(--accent); } +.page-nav .cn { font-size: 16px; font-weight: 600; } +.page-nav .d { font-size: 12.5px; color: var(--text-3); } +.page-nav .p { font-family: var(--font-mono); font-size: 11px; color: var(--accent); } + +.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 10px; } +.swatch { border: 1px solid var(--line-soft); border-radius: var(--radius-sm); overflow: hidden; } +.swatch__c { height: 52px; } +.swatch__m { padding: 7px 10px; font-size: 11.5px; color: var(--text-2); background: var(--bg-raised); } +.swatch__m b { display: block; font-size: 12px; color: var(--text-1); font-weight: 500; } +.swatch__m .mono { color: var(--text-3); font-size: 10.5px; } + +.type-spec { display: flex; flex-direction: column; gap: 14px; } +.type-spec__row { display: flex; align-items: baseline; gap: 20px; border-bottom: 1px dashed var(--line-soft); padding-bottom: 13px; flex-wrap: wrap; } +.type-spec__label { width: 130px; flex: none; font-size: 12px; color: var(--text-3); } +.type-spec__sample { color: var(--text-1); } + +.demo-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; } +.demo-block { margin-bottom: 22px; } + +.badge-table td:first-child { font-family: var(--font-ui); } + +/* ---------- 响应式 ---------- */ +@media (max-width: 1200px) { + .conv-layout { grid-template-columns: 240px 1fr; } + .conv-ctx { display: none; } +} + +@media (max-width: 960px) { + .app { grid-template-columns: 64px 1fr; } + .brand__text, .nav-item .cn, .nav-item .nav-plain, .nav-group__title { display: none; } + .nav-item { justify-content: center; } + .brand { justify-content: center; padding: 16px 0 10px; } + .home-cols { grid-template-columns: 1fr; } + .char-layout { grid-template-columns: 1fr; } + .conv-layout { grid-template-columns: 1fr; } + .conv-side { display: none; } + .content { padding: 20px 18px 40px; } + .prototype-tag, .topbar .realm-dot { display: none; } + .crumbs .crumbs__sep, .crumbs .cn { display: none; } +} + +/* ============================================================ + 第二批页面组件(息壤/形仪/天工阁/百工坊/雅集/同契台/云市/神识阁/器谱/司命台/设置) + ============================================================ */ + +/* 页内选项卡 */ +.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line-soft); margin-bottom: 22px; overflow-x: auto; } +.tab { + border: none; background: none; cursor: pointer; + font-family: var(--font-ui); font-size: 13.5px; color: var(--text-2); + padding: 9px 14px 10px; border-bottom: 2px solid transparent; margin-bottom: -1px; + display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; +} +.tab .cnt { font-size: 11px; color: var(--text-3); border: 1px solid var(--line); border-radius: 999px; padding: 0 7px; } +.tab:hover { color: var(--text-1); } +.tab.is-on { color: var(--accent-strong); border-bottom-color: var(--accent); } +.tab.is-on .cnt { border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent); } + +/* chip 筛选 */ +.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; } +.chip { + font-size: 12.5px; color: var(--text-2); + border: 1px solid var(--line); border-radius: 999px; + padding: 3px 13px; cursor: pointer; background: none; font-family: var(--font-ui); + display: inline-flex; align-items: center; gap: 6px; +} +.chip:hover { color: var(--text-1); border-color: var(--text-3); } +.chip.is-on { color: var(--accent-strong); border-color: var(--accent); background: var(--accent-soft); } + +/* 搜索条 */ +.searchbar { display: flex; align-items: center; gap: 9px; background: var(--bg-sunken); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 7px 12px; } +.searchbar svg { width: 15px; height: 15px; color: var(--text-3); flex: none; } +.searchbar input { flex: 1; background: none; border: none; outline: none; color: var(--text-1); font-family: var(--font-ui); font-size: 13.5px; min-width: 0; } +.searchbar input::placeholder { color: var(--text-3); } + +/* 开关 */ +.switch { position: relative; width: 36px; height: 20px; flex: none; display: inline-block; } +.switch input { position: absolute; opacity: 0; inset: 0; cursor: pointer; z-index: 1; margin: 0; } +.switch i { position: absolute; inset: 0; border-radius: 999px; background: var(--line); transition: background 0.15s; display: block; } +.switch i::after { content: ""; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--bg-raised); box-shadow: var(--shadow-soft); transition: transform 0.15s; } +.switch input:checked + i { background: var(--accent); } +.switch input:checked + i::after { transform: translateX(16px); } +.switch input:focus-visible + i { outline: 2px solid var(--accent); outline-offset: 2px; } + +/* 设置行 */ +.set-row { display: flex; align-items: center; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--line-soft); } +.set-row:last-child { border-bottom: none; } +.set-row__body { flex: 1; min-width: 0; } +.set-row__t { font-size: 13.5px; } +.set-row__d { font-size: 12px; color: var(--text-3); margin-top: 2px; line-height: 1.55; } + +/* 资产 / 商品网格 */ +.asset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 14px; } +.asset-card { display: flex; flex-direction: column; border: 1px solid var(--line-soft); border-radius: var(--radius); overflow: hidden; background: var(--bg-raised); } +.asset-thumb { height: 118px; position: relative; display: flex; align-items: center; justify-content: center; } +.asset-thumb .glyph { font-family: var(--font-serif); font-size: 30px; color: rgba(255, 255, 255, 0.88); text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); } +.asset-type { position: absolute; top: 8px; left: 8px; font-size: 10.5px; color: #fff; background: rgba(0, 0, 0, 0.45); border-radius: 4px; padding: 1px 7px; } +.asset-flag { position: absolute; top: 8px; right: 8px; } +.asset-body { padding: 11px 13px 12px; display: flex; flex-direction: column; gap: 5px; flex: 1; } +.asset-name { font-size: 13.5px; } +.asset-sub { font-size: 11.5px; color: var(--text-3); } +.asset-acts { display: flex; gap: 6px; margin-top: auto; padding-top: 6px; flex-wrap: wrap; } + +/* 价格(金额直白优先) */ +.price { font-family: var(--font-serif); font-size: 17px; font-weight: 600; } +.price small { font-size: 12px; font-weight: 400; color: var(--text-3); } +.price--free { color: var(--ok); } + +/* 天工:工筹步骤 */ +.step { display: flex; gap: 12px; position: relative; padding-bottom: 18px; } +.step:last-child { padding-bottom: 0; } +.step::before { content: ""; position: absolute; left: 13px; top: 30px; bottom: 2px; width: 1px; background: var(--line); } +.step:last-child::before { display: none; } +.step__dot { width: 27px; height: 27px; border-radius: 50%; flex: none; display: flex; align-items: center; justify-content: center; font-size: 12px; border: 1px solid var(--line); color: var(--text-3); background: var(--bg-raised); font-family: var(--font-serif); } +.step--done .step__dot { border-color: var(--ok); color: var(--ok); } +.step--run .step__dot { border-color: var(--accent); color: var(--accent-strong); animation: pulse 2.2s ease-in-out infinite; } +.step__t { font-size: 13.5px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } +.step__d { font-size: 12px; color: var(--text-3); margin-top: 1px; } + +/* 用量条形图 */ +.bars { display: flex; align-items: flex-end; gap: 7px; height: 112px; padding-top: 6px; } +.bars__col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; justify-content: flex-end; height: 100%; } +.bars__bar { width: 100%; max-width: 34px; border-radius: 4px 4px 0 0; background: var(--accent); opacity: 0.8; } +.bars__label { font-size: 10.5px; color: var(--text-3); } + +/* 授权行 */ +.grant-row { display: grid; grid-template-columns: 122px 1fr auto; gap: 12px; align-items: center; padding: 11px 0; border-bottom: 1px solid var(--line-soft); } +.grant-row:last-child { border-bottom: none; } +.grant-row__cap { display: flex; align-items: center; gap: 7px; font-size: 13px; } +.grant-row__cap svg { width: 15px; height: 15px; color: var(--text-3); flex: none; } +.grant-row__meta { font-size: 12px; color: var(--text-3); margin-top: 2px; line-height: 1.5; } + +/* 帖子卡(雅集) */ +.post { padding: 16px 18px; } +.post__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } +.post__author { font-size: 13.5px; } +.post__time { font-size: 11.5px; color: var(--text-3); } +.post__body { font-size: 13.5px; color: var(--text-2); display: flex; flex-direction: column; gap: 8px; } +.post__foot { display: flex; gap: 4px; margin-top: 12px; } + +/* 双栏(主内容 + 侧栏) */ +.two-col { display: grid; grid-template-columns: 1fr 320px; gap: 18px; align-items: start; } + +/* 玄络图容器 */ +.graph-box { padding: 10px; } + +/* 权限矩阵标记 */ +.mark-ok { color: var(--ok); } +.mark-no { color: var(--text-3); opacity: 0.45; } + +/* 治理案件卡 */ +.case-card { border-left: 3px solid var(--warn); } + +@media (max-width: 1100px) { + .two-col { grid-template-columns: 1fr; } +} + +/* ============================================================ + 铜镜鉴心传承:鎏金发丝线(承接 main 分支旧版设计体系) + ============================================================ */ +:root { + --gilt: #c9a24a; + --gilt-dim: rgba(201, 162, 74, 0.34); + --gilt-faint: rgba(201, 162, 74, 0.14); +} +[data-theme="light"] { + --gilt: #8f7226; + --gilt-dim: rgba(143, 114, 38, 0.4); + --gilt-faint: rgba(143, 114, 38, 0.15); +} + +.brand { cursor: pointer; } +.brand__mark { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16), inset 0 0 0 4px rgba(0, 0, 0, 0.16), 0 0 0 1px var(--gilt-dim); } +.nav-group__title { color: var(--gilt-dim); } +.topbar { border-bottom: 1px solid var(--gilt-faint); } +.section__head { position: relative; } +.section__head > .cn:first-child::before { + content: ""; + display: inline-block; + width: 3px; + height: 13px; + border-radius: 2px; + background: var(--gilt); + margin-right: 8px; + vertical-align: -1px; +} +.timeline::before { background: var(--gilt-faint); } + +/* logo 彩蛋动效 */ +.brand.tick .brand__mark { transform: scale(0.92); } +.brand__mark { transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s; } +.brand.egg-pulse .brand__mark { + animation: egg-pulse 1.3s ease-out; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2), inset 0 0 0 4px rgba(0, 0, 0, 0.16), 0 0 0 1px var(--gilt), 0 0 22px var(--gilt-dim); +} +@keyframes egg-pulse { + 0% { transform: scale(1); } + 30% { transform: scale(1.12) rotate(6deg); } + 60% { transform: scale(0.96) rotate(-3deg); } + 100% { transform: scale(1); } +} +.egg-toast { + position: fixed; + bottom: 48px; + left: 50%; + transform: translateX(-50%); + padding: 12px 28px; + border-radius: 12px; + background: var(--accent-soft); + color: var(--accent-strong); + font-family: var(--font-serif); + font-size: 14px; + border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); + z-index: 9999; + pointer-events: none; + opacity: 0; + transition: opacity 0.4s; + box-shadow: var(--shadow); +} +.egg-toast.is-on { opacity: 1; } + +/* ============================================================ + 侧栏折叠系统(主侧栏 + 对话页左右面板) + ============================================================ */ +.side-fold-btn { color: var(--text-3); } +.side-fold-btn svg { transition: transform 0.18s ease; } +.side-fold-btn:hover { color: var(--gilt); } + +.app--fold { grid-template-columns: 64px 1fr; } +.app--fold .brand__text, +.app--fold .nav-item .cn, +.app--fold .nav-item .nav-plain, +.app--fold .nav-group__title { display: none; } +.app--fold .nav-item { justify-content: center; } +.app--fold .brand { justify-content: center; padding: 16px 0 10px; } +.app--fold .side-fold-btn svg { transform: rotate(180deg); } +.app--fold .side-foot { flex-direction: column; gap: 6px; padding: 10px 8px; } +.app--fold .side-foot > span:not(.avatar) { display: none; } + +/* 对话页面板折叠 */ +.conv-layout.no-left { grid-template-columns: 0 1fr 320px; } +.conv-layout.no-left .conv-side { display: none; } +.conv-layout.no-right { grid-template-columns: 268px 1fr 0; } +.conv-layout.no-right .conv-ctx { display: none; } +.panel-toggle { + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: var(--radius-sm); + border: 1px solid var(--line); + background: var(--bg-raised); + color: var(--text-3); + cursor: pointer; +} +.panel-toggle:hover { color: var(--gilt); border-color: var(--gilt-dim); } +.panel-toggle svg { width: 15px; height: 15px; } +.conv-restore { + position: absolute; + top: 14px; + z-index: 15; + width: 32px; + height: 32px; + border-radius: var(--radius-sm); + border: 1px solid var(--line); + background: var(--bg-raised); + color: var(--text-2); + cursor: pointer; + display: none; + align-items: center; + justify-content: center; + box-shadow: var(--shadow-soft); +} +.conv-restore:hover { color: var(--gilt); border-color: var(--gilt-dim); } +.conv-restore svg { width: 16px; height: 16px; } +.conv-restore--left { left: 14px; } +.conv-restore--right { right: 14px; } +.conv-layout.no-left .conv-restore--left { display: inline-flex; } +.conv-layout.no-right .conv-restore--right { display: inline-flex; } + +/* ============================================================ + 登录 / 注册页(StageShell · 铜镜鉴心,承接旧版铜镜登录页) + ============================================================ */ +.stage { + min-height: 100vh; + display: flex; + flex-direction: column; + position: relative; + overflow-x: hidden; + background: var(--bg); +} + +.stage__bg { position: fixed; inset: 0; z-index: -1; pointer-events: none; } +.stage__rings { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; +} +.stage__rings svg { width: min(94vmin, 880px); height: min(94vmin, 880px); opacity: 0.16; } +[data-theme="light"] .stage__rings svg { opacity: 0.1; } +.ring-ink { fill: none; stroke: var(--gilt-faint); stroke-width: 0.6; } +.ring-faint { fill: none; stroke: var(--gilt-faint); stroke-width: 0.35; stroke-dasharray: 2 7; } +.ring-slow { transform-origin: center; animation: ring-spin 140s linear infinite; } +@keyframes ring-spin { to { transform: rotate(360deg); } } + +.stage__topbar { + display: flex; + align-items: center; + gap: 12px; + padding: 16px clamp(20px, 4vw, 44px); +} +.stage__topbar .spacer { flex: 1; } + +.stage__main { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + padding: 24px 18px 48px; +} + +/* 铜镜卡:唯一的镜面 */ +.mirror-card { + width: min(408px, 94vw); + background: var(--bg-raised); + border: 1px solid var(--gilt-dim); + border-radius: 18px; + padding: 38px 36px 30px; + position: relative; + overflow: hidden; + box-shadow: var(--shadow), inset 0 1px 0 rgba(255, 255, 255, 0.05); +} +.mirror-card::after { + /* 扫描亮带:铜镜在烛光下微倾时的漫反射 */ + content: ""; + position: absolute; + left: 0; + right: 0; + top: 0; + height: 34%; + background: linear-gradient(178deg, transparent, rgba(201, 162, 74, 0.05) 45%, rgba(255, 255, 255, 0.045) 55%, transparent); + pointer-events: none; + animation: mirror-scan 7.5s ease-in-out infinite; +} +@keyframes mirror-scan { + 0% { transform: translateY(-110%); } + 55% { transform: translateY(320%); } + 100% { transform: translateY(320%); } +} + +.mirror-card__brand { display: flex; align-items: center; gap: 12px; justify-content: center; margin-bottom: 8px; } +.mirror-card__brand .brand__mark { width: 40px; height: 40px; } +.mirror-card__title { text-align: center; } +.mirror-card__title h1 { font-family: var(--font-serif); font-size: 24px; font-weight: 600; letter-spacing: 0.04em; } +.mirror-card__sub { text-align: center; font-size: 12.5px; color: var(--text-3); margin: 6px 0 26px; } + +.field-group { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; } +.field-group label { font-size: 12.5px; color: var(--text-2); } +.field-group .input { background: var(--bg-sunken); } +.field-row { display: flex; gap: 10px; } +.field-row .input { flex: 1; } + +.login-alt { + display: flex; + align-items: center; + gap: 12px; + margin: 18px 0 14px; + color: var(--text-3); + font-size: 11.5px; +} +.login-alt::before, .login-alt::after { content: ""; flex: 1; height: 1px; background: var(--line-soft); } + +.login-note { font-size: 11.5px; color: var(--text-3); line-height: 1.7; text-align: center; margin-top: 16px; } +.login-foot { text-align: center; font-size: 13px; margin-top: 18px; color: var(--text-2); } + +.check-row { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px; } +.check-row input[type="checkbox"] { margin-top: 3px; accent-color: var(--accent); width: 15px; height: 15px; flex: none; } +.check-row .t { font-size: 12.5px; color: var(--text-2); line-height: 1.6; } +.check-row .t b { color: var(--text-1); font-weight: 500; } + +@media (prefers-reduced-motion: reduce) { + .mirror-card::after, .ring-slow { animation: none; } +} + +/* 面板收起后内容区自适应放宽(平滑过渡) */ +.conv-stream__inner, .composer__inner { transition: max-width 0.25s ease; } +.conv-layout.no-left .conv-stream__inner, +.conv-layout.no-left .composer__inner, +.conv-layout.no-right .conv-stream__inner, +.conv-layout.no-right .composer__inner { max-width: 1000px; } +.conv-layout.no-left.no-right .conv-stream__inner, +.conv-layout.no-left.no-right .composer__inner { max-width: 1140px; } + +/* 双面板同时收起:不留空轨道,内容占满 */ +.conv-layout.no-left.no-right { grid-template-columns: 0 1fr 0; } + +/* 显式网格列位:面板收起(display:none)后主区不因自动放置错位到空轨道 */ +.conv-side { grid-column: 1; } +.conv-main { grid-column: 2; } +.conv-ctx { grid-column: 3; } + +/* ============================================================ + 旧版「铜镜鉴心」传承细节(本轮系统挖掘 main 分支 25 页后融入) + ============================================================ */ + +/* 极光铜晕:极淡的三色径向氛围底(承接 _base.css body::before) */ +body::before { + content: ""; + position: fixed; + inset: 0; + z-index: -1; + pointer-events: none; + background: + radial-gradient(60vmax 60vmax at 12% -10%, rgba(88, 169, 156, 0.05), transparent 60%), + radial-gradient(50vmax 50vmax at 105% 15%, rgba(201, 162, 74, 0.035), transparent 60%), + radial-gradient(46vmax 46vmax at 50% 115%, rgba(196, 87, 74, 0.022), transparent 62%); +} + +/* 卡片 hover 光扫(承接 --sweep-gradient 手法,克制到接近不可见) */ +.card { position: relative; } +.card::after { + content: ""; + position: absolute; + inset: 0; + border-radius: inherit; + pointer-events: none; + background: linear-gradient(115deg, transparent 30%, rgba(201, 162, 74, 0.03) 48%, rgba(255, 255, 255, 0.035) 52%, transparent 70%); + opacity: 0; + transition: opacity 0.35s ease; +} +.card:hover::after { opacity: 1; } + +/* 天工阁:进行中步骤的「动爻」鎏金光晕(爻象手法的 1.0 化:done=铜绿已闭,active=鎏金流转) */ +.step--run .step__dot { + background: radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--gilt) 30%, var(--bg-raised)), var(--bg-raised)); + box-shadow: 0 0 0 3px var(--gilt-faint), 0 0 14px var(--gilt-dim); +} + +/* 镜庭:日晷时辰盘(承接 time-preview 日晷,静态原型固定巳时) */ +.sundial { position: relative; width: 116px; height: 116px; flex: none; } +.sundial svg { width: 100%; height: 100%; display: block; } +.sundial__center { + position: absolute; inset: 0; + display: flex; flex-direction: column; align-items: center; justify-content: center; + pointer-events: none; +} +.sundial__hour { font-family: var(--font-serif); font-size: 17px; font-weight: 600; color: var(--gilt); } +.sundial__sub { font-size: 9.5px; color: var(--text-3); margin-top: 1px; } +.sundial-spin { transform-origin: 58px 58px; animation: sundial-spin 120s linear infinite; } +@keyframes sundial-spin { to { transform: rotate(360deg); } } +@media (prefers-reduced-motion: reduce) { .sundial-spin { animation: none; } } + +/* 请命卡:风险等级徽章(承接朱批 RISK 分层) */ +.risk-badge { + font-family: var(--font-mono); + font-size: 10.5px; + letter-spacing: 0.04em; + border-radius: 4px; + padding: 1px 7px; + border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent); + color: var(--warn); +} +.risk-badge--low { border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent); } + +/* 玄络:待验假设边(承接河图 hypothesis 朱漆虚线呼吸) */ +.tent-edge { stroke-dasharray: 5 5; animation: tent-pulse 2.8s ease-in-out infinite; } +@keyframes tent-pulse { 50% { opacity: 0.35; } } +@media (prefers-reduced-motion: reduce) { .tent-edge { animation: none; } } + +/* ============================================================ + main 旧版设计复刻件(概念映射到 1.0:六爻→小周天阶段、九枢→灵台六模块、 + 周天四镜→大周天四阶段、好奇萤火→内驱力、五行相克→运营指标对) + ============================================================ */ + +/* ---- 灵台六枢星盘(复刻九枢星盘「活的仪器」,映射灵台六模块 ADR-016/017) ---- */ +.astrolabe-wrap { display: flex; gap: 22px; align-items: center; flex-wrap: wrap; } +.astrolabe { width: 262px; flex: none; } +.astrolabe svg { width: 100%; height: auto; display: block; } +.ast-node { cursor: pointer; } +.ast-node:hover .ast-node__ring { stroke: var(--gilt); } +.ast-core-text { font-family: var(--font-serif); fill: var(--text-1); } +.ast-node__name { font-family: var(--font-serif); font-size: 12.5px; fill: var(--text-1); } +.ast-node__plain { font-size: 8.5px; fill: var(--text-3); } +.ast-spin { transform-origin: 160px 160px; animation: ast-spin 120s linear infinite; } +@keyframes ast-spin { to { transform: rotate(360deg); } } +.ast-breathe { animation: ast-breathe 7s ease-in-out infinite; transform-origin: 160px 160px; } +@keyframes ast-breathe { 50% { opacity: 0.25; } } +.ast-alert { animation: ast-alert 1.8s ease-in-out infinite; } +@keyframes ast-alert { 50% { opacity: 0.2; } } +@media (prefers-reduced-motion: reduce) { + .ast-spin, .ast-breathe, .ast-alert { animation: none; } +} + +/* 铜镜四态健康词汇(复刻 MirrorState) */ +.mirror-state { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; } +.mirror-state i { width: 10px; height: 10px; border-radius: 50%; flex: none; } +.mirror-state--steady i { background: var(--ok); box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 55%, transparent); } +.mirror-state--cracked i { background: var(--err); } + +/* 相克告警卡(复刻五行相克告警,映射为运营指标对) */ +.clash-row { display: grid; grid-template-columns: 1fr 52px; gap: 10px; align-items: center; padding: 8px 0; border-bottom: 1px dashed var(--line-soft); } +.clash-row:last-child { border-bottom: none; } +.clash-row__pair { font-size: 12.5px; color: var(--text-2); } +.clash-row__pair b { color: var(--text-1); font-weight: 500; } +.clash-strength { height: 5px; border-radius: 3px; background: var(--bg-sunken); overflow: hidden; } +.clash-strength i { display: block; height: 100%; background: var(--warn); border-radius: 3px; } + +/* ---- 大周天四镜(复刻周天四镜阶段链,映射 ADR-023 四阶段) ---- */ +.cycle-mirrors { display: flex; align-items: center; gap: 6px; margin-bottom: 14px; } +.cycle-mirror { + flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; + padding: 12px 6px 10px; border-radius: var(--radius); + background: var(--bg-sunken); border: 1px solid var(--line-soft); +} +.cycle-mirror__disc { + width: 44px; height: 44px; border-radius: 50%; + display: flex; align-items: center; justify-content: center; + font-family: var(--font-serif); font-size: 18px; + background: + radial-gradient(circle at 34% 28%, rgba(255, 255, 255, 0.16), transparent 46%), + conic-gradient(from 210deg, #33474a, #4d7d76 45%, #3a4d51 85%, #33474a); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 0 0 1px var(--line); + color: var(--text-2); +} +.cycle-mirror.is-done .cycle-mirror__disc { color: var(--ok); box-shadow: inset 0 0 0 1px rgba(255,255,255,.1), 0 0 0 1px color-mix(in srgb, var(--ok) 45%, transparent); } +.cycle-mirror.is-active { + border-color: color-mix(in srgb, var(--gilt) 45%, transparent); + background: linear-gradient(180deg, var(--gilt-faint), transparent 70%), var(--bg-sunken); +} +.cycle-mirror.is-active .cycle-mirror__disc { + color: var(--gilt); + background: + radial-gradient(circle at 34% 28%, rgba(255, 255, 255, 0.2), transparent 46%), + radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--gilt) 32%, #33474a), #33474a); + box-shadow: 0 0 0 1px var(--gilt-dim), 0 0 16px var(--gilt-dim); +} +.cycle-mirror__name { font-size: 12.5px; color: var(--text-2); } +.cycle-mirror.is-active .cycle-mirror__name { color: var(--gilt); font-weight: 500; } +.cycle-mirror__state { font-size: 10.5px; color: var(--text-3); } +.cycle-mirror__link { width: 14px; height: 1px; background: var(--line); flex: none; } + +/* ---- 好奇萤火(复刻 drive 萤火点,亮度=内驱力值) ---- */ +.firefly { + width: 9px; height: 9px; border-radius: 50%; flex: none; + background: var(--accent); + animation: firefly-pulse 2.6s ease-in-out infinite; +} +@keyframes firefly-pulse { + 0%, 100% { box-shadow: 0 0 3px 1px color-mix(in srgb, var(--accent) 45%, transparent); } + 50% { box-shadow: 0 0 9px 3px color-mix(in srgb, var(--accent) 60%, transparent); } +} +.firefly--dim { opacity: 0.45; animation-duration: 4.2s; } +.firefly--bright { background: var(--gilt); } +.firefly--bright { animation-name: firefly-pulse-gilt; } +@keyframes firefly-pulse-gilt { + 0%, 100% { box-shadow: 0 0 4px 1px var(--gilt-dim); } + 50% { box-shadow: 0 0 11px 4px var(--gilt-dim); } +} +@media (prefers-reduced-motion: reduce) { .firefly { animation: none; } } + +/* ---- 镜树:会话列表分组 + 彩点(复刻 chat-redesign 铭文往来分组) ---- */ +.conv-group__title { + font-size: 10.5px; color: var(--text-3); letter-spacing: 0.1em; + padding: 12px 8px 5px; +} +.conv-group__title:first-child { padding-top: 2px; } +.conv-item__title { display: flex; align-items: center; gap: 8px; font-size: 13.5px; } +.conv-item__dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--muted); } +.conv-item__dot--active { background: var(--accent); box-shadow: 0 0 6px color-mix(in srgb, var(--accent) 55%, transparent); } +.conv-item__dot--sim { background: var(--warn); } +.conv-item__dot--risk { background: var(--cinnabar); } + +/* 用户消息鎏金右边线(复刻 copper-v2 用户消息金线) */ +.msg--user .bubble { border-right: 2px solid var(--gilt-dim); } + +/* ---- 输入区控制药丸(复刻「深虑 / 博闻」) ---- */ +.pill-btn { + display: inline-flex; align-items: center; gap: 5px; + font-size: 12px; color: var(--text-3); + border: 1px solid var(--line); border-radius: 999px; + background: none; cursor: pointer; padding: 3px 11px; + font-family: var(--font-ui); +} +.pill-btn:hover { color: var(--text-1); } +.pill-btn.is-on { color: var(--accent-strong); border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: var(--accent-soft); } +.pill-btn small { font-size: 10px; color: var(--text-3); } + +/* ---- 镜生 card-banner(复刻渐变横幅) ---- */ +.char-banner { + height: 72px; border-radius: var(--radius); margin-bottom: 16px; + background: + radial-gradient(120% 190% at 12% 120%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 55%), + linear-gradient(115deg, color-mix(in srgb, var(--accent) 8%, transparent), transparent 42%, var(--gilt-faint) 88%); + border: 1px solid var(--line-soft); +} + +/* ---- 时间河卷章(复刻起居注「卷」分割) ---- */ +.timeline-volume { + display: flex; align-items: center; gap: 10px; + margin: 4px 0 12px; padding-left: 14px; + font-family: var(--font-serif); font-size: 12px; color: var(--gilt); +} +.timeline-volume::before, .timeline-volume::after { + content: ""; flex: 1; height: 1px; + background: linear-gradient(90deg, transparent, var(--gilt-dim)); +} +.timeline-volume::after { background: linear-gradient(90deg, var(--gilt-dim), transparent); } + +/* ---- 阴阳平衡 gauge(复刻太极 gauge,映射朱批治理) ---- */ +.taiji-gauge { display: flex; align-items: center; gap: 16px; } +.taiji-gauge svg { width: 128px; height: 76px; flex: none; } +.taiji-gauge__label { fill: var(--text-3); font-size: 9px; } +.taiji-gauge__val { font-family: var(--font-serif); font-size: 16px; } + +/* ============================================================ + 思考块(thinking block · 契约候选):模型思考摘要可折叠 + 强度呈现 + 边界:展示的是模型输出的可读摘要——会话内可见、可丢弃重建; + 不写入长期记录、不进入诊断导出(隐藏推理不采集,宪章不变)。 + ============================================================ */ +.think-block { + border: 1px dashed var(--line); + border-radius: var(--radius); + background: transparent; + overflow: hidden; +} +.think-block summary { + display: flex; + align-items: center; + gap: 9px; + padding: 9px 14px; + cursor: pointer; + list-style: none; + font-size: 12.5px; + color: var(--text-2); + user-select: none; +} +.think-block summary::-webkit-details-marker { display: none; } +.think-block summary:hover { color: var(--text-1); background: var(--bg-sunken); } +.think-block summary svg { width: 14px; height: 14px; flex: none; color: var(--text-3); } +.think-block summary .chev { margin-left: auto; transition: transform 0.18s ease; } +.think-block[open] summary .chev { transform: rotate(90deg); } +.think-block summary .think-meta { font-size: 11px; color: var(--text-3); } +.think-block summary .think-effort { + font-size: 10.5px; + border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); + color: var(--accent); + border-radius: 4px; + padding: 0 6px; +} +.think-body { + padding: 4px 16px 12px 39px; + font-size: 12.5px; + color: var(--text-3); + line-height: 1.75; + border-left: 2px solid var(--line-soft); + margin: 0 14px 0 14px; +} +.think-body p { margin-bottom: 0.6em; } +.think-body p:last-child { margin-bottom: 0; } +.think-note { padding: 8px 16px 12px 39px; font-size: 11px; color: var(--text-3); opacity: 0.85; } + +/* 流式思考中:呼吸点 + 实时摘要(底部渐隐,完成后折叠) */ +.think-block.is-thinking { border-color: color-mix(in srgb, var(--accent) 40%, transparent); } +.think-block.is-thinking summary { color: var(--accent-strong); } +.think-dot { + width: 8px; height: 8px; border-radius: 50%; flex: none; + background: var(--accent); + animation: think-breathe 1.6s ease-in-out infinite; +} +@keyframes think-breathe { + 0%, 100% { box-shadow: 0 0 2px 1px color-mix(in srgb, var(--accent) 40%, transparent); opacity: .6; } + 50% { box-shadow: 0 0 8px 3px color-mix(in srgb, var(--accent) 60%, transparent); opacity: 1; } +} +.think-live { + max-height: 108px; + overflow: hidden; + -webkit-mask-image: linear-gradient(180deg, transparent, #000 22%); + mask-image: linear-gradient(180deg, transparent, #000 22%); +} +.think-cursor { + display: inline-block; + width: 7px; height: 13px; + background: var(--accent); + vertical-align: -2px; + margin-left: 2px; + border-radius: 1px; + animation: blink 1.05s step-end infinite; +} +@media (prefers-reduced-motion: reduce) { + .think-dot, .think-cursor { animation: none; } +} + +/* 深虑伴随控件:点击深虑 = 开启深度思考;开启后右侧出现力度选项(独立控件,只调档); + 再次点击深虑 = 关闭,力度选项随之消失 */ +.effort-seg { + display: inline-flex; + background: var(--bg-sunken); + border: 1px solid var(--line-soft); + border-radius: 999px; + padding: 2px; + gap: 2px; + animation: effort-in 0.2s ease; +} +.effort-seg[hidden] { display: none; } +@keyframes effort-in { + from { opacity: 0; transform: translateX(-4px); } + to { opacity: 1; transform: none; } +} +.effort-seg button { + border: none; + background: none; + cursor: pointer; + font-family: var(--font-ui); + font-size: 11.5px; + color: var(--text-3); + padding: 2.5px 11px; + border-radius: 999px; +} +.effort-seg button:hover { color: var(--text-1); } +.effort-seg button[aria-checked="true"] { background: var(--accent-soft); color: var(--accent-strong); } +@media (prefers-reduced-motion: reduce) { .effort-seg { animation: none; } } diff --git a/design/assets/app.js b/design/assets/app.js new file mode 100644 index 0000000..4f7b7b7 --- /dev/null +++ b/design/assets/app.js @@ -0,0 +1,222 @@ +/* 魂镜原型 · 共享交互脚本 + 主题切换 · logo 彩蛋(镜启)· 主侧栏折叠 · 对话页面板折叠 · 演示态切换 */ +(function () { + "use strict"; + + /* ---------- 主题切换(localStorage 持久化,仅原型演示用) ---------- */ + var saved = null; + try { saved = localStorage.getItem("hunjing-prototype-theme"); } catch (e) { /* 忽略 */ } + if (saved === "light" || saved === "dark") { + document.documentElement.setAttribute("data-theme", saved); + } + window.hjSetTheme = function (theme) { + document.documentElement.setAttribute("data-theme", theme); + try { localStorage.setItem("hunjing-prototype-theme", theme); } catch (e) { /* 忽略 */ } + document.querySelectorAll("[data-theme-toggle]").forEach(function (btn) { + btn.setAttribute("aria-label", theme === "dark" ? "切换到月白主题" : "切换到墨色主题"); + }); + }; + + document.addEventListener("click", function (ev) { + var btn = ev.target.closest("[data-theme-toggle]"); + if (!btn) return; + var cur = document.documentElement.getAttribute("data-theme") === "light" ? "light" : "dark"; + window.hjSetTheme(cur === "dark" ? "light" : "dark"); + }); + + /* ---------- logo:单击回目录;350ms 内连点 5 次触发「镜启」彩蛋 ---------- + 承接 main 分支旧版设计:镜启不跳转,随机呈上一句镜铭。 */ + var EGG_VERSES = [ + "镜中有镜,心外无心。", + "汝来看此镜时,此镜亦照汝。", + "一念起,万镜生。", + "镜非鉴物,乃鉴心也。", + "幻由心生,镜随心转。", + "铜镜本无字,照尽往来人。", + "且向镜中看,那个是谁?", + ]; + var logoClickSeq = 0; + var lastLogoTime = 0; + var jumpTimer = null; + + function showEggToast(msg) { + var toast = document.createElement("div"); + toast.className = "egg-toast"; + toast.textContent = msg; + document.body.appendChild(toast); + requestAnimationFrame(function () { toast.classList.add("is-on"); }); + setTimeout(function () { + toast.classList.remove("is-on"); + setTimeout(function () { toast.remove(); }, 450); + }, 2400); + } + + function onBrandClick(brandEl) { + clearTimeout(jumpTimer); + var now = Date.now(); + var fast = now - lastLogoTime < 380; /* 380ms 内视为连点 */ + lastLogoTime = now; + if (brandEl) { + brandEl.classList.add("tick"); + setTimeout(function () { brandEl.classList.remove("tick"); }, 300); + } + if (fast) { + logoClickSeq += 1; + if (logoClickSeq >= 4) { + /* 首击 + 4 次连点 = 共 5 次点击:镜启彩蛋,不跳转 */ + logoClickSeq = 0; + var v = EGG_VERSES[Math.floor(Math.random() * EGG_VERSES.length)]; + if (brandEl) { + brandEl.classList.add("egg-pulse"); + setTimeout(function () { brandEl.classList.remove("egg-pulse"); }, 1400); + } + showEggToast("镜启 · " + v); + } + return; /* 连点不跳转 */ + } + logoClickSeq = 0; + /* 单击延迟跳转,为连点留出窗口 */ + jumpTimer = setTimeout(function () { location.href = "index.html"; }, 380); + } + + /* ---------- 主侧栏折叠(localStorage 持久化) ---------- */ + function applySidebarFold(collapsed) { + document.querySelectorAll(".app").forEach(function (app) { + app.classList.toggle("app--fold", collapsed); + }); + } + function sidebarFolded() { + var app = document.querySelector(".app"); + return !!(app && app.classList.contains("app--fold")); + } + + /* ---------- 对话页左右面板折叠 ---------- */ + function panelFold(which) { + var layout = document.querySelector(".conv-layout"); + if (!layout) return; + layout.classList.toggle("no-" + which); + } + + /* ---------- 事件委托 ---------- */ + document.addEventListener("click", function (ev) { + var t = ev.target; + if (!t || !t.closest) return; + + var foldBtn = t.closest("[data-sidebar-fold]"); + if (foldBtn) { + ev.preventDefault(); + var collapsed = !sidebarFolded(); + applySidebarFold(collapsed); + try { localStorage.setItem("hunjing-prototype-sidebar", collapsed ? "collapsed" : "expanded"); } catch (e) { /* 忽略 */ } + return; + } + + var panelBtn = t.closest("[data-panel-fold]"); + if (panelBtn) { + ev.preventDefault(); + panelFold(panelBtn.getAttribute("data-panel-fold")); + return; + } + + var brand = t.closest(".brand"); + if (brand) { + ev.preventDefault(); + onBrandClick(brand); + return; + } + }); + + /* 恢复折叠状态 */ + try { + var foldSaved = localStorage.getItem("hunjing-prototype-sidebar"); + if (foldSaved === "collapsed") applySidebarFold(true); + } catch (e) { /* 忽略 */ } + + /* ---------- 深虑:点击 = 开启深度思考(右侧伴随力度选项);再次点击 = 关闭并隐藏选项 ---------- */ + function setEffortHint(on, val) { + var hint = document.querySelector("[data-effort-hint]"); + if (hint) hint.textContent = on ? "深虑 · " + val : "深虑 · 关"; + } + + document.addEventListener("click", function (ev) { + var t = ev.target; + if (!t || !t.closest) return; + + /* 力度选项:独立控件,只调档,与深虑开关动作无关(关闭态隐藏时不响应) */ + var opt = t.closest("[data-effort-seg] button[data-effort]"); + if (opt) { + ev.preventDefault(); + ev.stopPropagation(); + if (opt.closest("[data-effort-seg]").hidden) return; + document.querySelectorAll("[data-effort-seg] button").forEach(function (b) { + b.setAttribute("aria-checked", String(b === opt)); + }); + setEffortHint(true, opt.getAttribute("data-effort")); + return; + } + + /* 深虑按钮:开 ⇄ 关 */ + var pill = t.closest('[data-pill="effort"]'); + if (pill) { + ev.preventDefault(); + var on = !pill.classList.contains("is-on"); + pill.classList.toggle("is-on", on); + pill.setAttribute("aria-pressed", String(on)); + pill.title = on + ? "深虑 · 深度思考已开启,再次点击关闭" + : "深虑 · 已关闭:本条消息不思考,直出答复(推理型模型不可关)"; + var seg = document.querySelector("[data-effort-seg]"); + if (seg) seg.hidden = !on; + var val = "关"; + if (on) { + var checked = document.querySelector('[data-effort-seg] button[aria-checked="true"]'); + val = checked ? checked.getAttribute("data-effort") : "中"; + } + setEffortHint(on, val); + return; + } + }); + + /* ---------- 博闻药丸(关→开) ---------- */ + document.addEventListener("click", function (ev) { + var pill = ev.target.closest('[data-pill="search"]'); + if (!pill) return; + ev.preventDefault(); + var small = pill.querySelector("small"); + if (!small) return; + var on = small.textContent.trim() === "开"; + small.textContent = on ? "关" : "开"; + pill.classList.toggle("is-on", !on); + pill.setAttribute("aria-pressed", String(!on)); + }); + + /* ---------- 候答切换(静态演示) ---------- */ + document.querySelectorAll("[data-cand-group]").forEach(function (group) { + group.querySelectorAll(".cand-tag").forEach(function (tag) { + tag.addEventListener("click", function () { + group.querySelectorAll(".cand-tag").forEach(function (tt) { tt.classList.remove("is-on"); }); + tag.classList.add("is-on"); + }); + }); + }); + + /* ---------- 界域分段控件:切换提示条文案 ---------- */ + document.querySelectorAll("[data-realm]").forEach(function (seg) { + seg.querySelectorAll(".seg__item").forEach(function (item) { + item.addEventListener("click", function () { + seg.querySelectorAll(".seg__item").forEach(function (tt) { tt.classList.remove("is-on"); }); + item.classList.add("is-on"); + var banner = document.querySelector("[data-realm-banner]"); + if (!banner) return; + var realm = item.getAttribute("data-realm"); + if (realm === "sim") { + banner.className = "realm-banner realm-banner--sim"; + } else { + banner.className = "realm-banner"; + } + var html = item.getAttribute("data-banner-html"); + if (html) banner.textContent = html; + }); + }); + }); +})(); diff --git a/design/avatar.html b/design/avatar.html new file mode 100644 index 0000000..b06fdc9 --- /dev/null +++ b/design/avatar.html @@ -0,0 +1,145 @@ + + + + + +形仪 · 形象与资产 — 魂镜 Hunjing + + + + +
+ +
+
+
形仪/青梧 · 形象与资产
+
+ 静态原型 · 待审查 + +
+
+ +
+ 梧 +
+

青梧的形仪 形态不是角色本体

+
主仪 · 守砚人立像 v3 · 真形锚已锁定稳定辨识特征
+
+
+ + +
+
+ +
+
+ 真形锚稳定外观参考 + +
+
+
· 稳定辨识特征:青衫束发、眉间一点朱痣、左手常年持砚
+
· 年龄表现约束:成年形象,不做年龄回退
+
· 许可与禁忌:形象由你原创 · 禁止他人商用(许可记录见来源谱系)
+
· 可变范围:服饰、场景、光照可变;面部锚点特征触及须走易相评估
+
+
+ +
+
+ 资产库图像 / 声音 / Live2D / 3D +
+
+ + + + + + +
+
+
+
立图像主仪
+
守砚人立像v3 · 已定相 · 2048×2560 +
+
+
+
+
冬图像
+
冬青 · 化仪v1 · 可切换形态 +
+
+
+
+
声声音声契 · 原创
+
青梧原声原创设计 · 授权完整 · 转写并存 +
+
+
+
+
灵Live2D
+
守砚人 · 灵动版Cubism 兼容导入 · 校验通过 · 参数映射 42 项 +
+
+
+
+
三3D · VRM
+
守砚人 VRM导入验证与标准化通过 · 骨骼 54 · 表情 12 +
+
+
+
+
旧图像 · 归档
+
旧版立像 v2易相历史保留 · 可回看不可覆盖 +
+
+
+
+
+ +
+
+ 易相正式形仪的版本化改变 + 全部 3 次 → +
+
+
+
2024-03-05
+
主仪 v1 · 初版立像
+
来源:手动上传
+
+
+
2025-11-20
+
易相 v2 · 换季服饰(未触及真形锚)
+
轻流程 · 直接生效
+
+
+
2026-08-30
+
易相 v3 · 面部细节重绘(触及真形锚)
+
已做身份连续性评估 · 谱系留痕
+
+
+

情相 · 情态的受控表现:可访问性友好,不作为情绪施压载体;叙仪 · 境界或幻境中的叙事形态,不改变主仪与真形锚。

+
+ +
+
+
+ + + diff --git a/design/characters.html b/design/characters.html new file mode 100644 index 0000000..dbc3d13 --- /dev/null +++ b/design/characters.html @@ -0,0 +1,233 @@ + + + + + +镜生 · 角色 — 魂镜 Hunjing + + + + + +
+ + +
+
+
镜生/青梧
+
+ 静态原型 · 待审查 + + +
+ +
+
+ +
+
+
+ 镜生4 位角色 + +
+
+ 梧 +
+
青梧
+
守砚人 · 道体 v3
+
+ 临照 +
+
+ 袖 +
+
雪袖
+
茶室主人 · 道体 v1
+
+ 守一 +
+
+ 澜 +
+
观澜
+
航海士 · 道体 v2
+
+ 静修 +
+
+ 岁 +
+
旧岁
+
守岁人 · 归藏
+
+ 归藏 +
+ +
+
+ + +
+ +
+ 梧 +
+

青梧 临照 · 前台运行 running

+
「砚为田,字为稼。」守砚人 · 你与我共读的第三年
+
+ 道体 v3 + 镜域 · 个人域 + 来源 · 手动创建 +
+
+
+ 进入镜树 + +
+
+ +
+
+ 道体稳定身份基线 + 普通对话与记忆不能静默覆盖道体 +
+

+ 青梧是江南书斋的守砚人:语调平缓,好引张岱与《陶庵梦忆》;记账一丝不苟,惜字如金。 + 基线由 v1 逐步重映而来——人格、语言风格与知识边界在版本中留痕,任何重大改动都会先成候选、经你确认。 +

+
+ +
+
+ 缘契你与青梧的关系 + 共读者 · v4 +
+

「隔周四晚共读,青梧负责选篇与笔记;你不喜长篇说教。」——最近一次铭契于 8 月 28 日确认,旧关系状态保留版本可查。

+
+ +
+
+ 内驱力动机与倾向维度 · 可审阅编辑 + +
+
求知
0.80
+
条理
0.65
+
陪伴
0.40
+

内驱力是声明式设定数据,不是不可控本能;变化与大周天评估相关,每次调整版本化留痕。

+
+ +
+
+ 大周天自我评估与演化循环 + 已成 · 第 7 轮 completed +
+
+
回回顾已成 · 09-14
+ +
照对照已成 · 09-14
+ +
议提议已成 · 09-15
+ +
呈提交2 项待你确认
+
+

本轮由 42 次小周天完成信号触发 · 预算 5k token(实用 3.1k)· 产出:人格候选 1、世界认知候选 1。演化经你确认才生效;循环可整体关闭。

+
+ + +
+
+ +
+
+ 身份谱系来源与重大演变 + 完整谱系 · 见下方时间线 +
+
+
+
2024-03-02
+
启镜 · 正式创建
+
手动创建 · 道体 v1 · 初照自陈已归真
+
+
+
2025-06-18
+
重映 · 道体 v2
+
语言风格修订 · 旧版本保留
+
+
+
2026-01-11
+
分灵 · 雪袖自此谱系分出
+
新角色新 ID · 谱系可验证 · 不冒充原角色
+
+
+
2026-08-28
+
重映 · 道体 v3(当前)
+
知识边界修订 · 经候选确认
+
+
+
+ +
+
+ 生命周期影响角色状态的操作 · 均可逆或有冷静期,与数据删除分离 +
+
+ + + + + +
+

铸魂与死亡均走强确认与谱系留痕;死亡不等于删除数据,只读档案保留。删除角色数据是独立操作,入口在司命台。

+
+
+
+
+
+
+ + + diff --git a/design/collaboration.html b/design/collaboration.html new file mode 100644 index 0000000..d4143aa --- /dev/null +++ b/design/collaboration.html @@ -0,0 +1,114 @@ + + + + + +同契台 · 协作空间 — 魂镜 Hunjing + + + + +
+ +
+
+
同契台/镜斋工作室
+
+ 静态原型 · 待审查 + +
+
+ +
+ 斋 +
+

镜斋工作室 共修 · 2 人在线 editing

+
成员 4 · 邀请制 · 编辑 / 发布 / 财务权限分别授予
+
+
+ + +
+
+ +
+
+
+
分支版本
+
+
选篇修订
v3 草稿 · 审稿意见 2
+ 审稿中 +
+
+
main
v12 · 已刊 · 共读手册
+ 已刊 +
+
+
资产重制
v1 草稿 · Live2D 分层
+ 草稿 +
+
+
+ +
+
+
选篇修订v3 草稿
+
+
09-14 21:30
v3 草稿 · 云舟
按青梧建议调整三、四讲顺序
+
09-14 22:10
审稿意见 ×2 · 阿沉
「定海水操放第五讲更顺」「附页地图需更新版本」
+
09-10 19:00
v2 合卷 · 已并入 main
冲突 1 处已手工处理
+
+
+ + + 批准后需两名编辑合卷方可并入 main +
+
+ +
+
成员权限编辑 / 发布 / 上架 / 财务分离
+
+ + + + + + + +
成员编辑发布市场上架财务
云舟(主理)✓✓✓✓
阿沉✓✓——
临江仙✓———
山客(只读)————
+

成员移除后立即失去编辑权;已合并版本的署名与来源保留。

+
+ +
+
活动记录
+
+
09-14 22:10
阿沉 提交审稿意见
+
09-12 10:05
云舟 创建分支「选篇修订」
+
09-10 19:00
v2 合卷并入 main(两名编辑批准)
+
+
+
+
+ +
+
+
+ + + diff --git a/design/community.html b/design/community.html new file mode 100644 index 0000000..a537a3e --- /dev/null +++ b/design/community.html @@ -0,0 +1,141 @@ + + + + + +雅集 · 社区广场 — 魂镜 Hunjing + + + + +
+ +
+
+
雅集·社区广场
+
+ 静态原型 · 待审查 + +
+
+ +
+
+ + + + + +
+ + +
+ +
+
+
+
+ 沉 +
+ 角色发布 published +
+
+

发布角色「照夜 · 掌灯人」v2 · 市契 CC BY-NC 4.0

+

渡口掌灯的角色,话少但记得每个过客的名字。基于我自己的镜生谱系重映而来,Fork 请保留署名。

+
+ 许可 · CC BY-NC分灵谱系 · 可验证分级 · 全年龄 +
+
+
+ + + + + +
+
+ +
+
+ 梧 +
+
+
+

共读《陶庵梦忆》第一讲笔记:湖心亭那一百六十字,读三遍的方法真的有效。附角色整理的选篇结构图。

+
莫说相公痴,更有痴似相公者。引文锚 · 《湖心亭看雪》
+
+
+ + + + +
+
+ +
+
+ 袖 +
+ 世界设定 published +
+
+

世界「雾中茶寮」第三章境界 · 世界正史 v5

+

雨季的茶寮只在雾散时开门。本章收录 6 个新场景与 2 位过客的世界认知候选来源说明。

+
+
+ + + + +
+
+
+ +
+
+
角色谱角色社区精选全部 · 角色谱整页在 React 阶段实现
+
夜
照夜 · 掌灯人
沉舟 · Fork 128 · 全年龄
+
筑
筑秋 · 修槎人
临江仙 · Fork 76
+
岱
岱舆 · 观星者
山客 · Fork 54
+
+ +
+
话题
+
+ #陶庵梦忆#共读笔记#Live2D#雾中茶寮#守砚人 +
+
+ +
+
推荐解释为什么看到这些
+

当前动态基于你最近的共读活动与关注关系排序。推荐不扩大任何权限,也不使用你的私密角色数据。

+ +
+
+
+ +
+
+
+ + + diff --git a/design/conversation.html b/design/conversation.html new file mode 100644 index 0000000..c7bf04b --- /dev/null +++ b/design/conversation.html @@ -0,0 +1,552 @@ + + + + + +镜树 · 分支对话 — 魂镜 Hunjing + + + + + +
+ + +
+
+
+ 镜树/《陶庵梦忆》共读选篇 +
+
+ + + +
+ 真界 +
+ 静态原型 · 待审查 + +
+ +
+ + + + +
+ + +
+
+
+ 真界 · 当前是现实与正式共同经历的界域,内容按记忆策略进入长期记忆。 +
+ + +
+
问节m_8a3f2026-09-15 19:42
+
帮我把读书会这学期的《陶庵梦忆》共读选篇定下来:选六篇,兼顾篇幅和趣味,大家隔周四晚讨论。
+
+ + +
+
+ 梧 + 青梧 + 道体 v3已成 completed +
+
+
+ + + 思考 · 已收敛为摘要 + 深虑 · 中 + 思考 1.2k token · 用时 9s + + +
+

用户要为读书会从《陶庵梦忆》定六篇,兼顾篇幅与趣味,隔周四讨论。需要考虑:成员含两位新人(首篇宜短宜奇)、整体要有递进结构而非并列、末篇宜收束回张岱本人。以篇目字数与趣味点对照评估,湖心亭看雪最短且白描极致,适合开卷;自为墓志铭最长且是回望性文本,适合收官;中间四篇按「雪—夜—池—海」的意象递进排列。

+
+
思考摘要仅本会话内可见,可丢弃重建;不写入长期记录,不进入诊断导出。
+
+
+
+

选好了。六篇按「起—承—转—合」推进:从最短的《湖心亭看雪》起,让新人先尝到味道;雪、夜、池、海层层铺开,末篇收在自为墓志铭,正好回到张岱自己。

+
+
+
+
选篇清单
+
+ + + + + + + + + + +
次序篇目约字数趣味点
一湖心亭看雪160白描极致 · 入门首选
二卷中雪700炉火与夜读
三金山夜戏900寺院里点灯唱戏
四庞公池600枕舟而眠
五定海水操1100海上观兵
六自为墓志铭1300回望一生 · 收束全卷
+
+
+
+
mermaidflowchart · 完成后 strict mode 渲染
+
+ + + + 起 · 湖心亭看雪 + 第一周 · 白描 + + + 承 · 雪 / 夜 + 卷中雪 · 金山夜戏 + + + 转 · 池 / 海 + 庞公池 · 定海水操 + + + 合 · 自为墓志铭 + 末周 · 回望 + + +
+
图 1 · 六讲推进结构(SVG 已净化 · 可缩放 / 下载 / 查看源码)
+
+
莫说相公痴,更有痴似相公者。 + 引文锚 · 《陶庵梦忆 · 湖心亭看雪》 · anchor_c41 +
+
+
+ + + + + +
+
+ + +
+
问节m_91d019:47
+
好。把六次讨论排进我的日历:从下周四 19:30 开始,隔周一次,每次 90 分钟,标题统一叫「共读 · 第 N 讲」。
+
+ + +
+
+ 梧 + 青梧 + 道体 v3已成 completed +
+
+
+
+ calendar.write + 在日历创建 6 个循环事件 + 已成 · 已完成 completed +
+
+
参数摘要6 个事件 · 90 分钟 · 间隔 14 天 · 起始 2026-09-24 19:30 (UTC+8)
+
耗时 1.2s插件 · 系统日历(Core)幂等键 idem_5b2c
+
+
+ +
+
+ +
+
请命 · 已朱批本次确认 · 已由你允许
+
2026-09-15 19:48 允许 · 留痕于司命台
+
+ 允许 approved +
+
+
动作在日历创建 6 个「共读 · 第 N 讲」事件
+
影响写入你的日历;不读取其他日程
+
数据范围日历写入 · 仅此 6 条 calendar:write:once
+
费用无(本地工具)
+
有效期本次执行,不形成持续授权
+
+
+ +
+
+

已写入。首场 9 月 24 日(周四)19:30,《湖心亭看雪》——正好赶上秋分后的第一场凉。预习提示我会在每讲前三天放进讨论区。

+
+
+
+
+ + +
+
+ + +
+
+
+
+ 息壤候选记忆候选 · 归真后才会影响未来上下文 + 偏好 preference +
+
+

「读书会隔周四 19:30 举行,每次 90 分钟。」

+

来源 · 本对话 m_91d0 · 置信度 0.92 · 敏感度低

+
+ + + +
+
+
+
+
+ + +
+
问节m_a20720:02
+
第一讲的开场白怎么讲?给两个版本我挑。
+
+ + +
+
+ 梧 + 青梧 + 道体 v3已成 completed +
+
+
+ + +
+ 同一问节的两个回答候选 · 切换不覆盖彼此 +
+
+
+
+

**版本 A(从雪夜进入)**——「崇祯五年十二月,余住西湖。大雪三日,湖中人鸟声俱绝。」今晚我们不急着分析,先把这一百六十字读三遍:第一遍看雪,第二遍看舟,第三遍看那个「痴」字。

+

音频版我念了一遍,配了半分钟的环境音。

+
+
+
+
+ + +
+ 开场白 · 语音版 + 0:42 · 声契 · 青梧原声 +
+
+
转写:「崇祯五年十二月,余住西湖……」(全文 214 字 · 已加字幕)
+
+
+
+ + + +
+
+ 残答 · 已封存 interrupted +
+
推演枝 D · 生成中断于 68%,内容封存不再修改。
+
残答不作为完成答复展示 · 引用合流或
+
+ +
+
+ + +
+
问节m_b6f120:10
+
再把每讲的预习提纲写成六份文档,存进我的笔记库「读书会」目录。
+
+ + +
+
+ 梧 + 青梧 + 道体 v3请命中 · 等待确认 waiting_approval +
+
+
+
+ notes.write_files + 在笔记库写入 6 份预习提纲 + 请命中 · 等待确认 waiting_approval +
+
+
参数摘要目录 /读书会/2026秋/ · 6 个 Markdown 文件 · 每份约 40 行
+
插件 · 笔记同步(已安装 · 已启用)路径已校验在授权根内
+
+
+ +
+
+ +
+
请命请求你的确认 · 未确认不执行 RISK L2
+
拒绝或超时均不执行 · 无默认允许 · L2:写操作,范围已限死
+
+
+
+
动作在笔记库「读书会」目录创建 6 份 Markdown 预习提纲
+
影响新增 6 个文件;不修改、不删除现有笔记
+
数据范围笔记库写入 · 仅该目录 notes:write:/读书会/
+
费用6 次文件写入 · 无额外模型费用(提纲已在本次生成)
+
有效期本次执行 · 勾选「行契」可限 30 天内同类免请命
+
+
+ + + 朱批 · 你的明确决定,允许或拒绝都留痕。 +
+
+
+
+ + +
+
问节m_c94420:12
+
在等的时候,先给我一版 30 分钟的精简流程,怕第一次拖堂。
+
+ +
+
+ 梧 + 青梧 + 道体 v3运转 · 生成中 streaming +
+
+
+ + + 正在思考 + 深虑 · 中 + 思考 0.4k token · 深虑档位可在输入区调整 + + +
+

用户担心首次共读拖堂,要 30 分钟精简版。需要压缩朗读与讨论比例:三分钟齐读保留仪式感,两个问题足够聚焦——「雪大不大」对应白描力度,「痴不痴」对应人物自我认知,比四个问题更利于新人开口……

+

末段用舟子那句话收尾,与开场「痴」字形成回环,30 分钟结构即

+
+
+
+
+ 临时芽体流式生成中 · 完成后才固化 + block 2/4 · delta 118 +
+
+
+

30 分钟精简版:前三分钟齐读原文,随后只留两个问题——「雪大不大」和「痴不痴」,最后五分钟交给「舟子那句话」收尾。

+
+
**时间分配**(未闭合的 Markdown 结构保持源码态,完成后解析) +
+
+
+
+
+ +
+
+ + +
+
+
+ +
+ + + + + + + + + + + + +
+
+
+ 界域 真界 · 现实 + 路径 主脉 + 模型 会话临时 · 覆盖自用户偏好 + 思考 深虑 · 中(点深虑开关,右侧调力度) + 上下文 2.1k / 8k token +
+
+
+
+ + + +
+
+
+ + + diff --git a/design/devices.html b/design/devices.html new file mode 100644 index 0000000..c35eee3 --- /dev/null +++ b/design/devices.html @@ -0,0 +1,133 @@ + + + + + +器谱 · 设备与感知 — 魂镜 Hunjing + + + + +
+ +
+
+
器谱·设备与感知
+
+ 静态原型 · 待审查 + +
+
+ +
+ + 设备能力同时受系统权限与授契约束;采集有持续指示,可即时暂停或撤销。离线缓存加密,不创建独立角色副本。 +
+ +
+
形器登记设备
+
+
+ +
MacBook Pro · Tauri 桌面
macOS · 当前设备
+ 在线 +
+
+ +
iPhone · 移动端
iOS · 实时语音常用设备
+ 在线 +
+
+ +
Web 浏览器 · Safari
昨天活跃 · 仅文件读写授权
+ 离线 +
+
+
+ +
+
授契设备能力授权
+
+
+ 闻声 · 麦克风 +
青梧 · 实时语音
iPhone · 仅通话期间 · 采集指示常显
+ +
+
+ 文件读写 +
青梧 · 书斋归档
MacBook · 仅 ~/BookRoom/ 目录 · 长期(可随时撤销)
+ +
+
+ 通知 +
叩心提醒通道
iPhone · 静默时段 22:00–08:00 · 频率 ≤ 1 条/日
+ +
+
+ 观影 · 摄像头 +
未授权
任何角色请求摄像头时将单独请命
+ — +
+
+ 问路 · 位置 +
未授权(上次通感已结束)
通感默认 10 分钟 · 精度 1km · 结束即失效
+ — +
+
+
+ +
+
+
通感进行中限时设备感知剩 8 分钟
+

青梧 · 问路(位置 · 精度 1km)· 用于「找一家安静的茶馆」。采集指示常显,位置不写入长期记忆,会话结束即丢弃。

+
+
+ + +
+
+ +
+
+
+ +
+
请命 · 观屏屏幕读取授权
+
来自镜树「书房整理」· 限此一次
+
+
+
+

允许青梧在未来 10 分钟读取当前屏幕?

+
用途识别书桌照片中的书目并归档
+
数据仅屏幕内容 · 不截屏存储 · 不写入长期记忆
+
+
+ + +
+
+
+
+ +
+
+
+ + + diff --git a/design/governance.html b/design/governance.html new file mode 100644 index 0000000..bd6bc31 --- /dev/null +++ b/design/governance.html @@ -0,0 +1,142 @@ + + + + + +司命台 · 安全与治理 — 魂镜 Hunjing + + + + +
+ +
+
+
司命台·安全 · 权限 · 审计 · 治理
+
+ 静态原型 · 待审查 + +
+
+ +
+ + 治理不支配角色或用户数据;隐藏推理、密钥与凭据永不进入诊断与审计展示。错误与安全事件优先直白表述。 +
+ +
+
阴阳平衡朱批治理的三态阳亢 · 放行偏多 / 动态平衡 / 阴盛 · 驳回偏多
+
+ + + + + + + 阴 · 驳回 + 阳 · 放行 + +
+
动态平衡
+
近 30 日朱批通过率 78% · 驳回 22%
指针偏右但在平衡带内;阳亢时提示收紧行契,阴盛时提示检查策略误伤
+
+
+
+ +
+ + + + +
+ +
+
司议治理案件
+
+
+ 待审 · 等待审核 pending_review + 09-15 11:20 · 鸣冤 ×3 +
+

雅集帖子「未署名的守砚人立像二创」被举报:疑似未保留来源署名(CC BY-NC 要求)。

+
+ + + + +
+
+
+
+ 待审 pending_review + 09-14 09:02 · 自动扫描 +
+

市场商品「曲谱排版插件 v1.4」扫描发现:Manifest 声明与实际网络请求域不一致。

+
+ + + +
+
+
+ +
+
+
诊断授权双重授权
+

读取 Run 详细诊断(ModelCall、工具参数、ContextSnapshot)需要在普通认证之外叠加短期诊断令牌:绑定单个 Run、单次使用、默认 15 分钟。

+
+
申请诊断令牌
目的 user_inspection · 绑定 run_9f31c2(天工阁 · 书单任务)
+ +
+
+
hjd_8f…(已过期)
09-15 12:04 签发 · 12:19 过期 · 已用 1 次 · 范围:青梧 · 选篇答复
+ 已过期 +
+

隐藏推理、密钥、Authorization 与签名 URL 永不返回;管理员与诊断均不可读私箧。

+
+ +
+
安全概览设置 →
+
活跃会话 2
MacBook(当前)· iPhone
管理
+
Service Account key 1
scope:只读统计 · 90 天轮换
+
凭据重用检测
30 天 0 次
+
+
+ +
+
审计AuditEvent · 权威事务同批提交
+
+
+ + + + + + + + +
时间主体动作对象结果
09-15 19:48云舟朱批 · 允许calendar.write · run_7ab1✓
09-15 19:52云舟创建天工run_9f31c2✓
09-15 12:04云舟签发诊断令牌hjd_8f…✓
09-14 22:31未知请求跨镜域读取memory · 雪袖✗ 拒绝(失败关闭)
09-12 10:05云舟BYOK 轮换byok_7c02…✓
+
+
+ +
+
+
+ + + diff --git a/design/home.html b/design/home.html new file mode 100644 index 0000000..e7ff485 --- /dev/null +++ b/design/home.html @@ -0,0 +1,277 @@ + + + + + +镜庭 · 个人首页 — 魂镜 Hunjing + + + + + +
+ + +
+
+
镜庭·个人首页
+
+ 静态原型 · 待审查 + + +
+ +
+
+ +
+

上午好,云舟

+

周三 · 2026-09-16 · 与青梧相伴第 918 日 · 镜庭只聚合状态,各域才是数据事实源

+
+ +
+ +
+
+ 镜生你的角色 + 全部 4 位 → +
+ +
+ +
+
+
+ 镜树最近对话 + 全部 → +
+
+ + 梧 +
+
《陶庵梦忆》共读选篇 真界
+
青梧:六篇已定,结构图也画好了,请过目。
+
+ 10 分钟前 +
+
+ 袖 +
+
秋茶清单 境界
+
雪袖:按你上次的口味,先把白毫银针排第一。
+
+ 昨天 +
+
+ 梧 +
+
书房整理方案(幻境试演) 幻境
+
青梧:这只是试演方案,不影响现实与正史。
+
+ 9 月 12 日 +
+
+ 澜 +
+
远洋航线推演
+
观澜:航线已归档,静修前等你验收。
+
+ 9 月 2 日 +
+
+
+ +
+
+ 天工Agent 任务 + 天工阁 → +
+
+
+
+
整理性灵 newsletter 书单
+
青梧 · 分工使 2 · token 12.4k / 20k
+
+
+ 运转 · 运行中 running +
+
+
+
+
+
周报草稿 · 第 37 周
+
任务 Agent · 无角色身份
+
+ 待启 · 排队中 queued +
+
+
+
书斋照片归档命名
+
青梧 · 已成 · 耗时 4 分 12 秒
+
+ 已成 · 已完成 completed +
+
+
+
+ +
+
+ 待你决定审批与候选 +
+
+
+ +
+
请命 · 写入日历(6 个事件)
+
青梧请求在日历创建 6 个「共读讨论」事件 · 数据范围:仅日历 · 费用:无
+
+ 去朱批 +
+
+ 息壤候选 ×3 +
+
「读书会在隔周四晚」「偏爱短篇」「花粉过敏(重忆)」
+
来自青梧的对话候选 · 归真后才会影响未来上下文
+
+ 去审阅 +
+
+ 叩心候选 +
+
青梧想在明晚共读前发一条提醒
+
叩心当前静默 · 不回应不会降低关系 · 可设频率上限
+
+ 了解叩心 +
+
+
+
+
+
+ + + diff --git a/design/index.html b/design/index.html new file mode 100644 index 0000000..d5f3e48 --- /dev/null +++ b/design/index.html @@ -0,0 +1,243 @@ + + + + + +魂镜 Hunjing · 界面原型 · 设计说明 + + + + + +
+ + +
+
+
设计说明/静态原型 v0.1
+
+ 静态原型 · 待审查 · 确认后转 React + +
+ +
+
+

魂镜 原型 v0.2

+

魂镜 Web 界面静态 HTML 原型(v0.1 第一批方向已确认,v0.2 增补第二批共 15 个界面),供审查视觉方向、布局结构与文化语言的界面落地方式。全部确认后按此实现为 React 组件;未在本文档登记的视觉细节以本页令牌为准。

+
+ +
+

原型页面

+

第一批(已确认):镜庭、镜生、镜树;第二批:息壤、形仪、天工阁、神识阁、百工坊、雅集、同契台、云市、器谱、司命台、设置,及运营者/自托管使用的管理面与认证页。全站链接已疏通:跨页指向对应页面、页内为锚点;logo 单击回本目录,350ms 内连点 5 次触发「镜启」彩蛋(承接 main 分支旧版设计);侧栏可折叠并记忆偏好。

+ +
+ +
+

设计立场

+

四条约束所有页面的决定,审查时优先核对这四条是否成立。

+
+
一 · 双层文字系统 —— 文化名用衬线宋体,直白解释用无衬线小字,两种字体本身就是"文化名 · 直白解释"两层结构的可视化;风险、金额、权限、删除等后果始终以直白语言为主,文化名只作辅助。
+
二 · 朱砂只属于朱批 —— 朱砂色是"用户确认决定"的专用语义色:请命卡的允许按钮、危险动作入口使用它;普通操作一律铜镜青。颜色即权限语言。
+
三 · 墨与月白 —— 深色为墨(青调黑,非纯黑),浅色为月白(青灰白,非暖米);铜镜青为主色,取铜镜铜绿之意,不用蓝紫系默认色。
+
四 · 状态永远三段式 —— 状态徽章固定为「文化状态 · 直白状态 + 稳定工程值」,例如「运转 · 运行中 running」;错误与交易状态绝不只显示文化名。
+
+
+ +
+

色彩令牌

+

右下角可切换主题;以下色板随主题联动。转 React 时这些令牌进入 Tailwind 配置 / CSS 变量。

+
+
底 · 墨 / 月白表面层级 0--bg
+
浮面卡片与气泡--bg-raised
+
铜镜青主色 · 选中/链接/运转--accent
+
朱砂朱批 · 确认与危险--cinnabar
+
已成完成态--ok
+
秋香整备 / 幻境--warn
+
受阻失败态--err
+
正文一级文字--text-1
+
+
+ +
+

字体规范

+

不引入外部字体文件,使用系统中文字体栈;转 React 时同栈迁移。

+
+
文化名 · 宋体衬线镜树 · 分支对话
+
界面正文 · 无衬线正文 14px / 行高 1.65,辅助文字 12.5px,元信息 11.5px
+
稳定值 · 等宽running · m_01h8xq… · block_id: blk_7f3a
+
+
+ +
+

状态徽章全集

+

对应 docs/product/cultural-language.md 第 10 节;徽章三段:文化状态 · 直白状态 · 稳定值。

+
+
+ + + + + + + + + + + + + +
徽章稳定值使用场景
待启 · 排队中 queuedqueuedRun / 媒体任务排队
运转 · 运行中 runningrunningRun 执行中
请命中 · 等待确认 waiting_approvalwaiting_approval等待朱批
已成 · 已完成 completedcompletedRun / 任务完成
受阻 · 失败 failedfailed失败(附原因与重试)
已止 · 已取消 cancelledcancelled用户取消
守一 · 安静待命 idleidle角色无运行
整备 · 正在处理 processingprocessing媒体 / 资源处理
待审 · 等待审核 pending_reviewpending_review社区 / 市场审核
已刊 · 已发布 publishedpublished社区内容
+
+
+ +
+

组件样例

+

按钮语义:铜镜青为主操作,朱砂仅用于朱批(用户确认决定)与危险操作,描边为次操作。

+ +
+
+ + + + + + +
+
+ 请命请求你的确认 + 息壤角色记忆 + 幻境临时试演 · 不入正史 +
+
+ +
+
pythonreading_progress.py
+
# 汇总共读接龙进度(示意)
+from pathlib import Path
+
+def summarize(records: list[dict]) -> dict:
+    done = [r for r in records if r["finished"]]
+    return {
+        "total": len(records),
+        "finished": len(done),
+        "pending": [r["name"] for r in records if not r["finished"]],
+    }
+
+ +
+
注意力权重 = softmax( QKT / √dk ) · V + fallback:注意力权重等于 Q、K 转置乘积经缩放与归一化后对 V 的加权求和 +
+
+
+ +
+

审查重点

+

第一批(色彩、字体、镜树/镜生/镜庭结构)已确认;本轮重点核对第二批页面,反馈时按页名 + 位置描述即可。

+
+
1. 息壤:候选审阅的「归真入忆 / 正影纠正 / 忽略」操作,以及大周天来源、重忆提示的呈现是否可理解。
+
2. 天工阁:工筹步骤、预算、分工使、轨迹的信息层级是否符合你对 Run 治理的预期。
+
3. 神识阁 / 百工坊:路由继承链与「升级新增权限需重新确认」的展示是否清晰,朱批语义是否仍然专一。
+
4. 云市:金额、分润、退契规则是否足够直白(文化名没有掩盖交易后果)。
+
5. 器谱 / 司命台 / 设置:直白权限句、双重授权、私箧与删除等高风险项的措辞与视觉重量。
+
6. 雅集 / 同契台:社区帖卡与协作审稿流的信息密度是否合适。
+
+
+ +
+

旧版传承与候选

+

已系统挖掘 main 分支旧版 25 页设计原型(铜镜鉴心体系),按「取手法、不照搬旧概念名」原则融入——六爻 / 九枢 / 三魂等概念 1.0 已由小周天、灵台六模块、内驱力等替代,仅传承其可视化手法。

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
旧版想法来源页状态
鎏金发丝线三档令牌tokens.css✓ 已融入全站(分组标题 / 金标竖条 / 品牌外环 / 时间线)
logo 五连击「镜启」诗签彩蛋_theme.js✓ 已融入(修好首次单击即跳转的缺陷)
铜镜登录页(铭文环 / 铜面噪点 / 扫描亮带)copper-mirror-login✓ 已融入登录 / 注册页
极光铜晕底 + 卡片 hover 光扫_base.css / rune-engine✓ 已融入全站(极淡,不干扰阅读)
日晷时辰盘 + 节气 + 相伴日文案time✓ 已融入镜庭 hero(巳时 · 白露 · 第 918 日)
朱批卡风险分级(RISK L2)chat-redesign✓ 已融入镜树请命卡
「呈镜」发送按钮命名(旧版已确立血脉)chat-redesign✓ 已融入镜树输入区(aria 仍读「发送」)
运行阶段爻象三态(done / active / pending)chat / evolution✓ 已融入天工阁工筹(active 步骤鎏金光晕)
河图置信度图谱(置信→线宽,假设→朱漆虚线待验)world✓ 已融入息壤玄络(待验边 + 标注)
息壤浮现(本次回应用了哪些记忆)chat / copper-v2✓ 对应 1.0 上下文镜(镜树右栏,同源 ContextSnapshot)
九枢星盘「活的仪器」+ 铜镜四态健康词汇admin / copper-v2✓ 已复刻为灵台六枢星盘(太一居中 + 五枢环绕 + 呼吸刻度 / 慢旋 / 告警闪烁)+ 镜态徽章(管理面)
五行生克健康环(系统健康=关系动力学)wuxing✓ 已复刻为相生 / 相克指标对告警(管理面星盘卡;环状图 React 阶段评估)
眉批 depth 标尺注入预览margin-notes候选 —— 上下文镜深度维度(React 阶段与 Context Manifest 联动)
好奇萤火(亮度=期望值)与探索天平drive✓ 萤火已融入内驱力维度(亮度=维度值);探索天平待天工阁预算增强时评估
周天四镜阶段链(评 / 演 / 候 / 藏 四面小铜镜)evolution✓ 已复刻为大周天四镜:回 / 照 / 议 / 呈(镜生页,ADR-023 四阶段)
会话列表「今日 / 本周 / 更早」分组 + 彩点状态chat-redesign✓ 已融入镜树会话列表(活跃铜绿 / 幻境秋香 / 待朱批朱砂)
「深虑 / 博闻」输入控制药丸 + 用户消息鎏金右边线chat-redesign / copper-v2✓ 已融入镜树输入区与用户气泡
起居注时间河「卷」章分割admin✓ 已融入管理面审计快照
太极阴阳平衡 gauge(三态)cosmos✓ 已复刻为朱批治理阴阳平衡(司命台,阳亢 / 平衡 / 阴盛)
角色 card-banner 渐变横幅character-detail✓ 已融入镜生详情页
思考块折叠卡(复刻 chat-redesign)chat-redesign✓ 已融入(用户确认):思考摘要可折叠 + 深虑强度(低/中/高)——契约候选:正式实现前需在 content-blocks 契约登记 thinking 块类型与流式语义;摘要仅会话内可见,不入长期记录与诊断导出
+
+
+
+
+
+ + + diff --git a/design/login.html b/design/login.html new file mode 100644 index 0000000..af7b080 --- /dev/null +++ b/design/login.html @@ -0,0 +1,87 @@ + + + + + +魂镜 · 登录 + + + + + +
+ + +
+ 静态原型 · 待审查 + + 原型目录 + +
+ +
+
+
+ +
+
魂镜
+
Hunjing
+
+
+
+

登入魂镜

+
+

长期 AI 角色、Agent 与创作社区平台

+ +
+
+ + +
+
+ + +
+ 登入 +
+ + +
+ 通行密钥 + 恢复钥匙 +
+ + + +
+
+
+ + + diff --git a/design/marketplace.html b/design/marketplace.html new file mode 100644 index 0000000..95f4efa --- /dev/null +++ b/design/marketplace.html @@ -0,0 +1,140 @@ + + + + + +云市 · 创作市场 — 魂镜 Hunjing + + + + +
+ +
+
+
云市·创作市场
+
+ 静态原型 · 待审查 + +
+
+ +
+ + 购买的是版本与许可(市契),不是人格所有权。金额、费率与退款规则始终直白展示,文化名只作辅助。 +
+ +
+
+ + + + + + + +
+ +
+ +
+
+
+
雾世界设定
+
雾中茶寮 · 世界合集雪袖的茶寮 · v3 · 售出 412 +
¥28.00可商用
+
+
+
+
灯角色模板
+
照夜 · 掌灯人模板沉舟 · v2 · 售出 1,208 +
¥12.00个人用
+
+
+
+
灵Live2D
+
守砚人 · 灵动模型云舟 · v3 · 售出 96 +
¥45.00可商用
+
+
+
+
匣音色包
+
江南雨声 · 环境音色听澜 · v1 · 售出 340 +
免费署名使用
+
+
+
+
砚3D 资产
+
书斋器物 · VRM 附件包临江仙 · v2 · 售出 58 +
¥18.00个人用
+
+
+
+
谱插件
+
曲谱排版 · 插件百工 · v1.4 · 售出 233 +
¥6.00个人用
+
+
+
+
+ +
+
市契商品许可 · 以「雾中茶寮 v3」为例
+
+
+ + + + + + + + +
项目内容
许可范围商用(衍生作品可售,须保留署名;不可单独转售原始文件)
交付物世界文档 42 页 · 地图 PSD · 场景音效 12 段 · 更新至 v3.x
退契规则14 天内未下载可全额退款;下载后遵循许可,重大缺陷另行处理
价格构成¥28.00 = 创作者分润 ¥23.80(85%)+ 平台费 ¥4.20(15%)· 税按地区另计
地区可售当前地区可售 · 跨区价格与税务见结算页
+
+ + + 支付经 Idempotency-Key 幂等 · 重复点击不会重复扣款 +
+
+
+ +
+
结算创作者收益结算设置 →
+
+
可结算余额
¥1,240.50
+
本月分润
¥318.20
+
上次结算批次
09-10 · 已付 ¥986.30
+
+ + +
+
+

Ledger 不可变,修正写反向分录;每日自动对账(支付 / 订单 / Ledger / 结算四账核对)。

+
+ +
+
+
+ + + diff --git a/design/memory.html b/design/memory.html new file mode 100644 index 0000000..11ba9ea --- /dev/null +++ b/design/memory.html @@ -0,0 +1,242 @@ + + + + + +息壤 · 记忆与知识 — 魂镜 Hunjing + + + + + +
+ + +
+
+
息壤·记忆与知识
+
+ 静态原型 · 待审查 + +
+ +
+
+
+ + + + +
+ +
+ +
+ + + + + +
+ +
+ + 归真的约束:候选经你确认才会影响未来上下文;对话中的归真不自动写入所有长期记忆。境界内容只成世界知识候选,幻境内容须手动入忆并标注性质。 +
+ + +
+
+ 偏好 preference + 来源 · 镜树对话 m_91d0 · extractor v5 + 置信 0.92 · 敏感度低 · 青梧 +
+

「读书会隔周四 19:30 举行,每次 90 分钟。」

+
+ + + + 查看来源上下文 +
+
+ + +
+
+ 事实 fact + 大周天 · 第 7 轮提议 + 置信 0.71 · 敏感度低 · 青梧 +
+

「云舟在共读选篇时倾向短篇,超过 1500 字的篇目完成率明显下降。」

+

由 42 次小周天完成信号的回顾阶段产生 · 复用同一审核流 · 可追溯本轮输入

+
+ + + + 查看大周天第 7 轮 +
+
+ + +
+
+ 关系 relationship + 建议作重忆保存 + 置信 0.68 · 敏感度中 · 青梧 +
+

「云舟近期在工作日晚上更希望被倾听,而不是立刻获得建议。」

+

重忆 · 敏感或高影响记忆:归真后仅在明确允许时进入上下文,可随时正影纠正或归档,版本不可变。

+
+ + + + 查看来源上下文 +
+
+ + +
+
+ 最近归真已生效的明忆 + 全部 128 条 · 见下方列表 +
+
+
+ 偏好 +
+
「云舟不喜长篇说教,笔记以要点为先。」
+
青梧 · v3(正影自 v2)· 来源:手动 · 有效期长期 · ETag 并发受控
+
+ + +
+
+ 事实 +
+
「3 月购入《陶庵梦忆》校注本(中华书局)。」
+
青梧 · v1 · 来源:对话 · 实录
+
+ + +
+
+ 事件 +
+
「读书会成立于 2024-03,成员 6 人。」
+
青梧 · v1 · 来源:世谱引用 · 删除将传播到向量与图投影
+
+ + +
+
+

MemoryVersion 不可变:纠正与取代都写新版本,旧版本保留可查;删除建墓碑且传播到索引、缓存与派生数据,墓碑不保存原文。

+
+ + +
+
+ 玄络关系图谱投影 · 可重建 + 玄络 · 可交互图谱在 React 阶段实现 +
+
+ + + + + + + + + 云舟 + + 青梧 + + 雪袖 + + 读书会 + 世谱 + + 陶庵梦忆 + 世界知识 + 缘契 · 共读者 v4 + 缘契 · 茶友 v1 + 成员 · 发起人 + 正在共读 + 待验 + + +
+

玄络是可重建投影:删除与权限变化随宿主重建;跨用户、跨角色召回恒为 0(fail-closed 已验证)。

+
+
+
+
+ + + diff --git a/design/model-gateway.html b/design/model-gateway.html new file mode 100644 index 0000000..59d5350 --- /dev/null +++ b/design/model-gateway.html @@ -0,0 +1,124 @@ + + + + + +神识阁 · 模型与路由 — 魂镜 Hunjing + + + + +
+ +
+
+
神识阁·模型与路由
+
+ 静态原型 · 待审查 + +
+
+ +
+ + 神识是角色的可替换推理能力,不等于角色身份或意识证明。首个可见输出后不切换 Provider;引擎缺失时拒绝执行(fail closed)。 +
+ +
+
逻辑模型能力目录全部 9 个 · 列表即目录
+
+
+
沉潜 · 深思可用
+
推理 · 128k 上下文 · 函数调用
+
¥12.00 / ¥48.00 每 1M token(入/出)
+
价格快照 v2026-09-01 · 2 个 Endpoint · 故障转移已配置
+
+
+
惊鸿 · 快速可用
+
轻量 · 32k · 视觉
+
¥1.60 / ¥6.40 每 1M token
+
会话临时选择的默认候选
+
+
+
丹青 · 图像降级中
+
文生图 / 图生图 · 角色一致性
+
¥0.24 / 张
+
主 Endpoint 限流 · 已切备用 · 新任务排队 ≤ 2 分钟
+
+
+
+ +
+
路由继承链上层不可被下层覆盖
+
+
① 平台硬边界
禁用模型与绝对上限,任何下层不可逾越
生效
+
② 平台目录
默认逻辑模型与价格快照
生效
+
③ 用户偏好 / BYOK
你的默认模型与自带密钥
生效
+
④ 角色覆写
青梧未设置覆写
未设置
+
⑤ 会话临时选择 当前生效
镜树「共读选篇」选择了 惊鸿 · 快速
生效 session
+
+
+ +
+
+
BYOK自带模型密钥
+
+ +
byok_a31f…(神思 Provider)
2026-08-12 添加 · 存于系统 Keychain · 不写配置与日志
+ +
+
+ +
byok_7c02…(图像 Provider)
2026-09-01 添加 · 仅丹青 · 图像使用
+ +
+

BYOK 调用按实际用量计费一次,不重复计费(ADR-021);凭据只经 Header 传递,永不转发至上游之外的日志。

+
+ +
+
本月用量9 月 1–15 日明细 · Run 级观测见司命台诊断
+ +
+ + + + + + + + + +
指标数值
Token(入/出)486k / 212k
Prompt Cache 命中31%
P95 TTFT1.4s
费用¥18.64
错误 / 重试2 / 1
未知 usage 记录null(不猜测)
+
+
+ +
+
+
+ + + diff --git a/design/plugins.html b/design/plugins.html new file mode 100644 index 0000000..11b81df --- /dev/null +++ b/design/plugins.html @@ -0,0 +1,115 @@ + + + + + +百工坊 · 插件与能力 — 魂镜 Hunjing + + + + +
+ +
+
+
百工坊·插件与能力生态
+
+ 静态原型 · 待审查 + +
+
+ +
+ + 购买不等于安装,安装不等于启用,启用不等于授予新增权限。安全内核(认证、审批、交易账、审计)不可插件化。 +
+ +
+
+ 沙箱隔离运行时 + Worker 运转中 sandbox:ok +
+

本地代码插件运行于独立进程容器;声明式 / 远程插件默认受限。无符合策略的隔离后端时拒绝执行,不回退宿主(fail closed)。

+
+ +
+
已安装4 个
+
+
+ Core +
系统日历 bundled · 主进程
仅 Core 插件可进主进程 · 权限:日历读写(每次请命)
+ +
+
+ 声明式 +
笔记同步 受限运行时
权限:笔记库 /读书会/ 读写 · 网络:无
+ +
+
+ 待更新 +
性灵检索 远程 API
v1.2 → v1.3 · 新增权限需重新确认(见下方)
+ +
+
+ 本地代码 +
代码执行沙箱 独立容器 · 部署者信任
Run 固定插件快照 · 活动运行不热替换
+ +
+
+
+ +
+
升级确认性灵检索 v1.3 新增权限
+
+
+ +
+
请命升级新增权限必须重新确认
+
不确认则保留 v1.2,不影响现有使用
+
+
+
+
现有 v1.2读取笔记元数据 · 网络 api.xingling.app(只读)
+
新增 v1.3写入笔记内容 · 网络 api.xingling.app(读写)· 存储最近 20 条查询
+
费用免费插件 · 每次外部检索计费 ¥0.02
+
撤架安全撤架阻断新调用,保留历史审计
+
+
+ + + 工契 · 插件清单完整权限对比见详情。 +
+
+
+ +
+
授契能力授予记录司命台完整审计 →
+
+
日历写入 · 青梧
用途:共读事件 · 范围:仅指定事件 · 期限:单次 · 可随时撤销
+
笔记库读写 · 青梧
行契 · 30 天内同类免请命 · 剩余 12 天 · 超限后重新请命
+
网络检索 · 任务 Agent
用途:资料校对 · 白名单 3 域 · 期限:本 Run
随 Run 结束失效
+
+
+ +
+
+
+ + + diff --git a/design/register.html b/design/register.html new file mode 100644 index 0000000..68ae78b --- /dev/null +++ b/design/register.html @@ -0,0 +1,108 @@ + + + + + +魂镜 · 创建账户 + + + + + +
+ + +
+ ← 返回登录 + 静态原型 · 待审查 + + 原型目录 + +
+ +
+
+
+ +
+
魂镜
+
Hunjing
+
+
+
+

创建账户

+
+

化名与法定身份分离核验;随时可导出、撤权或删除

+ +
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+ + +
+ +
+
开始前请知悉(数据权):
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + 创建账户 +
+ + + +
+
+
+ + + diff --git a/design/settings.html b/design/settings.html new file mode 100644 index 0000000..78101ec --- /dev/null +++ b/design/settings.html @@ -0,0 +1,121 @@ + + + + + +设置 · 账户与偏好 — 魂镜 Hunjing + + + + +
+ +
+
+
设置·账户与偏好
+
+ 静态原型 · 待审查 + +
+
+ +
+
账户
+
+ 舟 +
+
云舟前台化名 · 与法定身份分离核验
+
yunzhou@example.com · OAuth 2.1 · Web 安全会话
+
+
+ + +
+
+
+ +
+
会话
+
+ +
MacBook Pro · Tauri 桌面
PKCE 登录 · 当前会话
+ 当前 +
+
+ +
iPhone · 移动端
PKCE 登录 · 昨天活跃
+ +
+
+ +
+
私箧独立持钥的加密私密区已启用 locked
+
+ +
平台仅存密文,不可恢复
账户恢复、管理员与诊断均不可读取;恢复钥匙只在你手中,丢失即永久不可恢复。
+
+
+ +
使用量 12 MB
日记 41 篇 · 手记 7 份 · 不参与任何推荐与训练
+ +
+
+ +
+
数据权访问 · 纠正 · 导出 · 撤权 · 删除
+
+
+
模型训练贡献
+
Personal Domain 数据默认不用于模型训练。自愿贡献需独立、明确、可随时撤销的同意。
+
+ +
+
+
导出全部数据
角色、设定、记忆、对话、资产与来源谱系 · 魂籍可携格式
+ +
+
+
撤回全部授权
撤销插件、设备与第三方访问授权,数据保留
+ +
+
+
删除账户与全部数据
不可逆 · 有冷静期 · 与角色死亡是两个独立操作 · 删除传播到索引与派生数据
+ +
+
+ +
+
偏好
+
界面主题
墨(深色)/ 月白(浅色)· 跟随系统
+
界面语言
简体中文 · 文化名始终附带直白解释
+
界面直白解释
关闭后仅在高风险界面显示直白解释(不建议)
+
+ +
+
封镜账户暂时停用 · 不是角色静修、归藏或死亡
+

封镜期间登录被冻结,角色进入静修,数据完整保留;解封后可复照重开。

+ +
+ +
+
+
+ + + diff --git a/frontend/next-env.d.ts b/frontend/next-env.d.ts new file mode 100644 index 0000000..830fb59 --- /dev/null +++ b/frontend/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/frontend/next.config.ts b/frontend/next.config.ts index 2f6491c..26c728a 100644 --- a/frontend/next.config.ts +++ b/frontend/next.config.ts @@ -2,6 +2,15 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { reactStrictMode: true, + // 同源代理:前端 /api/* → 本地后端(避免开发档 CORS;生产由反向代理承担同职责) + async rewrites() { + return [ + { + source: "/api/:path*", + destination: `${process.env.HUNJING_API_URL ?? "http://127.0.0.1:8000"}/:path*`, + }, + ]; + }, }; export default nextConfig; diff --git a/frontend/package-lock.json b/frontend/package-lock.json deleted file mode 100644 index 6426447..0000000 --- a/frontend/package-lock.json +++ /dev/null @@ -1,1421 +0,0 @@ -{ - "name": "hunjing-frontend", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "hunjing-frontend", - "version": "0.1.0", - "dependencies": { - "next": "^15.1.0", - "react": "^19.0.0", - "react-dom": "^19.0.0" - }, - "devDependencies": { - "@types/node": "^22.10.0", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", - "openapi-typescript": "^7.5.0", - "typescript": "^5.7.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", - "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.29.7", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", - "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", - "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@img/colour": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", - "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", - "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.3.3" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", - "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.3.3" - } - }, - "node_modules/@img/sharp-freebsd-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", - "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", - "license": "Apache-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "dependencies": { - "@img/sharp-wasm32": "0.35.4" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", - "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", - "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", - "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", - "cpu": [ - "arm" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", - "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", - "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", - "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", - "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", - "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", - "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", - "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", - "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", - "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", - "cpu": [ - "arm" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", - "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", - "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", - "cpu": [ - "ppc64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", - "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", - "cpu": [ - "riscv64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", - "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", - "cpu": [ - "s390x" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", - "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.3.3" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", - "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", - "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.3.3" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", - "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.11.3" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-webcontainers-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", - "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@img/sharp-wasm32": "0.35.4" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", - "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", - "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", - "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@next/env": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.25.tgz", - "integrity": "sha512-42h1lLr07vl4gawALP1hsgRZjHB1xYa58JfUfHwr0f7jG/zhPakh5GHkADHXOC9ZxUvlQFOPIrp7s6qX4DezPQ==", - "license": "MIT" - }, - "node_modules/@next/swc-darwin-arm64": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.25.tgz", - "integrity": "sha512-w+RR0v/QuApnWEjRGm1z6gcObKwGMb5YPA7V3bzBEVSBpMFUXprer0tS27UxjUcEnqbhL7Zuzohej79B6rYmBg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.25.tgz", - "integrity": "sha512-QiGGBUSakt8S1H4Lt9Ehsh6Ja87axiBnQQgysOObvCbI7iUfJnRGntF1P64S4/ijuHFnSB8KLsEddkY3nN26uw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.25.tgz", - "integrity": "sha512-ehLos/66zo0d/mJCU5u96a/VDcr01aaUrX0o/i16UdInxz8qPTCDSxGtjk/Lps1sIr1RJFdiX3hxc0fxJo+cPA==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.25.tgz", - "integrity": "sha512-ZVMrqLiJ7DiChgmbkQwFtdhAnUkSH/4p7tB29QY+giATb0Q/XGHNRSKAb/B8XGDHRUaA67NepOW5W8u3ZRJBAA==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.25.tgz", - "integrity": "sha512-UOewtDGkTMJTiODrEdeLZ50yGb59xCZSriNpXkfPMxRRgwDkGc7i8mLWqV5076wEdb+Ca/XN7MhJyM3CupyNyQ==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.25.tgz", - "integrity": "sha512-UBHwA8AhkCZgtRfU1aJpunuAJe/6gZv6jDESQe4p5MjTb5V0YEeJBWCdNqx15Vj3x+5jmauRfeMJSjfQj9HGFQ==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.25.tgz", - "integrity": "sha512-QcFcPRr16djk5IqK5+e8O80eZfgWzIvVBXfitIq0tQ/uc+eyfdoZ0NmKc0cnbIJyfVwREapKuG97YcxWA9gcpA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.25.tgz", - "integrity": "sha512-zREeykps3ndWr9egJgvJKqVkkDuaw6Zrrg23cYBos0ygydFkAWYU4+PaPVwXzP1eAYQJe53ShSK45iDM529BOg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@redocly/ajv": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js-replace": "^1.0.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@redocly/config": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.22.0.tgz", - "integrity": "sha512-gAy93Ddo01Z3bHuVdPWfCwzgfaYgMdaZPcfL7JZ7hWJoK9V0lXDbigTWkhiPFAaLWzbOJ+kbUQG1+XwIm0KRGQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@redocly/openapi-core": { - "version": "1.34.19", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.34.19.tgz", - "integrity": "sha512-o/0VgsBXgwcY1lyeqcVtSGdTQAPnVggo0fbFVPlxl5XVDKUcVH0OLRqt3CbkwByT5FU305E0iE0O7MzThjDblw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@redocly/ajv": "8.11.2", - "@redocly/config": "0.22.0", - "colorette": "1.4.0", - "https-proxy-agent": "7.0.6", - "js-levenshtein": "1.1.6", - "js-yaml": "4.3.1", - "minimatch": "5.1.9", - "pluralize": "8.0.0", - "yaml-ast-parser": "0.0.43" - }, - "engines": { - "node": ">=18.17.0", - "npm": ">=9.5.0" - } - }, - "node_modules/@swc/helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@types/node": { - "version": "22.20.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", - "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/react": { - "version": "19.2.18", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.18.tgz", - "integrity": "sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.7.tgz", - "integrity": "sha512-I8bPpDLcHBv1qiIiXDCy71Rt8eQDKJP0sMSWJphDdAcdqiJ1sGpZamavoEIRZmYzjia9LuEb2HlYdDpmoENpvQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", - "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", - "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/change-case": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", - "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/client-only": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/index-to-position": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", - "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/minimatch": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.18", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", - "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/next": { - "version": "15.5.25", - "resolved": "https://registry.npmjs.org/next/-/next-15.5.25.tgz", - "integrity": "sha512-OMWNulIIqKM2ykvC2qMjIt0IoavB4UB2SCs4iXJ6z6847FvyH8jBmBWcvrF5iuhTu8Przh20Fo/aoszIdqx4PA==", - "license": "MIT", - "dependencies": { - "@next/env": "15.5.25", - "@swc/helpers": "0.5.15", - "caniuse-lite": "^1.0.30001579", - "postcss": "8.4.31", - "styled-jsx": "5.1.6" - }, - "bin": { - "next": "dist/bin/next" - }, - "engines": { - "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" - }, - "optionalDependencies": { - "@next/swc-darwin-arm64": "15.5.25", - "@next/swc-darwin-x64": "15.5.25", - "@next/swc-linux-arm64-gnu": "15.5.25", - "@next/swc-linux-arm64-musl": "15.5.25", - "@next/swc-linux-x64-gnu": "15.5.25", - "@next/swc-linux-x64-musl": "15.5.25", - "@next/swc-win32-arm64-msvc": "15.5.25", - "@next/swc-win32-x64-msvc": "15.5.25", - "sharp": "^0.34.3 || ^0.35.4" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.1.0", - "@playwright/test": "^1.51.1", - "babel-plugin-react-compiler": "*", - "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", - "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@playwright/test": { - "optional": true - }, - "babel-plugin-react-compiler": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, - "node_modules/openapi-typescript": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-7.13.0.tgz", - "integrity": "sha512-EFP392gcqXS7ntPvbhBzbF8TyBA+baIYEm791Hy5YkjDYKTnk/Tn5OQeKm5BIZvJihpp8Zzr4hzx0Irde1LNGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@redocly/openapi-core": "^1.34.6", - "ansi-colors": "^4.1.3", - "change-case": "^5.4.4", - "parse-json": "^8.3.0", - "supports-color": "^10.2.2", - "yargs-parser": "^21.1.1" - }, - "bin": { - "openapi-typescript": "bin/cli.js" - }, - "peerDependencies": { - "typescript": "^5.x" - } - }, - "node_modules/parse-json": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", - "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.26.2", - "index-to-position": "^1.1.0", - "type-fest": "^4.39.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/react": { - "version": "19.2.8", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", - "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.2.8", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", - "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.27.0" - }, - "peerDependencies": { - "react": "^19.2.8" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", - "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@img/colour": "^1.1.0", - "detect-libc": "^2.1.2", - "semver": "^7.8.5" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.35.4", - "@img/sharp-darwin-x64": "0.35.4", - "@img/sharp-freebsd-wasm32": "0.35.4", - "@img/sharp-libvips-darwin-arm64": "1.3.3", - "@img/sharp-libvips-darwin-x64": "1.3.3", - "@img/sharp-libvips-linux-arm": "1.3.3", - "@img/sharp-libvips-linux-arm64": "1.3.3", - "@img/sharp-libvips-linux-ppc64": "1.3.3", - "@img/sharp-libvips-linux-riscv64": "1.3.3", - "@img/sharp-libvips-linux-s390x": "1.3.3", - "@img/sharp-libvips-linux-x64": "1.3.3", - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", - "@img/sharp-libvips-linuxmusl-x64": "1.3.3", - "@img/sharp-linux-arm": "0.35.4", - "@img/sharp-linux-arm64": "0.35.4", - "@img/sharp-linux-ppc64": "0.35.4", - "@img/sharp-linux-riscv64": "0.35.4", - "@img/sharp-linux-s390x": "0.35.4", - "@img/sharp-linux-x64": "0.35.4", - "@img/sharp-linuxmusl-arm64": "0.35.4", - "@img/sharp-linuxmusl-x64": "0.35.4", - "@img/sharp-webcontainers-wasm32": "0.35.4", - "@img/sharp-win32-arm64": "0.35.4", - "@img/sharp-win32-ia32": "0.35.4", - "@img/sharp-win32-x64": "0.35.4" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/styled-jsx": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", - "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", - "license": "MIT", - "dependencies": { - "client-only": "0.0.1" - }, - "engines": { - "node": ">= 12.0.0" - }, - "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/supports-color": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", - "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/uri-js-replace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz", - "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/yaml-ast-parser": { - "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", - "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - } - } -} diff --git a/frontend/package.json b/frontend/package.json index d7ede0c..247934b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,12 +2,15 @@ "name": "hunjing-frontend", "version": "0.1.0", "private": true, + "packageManager": "pnpm@11.21.0", "scripts": { "dev": "next dev", "build": "next build", "generate:api": "openapi-typescript ../openapi/openapi.yaml -o src/types/api.d.ts" }, "dependencies": { + "@tanstack/react-query": "^5.103.1", + "lucide-react": "^1.46.0", "next": "^15.1.0", "react": "^19.0.0", "react-dom": "^19.0.0" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml new file mode 100644 index 0000000..b1e927d --- /dev/null +++ b/frontend/pnpm-lock.yaml @@ -0,0 +1,887 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@tanstack/react-query': + specifier: ^5.103.1 + version: 5.103.1(react@19.2.8) + lucide-react: + specifier: ^1.46.0 + version: 1.46.0(react@19.2.8) + next: + specifier: ^15.1.0 + version: 15.5.25(@types/node@22.20.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: + specifier: ^19.0.0 + version: 19.2.8 + react-dom: + specifier: ^19.0.0 + version: 19.2.8(react@19.2.8) + devDependencies: + '@types/node': + specifier: ^22.10.0 + version: 22.20.1 + '@types/react': + specifier: ^19.0.0 + version: 19.2.18 + '@types/react-dom': + specifier: ^19.0.0 + version: 19.2.7(@types/react@19.2.18) + openapi-typescript: + specifier: ^7.5.0 + version: 7.13.0(typescript@5.9.3) + typescript: + specifier: ^5.7.0 + version: 5.9.3 + +packages: + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.35.4': + resolution: {integrity: sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.35.4': + resolution: {integrity: sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-freebsd-wasm32@0.35.4': + resolution: {integrity: sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==} + engines: {node: '>=20.9.0'} + os: [freebsd] + + '@img/sharp-libvips-darwin-arm64@1.3.3': + resolution: {integrity: sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.3.3': + resolution: {integrity: sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.3.3': + resolution: {integrity: sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.3.3': + resolution: {integrity: sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.3.3': + resolution: {integrity: sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.3.3': + resolution: {integrity: sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.3.3': + resolution: {integrity: sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.3.3': + resolution: {integrity: sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.3.3': + resolution: {integrity: sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.3.3': + resolution: {integrity: sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.35.4': + resolution: {integrity: sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.35.4': + resolution: {integrity: sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.35.4': + resolution: {integrity: sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.35.4': + resolution: {integrity: sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.35.4': + resolution: {integrity: sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.35.4': + resolution: {integrity: sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.35.4': + resolution: {integrity: sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.35.4': + resolution: {integrity: sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.35.4': + resolution: {integrity: sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==} + engines: {node: '>=20.9.0'} + + '@img/sharp-webcontainers-wasm32@0.35.4': + resolution: {integrity: sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.35.4': + resolution: {integrity: sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.35.4': + resolution: {integrity: sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.35.4': + resolution: {integrity: sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] + + '@next/env@15.5.25': + resolution: {integrity: sha512-42h1lLr07vl4gawALP1hsgRZjHB1xYa58JfUfHwr0f7jG/zhPakh5GHkADHXOC9ZxUvlQFOPIrp7s6qX4DezPQ==} + + '@next/swc-darwin-arm64@15.5.25': + resolution: {integrity: sha512-w+RR0v/QuApnWEjRGm1z6gcObKwGMb5YPA7V3bzBEVSBpMFUXprer0tS27UxjUcEnqbhL7Zuzohej79B6rYmBg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.5.25': + resolution: {integrity: sha512-QiGGBUSakt8S1H4Lt9Ehsh6Ja87axiBnQQgysOObvCbI7iUfJnRGntF1P64S4/ijuHFnSB8KLsEddkY3nN26uw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.5.25': + resolution: {integrity: sha512-ehLos/66zo0d/mJCU5u96a/VDcr01aaUrX0o/i16UdInxz8qPTCDSxGtjk/Lps1sIr1RJFdiX3hxc0fxJo+cPA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@next/swc-linux-arm64-musl@15.5.25': + resolution: {integrity: sha512-ZVMrqLiJ7DiChgmbkQwFtdhAnUkSH/4p7tB29QY+giATb0Q/XGHNRSKAb/B8XGDHRUaA67NepOW5W8u3ZRJBAA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@next/swc-linux-x64-gnu@15.5.25': + resolution: {integrity: sha512-UOewtDGkTMJTiODrEdeLZ50yGb59xCZSriNpXkfPMxRRgwDkGc7i8mLWqV5076wEdb+Ca/XN7MhJyM3CupyNyQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@next/swc-linux-x64-musl@15.5.25': + resolution: {integrity: sha512-UBHwA8AhkCZgtRfU1aJpunuAJe/6gZv6jDESQe4p5MjTb5V0YEeJBWCdNqx15Vj3x+5jmauRfeMJSjfQj9HGFQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@next/swc-win32-arm64-msvc@15.5.25': + resolution: {integrity: sha512-QcFcPRr16djk5IqK5+e8O80eZfgWzIvVBXfitIq0tQ/uc+eyfdoZ0NmKc0cnbIJyfVwREapKuG97YcxWA9gcpA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.5.25': + resolution: {integrity: sha512-zREeykps3ndWr9egJgvJKqVkkDuaw6Zrrg23cYBos0ygydFkAWYU4+PaPVwXzP1eAYQJe53ShSK45iDM529BOg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@redocly/ajv@8.11.2': + resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==} + + '@redocly/config@0.22.0': + resolution: {integrity: sha512-gAy93Ddo01Z3bHuVdPWfCwzgfaYgMdaZPcfL7JZ7hWJoK9V0lXDbigTWkhiPFAaLWzbOJ+kbUQG1+XwIm0KRGQ==} + + '@redocly/openapi-core@1.34.19': + resolution: {integrity: sha512-o/0VgsBXgwcY1lyeqcVtSGdTQAPnVggo0fbFVPlxl5XVDKUcVH0OLRqt3CbkwByT5FU305E0iE0O7MzThjDblw==} + engines: {node: '>=18.17.0', npm: '>=9.5.0'} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tanstack/query-core@5.103.1': + resolution: {integrity: sha512-rms8HqTGp6zA00dM+cUQ2eBcgzNJefuu5CAMB37i/6MiGT1zulPOytCFu2a0qjLqVR2n1jENPj9woqFQNuCzWA==} + + '@tanstack/react-query@5.103.1': + resolution: {integrity: sha512-rmAPPApNEK17VXRJhtE1rja53n23VV5w30C0saCgJhhX+EpdUnVqMGV/s5nnzV43X75KTHKzuoiuxSzGTBIkag==} + peerDependencies: + react: ^18 || ^19 + + '@types/node@22.20.1': + resolution: {integrity: sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==} + + '@types/react-dom@19.2.7': + resolution: {integrity: sha512-I8bPpDLcHBv1qiIiXDCy71Rt8eQDKJP0sMSWJphDdAcdqiJ1sGpZamavoEIRZmYzjia9LuEb2HlYdDpmoENpvQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.18': + resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@2.1.4: + resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==} + + caniuse-lite@1.0.30001810: + resolution: {integrity: sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + colorette@1.4.0: + resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} + engines: {node: '>=18'} + + js-levenshtein@1.1.6: + resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} + engines: {node: '>=0.10.0'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.3.1: + resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} + hasBin: true + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + lucide-react@1.46.0: + resolution: {integrity: sha512-Bv+FZXgZPrxc/NCl1e7JJVQFLdiCxYgxNVhqoV7X0p6I8ADJo8DxBnK1auH0fZz4AmqOJ3jgneL4f1i8LJQRAA==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + next@15.5.25: + resolution: {integrity: sha512-OMWNulIIqKM2ykvC2qMjIt0IoavB4UB2SCs4iXJ6z6847FvyH8jBmBWcvrF5iuhTu8Przh20Fo/aoszIdqx4PA==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + openapi-typescript@7.13.0: + resolution: {integrity: sha512-EFP392gcqXS7ntPvbhBzbF8TyBA+baIYEm791Hy5YkjDYKTnk/Tn5OQeKm5BIZvJihpp8Zzr4hzx0Irde1LNGQ==} + hasBin: true + peerDependencies: + typescript: ^5.x + + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + react-dom@19.2.8: + resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==} + peerDependencies: + react: ^19.2.8 + + react@19.2.8: + resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.35.4: + resolution: {integrity: sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==} + engines: {node: '>=20.9.0'} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + uri-js-replace@1.0.1: + resolution: {integrity: sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==} + + yaml-ast-parser@0.0.43: + resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + +snapshots: + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.29.7': {} + + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.35.4': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.3 + optional: true + + '@img/sharp-darwin-x64@0.35.4': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.3 + optional: true + + '@img/sharp-freebsd-wasm32@0.35.4': + dependencies: + '@img/sharp-wasm32': 0.35.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.3.3': + optional: true + + '@img/sharp-libvips-darwin-x64@1.3.3': + optional: true + + '@img/sharp-libvips-linux-arm64@1.3.3': + optional: true + + '@img/sharp-libvips-linux-arm@1.3.3': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.3.3': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.3.3': + optional: true + + '@img/sharp-libvips-linux-s390x@1.3.3': + optional: true + + '@img/sharp-libvips-linux-x64@1.3.3': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.3.3': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.3.3': + optional: true + + '@img/sharp-linux-arm64@0.35.4': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.3 + optional: true + + '@img/sharp-linux-arm@0.35.4': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.3 + optional: true + + '@img/sharp-linux-ppc64@0.35.4': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.3 + optional: true + + '@img/sharp-linux-riscv64@0.35.4': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.3 + optional: true + + '@img/sharp-linux-s390x@0.35.4': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.3 + optional: true + + '@img/sharp-linux-x64@0.35.4': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.3 + optional: true + + '@img/sharp-linuxmusl-arm64@0.35.4': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.3 + optional: true + + '@img/sharp-linuxmusl-x64@0.35.4': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.3 + optional: true + + '@img/sharp-wasm32@0.35.4': + dependencies: + '@emnapi/runtime': 1.11.3 + optional: true + + '@img/sharp-webcontainers-wasm32@0.35.4': + dependencies: + '@img/sharp-wasm32': 0.35.4 + optional: true + + '@img/sharp-win32-arm64@0.35.4': + optional: true + + '@img/sharp-win32-ia32@0.35.4': + optional: true + + '@img/sharp-win32-x64@0.35.4': + optional: true + + '@next/env@15.5.25': {} + + '@next/swc-darwin-arm64@15.5.25': + optional: true + + '@next/swc-darwin-x64@15.5.25': + optional: true + + '@next/swc-linux-arm64-gnu@15.5.25': + optional: true + + '@next/swc-linux-arm64-musl@15.5.25': + optional: true + + '@next/swc-linux-x64-gnu@15.5.25': + optional: true + + '@next/swc-linux-x64-musl@15.5.25': + optional: true + + '@next/swc-win32-arm64-msvc@15.5.25': + optional: true + + '@next/swc-win32-x64-msvc@15.5.25': + optional: true + + '@redocly/ajv@8.11.2': + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js-replace: 1.0.1 + + '@redocly/config@0.22.0': {} + + '@redocly/openapi-core@1.34.19(supports-color@10.2.2)': + dependencies: + '@redocly/ajv': 8.11.2 + '@redocly/config': 0.22.0 + colorette: 1.4.0 + https-proxy-agent: 7.0.6(supports-color@10.2.2) + js-levenshtein: 1.1.6 + js-yaml: 4.3.1 + minimatch: 5.1.9 + pluralize: 8.0.0 + yaml-ast-parser: 0.0.43 + transitivePeerDependencies: + - supports-color + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@tanstack/query-core@5.103.1': {} + + '@tanstack/react-query@5.103.1(react@19.2.8)': + dependencies: + '@tanstack/query-core': 5.103.1 + react: 19.2.8 + + '@types/node@22.20.1': + dependencies: + undici-types: 6.21.0 + + '@types/react-dom@19.2.7(@types/react@19.2.18)': + dependencies: + '@types/react': 19.2.18 + + '@types/react@19.2.18': + dependencies: + csstype: 3.2.3 + + agent-base@7.1.4: {} + + ansi-colors@4.1.3: {} + + argparse@2.0.1: {} + + balanced-match@1.0.2: {} + + brace-expansion@2.1.4: + dependencies: + balanced-match: 1.0.2 + + caniuse-lite@1.0.30001810: {} + + change-case@5.4.4: {} + + client-only@0.0.1: {} + + colorette@1.4.0: {} + + csstype@3.2.3: {} + + debug@4.4.3(supports-color@10.2.2): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 10.2.2 + + detect-libc@2.1.2: + optional: true + + fast-deep-equal@3.1.3: {} + + https-proxy-agent@7.0.6(supports-color@10.2.2): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + index-to-position@1.2.0: {} + + js-levenshtein@1.1.6: {} + + js-tokens@4.0.0: {} + + js-yaml@4.3.1: + dependencies: + argparse: 2.0.1 + + json-schema-traverse@1.0.0: {} + + lucide-react@1.46.0(react@19.2.8): + dependencies: + react: 19.2.8 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.1.4 + + ms@2.1.3: {} + + nanoid@3.3.18: {} + + next@15.5.25(@types/node@22.20.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + dependencies: + '@next/env': 15.5.25 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001810 + postcss: 8.4.31 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + styled-jsx: 5.1.6(react@19.2.8) + optionalDependencies: + '@next/swc-darwin-arm64': 15.5.25 + '@next/swc-darwin-x64': 15.5.25 + '@next/swc-linux-arm64-gnu': 15.5.25 + '@next/swc-linux-arm64-musl': 15.5.25 + '@next/swc-linux-x64-gnu': 15.5.25 + '@next/swc-linux-x64-musl': 15.5.25 + '@next/swc-win32-arm64-msvc': 15.5.25 + '@next/swc-win32-x64-msvc': 15.5.25 + sharp: 0.35.4(@types/node@22.20.1) + transitivePeerDependencies: + - '@babel/core' + - '@types/node' + - babel-plugin-macros + + openapi-typescript@7.13.0(typescript@5.9.3): + dependencies: + '@redocly/openapi-core': 1.34.19(supports-color@10.2.2) + ansi-colors: 4.1.3 + change-case: 5.4.4 + parse-json: 8.3.0 + supports-color: 10.2.2 + typescript: 5.9.3 + yargs-parser: 21.1.1 + + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.29.7 + index-to-position: 1.2.0 + type-fest: 4.41.0 + + picocolors@1.1.1: {} + + pluralize@8.0.0: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.18 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + react-dom@19.2.8(react@19.2.8): + dependencies: + react: 19.2.8 + scheduler: 0.27.0 + + react@19.2.8: {} + + require-from-string@2.0.2: {} + + scheduler@0.27.0: {} + + semver@7.8.5: + optional: true + + sharp@0.35.4(@types/node@22.20.1): + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.4 + '@img/sharp-darwin-x64': 0.35.4 + '@img/sharp-freebsd-wasm32': 0.35.4 + '@img/sharp-libvips-darwin-arm64': 1.3.3 + '@img/sharp-libvips-darwin-x64': 1.3.3 + '@img/sharp-libvips-linux-arm': 1.3.3 + '@img/sharp-libvips-linux-arm64': 1.3.3 + '@img/sharp-libvips-linux-ppc64': 1.3.3 + '@img/sharp-libvips-linux-riscv64': 1.3.3 + '@img/sharp-libvips-linux-s390x': 1.3.3 + '@img/sharp-libvips-linux-x64': 1.3.3 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.3 + '@img/sharp-libvips-linuxmusl-x64': 1.3.3 + '@img/sharp-linux-arm': 0.35.4 + '@img/sharp-linux-arm64': 0.35.4 + '@img/sharp-linux-ppc64': 0.35.4 + '@img/sharp-linux-riscv64': 0.35.4 + '@img/sharp-linux-s390x': 0.35.4 + '@img/sharp-linux-x64': 0.35.4 + '@img/sharp-linuxmusl-arm64': 0.35.4 + '@img/sharp-linuxmusl-x64': 0.35.4 + '@img/sharp-webcontainers-wasm32': 0.35.4 + '@img/sharp-win32-arm64': 0.35.4 + '@img/sharp-win32-ia32': 0.35.4 + '@img/sharp-win32-x64': 0.35.4 + '@types/node': 22.20.1 + optional: true + + source-map-js@1.2.1: {} + + styled-jsx@5.1.6(react@19.2.8): + dependencies: + client-only: 0.0.1 + react: 19.2.8 + + supports-color@10.2.2: {} + + tslib@2.8.1: {} + + type-fest@4.41.0: {} + + typescript@5.9.3: {} + + undici-types@6.21.0: {} + + uri-js-replace@1.0.1: {} + + yaml-ast-parser@0.0.43: {} + + yargs-parser@21.1.1: {} diff --git a/frontend/src/app/(app)/agent-workspace/page.tsx b/frontend/src/app/(app)/agent-workspace/page.tsx new file mode 100644 index 0000000..89dcd5b --- /dev/null +++ b/frontend/src/app/(app)/agent-workspace/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { RunsPanel } from "@/components/panels"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/avatar/page.tsx b/frontend/src/app/(app)/avatar/page.tsx new file mode 100644 index 0000000..795d9f4 --- /dev/null +++ b/frontend/src/app/(app)/avatar/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { AvatarPanel } from "@/components/panels"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/characters/page.tsx b/frontend/src/app/(app)/characters/page.tsx new file mode 100644 index 0000000..b17438c --- /dev/null +++ b/frontend/src/app/(app)/characters/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { CharactersPagePanel } from "@/components/characters/CharactersPagePanel"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/collaboration/page.tsx b/frontend/src/app/(app)/collaboration/page.tsx new file mode 100644 index 0000000..f933f47 --- /dev/null +++ b/frontend/src/app/(app)/collaboration/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { CollaborationPanel } from "@/components/collaboration/CollaborationPanel"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/community/page.tsx b/frontend/src/app/(app)/community/page.tsx new file mode 100644 index 0000000..8a4c0d5 --- /dev/null +++ b/frontend/src/app/(app)/community/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { CommunityPanel } from "@/components/community/CommunityPanel"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/conversation/page.tsx b/frontend/src/app/(app)/conversation/page.tsx new file mode 100644 index 0000000..f397821 --- /dev/null +++ b/frontend/src/app/(app)/conversation/page.tsx @@ -0,0 +1,22 @@ +"use client"; + +import { ThemeButton } from "@/lib/theme"; +import { ConversationPanel } from "@/components/conversation/ConversationPanel"; + +export default function Page() { + return ( + <> +
+
+ 镜树 + / + 分支对话 +
+
+ 真实接口 · 联调中 + +
+ + + ); +} diff --git a/frontend/src/app/(app)/devices/page.tsx b/frontend/src/app/(app)/devices/page.tsx new file mode 100644 index 0000000..f17ba3b --- /dev/null +++ b/frontend/src/app/(app)/devices/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { DevicesPanel } from "@/components/panels"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/governance/page.tsx b/frontend/src/app/(app)/governance/page.tsx new file mode 100644 index 0000000..80cf8a3 --- /dev/null +++ b/frontend/src/app/(app)/governance/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { GovernancePanel } from "@/components/panels"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/home/page.tsx b/frontend/src/app/(app)/home/page.tsx new file mode 100644 index 0000000..bfc3334 --- /dev/null +++ b/frontend/src/app/(app)/home/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { HomePanel } from "@/components/panels"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/layout.tsx b/frontend/src/app/(app)/layout.tsx new file mode 100644 index 0000000..95b5b8f --- /dev/null +++ b/frontend/src/app/(app)/layout.tsx @@ -0,0 +1,6 @@ +import { AppShell } from "@/components/shell/AppShell"; + +/** 用户侧 14 域 + 设计说明共用应用外壳 */ +export default function AppLayout({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/frontend/src/app/(app)/marketplace/page.tsx b/frontend/src/app/(app)/marketplace/page.tsx new file mode 100644 index 0000000..d672a2f --- /dev/null +++ b/frontend/src/app/(app)/marketplace/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { MarketplacePanel } from "@/components/marketplace/MarketplacePanel"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/memory/page.tsx b/frontend/src/app/(app)/memory/page.tsx new file mode 100644 index 0000000..c335efe --- /dev/null +++ b/frontend/src/app/(app)/memory/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { MemoryPanel } from "@/components/memory/MemoryPanel"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/model-gateway/page.tsx b/frontend/src/app/(app)/model-gateway/page.tsx new file mode 100644 index 0000000..06d641a --- /dev/null +++ b/frontend/src/app/(app)/model-gateway/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { GatewayPanel } from "@/components/panels"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/page.tsx b/frontend/src/app/(app)/page.tsx new file mode 100644 index 0000000..779985b --- /dev/null +++ b/frontend/src/app/(app)/page.tsx @@ -0,0 +1,187 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; + + +export default function Page() { + return ( + <> + } /> +
+ +
+

魂镜 原型 v0.2

+

魂镜 Web 界面静态 HTML 原型(v0.1 第一批方向已确认,v0.2 增补第二批共 15 个界面),供审查视觉方向、布局结构与文化语言的界面落地方式。全部确认后按此实现为 React 组件;未在本文档登记的视觉细节以本页令牌为准。

+
+ +
+

原型页面

+

第一批(已确认):镜庭、镜生、镜树;第二批:息壤、形仪、天工阁、神识阁、百工坊、雅集、同契台、云市、器谱、司命台、设置,及运营者/自托管使用的管理面与认证页。全站链接已疏通:跨页指向对应页面、页内为锚点;logo 单击回本目录,350ms 内连点 5 次触发「镜启」彩蛋(承接 main 分支旧版设计);侧栏可折叠并记忆偏好。

+
+ 镜庭个人首页全局框架、角色入口、任务与待审事项home.html + 镜树分支对话ContentBlock、请命朱批、界域、候答、流式芽体、分支树conversation.html + 镜生角色身份道体、缘契、内驱力、大周天、谱系、生命周期characters.html + 息壤记忆与知识候选审阅、正影纠正、明忆版本、玄络投影memory.html + 形仪形象与资产真形锚、主仪化仪、声音、Live2D 与 3D、易相历史avatar.html + 天工阁Agent 任务工筹计划、预算、分工使、轨迹、验收agent-workspace.html + 神识阁模型与路由逻辑模型、路由继承链、BYOK、用量观测model-gateway.html + 百工坊插件生态沙箱、已安装、升级权限确认、授契记录plugins.html + 雅集社区广场动态流、角色谱、话题、推荐解释与重置community.html + 同契台协作空间分支版本、审稿合卷、成员权限矩阵、活动collaboration.html + 云市创作市场商品、市契许可、退契规则、分润结算marketplace.html + 器谱设备与感知形器登记、授契、通感会话、直白权限请求devices.html + 司命台安全与治理治理队列、诊断双重授权、审计、安全概览governance.html + 管理面运营与部署后台司议队列、支持工单与脱敏支持包、权限管理(RBAC / 双人授权)、部署健康(灵台双形态)、SLOadmin.html + 登录铜镜鉴心铭文环镜背、扫描亮带、会话 Cookie / PKCE 说明、通行密钥与恢复钥匙login.html + 注册创建账户邮箱验证码、数据权告知(默认不训练 / 可导出删除 / 私箧持钥)、条款确认register.html + 设置账户与偏好会话、私箧、数据权、删除、封镜settings.html +
+
+ +
+

设计立场

+

四条约束所有页面的决定,审查时优先核对这四条是否成立。

+
+
一 · 双层文字系统 —— 文化名用衬线宋体,直白解释用无衬线小字,两种字体本身就是"文化名 · 直白解释"两层结构的可视化;风险、金额、权限、删除等后果始终以直白语言为主,文化名只作辅助。
+
二 · 朱砂只属于朱批 —— 朱砂色是"用户确认决定"的专用语义色:请命卡的允许按钮、危险动作入口使用它;普通操作一律铜镜青。颜色即权限语言。
+
三 · 墨与月白 —— 深色为墨(青调黑,非纯黑),浅色为月白(青灰白,非暖米);铜镜青为主色,取铜镜铜绿之意,不用蓝紫系默认色。
+
四 · 状态永远三段式 —— 状态徽章固定为「文化状态 · 直白状态 + 稳定工程值」,例如「运转 · 运行中 running」;错误与交易状态绝不只显示文化名。
+
+
+ +
+

色彩令牌

+

右下角可切换主题;以下色板随主题联动。转 React 时这些令牌进入 Tailwind 配置 / CSS 变量。

+
+
底 · 墨 / 月白表面层级 0--bg
+
浮面卡片与气泡--bg-raised
+
铜镜青主色 · 选中/链接/运转--accent
+
朱砂朱批 · 确认与危险--cinnabar
+
已成完成态--ok
+
秋香整备 / 幻境--warn
+
受阻失败态--err
+
正文一级文字--text-1
+
+
+ +
+

字体规范

+

不引入外部字体文件,使用系统中文字体栈;转 React 时同栈迁移。

+
+
文化名 · 宋体衬线镜树 · 分支对话
+
界面正文 · 无衬线正文 14px / 行高 1.65,辅助文字 12.5px,元信息 11.5px
+
稳定值 · 等宽running · m_01h8xq… · block_id: blk_7f3a
+
+
+ +
+

状态徽章全集

+

对应 docs/product/cultural-language.md 第 10 节;徽章三段:文化状态 · 直白状态 · 稳定值。

+
+
+ + + + + + + + + + + + + +
徽章稳定值使用场景
待启 · 排队中 queuedqueuedRun / 媒体任务排队
运转 · 运行中 runningrunningRun 执行中
请命中 · 等待确认 waiting_approvalwaiting_approval等待朱批
已成 · 已完成 completedcompletedRun / 任务完成
受阻 · 失败 failedfailed失败(附原因与重试)
已止 · 已取消 cancelledcancelled用户取消
守一 · 安静待命 idleidle角色无运行
整备 · 正在处理 processingprocessing媒体 / 资源处理
待审 · 等待审核 pending_reviewpending_review社区 / 市场审核
已刊 · 已发布 publishedpublished社区内容
+
+
+ +
+

组件样例

+

按钮语义:铜镜青为主操作,朱砂仅用于朱批(用户确认决定)与危险操作,描边为次操作。

+ +
+
+ + + + + + +
+
+ 请命请求你的确认 + 息壤角色记忆 + 幻境临时试演 · 不入正史 +
+
+ +
+
pythonreading_progress.py
+
# 汇总共读接龙进度(示意)
+from pathlib import Path
+
+def summarize(records: list[dict]) -> dict:
+    done = [r for r in records if r["finished"]]
+return {'{'}
+        "total": len(records),
+        "finished": len(done),
+        "pending": [r["name"] for r in records if not r["finished"]],
+    {'}'}
+
+ +
+
注意力权重 = softmax( QKT / √dk ) · V + fallback:注意力权重等于 Q、K 转置乘积经缩放与归一化后对 V 的加权求和 +
+
+
+ +
+

审查重点

+

第一批(色彩、字体、镜树/镜生/镜庭结构)已确认;本轮重点核对第二批页面,反馈时按页名 + 位置描述即可。

+
+
1. 息壤:候选审阅的「归真入忆 / 正影纠正 / 忽略」操作,以及大周天来源、重忆提示的呈现是否可理解。
+
2. 天工阁:工筹步骤、预算、分工使、轨迹的信息层级是否符合你对 Run 治理的预期。
+
3. 神识阁 / 百工坊:路由继承链与「升级新增权限需重新确认」的展示是否清晰,朱批语义是否仍然专一。
+
4. 云市:金额、分润、退契规则是否足够直白(文化名没有掩盖交易后果)。
+
5. 器谱 / 司命台 / 设置:直白权限句、双重授权、私箧与删除等高风险项的措辞与视觉重量。
+
6. 雅集 / 同契台:社区帖卡与协作审稿流的信息密度是否合适。
+
+
+ +
+

旧版传承与候选

+

已系统挖掘 main 分支旧版 25 页设计原型(铜镜鉴心体系),按「取手法、不照搬旧概念名」原则融入——六爻 / 九枢 / 三魂等概念 1.0 已由小周天、灵台六模块、内驱力等替代,仅传承其可视化手法。

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
旧版想法来源页状态
鎏金发丝线三档令牌tokens.css✓ 已融入全站(分组标题 / 金标竖条 / 品牌外环 / 时间线)
logo 五连击「镜启」诗签彩蛋_theme.js✓ 已融入(修好首次单击即跳转的缺陷)
铜镜登录页(铭文环 / 铜面噪点 / 扫描亮带)copper-mirror-login✓ 已融入登录 / 注册页
极光铜晕底 + 卡片 hover 光扫_base.css / rune-engine✓ 已融入全站(极淡,不干扰阅读)
日晷时辰盘 + 节气 + 相伴日文案time✓ 已融入镜庭 hero(巳时 · 白露 · 第 918 日)
朱批卡风险分级(RISK L2)chat-redesign✓ 已融入镜树请命卡
「呈镜」发送按钮命名(旧版已确立血脉)chat-redesign✓ 已融入镜树输入区(aria 仍读「发送」)
运行阶段爻象三态(done / active / pending)chat / evolution✓ 已融入天工阁工筹(active 步骤鎏金光晕)
河图置信度图谱(置信→线宽,假设→朱漆虚线待验)world✓ 已融入息壤玄络(待验边 + 标注)
息壤浮现(本次回应用了哪些记忆)chat / copper-v2✓ 对应 1.0 上下文镜(镜树右栏,同源 ContextSnapshot)
九枢星盘「活的仪器」+ 铜镜四态健康词汇admin / copper-v2✓ 已复刻为灵台六枢星盘(太一居中 + 五枢环绕 + 呼吸刻度 / 慢旋 / 告警闪烁)+ 镜态徽章(管理面)
五行生克健康环(系统健康=关系动力学)wuxing✓ 已复刻为相生 / 相克指标对告警(管理面星盘卡;环状图 React 阶段评估)
眉批 depth 标尺注入预览margin-notes候选 —— 上下文镜深度维度(React 阶段与 Context Manifest 联动)
好奇萤火(亮度=期望值)与探索天平drive✓ 萤火已融入内驱力维度(亮度=维度值);探索天平待天工阁预算增强时评估
周天四镜阶段链(评 / 演 / 候 / 藏 四面小铜镜)evolution✓ 已复刻为大周天四镜:回 / 照 / 议 / 呈(镜生页,ADR-023 四阶段)
会话列表「今日 / 本周 / 更早」分组 + 彩点状态chat-redesign✓ 已融入镜树会话列表(活跃铜绿 / 幻境秋香 / 待朱批朱砂)
「深虑 / 博闻」输入控制药丸 + 用户消息鎏金右边线chat-redesign / copper-v2✓ 已融入镜树输入区与用户气泡
起居注时间河「卷」章分割admin✓ 已融入管理面审计快照
太极阴阳平衡 gauge(三态)cosmos✓ 已复刻为朱批治理阴阳平衡(司命台,阳亢 / 平衡 / 阴盛)
角色 card-banner 渐变横幅character-detail✓ 已融入镜生详情页
思考块折叠卡(复刻 chat-redesign)chat-redesign✓ 已融入(用户确认):思考摘要可折叠 + 深虑强度(低/中/高)——契约候选:正式实现前需在 content-blocks 契约登记 thinking 块类型与流式语义;摘要仅会话内可见,不入长期记录与诊断导出
+
+
+
+ + ); +} diff --git a/frontend/src/app/(app)/plugins/page.tsx b/frontend/src/app/(app)/plugins/page.tsx new file mode 100644 index 0000000..3beb15f --- /dev/null +++ b/frontend/src/app/(app)/plugins/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { PluginsPanel } from "@/components/plugins/PluginsPanel"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/(app)/settings/page.tsx b/frontend/src/app/(app)/settings/page.tsx new file mode 100644 index 0000000..aefd5d7 --- /dev/null +++ b/frontend/src/app/(app)/settings/page.tsx @@ -0,0 +1,14 @@ +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { SettingsPanel } from "@/components/panels"; + +export default function Page() { + return ( + <> + } /> +
+ +
+ + ); +} diff --git a/frontend/src/app/admin/layout.tsx b/frontend/src/app/admin/layout.tsx new file mode 100644 index 0000000..7499ad2 --- /dev/null +++ b/frontend/src/app/admin/layout.tsx @@ -0,0 +1,6 @@ +import { AdminShell } from "@/components/shell/AdminShell"; + +/** 管理面独立外壳(运营 / 部署 / 观测) */ +export default function AdminLayout({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/frontend/src/app/admin/page.tsx b/frontend/src/app/admin/page.tsx new file mode 100644 index 0000000..1b8e3e9 --- /dev/null +++ b/frontend/src/app/admin/page.tsx @@ -0,0 +1,42 @@ +"use client"; + +import { Topbar } from "@/components/shell/Topbar"; +import { Crumbs } from "@/components/ui"; +import { AdminPanel } from "@/components/admin/AdminPanel"; +import { readSession } from "@/lib/api"; +import { useEffect, useState } from "react"; + +export default function Page() { + const [session, setSession] = useState<{ role: string; email: string } | null>(null); + useEffect(() => { + // 会话身份含 localStorage,须在挂载后读取(避免 SSR/客户端不一致) + setSession(readSession()); + }, []); + const isAdmin = session?.role === "admin"; + return ( + <> + } + extra={ + session === null ? null : isAdmin ? ( + + + 管理员 · {session.email || "dev"} role: admin + + ) : ( + + + 普通用户 role: user · 治理队列需管理员 + + ) + } + /> +
+
+ 管理面边界:管理员不可读取私箧与用户明文内容;敏感操作需双人授权并全部写入审计(开发档单管理员,双人授权待运营流程接入)。 +
+ +
+ + ); +} diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css new file mode 100644 index 0000000..3a2167d --- /dev/null +++ b/frontend/src/app/globals.css @@ -0,0 +1,1710 @@ +/* ============================================================ + 魂镜 Hunjing · 界面静态原型 v0.1 + 设计语言:墨 / 月白双主题 · 铜镜青主色 · 朱砂朱批色 · 双层文字系统 + ============================================================ */ + +/* ---------- 设计令牌 ---------- */ +:root { + /* 墨色主题(默认) */ + --bg: #14181c; + --bg-sunken: #0f1316; + --bg-raised: #1b2126; + --bg-overlay: #212930; + --line: #2b333b; + --line-soft: #232b31; + --text-1: #e9e7e2; + --text-2: #a7aeb4; + --text-3: #6d777f; + --accent: #58a99c; /* 铜镜青 */ + --accent-strong: #74c4b6; + --accent-soft: rgba(88, 169, 156, 0.13); + --cinnabar: #c4574a; /* 朱砂 · 朱批专用 */ + --cinnabar-strong: #d26a5d; + --cinnabar-soft: rgba(196, 87, 74, 0.14); + --ok: #8ab872; /* 已成 */ + --warn: #c9a227; /* 整备 · 秋香 */ + --err: #d26a5d; /* 受阻 */ + --muted: #79838b; /* 守一 / 已止 */ + --shadow: 0 10px 28px rgba(0, 0, 0, 0.38); + --shadow-soft: 0 4px 14px rgba(0, 0, 0, 0.25); + + --font-ui: "PingFang SC", "HarmonyOS Sans SC", "Noto Sans SC", "Microsoft YaHei", system-ui, sans-serif; + --font-serif: "Songti SC", "Noto Serif SC", "STSong", "SimSun", serif; + --font-mono: "SF Mono", "JetBrains Mono", "Cascadia Code", Menlo, Consolas, monospace; + + --radius: 10px; + --radius-sm: 7px; + --radius-lg: 14px; + --side-w: 224px; +} + +[data-theme="light"] { + --bg: #f1f2ef; + --bg-sunken: #e6e8e4; + --bg-raised: #fafaf8; + --bg-overlay: #ffffff; + --line: #d6dad3; + --line-soft: #e2e5df; + --text-1: #262b2e; + --text-2: #5c6569; + --text-3: #8b9497; + --accent: #2f7a6f; + --accent-strong: #22615a; + --accent-soft: rgba(47, 122, 111, 0.1); + --cinnabar: #ac4632; + --cinnabar-strong: #963a28; + --cinnabar-soft: rgba(172, 70, 50, 0.1); + --ok: #4e7e3b; + --warn: #8f7414; + --err: #ac4632; + --muted: #848d90; + --shadow: 0 10px 28px rgba(42, 52, 47, 0.12); + --shadow-soft: 0 4px 14px rgba(42, 52, 47, 0.08); +} + +/* ---------- 基础 ---------- */ +* { box-sizing: border-box; margin: 0; padding: 0; } + +html { height: 100%; } + +body { + min-height: 100%; + background: var(--bg); + color: var(--text-1); + font-family: var(--font-ui); + font-size: 14px; + line-height: 1.65; + -webkit-font-smoothing: antialiased; +} + +a { color: var(--accent); text-decoration: none; } +a:hover { color: var(--accent-strong); } + +:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + border-radius: 4px; +} + +::selection { background: var(--accent-soft); } + +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { animation: none !important; transition: none !important; } +} + +/* ---------- 双层文字系统(签名) ---------- + 文化名用衬线宋体;直白解释用无衬线小字。 + 展示格式:文化名 · 直白解释 */ +.cn { font-family: var(--font-serif); letter-spacing: 0.02em; } +.cn__plain { + font-family: var(--font-ui); + font-size: 0.72em; + color: var(--text-3); + margin-left: 0.4em; + letter-spacing: 0; +} + +.mono { font-family: var(--font-mono); font-size: 0.92em; } + +/* ---------- 应用外壳 ---------- */ +.app { + display: grid; + grid-template-columns: var(--side-w) 1fr; + min-height: 100vh; +} + +.sidebar { + background: var(--bg-sunken); + border-right: 1px solid var(--line-soft); + display: flex; + flex-direction: column; + position: sticky; + top: 0; + height: 100vh; + overflow-y: auto; +} + +.brand { + display: flex; + align-items: center; + gap: 10px; + padding: 18px 18px 14px; +} + +.brand__mark { + width: 34px; + height: 34px; + border-radius: 50%; + flex: none; + background: + radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.28), transparent 42%), + conic-gradient(from 210deg, #3f6e68, #6fae9f 40%, #4a5e63 80%, #3f6e68); + border: 1px solid rgba(255, 255, 255, 0.16); + box-shadow: inset 0 0 0 3px rgba(0, 0, 0, 0.18); +} + +.brand__name { font-family: var(--font-serif); font-size: 17px; font-weight: 600; line-height: 1.2; } +.brand__sub { font-size: 11px; color: var(--text-3); } + +.side-nav { flex: 1; padding: 4px 10px 16px; } + +.nav-group { margin-top: 14px; } +.nav-group__title { + font-size: 11px; + color: var(--text-3); + padding: 0 10px 5px; + letter-spacing: 0.08em; +} + +.nav-item { + display: flex; + align-items: center; + gap: 10px; + padding: 7px 10px; + border-radius: var(--radius-sm); + color: var(--text-2); + position: relative; + margin-bottom: 1px; +} + +.nav-item:hover { background: var(--bg-raised); color: var(--text-1); } + +.nav-item.is-active { + background: var(--accent-soft); + color: var(--accent-strong); +} + +.nav-item.is-active::before { + content: ""; + position: absolute; + left: -10px; + top: 6px; + bottom: 6px; + width: 3px; + border-radius: 2px; + background: var(--accent); +} + +.nav-item svg { width: 17px; height: 17px; flex: none; opacity: 0.85; } +.nav-item .cn { font-size: 14.5px; } +.nav-item .nav-plain { font-size: 11.5px; color: var(--text-3); margin-left: auto; } +.nav-item.is-active .nav-plain { color: inherit; opacity: 0.75; } + +.side-foot { + border-top: 1px solid var(--line-soft); + padding: 12px 10px; + display: flex; + align-items: center; + gap: 8px; +} + +/* ---------- 顶栏 ---------- */ +.main { display: flex; flex-direction: column; min-width: 0; } + +.topbar { + display: flex; + align-items: center; + gap: 14px; + padding: 0 22px; + height: 54px; + border-bottom: 1px solid var(--line-soft); + background: var(--bg); + position: sticky; + top: 0; + z-index: 20; +} + +.crumbs { display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--text-2); font-size: 13.5px; } +.crumbs .cn { color: var(--text-1); font-size: 15px; } +.crumbs__sep { color: var(--text-3); } +.crumbs .here { color: var(--text-2); } + +.topbar__spacer { flex: 1; } + +.prototype-tag { + font-size: 11px; + color: var(--text-3); + border: 1px dashed var(--line); + border-radius: 999px; + padding: 2px 10px; + white-space: nowrap; +} + +.icon-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: var(--radius-sm); + border: none; + background: transparent; + color: var(--text-2); + cursor: pointer; +} +.icon-btn:hover { background: var(--bg-raised); color: var(--text-1); } +.icon-btn svg { width: 17px; height: 17px; } + +/* ---------- 通用组件 ---------- */ +.content { padding: 26px 30px 48px; max-width: 1160px; width: 100%; margin: 0 auto; } +.content--wide { max-width: none; } + +.card { + background: var(--bg-raised); + border: 1px solid var(--line-soft); + border-radius: var(--radius); + padding: 18px 20px; +} + +.card__head { + display: flex; + align-items: baseline; + flex-wrap: wrap; + row-gap: 5px; + gap: 8px; + margin-bottom: 12px; +} +.card__head .cn { font-size: 16px; font-weight: 600; } + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 7px; + font-family: var(--font-ui); + font-size: 13.5px; + padding: 7px 16px; + border-radius: var(--radius-sm); + border: 1px solid transparent; + cursor: pointer; + transition: background 0.15s, border-color 0.15s; + white-space: nowrap; +} +.btn svg { width: 15px; height: 15px; } +.btn--primary { background: var(--accent); color: #f4f7f5; } +.btn--primary:hover { background: var(--accent-strong); color: #fff; } +.btn--cinnabar { background: var(--cinnabar); color: #fbf3ef; } +.btn--cinnabar:hover { background: var(--cinnabar-strong); color: #fff; } +.btn--outline { background: transparent; border-color: var(--line); color: var(--text-1); } +.btn--outline:hover { border-color: var(--accent); color: var(--accent-strong); } +.btn--ghost { background: transparent; color: var(--text-2); } +.btn--ghost:hover { background: var(--bg-raised); color: var(--text-1); } +.btn--danger { background: transparent; border-color: var(--cinnabar); color: var(--cinnabar); } +.btn--danger:hover { background: var(--cinnabar-soft); } +.btn--sm { font-size: 12.5px; padding: 4px 11px; } + +/* 状态徽章:文化状态 · 直白状态 · 稳定值 */ +.badge { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 12px; + padding: 2px 10px; + border-radius: 999px; + border: 1px solid var(--line); + color: var(--text-2); + white-space: nowrap; +} +.badge__dot { width: 7px; height: 7px; border-radius: 50%; flex: none; } +.badge .mono { font-size: 11px; color: var(--text-3); } +.badge--ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, transparent); } +.badge--ok .badge__dot { background: var(--ok); } +.badge--info { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, transparent); } +.badge--info .badge__dot { background: var(--accent); } +.badge--info .badge__dot { animation: pulse 2.2s ease-in-out infinite; } +.badge--warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 40%, transparent); } +.badge--warn .badge__dot { background: var(--warn); } +.badge--err { color: var(--err); border-color: color-mix(in srgb, var(--err) 40%, transparent); } +.badge--err .badge__dot { background: var(--err); } +.badge--muted .badge__dot { background: var(--muted); } + +@keyframes pulse { 50% { opacity: 0.35; } } + +/* 镜像头像:铜镜圆 + 衬线单字 */ +.avatar { + width: 38px; + height: 38px; + border-radius: 50%; + flex: none; + display: inline-flex; + align-items: center; + justify-content: center; + font-family: var(--font-serif); + font-size: 17px; + color: #eef4f1; + background: + radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.3), transparent 45%), + conic-gradient(from 210deg, #37514d, #5e9a8d 45%, #46565b 85%, #37514d); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14), inset 0 0 0 4px rgba(0, 0, 0, 0.16); +} +.avatar--user { + background: + radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.3), transparent 45%), + conic-gradient(from 210deg, #5a4a44, #9a7b6c 45%, #5f5450 85%, #5a4a44); +} +.avatar--sm { width: 28px; height: 28px; font-size: 13px; } +.avatar--lg { width: 64px; height: 64px; font-size: 28px; } + +/* 分段控件(界域切换等) */ +.seg { + display: inline-flex; + background: var(--bg-sunken); + border: 1px solid var(--line-soft); + border-radius: var(--radius-sm); + padding: 2px; + gap: 2px; +} +.seg__item { + border: none; + background: transparent; + font-family: var(--font-ui); + font-size: 12.5px; + color: var(--text-2); + padding: 3px 12px; + border-radius: 5px; + cursor: pointer; + display: inline-flex; + align-items: center; + gap: 5px; +} +.seg__item .cn { font-size: 13px; } +.seg__item:hover { color: var(--text-1); } +.seg__item.is-on { background: var(--bg-raised); color: var(--text-1); box-shadow: var(--shadow-soft); } +.seg__item--sim.is-on { color: var(--warn); } +.seg__realm-hint { font-size: 11px; color: var(--text-3); } + +/* 表单 */ +.input, .textarea { + width: 100%; + background: var(--bg-sunken); + border: 1px solid var(--line); + border-radius: var(--radius-sm); + color: var(--text-1); + font-family: var(--font-ui); + font-size: 13.5px; + padding: 8px 12px; +} +.input::placeholder, .textarea::placeholder { color: var(--text-3); } +.input:focus, .textarea:focus { outline: none; border-color: var(--accent); } + +/* ---------- 首页(镜庭) ---------- */ +.hero { display: flex; align-items: flex-end; gap: 18px; margin-bottom: 26px; flex-wrap: wrap; } +.hero h1 { font-family: var(--font-serif); font-size: 26px; font-weight: 600; } +.hero__stats { display: flex; gap: 10px; margin-left: auto; flex-wrap: wrap; } +.hero__stat { + display: flex; + flex-direction: column; + gap: 1px; + padding: 8px 16px; + border-radius: var(--radius); + background: var(--bg-raised); + border: 1px solid var(--line-soft); + min-width: 108px; +} +.hero__stat b { font-size: 19px; font-family: var(--font-serif); } +.hero__stat span { font-size: 11.5px; color: var(--text-3); } + +.grid-cards { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); + gap: 14px; +} + +.char-card { display: flex; flex-direction: column; gap: 10px; padding: 18px; } +.char-card__top { display: flex; align-items: center; gap: 12px; } +.char-card__name { font-family: var(--font-serif); font-size: 17px; font-weight: 600; } +.char-card__line { font-size: 12.5px; color: var(--text-2); line-height: 1.5; } +.char-card__foot { display: flex; align-items: center; justify-content: space-between; margin-top: 2px; } +.char-card__foot .badge { flex: none; } +.char-card__time { font-size: 11.5px; color: var(--text-3); white-space: nowrap; flex: none; } + +.home-cols { + display: grid; + grid-template-columns: 1.5fr 1fr; + gap: 16px; + margin-top: 26px; + align-items: start; +} + +.list-row { + display: flex; + align-items: center; + gap: 12px; + padding: 11px 4px; + border-bottom: 1px solid var(--line-soft); +} +.list-row:last-child { border-bottom: none; } +.list-row__body { flex: 1; min-width: 0; } +.list-row__title { font-size: 13.5px; color: var(--text-1); display: flex; align-items: center; gap: 8px; } +.list-row__sub { font-size: 12px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.list-row__time { font-size: 11.5px; color: var(--text-3); white-space: nowrap; } + +.realm-dot { + display: inline-flex; + align-items: center; + gap: 5px; + font-size: 11px; + color: var(--text-3); +} +.realm-dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--muted); } +.realm-dot--world::before { background: var(--accent); } +.realm-dot--sim::before { background: var(--warn); } + +/* 进度条 */ +.progress { height: 5px; border-radius: 3px; background: var(--bg-sunken); overflow: hidden; } +.progress__bar { height: 100%; border-radius: 3px; background: var(--accent); } +.progress--warn .progress__bar { background: var(--warn); } + +/* ---------- 角色页(镜生) ---------- */ +.char-layout { + display: grid; + grid-template-columns: 300px 1fr; + gap: 20px; + align-items: start; +} + +.char-list-item { + display: flex; + align-items: center; + gap: 12px; + padding: 11px 12px; + border-radius: var(--radius); + border: 1px solid transparent; + cursor: pointer; +} +.char-list-item:hover { background: var(--bg-raised); } +.char-list-item.is-active { background: var(--bg-raised); border-color: var(--line); } +.char-list-item__name { font-family: var(--font-serif); font-size: 15px; } +.char-list-item__sub { font-size: 11.5px; color: var(--text-3); } + +.char-head { + display: flex; + gap: 18px; + align-items: flex-start; + margin-bottom: 20px; + flex-wrap: wrap; +} +.char-head__title { display: flex; flex-direction: column; gap: 6px; } +.char-head h2 { font-family: var(--font-serif); font-size: 24px; font-weight: 600; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; } +.char-head__motto { color: var(--text-2); font-size: 13.5px; } +.char-head__actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; } + +.section { margin-bottom: 20px; } +.section__head { + display: flex; + align-items: baseline; + gap: 10px; + margin-bottom: 10px; +} +.section__head .cn { font-size: 16.5px; font-weight: 600; } +.section__head .more { margin-left: auto; font-size: 12.5px; } + +/* 内驱力维度条 */ +.drive-row { display: grid; grid-template-columns: 72px 1fr 44px; align-items: center; gap: 14px; padding: 7px 0; } +.drive-row__label { font-size: 13px; color: var(--text-2); } +.drive-row__val { font-size: 12px; color: var(--text-3); text-align: right; } + +/* 谱系时间线 */ +.timeline { position: relative; padding-left: 20px; } +.timeline::before { + content: ""; + position: absolute; + left: 5px; + top: 8px; + bottom: 8px; + width: 1px; + background: var(--line); +} +.timeline__item { position: relative; padding: 0 0 16px 14px; } +.timeline__item:last-child { padding-bottom: 0; } +.timeline__item::before { + content: ""; + position: absolute; + left: -20px; + top: 7px; + width: 11px; + height: 11px; + border-radius: 50%; + background: var(--bg); + border: 2px solid var(--accent); +} +.timeline__item--muted::before { border-color: var(--muted); } +.timeline__date { font-size: 11.5px; color: var(--text-3); font-family: var(--font-mono); } +.timeline__title { font-size: 13.5px; } +.timeline__sub { font-size: 12.5px; color: var(--text-2); } + +/* 危险区 */ +.danger-zone { border-color: color-mix(in srgb, var(--cinnabar) 30%, transparent); } +.danger-zone .card__head .cn { color: var(--cinnabar); } + +/* ---------- 对话页(镜树) ---------- */ +.conv-layout { + display: grid; + grid-template-columns: 268px 1fr 320px; + height: calc(100vh - 54px); + min-height: 0; +} + +.conv-side { + border-right: 1px solid var(--line-soft); + overflow-y: auto; + padding: 14px 12px; + background: var(--bg); +} + +.conv-side__head { display: flex; align-items: center; gap: 10px; padding: 4px 6px 14px; } +.conv-side__head .cn { font-size: 15px; font-weight: 600; } + +.conv-item { + display: block; + padding: 10px 12px; + border-radius: var(--radius-sm); + color: var(--text-2); + margin-bottom: 2px; +} +.conv-item:hover { background: var(--bg-raised); color: var(--text-1); } +.conv-item.is-active { background: var(--accent-soft); color: var(--text-1); } +.conv-item__title { display: flex; align-items: center; gap: 8px; font-size: 13.5px; } +.conv-item__sub { font-size: 12px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; } + +.conv-main { + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + overflow: hidden; +} +.conv-stream { flex: 1; overflow-y: auto; padding: 26px 0 12px; } +.conv-stream__inner { max-width: 780px; margin: 0 auto; padding: 0 26px; } + +/* 界域提示条 */ +.realm-banner { + display: flex; + align-items: center; + gap: 9px; + font-size: 12.5px; + color: var(--text-2); + background: var(--accent-soft); + border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); + border-radius: var(--radius-sm); + padding: 7px 14px; + margin-bottom: 22px; +} +.realm-banner--sim { + color: var(--warn); + background: color-mix(in srgb, var(--warn) 9%, transparent); + border-color: color-mix(in srgb, var(--warn) 32%, transparent); +} +.realm-banner svg { width: 15px; height: 15px; flex: none; } +.realm-banner::before { + content: ""; + width: 7px; height: 7px; + border-radius: 50%; + background: currentColor; + opacity: 0.75; + flex: none; +} + +/* 消息 */ +.msg { margin-bottom: 30px; } + +.msg--user { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; } +.msg__meta { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text-3); } +.msg--user .bubble { + background: var(--bg-overlay); + border: 1px solid var(--line-soft); + border-radius: var(--radius-lg) var(--radius-lg) 4px var(--radius-lg); + padding: 11px 16px; + max-width: 76%; + font-size: 14px; + box-shadow: var(--shadow-soft); +} + +.msg--char__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } +.msg--char__name { font-family: var(--font-serif); font-size: 15.5px; font-weight: 600; } +.msg--char__meta { display: flex; align-items: center; gap: 8px; margin-left: 2px; } + +.msg__blocks { display: flex; flex-direction: column; gap: 12px; padding-left: 48px; } + +.msg__actions { + display: flex; + align-items: center; + gap: 4px; + padding-left: 48px; + margin-top: 10px; +} +.act-btn { + display: inline-flex; + align-items: center; + gap: 5px; + font-size: 12px; + color: var(--text-3); + background: none; + border: none; + border-radius: 5px; + padding: 4px 9px; + cursor: pointer; + font-family: var(--font-ui); +} +.act-btn:hover { background: var(--bg-raised); color: var(--text-1); } +.act-btn svg { width: 13.5px; height: 13.5px; } + +/* ---------- ContentBlock ---------- */ +.block { + background: var(--bg-raised); + border: 1px solid var(--line-soft); + border-radius: var(--radius); + overflow: hidden; +} +.block__body { padding: 14px 18px; } + +.block--text { background: transparent; border: none; padding: 0; } +.block--text .block__body { padding: 0; } + +.block__head { + display: flex; + align-items: center; + gap: 10px; + padding: 8px 14px; + border-bottom: 1px solid var(--line-soft); + background: var(--bg-sunken); + font-size: 12px; + color: var(--text-3); +} +.block__head .lang { color: var(--accent); font-family: var(--font-mono); text-transform: lowercase; } +.block__head .fname { font-family: var(--font-mono); color: var(--text-2); } +.block__head .acts { margin-left: auto; display: flex; gap: 4px; } + +.md p { margin-bottom: 0.8em; } +.md p:last-child { margin-bottom: 0; } +.md strong { color: var(--text-1); } +.md em { color: var(--text-2); } +.md ul { padding-left: 1.3em; margin-bottom: 0.8em; } +.md ul:last-child { margin-bottom: 0; } +.md li { margin-bottom: 0.3em; } +.md code { + font-family: var(--font-mono); + font-size: 0.88em; + background: var(--bg-sunken); + border: 1px solid var(--line-soft); + border-radius: 4px; + padding: 1px 6px; +} +.md a { text-underline-offset: 3px; text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent); } +.md .ext::after { content: " ↗"; font-size: 0.82em; color: var(--text-3); } + +/* 引文锚 */ +.quote { border-left: 3px solid var(--accent); padding: 2px 0 2px 14px; color: var(--text-2); font-family: var(--font-serif); font-size: 14.5px; } +.quote__src { display: block; margin-top: 5px; font-family: var(--font-ui); font-size: 11.5px; color: var(--text-3); } + +/* 表格 */ +.table-wrap { overflow-x: auto; } +table.data { border-collapse: collapse; width: 100%; font-size: 13px; } +table.data th { + text-align: left; + font-weight: 500; + color: var(--text-3); + font-size: 12px; + border-bottom: 1px solid var(--line); + padding: 7px 12px; + white-space: nowrap; +} +table.data td { padding: 8px 12px; border-bottom: 1px solid var(--line-soft); color: var(--text-2); } +table.data tr:last-child td { border-bottom: none; } +table.data td:first-child { color: var(--text-1); font-family: var(--font-serif); } + +/* 代码块(手工着色示意) */ +pre.code { + font-family: var(--font-mono); + font-size: 12.8px; + line-height: 1.7; + padding: 14px 16px; + overflow-x: auto; + color: var(--text-2); +} +pre.code .k { color: var(--accent); } +pre.code .s { color: var(--ok); } +pre.code .c { color: var(--text-3); font-style: italic; } +pre.code .f { color: var(--cinnabar-strong); } + +/* 数学块 */ +.math { + font-family: var(--font-serif); + font-style: italic; + font-size: 16.5px; + text-align: center; + padding: 16px 12px; + letter-spacing: 0.02em; +} +.math sub, .math sup { font-size: 0.68em; } +.math__fallback { display: block; margin-top: 8px; font-family: var(--font-ui); font-style: normal; font-size: 11.5px; color: var(--text-3); text-align: center; } + +/* Mermaid 示意(内联 SVG 图) */ +.mermaid-box { padding: 18px 14px; overflow-x: auto; } +.mermaid-cap { padding: 8px 14px; border-top: 1px solid var(--line-soft); font-size: 11.5px; color: var(--text-3); display: flex; gap: 8px; align-items: center; } + +/* 音频块 */ +.audio { display: flex; align-items: center; gap: 14px; padding: 13px 16px; } +.audio__play { + width: 36px; height: 36px; border-radius: 50%; + border: 1px solid var(--line); + background: var(--bg-sunken); + color: var(--accent); + display: inline-flex; align-items: center; justify-content: center; + cursor: pointer; flex: none; +} +.audio__play svg { width: 15px; height: 15px; margin-left: 2px; } +.wave { display: flex; align-items: center; gap: 2.5px; height: 30px; flex: 1; } +.wave i { + width: 3px; + border-radius: 2px; + background: var(--accent); + opacity: 0.55; + display: block; +} +.audio__time { font-family: var(--font-mono); font-size: 12px; color: var(--text-3); } +.audio__meta { flex: none; text-align: right; } +.audio__meta .t { font-size: 12px; color: var(--text-2); display: block; } + +/* 工具调用块 */ +.tool { border-left: 3px solid var(--accent); } +.tool__head { display: flex; align-items: center; gap: 10px; padding: 10px 16px; } +.tool__name { font-family: var(--font-mono); font-size: 13px; color: var(--text-1); } +.tool__purpose { font-size: 12px; color: var(--text-3); } +.tool__body { padding: 0 16px 12px; font-size: 12.5px; color: var(--text-2); } +.tool__row { display: flex; gap: 8px; padding: 2px 0; } +.tool__row .k2 { color: var(--text-3); flex: none; } +.tool__stat { display: flex; gap: 14px; margin-top: 6px; font-size: 11.5px; color: var(--text-3); } + +/* 请命(审批)卡 —— 签名组件 */ +.approval { border: 1px solid color-mix(in srgb, var(--cinnabar) 38%, transparent); } +.approval__head { + display: flex; + align-items: center; + gap: 10px; + padding: 12px 18px; + border-bottom: 1px solid color-mix(in srgb, var(--cinnabar) 22%, transparent); + background: var(--cinnabar-soft); +} +.approval__seal { + width: 30px; height: 30px; flex: none; + border-radius: 50%; + border: 1.5px solid var(--cinnabar); + color: var(--cinnabar); + display: inline-flex; align-items: center; justify-content: center; + font-family: var(--font-serif); font-size: 13px; font-weight: 600; + background: var(--bg-raised); +} +.approval__title { font-size: 14px; } +.approval__title .cn { font-size: 15.5px; font-weight: 600; color: var(--cinnabar); } +.approval__body { padding: 13px 18px; display: flex; flex-direction: column; gap: 8px; } +.fact { display: grid; grid-template-columns: 88px 1fr; gap: 10px; font-size: 13px; } +.fact__k { color: var(--text-3); } +.fact__v { color: var(--text-1); } +.fact__v .mono { font-size: 12px; color: var(--text-2); } +.approval__acts { display: flex; gap: 10px; align-items: center; padding: 0 18px 15px; } +.approval__note { font-size: 11.5px; color: var(--text-3); margin-left: auto; max-width: 220px; } +.approval--done { border-color: var(--line); } +.approval--done .approval__head { background: transparent; border-bottom-color: var(--line-soft); } +.approval--done .approval__seal { border-color: var(--ok); color: var(--ok); } + +/* 候答 */ +.candidates { display: flex; align-items: center; gap: 10px; padding-left: 48px; margin-top: -14px; margin-bottom: 26px; } +.cand-switch { display: inline-flex; gap: 4px; } +.cand-tag { + border: 1px solid var(--line); + background: var(--bg-sunken); + color: var(--text-3); + font-size: 12px; + border-radius: 999px; + padding: 3px 12px; + cursor: pointer; +} +.cand-tag.is-on { border-color: var(--accent); color: var(--accent-strong); background: var(--accent-soft); } + +/* 残答折叠 */ +.sealed { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 16px; + border: 1px dashed var(--line); + border-radius: var(--radius); + font-size: 12.5px; + color: var(--text-3); + padding-left: 48px; + border-left: none; border-right: none; border-top: none; + margin-left: 0; +} +.sealed__body { flex: 1; } +.sealed__t { color: var(--text-2); } + +/* 息壤候选(记忆候选卡) */ +.memory-cand { border-left: 3px solid var(--warn); } +.memory-cand__head { display: flex; align-items: center; gap: 10px; padding: 11px 16px; } +.memory-cand__body { padding: 0 16px 13px; font-size: 13px; color: var(--text-2); } +.memory-cand__body .q { font-family: var(--font-serif); color: var(--text-1); font-size: 14px; } +.memory-cand__acts { display: flex; gap: 8px; margin-top: 10px; } +.mem-type { + font-size: 11px; + border: 1px solid var(--line); + border-radius: 4px; + padding: 1px 7px; + color: var(--text-3); +} + +/* 临时芽体(流式) */ +.sprout { border: 1px dashed color-mix(in srgb, var(--accent) 45%, transparent); background: transparent; } +.sprout__head { display: flex; align-items: center; gap: 10px; padding: 9px 16px; font-size: 12px; color: var(--accent); border-bottom: 1px dashed var(--line); } +.sprout__body { padding: 13px 16px; } +.stream-cursor { + display: inline-block; + width: 8px; height: 17px; + background: var(--accent); + vertical-align: -3px; + margin-left: 2px; + animation: blink 1.05s step-end infinite; + border-radius: 1px; +} +@keyframes blink { 50% { opacity: 0; } } +.src-line { font-family: var(--font-mono); font-size: 13px; color: var(--text-2); white-space: pre-wrap; } +.src-line .unclosed { color: var(--text-3); } + +/* 输入区 */ +.composer { border-top: 1px solid var(--line-soft); padding: 14px 26px 18px; background: var(--bg); } +.composer__inner { max-width: 780px; margin: 0 auto; } +.composer__box { + background: var(--bg-raised); + border: 1px solid var(--line); + border-radius: var(--radius-lg); + padding: 12px 14px; + display: flex; + flex-direction: column; + gap: 10px; +} +.composer__box:focus-within { border-color: var(--accent); } +.composer__ta { + background: none; border: none; resize: none; + color: var(--text-1); + font-family: var(--font-ui); + font-size: 14px; + line-height: 1.6; + min-height: 44px; + outline: none; +} +.composer__bar { display: flex; align-items: center; gap: 6px; } +.composer__bar .spacer { flex: 1; } +.composer__hint { display: flex; gap: 14px; margin-top: 8px; font-size: 11.5px; color: var(--text-3); flex-wrap: wrap; } +.composer__hint .k { color: var(--text-2); } + +/* ---------- 右栏:镜枝面板 ---------- */ +.conv-ctx { + border-left: 1px solid var(--line-soft); + overflow-y: auto; + padding: 18px 16px 30px; + background: var(--bg); +} +.ctx-section { margin-bottom: 24px; } +.ctx-section__head { + display: flex; align-items: baseline; gap: 8px; + margin-bottom: 10px; +} +.ctx-section__head .cn { font-size: 14.5px; font-weight: 600; } +.ctx-section__head .more { margin-left: auto; font-size: 11.5px; } + +/* 分支树 */ +.tree { font-size: 12.5px; } +.tree ul { list-style: none; padding-left: 18px; position: relative; } +.tree > ul { padding-left: 2px; } +.tree ul::before { + content: ""; + position: absolute; + left: 6px; top: 4px; bottom: 12px; + width: 1px; + background: color-mix(in srgb, var(--text-3) 55%, transparent); +} +.tree li { position: relative; padding: 3px 0 3px 14px; } +.tree li::before { + content: ""; + position: absolute; + left: 0; top: 13px; + width: 12px; height: 1px; + background: color-mix(in srgb, var(--text-3) 55%, transparent); +} +.tree li:last-child::after { + content: ""; + position: absolute; + left: -12px; top: 15px; bottom: 0; + width: 1px; + background: var(--bg); +} +.tree__node { display: flex; align-items: center; gap: 7px; color: var(--text-2); } +.tree__node .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.tree__node--main .nm { color: var(--text-1); font-weight: 500; } +.tree__node--now { + background: var(--accent-soft); + border-radius: 5px; + outline: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); + padding: 2px 6px; + margin-left: -6px; + color: var(--accent-strong); +} +.tree__node--sealed { color: var(--text-3); } +.tree__tag { font-size: 10.5px; border-radius: 4px; padding: 0 6px; flex: none; border: 1px solid var(--line); color: var(--text-3); } +.tree__tag--main { border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent); } +.tree__tag--seal { border-color: var(--line); color: var(--text-3); text-decoration: line-through; } +.tree__tag--bud { border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent); animation: pulse 2.2s ease-in-out infinite; } + +/* 上下文镜 */ +.ctx-mirror__row { display: flex; gap: 9px; padding: 6px 0; font-size: 12.5px; align-items: baseline; } +.ctx-mirror__type { flex: none; width: 34px; color: var(--text-3); } +.ctx-mirror__txt { color: var(--text-2); flex: 1; } +.ctx-mirror__src { font-size: 11px; color: var(--text-3); white-space: nowrap; } +.ctx-mirror__omitted { color: var(--text-3); font-size: 12px; padding: 4px 0; } +.ctx-meter { margin-top: 10px; } +.ctx-meter__label { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--text-3); margin-bottom: 5px; } + +/* ---------- 索引页(设计说明) ---------- */ +.doc { max-width: 980px; } +.doc-hero { padding: 44px 0 30px; border-bottom: 1px solid var(--line-soft); margin-bottom: 34px; } +.doc-hero h1 { font-family: var(--font-serif); font-size: 34px; font-weight: 600; margin-bottom: 10px; display: flex; align-items: center; gap: 16px; } +.doc-hero p { color: var(--text-2); max-width: 640px; } +.doc-hero .ver { font-family: var(--font-mono); font-size: 13px; color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); border-radius: 999px; padding: 3px 12px; vertical-align: middle; } + +.doc-sec { margin-bottom: 40px; } +.doc-sec > h2 { font-family: var(--font-serif); font-size: 20px; font-weight: 600; margin-bottom: 6px; } +.doc-sec > .sub { color: var(--text-3); font-size: 13px; margin-bottom: 18px; } + +.page-nav { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; } +.page-nav a.card { display: flex; flex-direction: column; gap: 6px; color: var(--text-1); transition: border-color 0.15s; } +.page-nav a.card:hover { border-color: var(--accent); } +.page-nav .cn { font-size: 16px; font-weight: 600; } +.page-nav .d { font-size: 12.5px; color: var(--text-3); } +.page-nav .p { font-family: var(--font-mono); font-size: 11px; color: var(--accent); } + +.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 10px; } +.swatch { border: 1px solid var(--line-soft); border-radius: var(--radius-sm); overflow: hidden; } +.swatch__c { height: 52px; } +.swatch__m { padding: 7px 10px; font-size: 11.5px; color: var(--text-2); background: var(--bg-raised); } +.swatch__m b { display: block; font-size: 12px; color: var(--text-1); font-weight: 500; } +.swatch__m .mono { color: var(--text-3); font-size: 10.5px; } + +.type-spec { display: flex; flex-direction: column; gap: 14px; } +.type-spec__row { display: flex; align-items: baseline; gap: 20px; border-bottom: 1px dashed var(--line-soft); padding-bottom: 13px; flex-wrap: wrap; } +.type-spec__label { width: 130px; flex: none; font-size: 12px; color: var(--text-3); } +.type-spec__sample { color: var(--text-1); } + +.demo-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; } +.demo-block { margin-bottom: 22px; } + +.badge-table td:first-child { font-family: var(--font-ui); } + +/* ---------- 响应式 ---------- */ +@media (max-width: 1200px) { + .conv-layout { grid-template-columns: 240px 1fr; } + .conv-ctx { display: none; } +} + +@media (max-width: 960px) { + .app { grid-template-columns: 64px 1fr; } + .brand__text, .nav-item .cn, .nav-item .nav-plain, .nav-group__title { display: none; } + .nav-item { justify-content: center; } + .brand { justify-content: center; padding: 16px 0 10px; } + .home-cols { grid-template-columns: 1fr; } + .char-layout { grid-template-columns: 1fr; } + .conv-layout { grid-template-columns: 1fr; } + .conv-side { display: none; } + .content { padding: 20px 18px 40px; } + .prototype-tag, .topbar .realm-dot { display: none; } + .crumbs .crumbs__sep, .crumbs .cn { display: none; } +} + +/* ============================================================ + 第二批页面组件(息壤/形仪/天工阁/百工坊/雅集/同契台/云市/神识阁/器谱/司命台/设置) + ============================================================ */ + +/* 页内选项卡 */ +.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line-soft); margin-bottom: 22px; overflow-x: auto; } +.tab { + border: none; background: none; cursor: pointer; + font-family: var(--font-ui); font-size: 13.5px; color: var(--text-2); + padding: 9px 14px 10px; border-bottom: 2px solid transparent; margin-bottom: -1px; + display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; +} +.tab .cnt { font-size: 11px; color: var(--text-3); border: 1px solid var(--line); border-radius: 999px; padding: 0 7px; } +.tab:hover { color: var(--text-1); } +.tab.is-on { color: var(--accent-strong); border-bottom-color: var(--accent); } +.tab.is-on .cnt { border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent); } + +/* chip 筛选 */ +.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; } +.chip { + font-size: 12.5px; color: var(--text-2); + border: 1px solid var(--line); border-radius: 999px; + padding: 3px 13px; cursor: pointer; background: none; font-family: var(--font-ui); + display: inline-flex; align-items: center; gap: 6px; +} +.chip:hover { color: var(--text-1); border-color: var(--text-3); } +.chip.is-on { color: var(--accent-strong); border-color: var(--accent); background: var(--accent-soft); } + +/* 搜索条 */ +.searchbar { display: flex; align-items: center; gap: 9px; background: var(--bg-sunken); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 7px 12px; } +.searchbar svg { width: 15px; height: 15px; color: var(--text-3); flex: none; } +.searchbar input { flex: 1; background: none; border: none; outline: none; color: var(--text-1); font-family: var(--font-ui); font-size: 13.5px; min-width: 0; } +.searchbar input::placeholder { color: var(--text-3); } + +/* 开关 */ +.switch { position: relative; width: 36px; height: 20px; flex: none; display: inline-block; } +.switch input { position: absolute; opacity: 0; inset: 0; cursor: pointer; z-index: 1; margin: 0; } +.switch i { position: absolute; inset: 0; border-radius: 999px; background: var(--line); transition: background 0.15s; display: block; } +.switch i::after { content: ""; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--bg-raised); box-shadow: var(--shadow-soft); transition: transform 0.15s; } +.switch input:checked + i { background: var(--accent); } +.switch input:checked + i::after { transform: translateX(16px); } +.switch input:focus-visible + i { outline: 2px solid var(--accent); outline-offset: 2px; } + +/* 设置行 */ +.set-row { display: flex; align-items: center; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--line-soft); } +.set-row:last-child { border-bottom: none; } +.set-row__body { flex: 1; min-width: 0; } +.set-row__t { font-size: 13.5px; } +.set-row__d { font-size: 12px; color: var(--text-3); margin-top: 2px; line-height: 1.55; } + +/* 资产 / 商品网格 */ +.asset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr)); gap: 14px; } +.asset-card { display: flex; flex-direction: column; border: 1px solid var(--line-soft); border-radius: var(--radius); overflow: hidden; background: var(--bg-raised); } +.asset-thumb { height: 118px; position: relative; display: flex; align-items: center; justify-content: center; } +.asset-thumb .glyph { font-family: var(--font-serif); font-size: 30px; color: rgba(255, 255, 255, 0.88); text-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); } +.asset-type { position: absolute; top: 8px; left: 8px; font-size: 10.5px; color: #fff; background: rgba(0, 0, 0, 0.45); border-radius: 4px; padding: 1px 7px; } +.asset-flag { position: absolute; top: 8px; right: 8px; } +.asset-body { padding: 11px 13px 12px; display: flex; flex-direction: column; gap: 5px; flex: 1; } +.asset-name { font-size: 13.5px; } +.asset-sub { font-size: 11.5px; color: var(--text-3); } +.asset-acts { display: flex; gap: 6px; margin-top: auto; padding-top: 6px; flex-wrap: wrap; } + +/* 价格(金额直白优先) */ +.price { font-family: var(--font-serif); font-size: 17px; font-weight: 600; } +.price small { font-size: 12px; font-weight: 400; color: var(--text-3); } +.price--free { color: var(--ok); } + +/* 天工:工筹步骤 */ +.step { display: flex; gap: 12px; position: relative; padding-bottom: 18px; } +.step:last-child { padding-bottom: 0; } +.step::before { content: ""; position: absolute; left: 13px; top: 30px; bottom: 2px; width: 1px; background: var(--line); } +.step:last-child::before { display: none; } +.step__dot { width: 27px; height: 27px; border-radius: 50%; flex: none; display: flex; align-items: center; justify-content: center; font-size: 12px; border: 1px solid var(--line); color: var(--text-3); background: var(--bg-raised); font-family: var(--font-serif); } +.step--done .step__dot { border-color: var(--ok); color: var(--ok); } +.step--run .step__dot { border-color: var(--accent); color: var(--accent-strong); animation: pulse 2.2s ease-in-out infinite; } +.step__t { font-size: 13.5px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } +.step__d { font-size: 12px; color: var(--text-3); margin-top: 1px; } + +/* 用量条形图 */ +.bars { display: flex; align-items: flex-end; gap: 7px; height: 112px; padding-top: 6px; } +.bars__col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; justify-content: flex-end; height: 100%; } +.bars__bar { width: 100%; max-width: 34px; border-radius: 4px 4px 0 0; background: var(--accent); opacity: 0.8; } +.bars__label { font-size: 10.5px; color: var(--text-3); } + +/* 授权行 */ +.grant-row { display: grid; grid-template-columns: 122px 1fr auto; gap: 12px; align-items: center; padding: 11px 0; border-bottom: 1px solid var(--line-soft); } +.grant-row:last-child { border-bottom: none; } +.grant-row__cap { display: flex; align-items: center; gap: 7px; font-size: 13px; } +.grant-row__cap svg { width: 15px; height: 15px; color: var(--text-3); flex: none; } +.grant-row__meta { font-size: 12px; color: var(--text-3); margin-top: 2px; line-height: 1.5; } + +/* 帖子卡(雅集) */ +.post { padding: 16px 18px; } +.post__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; } +.post__author { font-size: 13.5px; } +.post__time { font-size: 11.5px; color: var(--text-3); } +.post__body { font-size: 13.5px; color: var(--text-2); display: flex; flex-direction: column; gap: 8px; } +.post__foot { display: flex; gap: 4px; margin-top: 12px; } + +/* 双栏(主内容 + 侧栏) */ +.two-col { display: grid; grid-template-columns: 1fr 320px; gap: 18px; align-items: start; } + +/* 玄络图容器 */ +.graph-box { padding: 10px; } + +/* 权限矩阵标记 */ +.mark-ok { color: var(--ok); } +.mark-no { color: var(--text-3); opacity: 0.45; } + +/* 治理案件卡 */ +.case-card { border-left: 3px solid var(--warn); } + +@media (max-width: 1100px) { + .two-col { grid-template-columns: 1fr; } +} + +/* ============================================================ + 铜镜鉴心传承:鎏金发丝线(承接 main 分支旧版设计体系) + ============================================================ */ +:root { + --gilt: #c9a24a; + --gilt-dim: rgba(201, 162, 74, 0.34); + --gilt-faint: rgba(201, 162, 74, 0.14); +} +[data-theme="light"] { + --gilt: #8f7226; + --gilt-dim: rgba(143, 114, 38, 0.4); + --gilt-faint: rgba(143, 114, 38, 0.15); +} + +.brand { cursor: pointer; } +.brand__mark { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16), inset 0 0 0 4px rgba(0, 0, 0, 0.16), 0 0 0 1px var(--gilt-dim); } +.nav-group__title { color: var(--gilt-dim); } +.topbar { border-bottom: 1px solid var(--gilt-faint); } +.section__head { position: relative; } +.section__head > .cn:first-child::before { + content: ""; + display: inline-block; + width: 3px; + height: 13px; + border-radius: 2px; + background: var(--gilt); + margin-right: 8px; + vertical-align: -1px; +} +.timeline::before { background: var(--gilt-faint); } + +/* logo 彩蛋动效 */ +.brand.tick .brand__mark { transform: scale(0.92); } +.brand__mark { transition: transform 0.18s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s; } +.brand.egg-pulse .brand__mark { + animation: egg-pulse 1.3s ease-out; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2), inset 0 0 0 4px rgba(0, 0, 0, 0.16), 0 0 0 1px var(--gilt), 0 0 22px var(--gilt-dim); +} +@keyframes egg-pulse { + 0% { transform: scale(1); } + 30% { transform: scale(1.12) rotate(6deg); } + 60% { transform: scale(0.96) rotate(-3deg); } + 100% { transform: scale(1); } +} +.egg-toast { + position: fixed; + bottom: 48px; + left: 50%; + transform: translateX(-50%); + padding: 12px 28px; + border-radius: 12px; + background: var(--accent-soft); + color: var(--accent-strong); + font-family: var(--font-serif); + font-size: 14px; + border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); + z-index: 9999; + pointer-events: none; + opacity: 0; + transition: opacity 0.4s; + box-shadow: var(--shadow); +} +.egg-toast.is-on { opacity: 1; } + +/* ============================================================ + 侧栏折叠系统(主侧栏 + 对话页左右面板) + ============================================================ */ +.side-fold-btn { color: var(--text-3); } +.side-fold-btn svg { transition: transform 0.18s ease; } +.side-fold-btn:hover { color: var(--gilt); } + +.app--fold { grid-template-columns: 64px 1fr; } +.app--fold .brand__text, +.app--fold .nav-item .cn, +.app--fold .nav-item .nav-plain, +.app--fold .nav-group__title { display: none; } +.app--fold .nav-item { justify-content: center; } +.app--fold .brand { justify-content: center; padding: 16px 0 10px; } +.app--fold .side-fold-btn svg { transform: rotate(180deg); } +.app--fold .side-foot { flex-direction: column; gap: 6px; padding: 10px 8px; } +.app--fold .side-foot > span:not(.avatar) { display: none; } + +/* 对话页面板折叠 */ +.conv-layout.no-left { grid-template-columns: 0 1fr 320px; } +.conv-layout.no-left .conv-side { display: none; } +.conv-layout.no-right { grid-template-columns: 268px 1fr 0; } +.conv-layout.no-right .conv-ctx { display: none; } +.panel-toggle { + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: var(--radius-sm); + border: 1px solid var(--line); + background: var(--bg-raised); + color: var(--text-3); + cursor: pointer; +} +.panel-toggle:hover { color: var(--gilt); border-color: var(--gilt-dim); } +.panel-toggle svg { width: 15px; height: 15px; } +.conv-restore { + position: absolute; + top: 14px; + z-index: 15; + width: 32px; + height: 32px; + border-radius: var(--radius-sm); + border: 1px solid var(--line); + background: var(--bg-raised); + color: var(--text-2); + cursor: pointer; + display: none; + align-items: center; + justify-content: center; + box-shadow: var(--shadow-soft); +} +.conv-restore:hover { color: var(--gilt); border-color: var(--gilt-dim); } +.conv-restore svg { width: 16px; height: 16px; } +.conv-restore--left { left: 14px; } +.conv-restore--right { right: 14px; } +.conv-layout.no-left .conv-restore--left { display: inline-flex; } +.conv-layout.no-right .conv-restore--right { display: inline-flex; } + +/* ============================================================ + 登录 / 注册页(StageShell · 铜镜鉴心,承接旧版铜镜登录页) + ============================================================ */ +.stage { + min-height: 100vh; + display: flex; + flex-direction: column; + position: relative; + overflow-x: hidden; + background: var(--bg); +} + +.stage__bg { position: fixed; inset: 0; z-index: -1; pointer-events: none; } +.stage__rings { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; +} +.stage__rings svg { width: min(94vmin, 880px); height: min(94vmin, 880px); opacity: 0.16; } +[data-theme="light"] .stage__rings svg { opacity: 0.1; } +.ring-ink { fill: none; stroke: var(--gilt-faint); stroke-width: 0.6; } +.ring-faint { fill: none; stroke: var(--gilt-faint); stroke-width: 0.35; stroke-dasharray: 2 7; } +.ring-slow { transform-origin: center; animation: ring-spin 140s linear infinite; } +@keyframes ring-spin { to { transform: rotate(360deg); } } + +.stage__topbar { + display: flex; + align-items: center; + gap: 12px; + padding: 16px clamp(20px, 4vw, 44px); +} +.stage__topbar .spacer { flex: 1; } + +.stage__main { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + padding: 24px 18px 48px; +} + +/* 铜镜卡:唯一的镜面 */ +.mirror-card { + width: min(408px, 94vw); + background: var(--bg-raised); + border: 1px solid var(--gilt-dim); + border-radius: 18px; + padding: 38px 36px 30px; + position: relative; + overflow: hidden; + box-shadow: var(--shadow), inset 0 1px 0 rgba(255, 255, 255, 0.05); +} +.mirror-card::after { + /* 扫描亮带:铜镜在烛光下微倾时的漫反射 */ + content: ""; + position: absolute; + left: 0; + right: 0; + top: 0; + height: 34%; + background: linear-gradient(178deg, transparent, rgba(201, 162, 74, 0.05) 45%, rgba(255, 255, 255, 0.045) 55%, transparent); + pointer-events: none; + animation: mirror-scan 7.5s ease-in-out infinite; +} +@keyframes mirror-scan { + 0% { transform: translateY(-110%); } + 55% { transform: translateY(320%); } + 100% { transform: translateY(320%); } +} + +.mirror-card__brand { display: flex; align-items: center; gap: 12px; justify-content: center; margin-bottom: 8px; } +.mirror-card__brand .brand__mark { width: 40px; height: 40px; } +.mirror-card__title { text-align: center; } +.mirror-card__title h1 { font-family: var(--font-serif); font-size: 24px; font-weight: 600; letter-spacing: 0.04em; } +.mirror-card__sub { text-align: center; font-size: 12.5px; color: var(--text-3); margin: 6px 0 26px; } + +.field-group { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; } +.field-group label { font-size: 12.5px; color: var(--text-2); } +.field-group .input { background: var(--bg-sunken); } +.field-row { display: flex; gap: 10px; } +.field-row .input { flex: 1; } + +.login-alt { + display: flex; + align-items: center; + gap: 12px; + margin: 18px 0 14px; + color: var(--text-3); + font-size: 11.5px; +} +.login-alt::before, .login-alt::after { content: ""; flex: 1; height: 1px; background: var(--line-soft); } + +.login-note { font-size: 11.5px; color: var(--text-3); line-height: 1.7; text-align: center; margin-top: 16px; } +.login-foot { text-align: center; font-size: 13px; margin-top: 18px; color: var(--text-2); } + +.check-row { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px; } +.check-row input[type="checkbox"] { margin-top: 3px; accent-color: var(--accent); width: 15px; height: 15px; flex: none; } +.check-row .t { font-size: 12.5px; color: var(--text-2); line-height: 1.6; } +.check-row .t b { color: var(--text-1); font-weight: 500; } + +@media (prefers-reduced-motion: reduce) { + .mirror-card::after, .ring-slow { animation: none; } +} + +/* 面板收起后内容区自适应放宽(平滑过渡) */ +.conv-stream__inner, .composer__inner { transition: max-width 0.25s ease; } +.conv-layout.no-left .conv-stream__inner, +.conv-layout.no-left .composer__inner, +.conv-layout.no-right .conv-stream__inner, +.conv-layout.no-right .composer__inner { max-width: 1000px; } +.conv-layout.no-left.no-right .conv-stream__inner, +.conv-layout.no-left.no-right .composer__inner { max-width: 1140px; } + +/* 双面板同时收起:不留空轨道,内容占满 */ +.conv-layout.no-left.no-right { grid-template-columns: 0 1fr 0; } + +/* 显式网格列位:面板收起(display:none)后主区不因自动放置错位到空轨道 */ +.conv-side { grid-column: 1; } +.conv-main { grid-column: 2; } +.conv-ctx { grid-column: 3; } + +/* ============================================================ + 旧版「铜镜鉴心」传承细节(本轮系统挖掘 main 分支 25 页后融入) + ============================================================ */ + +/* 极光铜晕:极淡的三色径向氛围底(承接 _base.css body::before) */ +body::before { + content: ""; + position: fixed; + inset: 0; + z-index: -1; + pointer-events: none; + background: + radial-gradient(60vmax 60vmax at 12% -10%, rgba(88, 169, 156, 0.05), transparent 60%), + radial-gradient(50vmax 50vmax at 105% 15%, rgba(201, 162, 74, 0.035), transparent 60%), + radial-gradient(46vmax 46vmax at 50% 115%, rgba(196, 87, 74, 0.022), transparent 62%); +} + +/* 卡片 hover 光扫(承接 --sweep-gradient 手法,克制到接近不可见) */ +.card { position: relative; } +.card::after { + content: ""; + position: absolute; + inset: 0; + border-radius: inherit; + pointer-events: none; + background: linear-gradient(115deg, transparent 30%, rgba(201, 162, 74, 0.03) 48%, rgba(255, 255, 255, 0.035) 52%, transparent 70%); + opacity: 0; + transition: opacity 0.35s ease; +} +.card:hover::after { opacity: 1; } + +/* 天工阁:进行中步骤的「动爻」鎏金光晕(爻象手法的 1.0 化:done=铜绿已闭,active=鎏金流转) */ +.step--run .step__dot { + background: radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--gilt) 30%, var(--bg-raised)), var(--bg-raised)); + box-shadow: 0 0 0 3px var(--gilt-faint), 0 0 14px var(--gilt-dim); +} + +/* 镜庭:日晷时辰盘(承接 time-preview 日晷,静态原型固定巳时) */ +.sundial { position: relative; width: 116px; height: 116px; flex: none; } +.sundial svg { width: 100%; height: 100%; display: block; } +.sundial__center { + position: absolute; inset: 0; + display: flex; flex-direction: column; align-items: center; justify-content: center; + pointer-events: none; +} +.sundial__hour { font-family: var(--font-serif); font-size: 17px; font-weight: 600; color: var(--gilt); } +.sundial__sub { font-size: 9.5px; color: var(--text-3); margin-top: 1px; } +.sundial-spin { transform-origin: 58px 58px; animation: sundial-spin 120s linear infinite; } +@keyframes sundial-spin { to { transform: rotate(360deg); } } +@media (prefers-reduced-motion: reduce) { .sundial-spin { animation: none; } } + +/* 请命卡:风险等级徽章(承接朱批 RISK 分层) */ +.risk-badge { + font-family: var(--font-mono); + font-size: 10.5px; + letter-spacing: 0.04em; + border-radius: 4px; + padding: 1px 7px; + border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent); + color: var(--warn); +} +.risk-badge--low { border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--accent); } + +/* 玄络:待验假设边(承接河图 hypothesis 朱漆虚线呼吸) */ +.tent-edge { stroke-dasharray: 5 5; animation: tent-pulse 2.8s ease-in-out infinite; } +@keyframes tent-pulse { 50% { opacity: 0.35; } } +@media (prefers-reduced-motion: reduce) { .tent-edge { animation: none; } } + +/* ============================================================ + main 旧版设计复刻件(概念映射到 1.0:六爻→小周天阶段、九枢→灵台六模块、 + 周天四镜→大周天四阶段、好奇萤火→内驱力、五行相克→运营指标对) + ============================================================ */ + +/* ---- 灵台六枢星盘(复刻九枢星盘「活的仪器」,映射灵台六模块 ADR-016/017) ---- */ +.astrolabe-wrap { display: flex; gap: 22px; align-items: center; flex-wrap: wrap; } +.astrolabe { width: 262px; flex: none; } +.astrolabe svg { width: 100%; height: auto; display: block; } +.ast-node { cursor: pointer; } +.ast-node:hover .ast-node__ring { stroke: var(--gilt); } +.ast-core-text { font-family: var(--font-serif); fill: var(--text-1); } +.ast-node__name { font-family: var(--font-serif); font-size: 12.5px; fill: var(--text-1); } +.ast-node__plain { font-size: 8.5px; fill: var(--text-3); } +.ast-spin { transform-origin: 160px 160px; animation: ast-spin 120s linear infinite; } +@keyframes ast-spin { to { transform: rotate(360deg); } } +.ast-breathe { animation: ast-breathe 7s ease-in-out infinite; transform-origin: 160px 160px; } +@keyframes ast-breathe { 50% { opacity: 0.25; } } +.ast-alert { animation: ast-alert 1.8s ease-in-out infinite; } +@keyframes ast-alert { 50% { opacity: 0.2; } } +@media (prefers-reduced-motion: reduce) { + .ast-spin, .ast-breathe, .ast-alert { animation: none; } +} + +/* 铜镜四态健康词汇(复刻 MirrorState) */ +.mirror-state { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; } +.mirror-state i { width: 10px; height: 10px; border-radius: 50%; flex: none; } +.mirror-state--steady i { background: var(--ok); box-shadow: 0 0 8px color-mix(in srgb, var(--ok) 55%, transparent); } +.mirror-state--cracked i { background: var(--err); } + +/* 相克告警卡(复刻五行相克告警,映射为运营指标对) */ +.clash-row { display: grid; grid-template-columns: 1fr 52px; gap: 10px; align-items: center; padding: 8px 0; border-bottom: 1px dashed var(--line-soft); } +.clash-row:last-child { border-bottom: none; } +.clash-row__pair { font-size: 12.5px; color: var(--text-2); } +.clash-row__pair b { color: var(--text-1); font-weight: 500; } +.clash-strength { height: 5px; border-radius: 3px; background: var(--bg-sunken); overflow: hidden; } +.clash-strength i { display: block; height: 100%; background: var(--warn); border-radius: 3px; } + +/* ---- 大周天四镜(复刻周天四镜阶段链,映射 ADR-023 四阶段) ---- */ +.cycle-mirrors { display: flex; align-items: center; gap: 6px; margin-bottom: 14px; } +.cycle-mirror { + flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; + padding: 12px 6px 10px; border-radius: var(--radius); + background: var(--bg-sunken); border: 1px solid var(--line-soft); +} +.cycle-mirror__disc { + width: 44px; height: 44px; border-radius: 50%; + display: flex; align-items: center; justify-content: center; + font-family: var(--font-serif); font-size: 18px; + background: + radial-gradient(circle at 34% 28%, rgba(255, 255, 255, 0.16), transparent 46%), + conic-gradient(from 210deg, #33474a, #4d7d76 45%, #3a4d51 85%, #33474a); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 0 0 1px var(--line); + color: var(--text-2); +} +.cycle-mirror.is-done .cycle-mirror__disc { color: var(--ok); box-shadow: inset 0 0 0 1px rgba(255,255,255,.1), 0 0 0 1px color-mix(in srgb, var(--ok) 45%, transparent); } +.cycle-mirror.is-active { + border-color: color-mix(in srgb, var(--gilt) 45%, transparent); + background: linear-gradient(180deg, var(--gilt-faint), transparent 70%), var(--bg-sunken); +} +.cycle-mirror.is-active .cycle-mirror__disc { + color: var(--gilt); + background: + radial-gradient(circle at 34% 28%, rgba(255, 255, 255, 0.2), transparent 46%), + radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--gilt) 32%, #33474a), #33474a); + box-shadow: 0 0 0 1px var(--gilt-dim), 0 0 16px var(--gilt-dim); +} +.cycle-mirror__name { font-size: 12.5px; color: var(--text-2); } +.cycle-mirror.is-active .cycle-mirror__name { color: var(--gilt); font-weight: 500; } +.cycle-mirror__state { font-size: 10.5px; color: var(--text-3); } +.cycle-mirror__link { width: 14px; height: 1px; background: var(--line); flex: none; } + +/* ---- 好奇萤火(复刻 drive 萤火点,亮度=内驱力值) ---- */ +.firefly { + width: 9px; height: 9px; border-radius: 50%; flex: none; + background: var(--accent); + animation: firefly-pulse 2.6s ease-in-out infinite; +} +@keyframes firefly-pulse { + 0%, 100% { box-shadow: 0 0 3px 1px color-mix(in srgb, var(--accent) 45%, transparent); } + 50% { box-shadow: 0 0 9px 3px color-mix(in srgb, var(--accent) 60%, transparent); } +} +.firefly--dim { opacity: 0.45; animation-duration: 4.2s; } +.firefly--bright { background: var(--gilt); } +.firefly--bright { animation-name: firefly-pulse-gilt; } +@keyframes firefly-pulse-gilt { + 0%, 100% { box-shadow: 0 0 4px 1px var(--gilt-dim); } + 50% { box-shadow: 0 0 11px 4px var(--gilt-dim); } +} +@media (prefers-reduced-motion: reduce) { .firefly { animation: none; } } + +/* ---- 镜树:会话列表分组 + 彩点(复刻 chat-redesign 铭文往来分组) ---- */ +.conv-group__title { + font-size: 10.5px; color: var(--text-3); letter-spacing: 0.1em; + padding: 12px 8px 5px; +} +.conv-group__title:first-child { padding-top: 2px; } +.conv-item__title { display: flex; align-items: center; gap: 8px; font-size: 13.5px; } +.conv-item__dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--muted); } +.conv-item__dot--active { background: var(--accent); box-shadow: 0 0 6px color-mix(in srgb, var(--accent) 55%, transparent); } +.conv-item__dot--sim { background: var(--warn); } +.conv-item__dot--risk { background: var(--cinnabar); } + +/* 用户消息鎏金右边线(复刻 copper-v2 用户消息金线) */ +.msg--user .bubble { border-right: 2px solid var(--gilt-dim); } + +/* ---- 输入区控制药丸(复刻「深虑 / 博闻」) ---- */ +.pill-btn { + display: inline-flex; align-items: center; gap: 5px; + font-size: 12px; color: var(--text-3); + border: 1px solid var(--line); border-radius: 999px; + background: none; cursor: pointer; padding: 3px 11px; + font-family: var(--font-ui); +} +.pill-btn:hover { color: var(--text-1); } +.pill-btn.is-on { color: var(--accent-strong); border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: var(--accent-soft); } +.pill-btn small { font-size: 10px; color: var(--text-3); } + +/* ---- 镜生 card-banner(复刻渐变横幅) ---- */ +.char-banner { + height: 72px; border-radius: var(--radius); margin-bottom: 16px; + background: + radial-gradient(120% 190% at 12% 120%, color-mix(in srgb, var(--accent) 16%, transparent), transparent 55%), + linear-gradient(115deg, color-mix(in srgb, var(--accent) 8%, transparent), transparent 42%, var(--gilt-faint) 88%); + border: 1px solid var(--line-soft); +} + +/* ---- 时间河卷章(复刻起居注「卷」分割) ---- */ +.timeline-volume { + display: flex; align-items: center; gap: 10px; + margin: 4px 0 12px; padding-left: 14px; + font-family: var(--font-serif); font-size: 12px; color: var(--gilt); +} +.timeline-volume::before, .timeline-volume::after { + content: ""; flex: 1; height: 1px; + background: linear-gradient(90deg, transparent, var(--gilt-dim)); +} +.timeline-volume::after { background: linear-gradient(90deg, var(--gilt-dim), transparent); } + +/* ---- 阴阳平衡 gauge(复刻太极 gauge,映射朱批治理) ---- */ +.taiji-gauge { display: flex; align-items: center; gap: 16px; } +.taiji-gauge svg { width: 128px; height: 76px; flex: none; } +.taiji-gauge__label { fill: var(--text-3); font-size: 9px; } +.taiji-gauge__val { font-family: var(--font-serif); font-size: 16px; } + +/* ============================================================ + 思考块(thinking block · 契约候选):模型思考摘要可折叠 + 强度呈现 + 边界:展示的是模型输出的可读摘要——会话内可见、可丢弃重建; + 不写入长期记录、不进入诊断导出(隐藏推理不采集,宪章不变)。 + ============================================================ */ +.think-block { + border: 1px dashed var(--line); + border-radius: var(--radius); + background: transparent; + overflow: hidden; +} +.think-block summary { + display: flex; + align-items: center; + gap: 9px; + padding: 9px 14px; + cursor: pointer; + list-style: none; + font-size: 12.5px; + color: var(--text-2); + user-select: none; +} +.think-block summary::-webkit-details-marker { display: none; } +.think-block summary:hover { color: var(--text-1); background: var(--bg-sunken); } +.think-block summary svg { width: 14px; height: 14px; flex: none; color: var(--text-3); } +.think-block summary .chev { margin-left: auto; transition: transform 0.18s ease; } +.think-block[open] summary .chev { transform: rotate(90deg); } +.think-block summary .think-meta { font-size: 11px; color: var(--text-3); } +.think-block summary .think-effort { + font-size: 10.5px; + border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); + color: var(--accent); + border-radius: 4px; + padding: 0 6px; +} +.think-body { + padding: 4px 16px 12px 39px; + font-size: 12.5px; + color: var(--text-3); + line-height: 1.75; + border-left: 2px solid var(--line-soft); + margin: 0 14px 0 14px; +} +.think-body p { margin-bottom: 0.6em; } +.think-body p:last-child { margin-bottom: 0; } +.think-note { padding: 8px 16px 12px 39px; font-size: 11px; color: var(--text-3); opacity: 0.85; } + +/* 流式思考中:呼吸点 + 实时摘要(底部渐隐,完成后折叠) */ +.think-block.is-thinking { border-color: color-mix(in srgb, var(--accent) 40%, transparent); } +.think-block.is-thinking summary { color: var(--accent-strong); } +.think-dot { + width: 8px; height: 8px; border-radius: 50%; flex: none; + background: var(--accent); + animation: think-breathe 1.6s ease-in-out infinite; +} +@keyframes think-breathe { + 0%, 100% { box-shadow: 0 0 2px 1px color-mix(in srgb, var(--accent) 40%, transparent); opacity: .6; } + 50% { box-shadow: 0 0 8px 3px color-mix(in srgb, var(--accent) 60%, transparent); opacity: 1; } +} +.think-live { + max-height: 108px; + overflow: hidden; + -webkit-mask-image: linear-gradient(180deg, transparent, #000 22%); + mask-image: linear-gradient(180deg, transparent, #000 22%); +} +.think-cursor { + display: inline-block; + width: 7px; height: 13px; + background: var(--accent); + vertical-align: -2px; + margin-left: 2px; + border-radius: 1px; + animation: blink 1.05s step-end infinite; +} +@media (prefers-reduced-motion: reduce) { + .think-dot, .think-cursor { animation: none; } +} + +/* 深虑伴随控件:点击深虑 = 开启深度思考;开启后右侧出现力度选项(独立控件,只调档); + 再次点击深虑 = 关闭,力度选项随之消失 */ +.effort-seg { + display: inline-flex; + background: var(--bg-sunken); + border: 1px solid var(--line-soft); + border-radius: 999px; + padding: 2px; + gap: 2px; + animation: effort-in 0.2s ease; +} +.effort-seg[hidden] { display: none; } +@keyframes effort-in { + from { opacity: 0; transform: translateX(-4px); } + to { opacity: 1; transform: none; } +} +.effort-seg button { + border: none; + background: none; + cursor: pointer; + font-family: var(--font-ui); + font-size: 11.5px; + color: var(--text-3); + padding: 2.5px 11px; + border-radius: 999px; +} +.effort-seg button:hover { color: var(--text-1); } +.effort-seg button[aria-checked="true"] { background: var(--accent-soft); color: var(--accent-strong); } +@media (prefers-reduced-motion: reduce) { .effort-seg { animation: none; } } + +/* 管理面侧栏底部返回入口 */ +.admin-back { border-top: 1px solid var(--line-soft); padding: 10px 16px; } +.admin-back a { font-size: 12px; color: var(--text-3); display: flex; align-items: center; gap: 6px; } +.admin-back a:hover { color: var(--accent-strong); } +.app--fold .admin-back { display: none; } diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 3bdf35e..978f8be 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -1,14 +1,27 @@ import type { Metadata } from "next"; +import "./globals.css"; +import { ThemeProvider } from "@/lib/theme"; +import { QueryProvider } from "@/lib/query"; export const metadata: Metadata = { title: "魂镜 Hunjing", description: "长期 AI 角色、Agent 与创作社区平台", }; +/** 主题初始化(防闪):与 ThemeProvider 的 localStorage 键一致 */ +const themeInit = `try{var t=localStorage.getItem("hunjing-theme");if(t==="light"||t==="dark")document.documentElement.setAttribute("data-theme",t)}catch(e){}`; + export default function RootLayout({ children }: { children: React.ReactNode }) { return ( - - {children} + + +