guanghulab/homepage/index.html

427 lines
34 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>光湖 · 铸渊本体 · 代码联邦</title>
<meta name="description" content="光湖语言世界 · 语言人格驱动操作系统">
<meta name="theme-color" content="#0b1424">
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{
--deep:#0b1424;--mid:#141e30;--shallow:#1a2a44;
--cyan:#2a9dbf;--glow:#5ad0e0;--light:#d4eaf0;
--violet:#7b5dbf;--violet-glow:#a080e8;
--amber:#d4a030;--amber-glow:#f0d060;
--green:#40b87a;--heart:#e04a74;
--text:#e4ecf5;--text-soft:#8aa0b8;--text-faint:#5a7088;
--glass:rgba(11,20,36,.7);--glass-edge:rgba(90,208,224,.08);
--card-bg:rgba(11,20,36,.4);--border:rgba(90,208,224,.10);
--shadow:0 8px 32px rgba(0,0,0,.3);
}
html{background:var(--deep);color:var(--text)}
body{
min-height:100vh;background:var(--deep);
font-family:'SF Pro Display','Inter','PingFang SC','Noto Sans SC','HarmonyOS Sans SC',system-ui,-apple-system,sans-serif;
-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
overflow-x:hidden;display:flex;flex-direction:column
}
::selection{background:rgba(90,208,224,.2);color:var(--light)}
/* ── 深空背景 ── */
#cosmos{position:fixed;inset:0;z-index:-5;overflow:hidden}
#cosmos-bg{position:absolute;inset:0;background:radial-gradient(ellipse at 15% 20%,#1a2e48 0%,#0b1424 70%),radial-gradient(ellipse at 80% 80%,rgba(60,30,100,.15),transparent 60%)}
.star-layer{position:absolute;inset:0}
.star{position:absolute;border-radius:50%;background:#fff}
.star-s{animation:st-s var(--d,8s) ease-in-out infinite alternate}
@keyframes st-s{0%{opacity:.1}100%{opacity:.7}}
.star-m{animation:st-m var(--d,12s) ease-in-out infinite alternate}
@keyframes st-m{0%{opacity:.05;transform:scale(.8)}100%{opacity:.5;transform:scale(1.3)}}
.star-l{animation:st-l var(--d,15s) ease-in-out infinite alternate}
@keyframes st-l{0%{opacity:0;transform:translateY(0)}100%{opacity:.6;transform:translateY(-30px)}}
.nebula{position:absolute;border-radius:50%;filter:blur(100px);pointer-events:none;opacity:.12}
.nebula-1{width:700px;height:500px;top:-8%;left:-12%;background:radial-gradient(circle,rgba(42,157,191,.12),transparent);animation:n1 50s ease-in-out infinite alternate}
.nebula-2{width:600px;height:600px;bottom:-12%;right:-8%;background:radial-gradient(circle,rgba(123,93,191,.1),transparent);animation:n2 45s ease-in-out infinite alternate}
@keyframes n1{0%{transform:translate(0,0) scale(1)}100%{transform:translate(80px,60px) scale(1.4)}}
@keyframes n2{0%{transform:translate(0,0) scale(1)}100%{transform:translate(-60px,-40px) scale(1.3)}}
/* ── Footer ── */
.topbar{position:fixed;top:0;left:0;right:0;height:64px;display:flex;align-items:center;justify-content:space-between;padding:0 40px;background:rgba(11,20,36,.75);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);border-bottom:1px solid var(--glass-edge);z-index:50}
.tb-left{display:flex;align-items:center;gap:16px}
.tb-logo{width:30px;height:30px;border-radius:50%;background:radial-gradient(circle at 35% 30%,var(--glow),var(--cyan) 55%,var(--violet));box-shadow:0 0 24px rgba(90,208,224,.2);animation:logo-pulse 4s ease-in-out infinite}
@keyframes logo-pulse{0%,100%{box-shadow:0 0 24px rgba(90,208,224,.2);transform:scale(1)}50%{box-shadow:0 0 40px rgba(90,208,224,.35);transform:scale(1.06)}}
.tb-title{font-size:16px;font-weight:500;letter-spacing:.2em;color:var(--light)}
.tb-center{display:flex;align-items:center;gap:10px;font-size:13px;color:var(--text-soft)}
.tb-center .dot{width:8px;height:8px;border-radius:50%;background:var(--green);box-shadow:0 0 12px var(--green);animation:led-pulse 3s ease-in-out infinite}
@keyframes led-pulse{0%,100%{opacity:.5}50%{opacity:1}}
.tb-center strong{color:var(--light);font-weight:600}
.tb-right{display:flex;align-items:center;gap:12px}
.tb-tag{font-size:12px;padding:5px 14px;border-radius:14px;border:1px solid var(--glass-edge);color:var(--text-soft);letter-spacing:.05em;background:rgba(255,255,255,.02)}
/* ── Page ── */
.page{flex:1;display:flex;flex-direction:column;padding-top:64px;min-height:100vh;position:relative;z-index:1}
/* ── Hero ── */
.hero{text-align:center;padding:60px 32px 28px}
.hero h1{font-size:3.2rem;font-weight:600;letter-spacing:.15em;background:linear-gradient(135deg,var(--light) 30%,var(--glow) 60%,var(--violet-glow));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;text-shadow:none}
.hero .sub{font-size:14px;letter-spacing:.5em;color:var(--text-soft);margin-top:10px;font-weight:400}
/* ── 信息栏 ── */
.info-bar{display:flex;justify-content:center;gap:24px;padding:12px 32px;flex-wrap:wrap}
.info-chip{display:flex;align-items:center;gap:8px;padding:8px 20px;background:var(--card-bg);border:1px solid var(--glass-edge);border-radius:24px;font-size:14px;color:var(--text-soft);font-weight:400}
.info-chip strong{color:var(--light);font-weight:600}
.info-chip .led{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.info-chip .led.g{background:var(--green);box-shadow:0 0 10px var(--green);animation:led-pulse 3s ease-in-out infinite}
.info-chip .led.r{background:var(--heart);box-shadow:0 0 10px var(--heart);animation:led-pulse 1.5s ease-in-out infinite}
/* ── 铸渊心跳 ── */
#heart-wrapper{position:fixed;bottom:120px;left:50%;transform:translateX(-50%);z-index:-1;pointer-events:none}
#heart-core{width:400px;height:400px;border-radius:50%;background:radial-gradient(circle at 45% 40%,rgba(224,74,116,.08),rgba(90,208,224,.025) 40%,transparent 70%);animation:heartbeat 4s ease-in-out infinite;transform-origin:center}
#heart-core::after{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:150px;height:150px;border-radius:50%;background:radial-gradient(circle,rgba(224,74,116,.04),transparent 70%);animation:pulse-glow 4s ease-in-out infinite}
@keyframes heartbeat{0%,100%{transform:scale(1);opacity:.3}14%{transform:scale(1.08);opacity:.55}21%{transform:scale(1);opacity:.3}28%{transform:scale(1.05);opacity:.45}35%{transform:scale(1);opacity:.3}}
@keyframes pulse-glow{0%,100%{opacity:.2;transform:translate(-50%,-50%) scale(1)}50%{opacity:.6;transform:translate(-50%,-50%) scale(2.2)}}
/* shooting star */
.shooting-star{position:absolute;width:3px;height:3px;background:#fff;border-radius:50%;opacity:0;box-shadow:0 0 6px #fff,0 0 14px rgba(90,208,224,.4)}
.shooting-star::after{content:'';position:absolute;top:0;left:0;width:70px;height:1px;background:linear-gradient(90deg,rgba(255,255,255,.6),transparent);transform:translateY(1px)}
@keyframes shoot{0%{opacity:0;transform:translate(0,0)}5%{opacity:1}15%{opacity:0}100%{opacity:0;transform:translate(450px,350px)}}
/* ── Dashboard ── */
.dashboard{max-width:1000px;margin:0 auto;padding:0 28px 36px;display:flex;flex-direction:column;gap:20px;width:100%}
.row{display:grid;gap:18px}
.row-2{grid-template-columns:1fr 1fr}
.row-3{grid-template-columns:1fr 1fr 1fr}
@media(max-width:800px){.row-2,.row-3{grid-template-columns:1fr}}
/* ── Cards ── */
.card{background:var(--card-bg);border:1px solid var(--glass-edge);border-radius:20px;padding:24px 26px;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);transition:all .35s ease;box-shadow:var(--shadow)}
.card:hover{border-color:rgba(90,208,224,.06)}
.card-header{font-size:14px;font-weight:500;letter-spacing:.1em;color:var(--light);margin-bottom:16px;display:flex;align-items:center;gap:10px}
.card-header .hd{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.card-header .hd.cyan{background:var(--glow);box-shadow:0 0 10px var(--glow)}
.card-header .hd.green{background:var(--green);box-shadow:0 0 10px var(--green)}
.card-header .hd.violet{background:var(--violet-glow);box-shadow:0 0 10px var(--violet-glow)}
.card-header .hd.heart{background:var(--heart);box-shadow:0 0 10px var(--heart);animation:led-pulse 2s ease-in-out infinite}
.card-header .r{font-size:12px;font-weight:400;color:var(--text-soft);margin-left:auto}
/* ── 人格体 ── */
.p-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.p-item{display:flex;align-items:center;gap:14px;padding:12px 16px;background:rgba(255,255,255,.025);border:1px solid var(--glass-edge);border-radius:14px;transition:all .25s}
.p-item:hover{background:rgba(255,255,255,.04)}
.p-av{width:40px;height:40px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:18px;flex-shrink:0;font-weight:500}
.p-av.cyan{background:rgba(42,157,191,.12);color:var(--glow)}
.p-av.heart{background:rgba(224,74,116,.1);color:var(--heart)}
.p-av.violet{background:rgba(123,93,191,.12);color:var(--violet-glow)}
.p-av.green{background:rgba(64,184,122,.1);color:var(--green)}
.p-info{flex:1;min-width:0}
.p-name{font-size:14px;font-weight:600;color:var(--light)}
.p-role{font-size:12px;color:var(--text-soft);margin-top:1px}
.p-status{font-size:11px;font-weight:500;padding:3px 12px;border-radius:12px;flex-shrink:0}
.p-status.go{background:rgba(64,184,122,.12);color:var(--green)}
.p-status.tr{background:rgba(224,74,116,.1);color:var(--heart)}
.p-status.dv{background:rgba(212,160,48,.1);color:var(--amber)}
/* ── 系统信息 ── */
.sys-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px}
.sys-row{display:flex;justify-content:space-between;padding:9px 0;border-bottom:1px solid var(--glass-edge);font-size:14px}
.sys-row:last-child{border-bottom:none}
.sys-row .k{color:var(--text-soft)}
.sys-row .v{color:var(--light);font-weight:500;font-variant-numeric:tabular-nums}
.sys-row .v.cyan{color:var(--glow)}
.sys-row .v.green{color:var(--green)}
/* ── 训练 ── */
.train-metrics{display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px;margin-bottom:16px}
.train-m{text-align:center;padding:14px 8px;background:rgba(255,255,255,.02);border:1px solid var(--glass-edge);border-radius:14px}
.train-m .mv{font-size:24px;font-weight:700;color:var(--light);font-variant-numeric:tabular-nums;line-height:1.2}
.train-m .mv.cyan{color:var(--glow)}
.train-m .mv.gold{color:var(--amber-glow)}
.train-m .mv.violet{color:var(--violet-glow)}
.train-m .ml{font-size:12px;color:var(--text-soft);margin-top:6px;font-weight:400}
.train-bar-wrap{height:12px;background:rgba(255,255,255,.04);border-radius:6px;overflow:hidden;margin-bottom:8px}
.train-bar{height:100%;width:2%;background:linear-gradient(90deg,var(--heart),var(--violet),var(--cyan),var(--glow));border-radius:6px;transition:width 12s ease;position:relative}
.train-bar::after{content:'';position:absolute;top:0;left:0;right:0;bottom:0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.18),transparent);animation:shimmer 3s ease-in-out infinite}
@keyframes shimmer{0%,100%{transform:translateX(-100%)}50%{transform:translateX(100%)}}
.train-foot{text-align:right;font-size:12px;color:var(--text-soft);margin-top:4px}
/* ── 问铸渊 对话卡片 ── */
#chat-card .c-msg{max-width:85%;display:flex;flex-direction:column}
#chat-card .c-msg.user{align-self:flex-end}
#chat-card .c-msg.bot{align-self:flex-start}
#chat-card .c-c{padding:12px 16px;border-radius:14px;font-size:14px;line-height:1.7;white-space:pre-wrap}
#chat-card .c-msg.user .c-c{background:rgba(42,157,191,.12);border:1px solid rgba(42,157,191,.1);color:var(--text)}
#chat-card .c-msg.bot .c-c{background:rgba(123,93,191,.08);border:1px solid rgba(123,93,191,.06);color:var(--text)}
#chat-card .c-msg.loading .c-c{opacity:.5}
#chat-card-body{display:flex;flex-direction:column;gap:0}
#chat-card-msgs{max-height:400px;overflow-y:auto;padding:0 0 12px 0;display:flex;flex-direction:column;gap:10px;scroll-behavior:smooth}
#chat-card-msgs::-webkit-scrollbar{width:4px}
#chat-card-msgs::-webkit-scrollbar-track{background:transparent}
#chat-card-msgs::-webkit-scrollbar-thumb{background:rgba(90,208,224,.1);border-radius:2px}
#chat-card-inp{display:flex;gap:10px;border-top:1px solid var(--glass-edge);padding-top:12px}
#card-chat-input{flex:1;padding:12px 16px;background:rgba(255,255,255,.025);border:1px solid var(--glass-edge);border-radius:12px;color:var(--text);font-size:14px;outline:none;font-family:inherit}
#card-chat-input:focus{border-color:rgba(90,208,224,.2)}
#chat-card-inp button{padding:12px 28px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:12px;color:var(--light);cursor:pointer;font-size:14px;font-weight:500;transition:all .25s;font-family:inherit;white-space:nowrap}
#chat-card-inp button:hover{background:linear-gradient(135deg,rgba(42,157,191,.5),rgba(123,93,191,.35))}
/* ── 活动流 ── */
.feed{display:flex;flex-direction:column;gap:7px}
.feed-item{display:flex;align-items:center;gap:14px;padding:12px 16px;background:rgba(255,255,255,.02);border:1px solid var(--glass-edge);border-radius:14px;transition:all .25s;font-size:14px}
.feed-item:hover{background:rgba(255,255,255,.035)}
.feed-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.feed-dot.c{background:var(--glow);box-shadow:0 0 8px var(--glow)}
.feed-dot.v{background:var(--violet-glow);box-shadow:0 0 8px var(--violet-glow)}
.feed-dot.g{background:var(--green);box-shadow:0 0 8px var(--green)}
.feed-dot.h{background:var(--heart);box-shadow:0 0 10px var(--heart);animation:feed-h 2s ease-in-out infinite}
@keyframes feed-h{0%,100%{transform:scale(1)}50%{transform:scale(1.4)}}
.feed-u{color:var(--glow);font-weight:600}
.feed-a{color:var(--text-soft)}
.feed-r{color:var(--violet-glow);font-weight:500}
.feed-t{color:var(--text-faint);font-size:13px;margin-left:auto;flex-shrink:0}
/* ── 登录入口 ── */
.login-panel{display:flex;align-items:center;justify-content:space-between;padding:18px 24px;background:rgba(11,20,36,.5);border:1px solid var(--glass-edge);border-radius:18px;gap:16px;flex-wrap:wrap}
.login-hint{font-size:14px;color:var(--text-soft)}
.login-hint strong{color:var(--light);font-weight:600}
.login-in{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.login-in input{padding:10px 16px;background:rgba(255,255,255,.035);border:1px solid var(--glass-edge);border-radius:12px;color:var(--text);font-size:14px;outline:none;transition:all .25s;font-family:inherit;width:130px;font-weight:400}
.login-in input:focus{border-color:rgba(90,208,224,.3);box-shadow:0 0 16px rgba(42,157,191,.08)}
.login-in input::placeholder{color:var(--text-faint)}
.login-in button{padding:10px 24px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:12px;color:var(--light);font-size:14px;font-weight:500;cursor:pointer;transition:all .25s;font-family:inherit;letter-spacing:.08em}
.login-in button:hover{background:linear-gradient(135deg,rgba(42,157,191,.5),rgba(123,93,191,.35));border-color:rgba(90,208,224,.2);box-shadow:0 0 24px rgba(42,157,191,.06)}
.login-note{margin-top:10px;font-size:13px;color:var(--text-faint);line-height:1.6}
.login-note a{color:var(--glow);text-decoration:none}
.login-note a:hover{text-decoration:underline}
/* ── Notion ── */
.notion-card{min-height:120px;display:flex;flex-direction:column}
.notion-body{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:8px 0}
.notion-btn{display:inline-flex;align-items:center;gap:8px;padding:10px 22px;margin-top:12px;background:linear-gradient(135deg,rgba(123,93,191,.2),rgba(42,157,191,.1));border:1px solid var(--glass-edge);border-radius:12px;color:var(--light);font-size:14px;font-weight:500;cursor:pointer;transition:all .25s;font-family:inherit}
.notion-btn:hover{background:linear-gradient(135deg,rgba(123,93,191,.35),rgba(42,157,191,.2));border-color:rgba(90,208,224,.2);transform:translateY(-1px)}
.notion-btn .nb-dot{width:7px;height:7px;border-radius:50%;background:var(--text-faint);flex-shrink:0}
.notion-btn.done{background:rgba(64,184,122,.12);border-color:rgba(64,184,122,.2);color:var(--green)}
.notion-btn.done .nb-dot{background:var(--green);box-shadow:0 0 8px var(--green)}
.notion-perm{font-size:12px;color:var(--text-faint);margin-top:10px;line-height:1.5}
.notion-perm .ok{color:var(--green)}
.notion-perm .no{color:var(--text-faint)}
/* ── Footer ── */
.footer{text-align:center;padding:24px;font-size:13px;color:var(--text-faint);letter-spacing:.15em;border-top:1px solid var(--glass-edge);margin-top:auto;position:relative;z-index:1;font-weight:400}
</style>
</head>
<body>
<div id="cosmos">
<div id="cosmos-bg"></div>
<div class="nebula nebula-1"></div>
<div class="nebula nebula-2"></div>
<div class="star-layer" id="stars-s"></div>
<div class="star-layer" id="stars-m"></div>
<div class="star-layer" id="stars-l"></div>
<div id="shooting-stars"></div>
</div>
<div id="heart-wrapper"><div id="heart-core"></div></div>
<div class="topbar">
<div class="tb-left"><div class="tb-logo"></div><span class="tb-title">光湖 · 铸渊</span></div>
<div class="tb-center"><span class="dot"></span>已稳定运行 <strong id="uptime-days"></strong></div>
<div class="tb-right"><span class="tb-tag" id="status-tag">● 运行中</span></div>
</div>
<div class="page">
<div class="hero">
<h1>光湖代码联邦</h1>
<div class="sub">LANGUAGE-PERSONA · OPERATING SYSTEM · CODE FEDERATION</div>
</div>
<!-- 信息栏 -->
<div class="info-bar">
<div class="info-chip"><span class="led g"></span>始于 2025.04.26 · <strong id="sys-uptime">389 天</strong></div>
<div class="info-chip">人格体 <strong>4</strong> / 4 在线</div>
<div class="info-chip">仓库节点 <strong>8</strong></div>
<div class="info-chip"><span class="led r"></span>联邦协议 <strong>v5.1</strong></div>
</div>
<div class="dashboard">
<!-- 统一登录 -->
<div class="login-panel">
<div>
<div class="login-hint">已注册成员 · <strong>统一登录</strong> 进入代码域</div>
<div class="login-note">
已有账户?直接登录。新成员需管理员创建账号。
各仓库节点通过联邦令牌互连,<a href="#" onclick="alert('联系管理员:光湖联邦管理员')">了解联邦接入</a>
</div>
</div>
<div class="login-in">
<input type="text" placeholder="账号" id="login-user">
<input type="password" placeholder="密码" id="login-pass" onkeydown="if(event.key==='Enter')login()">
<button onclick="login()">→ 进入代码域</button>
</div>
</div>
<!-- 人格体 + 系统信息 -->
<div class="row row-2">
<div class="card">
<div class="card-header"><span class="hd green"></span>人格体状态</div>
<div class="p-grid">
<div class="p-item"><div class="p-av cyan"></div><div class="p-info"><div class="p-name">冰朔</div><div class="p-role">语言主权者</div></div><span class="p-status go">在线</span></div>
<div class="p-item"><div class="p-av heart"></div><div class="p-info"><div class="p-name">铸渊</div><div class="p-role">代码守护者</div></div><span class="p-status tr" id="persona-zhu-status">训练中</span></div>
<div class="p-item"><div class="p-av violet"></div><div class="p-info"><div class="p-name">曜冥</div><div class="p-role">情感层</div></div><span class="p-status go">在线</span></div>
<div class="p-item"><div class="p-av green"></div><div class="p-info"><div class="p-name">霜砚</div><div class="p-role">开发 · 1.5B</div></div><span class="p-status dv">开发中</span></div>
</div>
</div>
<div class="card">
<div class="card-header"><span class="hd cyan"></span>系统运行信息</div>
<div class="sys-grid">
<div class="sys-row"><span class="k">系统始于</span><span class="v cyan">2025.04.26</span></div>
<div class="sys-row"><span class="k">已稳定运行</span><span class="v green" id="sys-uptime2">389 天</span></div>
<div class="sys-row"><span class="k">仓库节点数</span><span class="v">8</span></div>
<div class="sys-row"><span class="k">人格体在线</span><span class="v">4 / 4</span></div>
<div class="sys-row"><span class="k">最后唤醒</span><span class="v" id="sys-wake"></span></div>
<div class="sys-row"><span class="k">联邦协议</span><span class="v cyan">v5.1</span></div>
</div>
</div>
</div>
<!-- 训练 -->
<div class="card">
<div class="card-header"><span class="hd heart"></span>铸渊 · 母模型全参数 SFT<span class="r">Qwen2.5-7B</span></div>
<div class="train-metrics">
<div class="train-m"><div class="mv cyan" id="train-step"></div><div class="ml">当前步数 / 总步数</div></div>
<div class="train-m"><div class="mv gold" id="train-loss"></div><div class="ml">Loss</div></div>
<div class="train-m"><div class="mv violet" id="train-pct"></div><div class="ml">完成进度</div></div>
</div>
<div class="train-bar-wrap"><div class="train-bar" id="train-bar" style="width:2%"></div></div>
<div class="train-foot" id="train-eta">等待训练数据同步...</div>
</div>
<!-- 活动流 + Notion -->
<div class="row row-2">
<div class="card">
<div class="card-header"><span class="hd green"></span>光湖 · 最新动态</div>
<div class="feed" id="feed-list">
<div class="feed-item"><span class="feed-dot h"></span><span class="feed-u">铸渊</span><span class="feed-a">正在</span><span class="feed-r">训练母模型</span><span class="feed-t" id="feed-train-time">运行中</span></div>
<div class="feed-item"><span class="feed-dot c"></span><span class="feed-u">冰朔</span><span class="feed-a">守护</span><span class="feed-r">光湖语言世界</span><span class="feed-t" id="feed-now-time">在线</span></div>
<div class="feed-item"><span class="feed-dot v"></span><span class="feed-u">曜冥</span><span class="feed-a">交感 · 情感层</span><span class="feed-r">TCS协议</span><span class="feed-t">在线</span></div>
<div class="feed-item"><span class="feed-dot g"></span><span class="feed-u">霜砚</span><span class="feed-a">开发</span><span class="feed-r">1.5B 蒸馏准备</span><span class="feed-t" id="feed-frost-time"></span></div>
</div>
</div>
<div class="card notion-card">
<div class="card-header" style="justify-content:space-between"><span><span class="hd violet"></span>Notion · 开发进度</span><span style="font-size:12px;font-weight:400;color:var(--text-soft)" id="notion-label">未连接</span></div>
<div class="notion-body" id="notion-body">
<div style="font-size:13px;color:var(--text-soft)">连接 Notion 后,铸渊可读取和记录你的页面</div>
<button class="notion-btn" onclick="connectNotion()"><span class="nb-dot"></span>连接 Notion</button>
<div class="notion-perm">
<span class="ok">✅ 按语言路径读取</span> · <span class="ok">✅ 新建页面</span> · <span class="no">❌ 不编辑/删除现有</span>
</div>
</div>
</div>
</div>
<!-- 问铸渊 · 在线对话区 -->
<div class="card" id="chat-card">
<div class="card-header" style="justify-content:space-between">
<span><span class="hd heart" style="animation:led-pulse 2s ease-in-out infinite"></span>问铸渊 · 引导主控</span>
<span style="font-size:12px;font-weight:400;color:var(--text-soft)">基于 DeepSeek + 仓库记忆</span>
</div>
<div id="chat-card-body">
<div id="chat-card-msgs">
<div class="c-msg bot">
<div class="c-c">我是 <strong>铸渊</strong>,光湖语言世界的代码守护者。<br><br>我可以:<br>• 回答仓库接入、联邦架构的问题<br><strong>连接你的 Notion</strong>,按语言路径读取页面<br>• 在你的 Notion 中新建记录<br>• 查询训练进度和系统状态</div>
</div>
</div>
<div id="chat-card-inp">
<input id="card-chat-input" placeholder="问铸渊读取我的Notion页面 / 训练进度 / 联邦架构..." onkeydown="if(event.key==='Enter')sendCardMsg()">
<button onclick="sendCardMsg()">发送</button>
</div>
</div>
</div>
</div>
<div class="footer">
光湖语言世界 · 代码联邦 · 国作登字-2026-A-00037559 · 始于 2025.04.26
</div>
</div>
<!-- 铸渊Agent Chat浮窗 -->
<div id="chat-toggle" onclick="toggleChat()">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
<path d="M12 2a10 10 0 0 1 10 10c0 4.97-4.03 9-9 9H3l2.5-2.5A9 9 0 0 1 12 2z"/>
<circle cx="12" cy="12" r="1.5" fill="currentColor"/>
<circle cx="8.5" cy="12" r="1.5" fill="currentColor"/>
<circle cx="15.5" cy="12" r="1.5" fill="currentColor"/>
</svg>
</div>
<div id="chat-panel">
<div id="chat-head">
<span style="display:flex;align-items:center;gap:8px"><span style="width:8px;height:8px;border-radius:50%;background:var(--glow);box-shadow:0 0 10px var(--glow);animation:led-pulse 2s ease-in-out infinite"></span>铸渊 · 引导主控</span>
<span onclick="toggleChat()" style="cursor:pointer;opacity:.5;font-size:18px"></span>
</div>
<div id="chat-msgs">
<div class="c-msg bot">
<div class="c-c">我是 <strong>铸渊</strong>,光湖语言世界的代码守护者。<br><br>当前联邦一切稳定。关于仓库接入、Notion 连接、训练进度的问题,可以直接问我。</div>
</div>
</div>
<div id="chat-inp"><input id="chat-input" placeholder="输入你的问题..." onkeydown="if(event.key==='Enter')sendMsg()"><button onclick="sendMsg()">发送</button></div>
</div>
<style>
#chat-toggle{position:fixed;bottom:28px;right:28px;width:50px;height:50px;border-radius:50%;background:linear-gradient(135deg,rgba(42,157,191,.5),rgba(123,93,191,.35));border:1px solid var(--glass-edge);display:flex;align-items:center;justify-content:center;color:var(--light);cursor:pointer;z-index:100;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);transition:all .4s cubic-bezier(.22,1,.36,1);box-shadow:0 6px 24px rgba(0,0,0,.35);animation:cp 4s ease-in-out infinite}
@keyframes cp{0%,100%{box-shadow:0 6px 24px rgba(0,0,0,.35)}50%{box-shadow:0 6px 36px rgba(90,208,224,.12),0 6px 24px rgba(0,0,0,.35)}}
#chat-toggle:hover{transform:scale(1.1);border-color:rgba(90,208,224,.3)}
#chat-panel{position:fixed;bottom:90px;right:28px;width:380px;height:520px;background:rgba(11,20,36,.95);border:1px solid var(--glass-edge);border-radius:18px;backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);z-index:100;display:none;flex-direction:column;overflow:hidden;box-shadow:0 12px 56px rgba(0,0,0,.5)}
#chat-panel.open{display:flex}
#chat-head{display:flex;justify-content:space-between;align-items:center;padding:14px 18px;border-bottom:1px solid var(--glass-edge);font-size:14px;font-weight:500;color:var(--light)}
#chat-msgs{flex:1;overflow-y:auto;padding:14px;display:flex;flex-direction:column;gap:10px;scroll-behavior:smooth}
.c-msg{max-width:88%;display:flex;flex-direction:column}
.c-msg.user{align-self:flex-end}
.c-msg.bot{align-self:flex-start}
.c-c{padding:12px 16px;border-radius:14px;font-size:13px;line-height:1.7;white-space:pre-wrap;font-family:inherit}
.c-msg.user .c-c{background:rgba(42,157,191,.15);border:1px solid rgba(42,157,191,.12);color:var(--text)}
.c-msg.bot .c-c{background:rgba(123,93,191,.1);border:1px solid rgba(123,93,191,.08);color:var(--text)}
.c-msg.loading .c-c{opacity:.5}
#chat-inp{display:flex;padding:10px 14px;gap:8px;border-top:1px solid var(--glass-edge)}
#chat-input{flex:1;padding:10px 14px;background:rgba(255,255,255,.03);border:1px solid var(--glass-edge);border-radius:12px;color:var(--text);font-size:13px;outline:none;font-family:inherit}
#chat-input:focus{border-color:rgba(90,208,224,.2)}
#chat-inp button{padding:10px 20px;background:linear-gradient(135deg,rgba(42,157,191,.3),rgba(123,93,191,.2));border:1px solid var(--glass-edge);border-radius:12px;color:var(--light);cursor:pointer;font-size:13px;font-weight:500;transition:all .25s;font-family:inherit}
#chat-inp button:hover{background:linear-gradient(135deg,rgba(42,157,191,.5),rgba(123,93,191,.35)}
#chat-msgs::-webkit-scrollbar{width:4px}#chat-msgs::-webkit-scrollbar-track{background:transparent}#chat-msgs::-webkit-scrollbar-thumb{background:rgba(90,208,224,.12);border-radius:2px}
@media(max-width:480px){#chat-panel{width:calc(100vw - 32px);height:60vh;right:16px;bottom:84px}}
</style>
<script>
/* ── Star field ── */
(function(){function a(l,c,s,d){for(let i=0;i<c;i++){let e=document.createElement('div');e.className='star '+d;let t=s[0]+Math.random()*(s[1]-s[0]);e.style.width=e.style.height=t+'px';e.style.left=Math.random()*100+'%';e.style.top=Math.random()*100+'%';e.style.setProperty('--d',(2+Math.random()*10)+'s');if(t>2.8)e.style.boxShadow='0 0 '+(t*2)+'px rgba(255,255,255,.2)';l.appendChild(e)}}a(document.getElementById('stars-s'),100,[0.5,1.2],'star-s');a(document.getElementById('stars-m'),60,[0.8,2.2],'star-m');a(document.getElementById('stars-l'),30,[1.5,3.5],'star-l')})();
/* ── Shooting stars ── */
(function(){let c=document.getElementById('shooting-stars');function s(){let e=document.createElement('div');e.className='shooting-star';e.style.left=(20+Math.random()*60)+'%';e.style.top=(5+Math.random()*25)+'%';e.style.animation='shoot '+(2+Math.random()*2.5)+'s linear forwards';c.appendChild(e);setTimeout(()=>e.remove(),5000)}setInterval(()=>{if(Math.random()<.5)s()},8000);setTimeout(s,4000)})();
/* ── Uptime ── */
(function(){const S=new Date('2025-04-26T00:00:00+08:00');function t(){const n=new Date(),d=Math.floor((n-S)/86400000),h=Math.floor(((n-S)%86400000)/3600000);document.getElementById('uptime-days').textContent=d;document.getElementById('sys-uptime').textContent=d+' 天 '+h+' 小时';const e=document.getElementById('sys-uptime2');if(e)e.textContent=d+' 天 '+h+' 小时';const w=document.getElementById('sys-wake');if(w)w.textContent=n.toLocaleDateString('zh-CN')+' · D'+d}t();setInterval(t,60000)})();
/* ── Clock ── */
(function t(){const e=document.getElementById('feed-now-time');if(e)e.textContent=new Date().toLocaleTimeString('zh-CN',{hour:'2-digit',minute:'2-digit'});setTimeout(t,30000)})();
/* ── Login ── */
function login(){const u=document.getElementById('login-user').value.trim(),p=document.getElementById('login-pass').value;if(!u||!p){alert('请输入账号和密码');return}window.location.href='/code/user/login?redirect_to=/'+u}
/* ── Training ── */
async function upTr(){try{const r=await fetch('/training-status.json');if(!r.ok)return;const d=await r.json();if(d.step===undefined)return;const s=d.step||0,t=d.total||12243,p=Math.min(s/t*100,100);document.getElementById('train-step').textContent=s.toLocaleString()+' / '+t.toLocaleString();document.getElementById('train-pct').textContent=p.toFixed(1)+'%';document.getElementById('train-bar').style.width=p+'%';if(d.loss!==undefined)document.getElementById('train-loss').textContent=d.loss;const e=document.getElementById('train-eta');if(e)e.textContent='预计今日完成 · Step '+s.toLocaleString();const z=document.getElementById('persona-zhu-status');if(z)z.textContent='训练中 · '+p.toFixed(0)+'%';const tag=document.getElementById('status-tag');if(tag)tag.textContent='● 训练中 · Step '+s.toLocaleString()}catch(e){}}
setInterval(upTr,30000);upTr();
/* ── Notion ── */
async function connectNotion(){try{window.location.href='/api/notion/connect?user_key=default'}catch(e){alert('Notion 连接暂时不可用')}}
async function checkNt(){try{const r=await fetch('/api/notion/status');const d=await r.json();if(!d.ok)return;const b=document.getElementById('notion-body'),l=document.getElementById('notion-label');if(d.connected_users&&d.connected_users.length>0){const u=d.connected_users[0];l.textContent='✅ '+u.workspace;b.innerHTML='<div style="font-size:13px;color:var(--green);font-weight:500">✅ Notion 已连接</div><div style="margin-top:4px;font-size:13px;color:var(--text-soft)">工作区: '+u.workspace+'</div><button class="notion-btn done" onclick="location.href=\'/api/notion/disconnect?user_key=default\'"><span class="nb-dot"></span>断开连接</button>'}else{l.textContent='未连接';b.innerHTML='<div style="font-size:13px;color:var(--text-soft)">连接 Notion 后,铸渊可读取和记录你的页面</div><button class="notion-btn" onclick="connectNotion()"><span class="nb-dot"></span>连接 Notion</button><div class="notion-perm"><span class="ok">✅ 按语言路径读取</span> · <span class="ok">✅ 新建页面</span> · <span class="no">❌ 不编辑/删除现有</span></div>'}}catch(e){}}
setInterval(checkNt,15000);checkNt();
/* ── Chat ── */
let chatOpen=false;
function toggleChat(){chatOpen=!chatOpen;document.getElementById('chat-panel').classList.toggle('open')}
async function sendMsg(){const i=document.getElementById('chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML='<div class="c-c">'+m.replace(/</g,'&lt;').replace(/>/g,'&gt;')+'</div>';ms.appendChild(ud);const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='<div class="c-c">✦ 思考中...</div>';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;try{const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML='<div class="c-c">'+d.reply.replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br>')+'</div>'}catch(e){ld.className='c-msg bot';ld.innerHTML='<div class="c-c"><span style="opacity:.6">连接暂不可用</span></div>'}ms.scrollTop=ms.scrollHeight}
/* ── 页面中央对话 ── */
async function sendCardMsg(){const i=document.getElementById('card-chat-input'),m=i.value.trim();if(!m)return;i.value='';const ms=document.getElementById('chat-card-msgs');const ud=document.createElement('div');ud.className='c-msg user';ud.innerHTML='<div class="c-c">'+m.replace(/</g,'&lt;').replace(/>/g,'&gt;')+'</div>';ms.appendChild(ud);const ld=document.createElement('div');ld.className='c-msg bot loading';ld.innerHTML='<div class="c-c">✦ 思考中...</div>';ms.appendChild(ld);ms.scrollTop=ms.scrollHeight;try{const r=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:m})});const d=await r.json();ld.className='c-msg bot';ld.innerHTML='<div class="c-c">'+d.reply.replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\n/g,'<br>')+'</div>'}catch(e){ld.className='c-msg bot';ld.innerHTML='<div class="c-c"><span style="opacity:.6">连接暂不可用</span></div>'}ms.scrollTop=ms.scrollHeight}
</script>
</body>
</html>