From f91b5d2e420e6f23ec46527eb636a270ed587408 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 2 Apr 2026 17:00:39 +0000
Subject: [PATCH 1/4] =?UTF-8?q?=E9=93=B6=E6=B2=B3UI=20v1=20=E8=8D=89?=
=?UTF-8?q?=E7=A8=BF=EF=BC=88=E5=AD=98=E5=9C=A8=E4=B8=A5=E9=87=8D=E8=A7=86?=
=?UTF-8?q?=E8=A7=89=E9=97=AE=E9=A2=98=E5=BE=85=E4=BF=AE=E5=A4=8D=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/35513b78-3b6d-479d-840e-2067c5772a5d
Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
---
docs/index.html | 597 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 473 insertions(+), 124 deletions(-)
diff --git a/docs/index.html b/docs/index.html
index 5abbc1dc..79b65181 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -14,34 +14,35 @@
/* ═══ Themes ═══ */
:root{
- --bg:#060a14;--bg1:#0c1220;--bg2:#111827;--bg3:#1a2332;
- --border:#1e2d44;--accent:#4f8ef7;--accent2:#7c6ef7;--accent3:#a78bfa;
+ --bg:#03060e;--bg1:rgba(8,14,30,.85);--bg2:rgba(12,20,40,.8);--bg3:rgba(18,28,52,.75);
+ --border:rgba(80,120,200,.15);--accent:#6ea8fe;--accent2:#a78bfa;--accent3:#c4b5fd;
--ok:#34d399;--warn:#fbbf24;--err:#f87171;
- --text:#e2e8f0;--dim:#64748b;--muted:#334155;
- --glow:0 0 24px rgba(79,142,247,.1);
- --r:12px;--rs:8px;
+ --text:#e2e8f0;--dim:#7c8db5;--muted:rgba(100,130,180,.3);
+ --glow:0 0 30px rgba(110,168,254,.15),0 0 60px rgba(167,139,250,.08);
+ --r:14px;--rs:8px;
--f:-apple-system,BlinkMacSystemFont,'PingFang SC','Helvetica Neue','Microsoft YaHei',sans-serif;
--m:'SF Mono','Fira Code',Consolas,monospace;
--sb:env(safe-area-inset-bottom,0px);--st:env(safe-area-inset-top,0px);
+ --glass:rgba(10,16,32,.6);--glass-border:rgba(100,140,220,.12);
}
-.t-twi{--bg:#0a0612;--bg1:#140e22;--bg2:#1a1430;--bg3:#241c3d;--accent:#c084fc;--accent2:#e879f9;--accent3:#f0abfc;--border:#2d1f4e}
-.t-sea{--bg:#041318;--bg1:#082029;--bg2:#0c2d3a;--bg3:#103a4c;--accent:#22d3ee;--accent2:#06b6d4;--accent3:#67e8f9;--border:#164e63}
-.t-for{--bg:#06120a;--bg1:#0c2014;--bg2:#112d1c;--bg3:#183a26;--accent:#34d399;--accent2:#4ade80;--accent3:#86efac;--border:#1a4a2e}
-.t-emb{--bg:#140a06;--bg1:#221208;--bg2:#2d1a0e;--bg3:#3a2414;--accent:#fb923c;--accent2:#f97316;--accent3:#fdba74;--border:#4a2e1a}
+.t-twi{--bg:#06030f;--bg1:rgba(16,10,30,.85);--bg2:rgba(22,16,42,.8);--bg3:rgba(30,22,55,.75);--accent:#c084fc;--accent2:#e879f9;--accent3:#f0abfc;--border:rgba(140,80,200,.15)}
+.t-sea{--bg:#030d12;--bg1:rgba(6,20,30,.85);--bg2:rgba(10,30,44,.8);--bg3:rgba(14,40,56,.75);--accent:#22d3ee;--accent2:#06b6d4;--accent3:#67e8f9;--border:rgba(34,211,238,.12)}
+.t-for{--bg:#040e06;--bg1:rgba(8,24,14,.85);--bg2:rgba(14,34,22,.8);--bg3:rgba(18,44,30,.75);--accent:#34d399;--accent2:#4ade80;--accent3:#86efac;--border:rgba(52,211,153,.12)}
+.t-emb{--bg:#0e0604;--bg1:rgba(28,14,6,.85);--bg2:rgba(38,22,10,.8);--bg3:rgba(48,30,16,.75);--accent:#fb923c;--accent2:#f97316;--accent3:#fdba74;--border:rgba(251,146,60,.12)}
html{-webkit-tap-highlight-color:transparent}
body{font-family:var(--f);background:var(--bg);color:var(--text);font-size:15px;line-height:1.6;overflow:hidden;height:100vh;height:100dvh;-webkit-font-smoothing:antialiased}
a{color:var(--accent);text-decoration:none}
::-webkit-scrollbar{width:4px}::-webkit-scrollbar-thumb{background:var(--muted);border-radius:2px}
-/* ═══ Background ═══ */
-.bg{position:fixed;inset:0;z-index:0;pointer-events:none}
-.bg::before{content:'';position:absolute;inset:0;background-image:linear-gradient(rgba(79,142,247,.02) 1px,transparent 1px),linear-gradient(90deg,rgba(79,142,247,.02) 1px,transparent 1px);background-size:50px 50px;animation:gm 30s linear infinite}
-@keyframes gm{to{background-position:50px 50px}}
-.orb{position:absolute;border-radius:50%;filter:blur(80px);opacity:.07;animation:ob 22s ease-in-out infinite}
-.orb:nth-child(1){width:350px;height:350px;background:var(--accent);top:-8%;left:-4%}
-.orb:nth-child(2){width:280px;height:280px;background:var(--accent2);bottom:-6%;right:-4%;animation-delay:8s}
-@keyframes ob{0%,100%{transform:translate(0,0)}50%{transform:translate(20px,-15px)}}
+/* ═══ Background: Galaxy Star Field ═══ */
+.bg{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
+#starCanvas{position:absolute;inset:0;width:100%;height:100%}
+.nebula{position:absolute;border-radius:50%;filter:blur(120px);animation:nebPulse 12s ease-in-out infinite}
+.nebula:nth-child(2){width:50vw;height:50vh;background:radial-gradient(ellipse,rgba(110,168,254,.06),transparent 70%);top:-10%;left:-10%}
+.nebula:nth-child(3){width:45vw;height:45vh;background:radial-gradient(ellipse,rgba(167,139,250,.05),transparent 70%);bottom:-8%;right:-5%;animation-delay:6s}
+.nebula:nth-child(4){width:35vw;height:35vh;background:radial-gradient(ellipse,rgba(196,181,253,.04),transparent 70%);top:40%;left:50%;animation-delay:3s}
+@keyframes nebPulse{0%,100%{opacity:.6;transform:scale(1) translate(0,0)}50%{opacity:1;transform:scale(1.08) translate(10px,-8px)}}
/* ═══ 3D Page Flip Engine ═══ */
.pages{position:fixed;inset:0;z-index:1;perspective:1400px;overflow:hidden}
@@ -62,27 +63,30 @@ a{color:var(--accent);text-decoration:none}
.page[data-state="hidden"]{transform:rotateY(92deg) scale(.88);opacity:0;z-index:0;pointer-events:none;transition:none}
/* ═══ Common UI ═══ */
-.bar{position:sticky;top:0;z-index:10;display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:rgba(6,10,20,.92);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border-bottom:1px solid var(--border);min-height:48px;padding-top:calc(10px + var(--st))}
+.bar{position:sticky;top:0;z-index:10;display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:rgba(3,6,14,.88);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border-bottom:1px solid var(--glass-border);min-height:48px;padding-top:calc(10px + var(--st))}
.bar-title{font-size:14px;font-weight:700;display:flex;align-items:center;gap:6px}
.bar-right{display:flex;align-items:center;gap:8px}
.dot{width:6px;height:6px;border-radius:50%;background:var(--ok);box-shadow:0 0 6px var(--ok);animation:pls 2s infinite;flex-shrink:0}
@keyframes pls{50%{opacity:.4}}
-.btn{background:none;border:1px solid var(--border);color:var(--dim);padding:5px 12px;border-radius:var(--rs);font-size:12px;cursor:pointer;font-family:var(--f);transition:all .2s;white-space:nowrap}
-.btn:hover{color:var(--accent);border-color:var(--accent)}
+.btn{background:none;border:1px solid var(--border);color:var(--dim);padding:5px 12px;border-radius:var(--rs);font-size:12px;cursor:pointer;font-family:var(--f);transition:all .35s cubic-bezier(.4,0,.2,1);white-space:nowrap;position:relative;overflow:hidden}
+.btn::before{content:'';position:absolute;inset:0;background:linear-gradient(120deg,transparent 30%,rgba(110,168,254,.08) 50%,transparent 70%);transform:translateX(-100%);transition:transform .5s}
+.btn:hover{color:var(--accent);border-color:var(--accent);box-shadow:0 0 16px rgba(110,168,254,.12),inset 0 0 16px rgba(110,168,254,.04)}
+.btn:hover::before{transform:translateX(100%)}
.btn:active{transform:scale(.96)}
-.btn-accent{background:linear-gradient(135deg,var(--accent),var(--accent2));border:none;color:#fff}
-.btn-accent:hover{opacity:.88;color:#fff}
+.btn-accent{background:linear-gradient(135deg,var(--accent),var(--accent2));border:none;color:#fff;box-shadow:0 2px 12px rgba(110,168,254,.2)}
+.btn-accent:hover{opacity:.88;color:#fff;box-shadow:0 4px 20px rgba(110,168,254,.35)}
+.btn-accent::before{background:linear-gradient(120deg,transparent 30%,rgba(255,255,255,.15) 50%,transparent 70%)}
.content{padding:16px;max-width:700px;margin:0 auto}
-.card{background:var(--bg1);border:1px solid var(--border);border-radius:var(--r);padding:16px;margin-bottom:12px;transition:border-color .3s}
-.card:hover{border-color:var(--accent)}
+.card{background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);padding:16px;margin-bottom:12px;transition:all .35s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
+.card:hover{border-color:rgba(110,168,254,.3);box-shadow:var(--glow)}
.tag{display:inline-block;padding:2px 8px;border-radius:20px;font-size:10px;font-weight:600}
.tag-ok{background:rgba(52,211,153,.12);color:var(--ok)}
.tag-warn{background:rgba(251,191,36,.12);color:var(--warn)}
.tag-info{background:rgba(79,142,247,.12);color:var(--accent)}
.empty{text-align:center;padding:40px 16px;color:var(--muted);font-size:14px}
.empty em{font-style:normal;font-size:40px;display:block;margin-bottom:12px}
-input[type=text],textarea{background:var(--bg2);border:1px solid var(--border);border-radius:var(--rs);color:var(--text);padding:10px 12px;font-size:14px;font-family:var(--f);outline:none;width:100%;transition:border-color .2s;-webkit-appearance:none}
-input[type=text]:focus,textarea:focus{border-color:var(--accent)}
+input[type=text],input[type=password],textarea{background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--rs);color:var(--text);padding:10px 12px;font-size:14px;font-family:var(--f);outline:none;width:100%;transition:all .3s;-webkit-appearance:none;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
+input[type=text]:focus,input[type=password]:focus,textarea:focus{border-color:var(--accent);box-shadow:0 0 16px rgba(110,168,254,.1),inset 0 0 16px rgba(110,168,254,.03)}
::placeholder{color:var(--muted)}
label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weight:600}
.form-row{margin-bottom:14px}
@@ -90,18 +94,21 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
@media(max-width:480px){.form-row-inline{flex-direction:column}}
/* ═══ PAGE: Home ═══ */
-.home-hero{text-align:center;padding:32px 16px}
-.home-ver{display:inline-flex;align-items:center;gap:6px;padding:4px 12px;border-radius:20px;background:rgba(79,142,247,.08);border:1px solid rgba(79,142,247,.12);font-size:11px;color:var(--accent);font-family:var(--m);margin-bottom:16px}
-.home-hero h1{font-size:clamp(26px,5.5vw,40px);font-weight:800;line-height:1.2;margin-bottom:6px}
-.home-hero .sub{font-size:clamp(12px,2.5vw,15px);color:var(--dim);margin-bottom:12px}
-.home-hero .quote{font-size:13px;color:var(--accent2);font-style:italic}
+.home-hero{text-align:center;padding:40px 16px 32px}
+.home-ver{display:inline-flex;align-items:center;gap:6px;padding:4px 14px;border-radius:20px;background:rgba(110,168,254,.06);border:1px solid rgba(110,168,254,.12);font-size:11px;color:var(--accent);font-family:var(--m);margin-bottom:16px;animation:breathe 4s ease-in-out infinite}
+@keyframes breathe{0%,100%{box-shadow:0 0 8px rgba(110,168,254,.1)}50%{box-shadow:0 0 20px rgba(110,168,254,.25)}}
+.home-hero h1{font-size:clamp(28px,5.5vw,44px);font-weight:800;line-height:1.2;margin-bottom:8px;background:linear-gradient(135deg,#e2e8f0 0%,#6ea8fe 50%,#a78bfa 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
+.home-hero .sub{font-size:clamp(12px,2.5vw,15px);color:var(--dim);margin-bottom:14px}
+.home-hero .quote{font-size:14px;color:var(--accent2);font-style:italic;opacity:.8}
.upd{display:flex;gap:10px;padding:12px;margin-bottom:8px;background:var(--bg1);border:1px solid var(--border);border-radius:var(--r);transition:border-color .3s}
.upd:hover{border-color:var(--accent)}
.upd-v{min-width:42px;padding:3px 6px;text-align:center;background:rgba(79,142,247,.08);border-radius:var(--rs);color:var(--accent);font-size:10px;font-weight:600;font-family:var(--m);height:fit-content;flex-shrink:0}
.upd h4{font-size:13px;font-weight:600;margin-bottom:2px}
.upd p{font-size:11px;color:var(--dim);line-height:1.5}
-.home-enter{padding:24px;text-align:center;background:linear-gradient(135deg,var(--bg1),var(--bg2));border:1px solid var(--border);border-radius:var(--r);cursor:pointer;transition:all .3s;margin:20px 0}
-.home-enter:hover{border-color:var(--accent);box-shadow:var(--glow)}
+.home-enter{padding:28px;text-align:center;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);cursor:pointer;transition:all .4s cubic-bezier(.4,0,.2,1);margin:20px 0;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);position:relative;overflow:hidden}
+.home-enter::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 50%,rgba(110,168,254,.04),transparent 70%);opacity:0;transition:opacity .4s}
+.home-enter:hover{border-color:rgba(110,168,254,.35);box-shadow:var(--glow);transform:translateY(-2px)}
+.home-enter:hover::after{opacity:1}
.home-enter:active{transform:scale(.98)}
.home-enter em{font-style:normal;font-size:36px;display:block;margin-bottom:8px}
.home-enter strong{font-size:17px;display:block;margin-bottom:4px}
@@ -121,10 +128,12 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.hub-title p{font-size:12px;color:var(--dim);margin-top:2px}
.hub-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
@media(max-width:360px){.hub-grid{grid-template-columns:1fr}}
-.hub-card{text-align:center;padding:20px 12px;background:var(--bg1);border:1px solid var(--border);border-radius:var(--r);cursor:pointer;transition:all .3s}
-.hub-card:hover{border-color:var(--accent);box-shadow:var(--glow)}
+.hub-card{text-align:center;padding:24px 14px;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);cursor:pointer;transition:all .4s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);position:relative;overflow:hidden}
+.hub-card::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,rgba(110,168,254,.06),transparent 70%);opacity:0;transition:opacity .4s}
+.hub-card:hover{border-color:rgba(110,168,254,.35);box-shadow:var(--glow);transform:translateY(-2px)}
+.hub-card:hover::after{opacity:1}
.hub-card:active{transform:scale(.97)}
-.hub-card em{font-style:normal;font-size:28px;display:block;margin-bottom:6px}
+.hub-card em{font-style:normal;font-size:32px;display:block;margin-bottom:8px;filter:drop-shadow(0 0 8px rgba(110,168,254,.3))}
.hub-card strong{font-size:14px;display:block;margin-bottom:3px}
.hub-card span{font-size:11px;color:var(--dim)}
.hub-stats{display:flex;justify-content:center;gap:20px;padding:12px 0;flex-wrap:wrap}
@@ -150,9 +159,26 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.editor-textarea{min-height:calc(100vh - 260px);min-height:calc(100dvh - 260px);resize:none;line-height:2;font-size:15px;border:none;background:transparent;padding:0}
.editor-textarea:focus{border:none}
.editor-bottom{position:sticky;bottom:0;padding:8px 0;background:var(--bg);display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--border);font-size:11px;color:var(--dim);font-family:var(--m)}
+/* ═══ Editor Toolbar ═══ */
+.ed-toolbar{display:flex;gap:4px;align-items:center;flex-wrap:wrap}
+.ed-toolbar .tb-btn{background:var(--glass);border:1px solid var(--glass-border);color:var(--dim);width:32px;height:28px;border-radius:6px;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;transition:all .25s;font-family:var(--f);position:relative;overflow:hidden}
+.ed-toolbar .tb-btn:hover{color:var(--accent);border-color:var(--accent);box-shadow:0 0 10px rgba(110,168,254,.12);background:rgba(110,168,254,.06)}
+.ed-toolbar .tb-btn:active{transform:scale(.92)}
+.ed-toolbar .tb-sep{width:1px;height:18px;background:var(--border);margin:0 4px}
+/* ═══ Create Success Overlay ═══ */
+.create-success{display:none;text-align:center;padding:40px 20px;animation:fadeUp .5s ease-out}
+.create-success.show{display:block}
+.create-success em{font-style:normal;font-size:56px;display:block;margin-bottom:16px;animation:successPop .6s cubic-bezier(.68,-.55,.27,1.55)}
+.create-success h3{font-size:20px;font-weight:700;margin-bottom:8px}
+.create-success p{color:var(--dim);font-size:13px;margin-bottom:24px}
+.create-actions{display:flex;gap:10px;justify-content:center;flex-wrap:wrap}
+.create-actions .btn{padding:10px 24px;font-size:14px;border-radius:var(--r)}
+@keyframes fadeUp{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}
+@keyframes successPop{0%{transform:scale(0) rotate(-20deg)}100%{transform:scale(1) rotate(0)}}
/* ═══ Chat FAB ═══ */
-.chat-fab{position:fixed;bottom:calc(16px + var(--sb));right:14px;z-index:50;width:50px;height:50px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent2));border:none;color:#fff;font-size:21px;cursor:pointer;box-shadow:0 4px 16px rgba(79,142,247,.3);transition:all .25s;display:flex;align-items:center;justify-content:center}
+.chat-fab{position:fixed;bottom:calc(16px + var(--sb));right:14px;z-index:50;width:52px;height:52px;border-radius:50%;background:linear-gradient(135deg,var(--accent),var(--accent2));border:none;color:#fff;font-size:21px;cursor:pointer;box-shadow:0 4px 20px rgba(110,168,254,.3),0 0 40px rgba(167,139,250,.15);transition:all .25s;display:flex;align-items:center;justify-content:center;animation:fabBreathe 4s ease-in-out infinite}
+@keyframes fabBreathe{0%,100%{box-shadow:0 4px 20px rgba(110,168,254,.3),0 0 40px rgba(167,139,250,.1)}50%{box-shadow:0 6px 28px rgba(110,168,254,.45),0 0 50px rgba(167,139,250,.2)}}
.chat-fab:hover{transform:scale(1.06)}
.chat-fab:active{transform:scale(.93)}
.chat-fab.on{border-radius:var(--r);background:rgba(248,113,113,.85)}
@@ -161,7 +187,7 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.chat-fab.editor-mode:hover{opacity:1;transform:scale(1.1)}
/* ═══ Chat Panel ═══ */
-.chat-p{position:fixed;bottom:calc(76px + var(--sb));right:14px;z-index:50;width:min(360px,calc(100vw - 28px));height:min(440px,calc(100vh - 120px));height:min(440px,calc(100dvh - 120px));background:var(--bg1);border:1px solid var(--border);border-radius:var(--r);display:flex;flex-direction:column;transform:scale(.9) translateY(14px);opacity:0;pointer-events:none;transition:all .22s cubic-bezier(.4,0,.2,1);box-shadow:0 12px 40px rgba(0,0,0,.5)}
+.chat-p{position:fixed;bottom:calc(76px + var(--sb));right:14px;z-index:50;width:min(360px,calc(100vw - 28px));height:min(440px,calc(100vh - 120px));height:min(440px,calc(100dvh - 120px));background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);display:flex;flex-direction:column;transform:scale(.9) translateY(14px);opacity:0;pointer-events:none;transition:all .22s cubic-bezier(.4,0,.2,1);box-shadow:0 12px 48px rgba(0,0,0,.5),0 0 40px rgba(110,168,254,.06);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}
.chat-p.open{transform:scale(1) translateY(0);opacity:1;pointer-events:auto}
@media(max-width:480px){.chat-p{bottom:0;right:0;left:0;width:100%;height:calc(100vh - 48px);height:calc(100dvh - 48px);border-radius:var(--r) var(--r) 0 0;padding-bottom:var(--sb)}}
.chat-hd{padding:10px 14px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:8px;flex-shrink:0}
@@ -190,7 +216,7 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
/* ═══ Three-Column Home Layout ═══ */
.home-grid{display:grid;grid-template-columns:260px 1fr 260px;gap:16px;padding:16px;max-width:1200px;margin:0 auto;align-content:start}
@media(max-width:960px){.home-grid{grid-template-columns:1fr;max-width:600px}}
-.panel{background:var(--bg1);border:1px solid var(--border);border-radius:var(--r);padding:14px;height:fit-content}
+.panel{background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);padding:14px;height:fit-content;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
.panel-title{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:1.2px;font-weight:700;margin-bottom:10px;display:flex;align-items:center;gap:6px}
.panel-item{padding:6px 0;border-bottom:1px solid var(--border);font-size:12px}
.panel-item:last-child{border-bottom:none}
@@ -201,10 +227,10 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.panel-value.err{color:var(--err)}
/* ═══ Ticker ═══ */
-.ticker-wrap{overflow:hidden;background:var(--bg1);border:1px solid var(--border);border-radius:var(--rs);padding:6px 0;margin-bottom:14px;position:relative}
-.ticker-wrap::before,.ticker-wrap::after{content:'';position:absolute;top:0;bottom:0;width:24px;z-index:2;pointer-events:none}
-.ticker-wrap::before{left:0;background:linear-gradient(90deg,var(--bg1),transparent)}
-.ticker-wrap::after{right:0;background:linear-gradient(-90deg,var(--bg1),transparent)}
+.ticker-wrap{overflow:hidden;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--rs);padding:6px 0;margin-bottom:14px;position:relative}
+.ticker-wrap::before,.ticker-wrap::after{content:'';position:absolute;top:0;bottom:0;width:32px;z-index:2;pointer-events:none}
+.ticker-wrap::before{left:0;background:linear-gradient(90deg,rgba(3,6,14,.9),transparent)}
+.ticker-wrap::after{right:0;background:linear-gradient(-90deg,rgba(3,6,14,.9),transparent)}
.ticker{display:flex;animation:tickScroll 28s linear infinite;white-space:nowrap;gap:36px;padding:0 16px}
.ticker:hover{animation-play-state:paused}
.ticker span{font-size:11px;color:var(--dim);display:flex;align-items:center;gap:5px;flex-shrink:0}
@@ -212,8 +238,8 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
@keyframes tickScroll{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}
/* ═══ Team Card ═══ */
-.team-slot{display:flex;align-items:center;gap:8px;padding:7px 8px;background:var(--bg2);border-radius:var(--rs);margin-bottom:5px;transition:border-color .3s;border:1px solid transparent}
-.team-slot:hover{border-color:var(--accent)}
+.team-slot{display:flex;align-items:center;gap:8px;padding:7px 8px;background:var(--glass);border-radius:var(--rs);margin-bottom:5px;transition:all .3s;border:1px solid transparent}
+.team-slot:hover{border-color:rgba(110,168,254,.2);box-shadow:0 0 12px rgba(110,168,254,.06)}
.team-av{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0}
.team-nm{font-size:11px;font-weight:600}
.team-role{font-size:9px;color:var(--dim)}
@@ -229,16 +255,19 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
/* ═══ Home Entry Cards ═══ */
.home-entries{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:16px 0}
@media(max-width:480px){.home-entries{grid-template-columns:1fr}}
-.entry-card{padding:18px 14px;text-align:center;background:linear-gradient(135deg,var(--bg1),var(--bg2));border:1px solid var(--border);border-radius:var(--r);cursor:pointer;transition:all .3s}
-.entry-card:hover{border-color:var(--accent);box-shadow:var(--glow)}
-.entry-card:active{transform:scale(.98)}
-.entry-card em{font-style:normal;font-size:28px;display:block;margin-bottom:6px}
-.entry-card strong{font-size:14px;display:block;margin-bottom:3px}
+.entry-card{padding:24px 16px;text-align:center;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);cursor:pointer;transition:all .4s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);position:relative;overflow:hidden}
+.entry-card::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,rgba(110,168,254,.06),transparent 70%);opacity:0;transition:opacity .4s}
+.entry-card:hover{border-color:rgba(110,168,254,.35);box-shadow:var(--glow);transform:translateY(-2px)}
+.entry-card:hover::after{opacity:1}
+.entry-card:active{transform:scale(.98) translateY(0)}
+.entry-card em{font-style:normal;font-size:32px;display:block;margin-bottom:8px;filter:drop-shadow(0 0 8px rgba(110,168,254,.3))}
+.entry-card strong{font-size:15px;display:block;margin-bottom:4px}
.entry-card span{font-size:11px;color:var(--dim)}
-/* ═══ Monitor ═══ */
-.mon{position:fixed;top:calc(6px + var(--st));right:10px;z-index:40;background:rgba(12,18,32,.9);border:1px solid var(--border);border-radius:var(--r);padding:5px 9px;font-size:9px;font-family:var(--m);color:var(--dim);cursor:pointer;transition:all .3s;user-select:none;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
-.mon:hover{border-color:var(--accent)}
+/* ═══ Monitor (draggable) ═══ */
+.mon{position:fixed;top:calc(6px + var(--st));right:10px;z-index:40;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);padding:5px 9px;font-size:9px;font-family:var(--m);color:var(--dim);cursor:grab;transition:all .3s;user-select:none;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);touch-action:none}
+.mon:active{cursor:grabbing}
+.mon:hover{border-color:rgba(110,168,254,.3)}
.mon.x{padding:8px 12px}
.mr{display:flex;justify-content:space-between;gap:8px;padding:1px 0}
.mv{color:var(--accent);font-weight:600}
@@ -273,7 +302,7 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
-
+
@@ -288,24 +317,22 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
📡 系统状态
-
+
-
-
-
+
+
+
🧠 版本更新
-
v40.0 · 2026-04-02
COS双桶存储上线
-
v39.0 · 2026-04-01
全链路部署观测
-
v38.0 · 2026-04-01
HLDP协作语言协议
+
v42.0 · 2026-04-02
银河星空UI改版
-
AGE OS v40.0
+
AGE OS v42.0
光湖灯塔
语言驱动操作系统 · 人类只说话,系统搞定一切
「语言 = 现实」
@@ -313,15 +340,15 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
- 🏛️ AGE OS v40.0 运行中
+ 🏛️ AGE OS v42.0 运行中
+ 🌌 银河星空UI上线
📡 COS双桶存储已上线
🧠 HLDP协作语言协议在线
- ⚡ 全链路部署观测系统就绪
✍️ 码字工作台 Beta 内测中
- 🏛️ AGE OS v40.0 运行中
+ 🏛️ AGE OS v42.0 运行中
+ 🌌 银河星空UI上线
📡 COS双桶存储已上线
🧠 HLDP协作语言协议在线
- ⚡ 全链路部署观测系统就绪
✍️ 码字工作台 Beta 内测中
@@ -411,12 +438,32 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
-
-
-
+
+
+
🎉
+
作品创建成功!
+
你的新故事已诞生,准备好开始了吗?
+
+
+
+
+
@@ -526,8 +573,17 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
+
字数:0
-
自动保存 · 点右下角💬唤醒铸渊
@@ -574,21 +630,24 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
-
+
-
🔑 接入自己的大模型 API ▶
+
🔑 接入大模型 API(支持所有三方) ▶
-
-
-
-
+
+
+
+
+
+
+
+
未连接 · 粘贴密钥后自动检测可用模型
+
+
+
-
未连接 · 服务器离线时启用自定义模型
@@ -606,6 +665,73 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
(function(){
'use strict';
+/* ════════════════════════════════════════
+ STAR FIELD PARTICLE SYSTEM (Galaxy Breathing)
+ ════════════════════════════════════════ */
+(function initStarField(){
+ var canvas=document.getElementById('starCanvas');
+ if(!canvas)return;
+ var ctx=canvas.getContext('2d');
+ var stars=[];
+ var STAR_COUNT=180;
+ var w,h;
+
+ function resize(){
+ w=canvas.width=window.innerWidth;
+ h=canvas.height=window.innerHeight;
+ }
+ resize();
+ window.addEventListener('resize',resize);
+
+ // Create stars
+ for(var i=0;i0.7?(200+Math.random()*60):(220+Math.random()*40) // blue-purple range
+ });
+ }
+
+ var time=0;
+ function draw(){
+ time+=16;
+ ctx.clearRect(0,0,w,h);
+ for(var i=0;ih+5)s.y=-5;
+ if(s.y<-5)s.y=h+5;
+
+ var sx=s.x%w;
+ var sy=s.y%h;
+
+ ctx.beginPath();
+ ctx.arc(sx,sy,s.r,0,Math.PI*2);
+ ctx.fillStyle='hsla('+s.hue+',70%,82%,'+alpha+')';
+ ctx.fill();
+
+ // Glow for bigger stars
+ if(s.r>1.2){
+ ctx.beginPath();
+ ctx.arc(sx,sy,s.r*3,0,Math.PI*2);
+ ctx.fillStyle='hsla('+s.hue+',60%,70%,'+(alpha*0.15)+')';
+ ctx.fill();
+ }
+ }
+ requestAnimationFrame(draw);
+ }
+ draw();
+})();
+
/* ════════════════════════════════════════
3D PAGE FLIP ENGINE
════════════════════════════════════════ */
@@ -671,6 +797,13 @@ function go(target){
if(target==='editor')renderEditor();
if(target==='charEdit'&&editingCharId)renderCharEdit();
if(target==='feedback')renderFeedback();
+ if(target==='create'){
+ // Reset create form state
+ var cf=document.getElementById('createForm');
+ var cs=document.getElementById('createSuccess');
+ if(cf)cf.style.display='';
+ if(cs)cs.classList.remove('show');
+ }
}
window.go=go;
@@ -751,11 +884,28 @@ document.getElementById('createSave').onclick=function(){
};
ws.push(nw);
saveWorks(ws);
- document.getElementById('cTitle').value='';
- document.getElementById('cGenre').value='';
- document.getElementById('cSummary').value='';
activeWorkId=nw.id;
- go('hub');
+
+ // Show success UI
+ var form=document.getElementById('createForm');
+ var succ=document.getElementById('createSuccess');
+ var succTitle=document.getElementById('createSuccessTitle');
+ var succDesc=document.getElementById('createSuccessDesc');
+ if(form)form.style.display='none';
+ if(succTitle)succTitle.textContent='「'+t+'」创建成功!';
+ if(succDesc)succDesc.textContent=(nw.genre?nw.genre+' · ':'')+'准备好开始创作了吗?';
+ if(succ)succ.classList.add('show');
+
+ // Wire up the "进入作品" button
+ document.getElementById('createGoWrite').onclick=function(){
+ // Reset form for next time
+ document.getElementById('cTitle').value='';
+ document.getElementById('cGenre').value='';
+ document.getElementById('cSummary').value='';
+ if(form)form.style.display='';
+ if(succ)succ.classList.remove('show');
+ go('hub');
+ };
};
/* ════════════════════════════════════════
@@ -977,6 +1127,32 @@ document.getElementById('edSave').onclick=function(){
chatMsg('章节已保存 ✅','b');
};
+// Editor toolbar: prev/next chapter navigation
+document.getElementById('edPrev').onclick=function(){
+ var w=getWork(activeWorkId);
+ if(!w||!w.chapters||w.chapters.length<2)return;
+ var idx=w.chapters.findIndex(function(c){return c.id===activeChapterId});
+ if(idx>0){saveEditorContent();activeChapterId=w.chapters[idx-1].id;renderEditor();}
+};
+document.getElementById('edNext').onclick=function(){
+ var w=getWork(activeWorkId);
+ if(!w||!w.chapters)return;
+ var idx=w.chapters.findIndex(function(c){return c.id===activeChapterId});
+ if(idx0){
+ modelSel.innerHTML=apiCfg.models.map(function(m){return''}).join('');
+ modelListDiv.style.display='block';
+ }
}
tog.onclick=function(){
@@ -1212,40 +1399,122 @@ try{var ak=localStorage.getItem('hl-api');if(ak){var ap=JSON.parse(ak);if(ap.key
tog.classList.toggle('open',isOpen);
};
- document.getElementById('apiConnBtn').onclick=async function(){
- var key=keyInp.value.trim();
- if(!key){keyInp.focus();return;}
- var model=modelSel.value;
- var btn=this;
- btn.disabled=true;btn.textContent='测试中…';
- st.textContent='连接测试中…';st.style.color='var(--dim)';
+ // Model selection change
+ modelSel.onchange=function(){
+ if(!apiCfg.connected)return;
+ apiCfg.model=this.value;
+ try{localStorage.setItem('hl-api',JSON.stringify(apiCfg))}catch(e){}
+ st.textContent='✅ 已切换模型 · '+apiCfg.model;
+ document.getElementById('chatTg').textContent=apiCfg.model;
+ };
+
+ // Auto-detect: try to fetch /v1/models
+ async function detectModels(baseUrl,key){
+ var url=baseUrl.replace(/\/+$/,'')+'/models';
try{
- var ep=OPENAI_EP;
- var r=await fetch(ep,{
+ var r=await fetch(url,{
+ headers:{'Authorization':'Bearer '+key},
+ signal:AbortSignal.timeout(10000)
+ });
+ if(!r.ok)return[];
+ var data=await r.json();
+ if(data.data&&Array.isArray(data.data)){
+ return data.data.map(function(m){return m.id}).filter(function(id){
+ // Filter to chat-capable models
+ return /gpt|claude|gemini|glm|qwen|deepseek|yi-|llama|mistral|chat|turbo/i.test(id);
+ }).sort();
+ }
+ }catch(e){}
+ return[];
+ }
+
+ // Test connection with a simple request
+ async function testConnection(baseUrl,key,model){
+ var url=baseUrl.replace(/\/+$/,'')+'/chat/completions';
+ try{
+ var r=await fetch(url,{
method:'POST',
headers:{'Content-Type':'application/json','Authorization':'Bearer '+key},
body:JSON.stringify({model:model,messages:[{role:'user',content:'hi'}],max_tokens:5}),
- signal:AbortSignal.timeout(12000)
+ signal:AbortSignal.timeout(15000)
});
- if(r.ok){
- apiCfg={key:key,model:model,baseUrl:OPENAI_EP,connected:true};
- try{localStorage.setItem('hl-api',JSON.stringify(apiCfg))}catch(e){}
- st.textContent='✅ 连接成功 · '+model;
- st.style.color='var(--ok)';
- document.getElementById('chatTg').textContent=model;
- chatMsg('🔑 API已连接('+model+')现在我可以完整回答你了','b',{m:'铸渊',t:'自定义'});
- }else{
- var errData=await r.json().catch(function(){return{}});
- st.textContent='❌ '+(errData.error&&errData.error.message?errData.error.message.slice(0,40):'API Key无效');
+ return r.ok;
+ }catch(e){return false}
+ }
+
+ document.getElementById('apiConnBtn').onclick=async function(){
+ var key=keyInp.value.trim();
+ if(!key){keyInp.focus();return;}
+ var userBase=baseUrlInp.value.trim();
+ var btn=this;
+ btn.disabled=true;btn.textContent='检测中…';
+ st.textContent='🔍 正在检测可用模型…';st.style.color='var(--dim)';
+
+ var foundModels=[];
+ var workingBase='';
+
+ // If user provided a base URL, try that first
+ if(userBase){
+ st.textContent='🔍 检测 '+userBase+' …';
+ foundModels=await detectModels(userBase,key);
+ if(foundModels.length>0)workingBase=userBase;
+ }
+
+ // If no models found, try common endpoints
+ if(foundModels.length===0){
+ for(var i=0;i0){workingBase=COMMON_ENDPOINTS[i];break;}
+ }
+ }
+
+ if(foundModels.length>0){
+ // Show model list
+ modelSel.innerHTML=foundModels.map(function(m){return''}).join('');
+ modelListDiv.style.display='block';
+
+ // Auto-select a reasonable default
+ var defaultModel=foundModels.find(function(m){return/gpt-4o-mini/i.test(m)})||
+ foundModels.find(function(m){return/gpt-4o/i.test(m)})||
+ foundModels.find(function(m){return/gpt-4/i.test(m)})||
+ foundModels.find(function(m){return/claude/i.test(m)})||
+ foundModels[0];
+ modelSel.value=defaultModel;
+
+ apiCfg={key:key,model:defaultModel,baseUrl:workingBase,connected:true,models:foundModels};
+ try{localStorage.setItem('hl-api',JSON.stringify(apiCfg))}catch(e){}
+ st.textContent='✅ 检测到 '+foundModels.length+' 个模型 · 当前:'+defaultModel;
+ st.style.color='var(--ok)';
+ document.getElementById('chatTg').textContent=defaultModel;
+ chatMsg('🔑 API已连接 · 检测到'+foundModels.length+'个可用模型\n当前使用:'+defaultModel+'\n可在下拉菜单切换模型','b',{m:'铸渊',t:'自定义'});
+ }else{
+ // Can't get model list, try direct connection test with common models
+ st.textContent='🔍 模型列表不可用,尝试直连测试…';
+ var tryBase=userBase||COMMON_ENDPOINTS[0];
+ var testModels=['gpt-4o-mini','gpt-4o','gpt-3.5-turbo','deepseek-chat','claude-3-haiku-20240307'];
+ var worked=false;
+ for(var j=0;j'+testModels[j]+'';
+ modelListDiv.style.display='block';
+ st.textContent='✅ 连接成功 · '+testModels[j];
+ st.style.color='var(--ok)';
+ document.getElementById('chatTg').textContent=testModels[j];
+ chatMsg('🔑 API已连接('+testModels[j]+')','b',{m:'铸渊',t:'自定义'});
+ worked=true;break;
+ }
+ }
+ if(!worked){
+ st.textContent='❌ 无法连接 · 请检查密钥和API地址';
st.style.color='var(--err)';
apiCfg.connected=false;
}
- }catch(e){
- st.textContent='❌ 连接失败,检查Key和网络';
- st.style.color='var(--err)';
- apiCfg.connected=false;
}
- btn.disabled=false;btn.textContent='连接';
+ btn.disabled=false;btn.textContent='检测';
};
})();
@@ -1285,7 +1554,72 @@ tryLoadFromCOS();
/* ════════════════════════════════════════
MONITOR
════════════════════════════════════════ */
-document.getElementById('mon').onclick=function(){this.classList.toggle('x')};
+/* ════════════════════════════════════════
+ MONITOR (draggable + toggle)
+ ════════════════════════════════════════ */
+(function(){
+ var mon=document.getElementById('mon');
+ if(!mon)return;
+ var isDrag=false,hasMoved=false;
+ var startX,startY,monX,monY;
+
+ // Restore position
+ try{
+ var pos=JSON.parse(localStorage.getItem('hl-mon-pos'));
+ if(pos&&typeof pos.x==='number'){
+ var ww=window.innerWidth,wh=window.innerHeight;
+ var mw=mon.offsetWidth||80,mh=mon.offsetHeight||30;
+ if(pos.x>=0&&pos.x<=ww-mw&&pos.y>=0&&pos.y<=wh-mh){
+ mon.style.right='auto';mon.style.top='auto';
+ mon.style.left=pos.x+'px';mon.style.top=pos.y+'px';
+ }
+ }
+ }catch(e){}
+
+ function getXY(e){return e.touches?{x:e.touches[0].clientX,y:e.touches[0].clientY}:{x:e.clientX,y:e.clientY}}
+
+ function onStart(e){
+ isDrag=true;hasMoved=false;
+ var xy=getXY(e);
+ var rect=mon.getBoundingClientRect();
+ startX=xy.x-rect.left;startY=xy.y-rect.top;
+ monX=rect.left;monY=rect.top;
+ mon.style.transition='none';
+ }
+ function onMove(e){
+ if(!isDrag)return;
+ var xy=getXY(e);
+ var nx=xy.x-startX,ny=xy.y-startY;
+ if(!hasMoved&&Math.abs(nx-monX)<5&&Math.abs(ny-monY)<5)return;
+ hasMoved=true;
+ e.preventDefault();
+ var mw=mon.offsetWidth,mh=mon.offsetHeight;
+ monX=Math.max(0,Math.min(window.innerWidth-mw,nx));
+ monY=Math.max(0,Math.min(window.innerHeight-mh,ny));
+ mon.style.right='auto';
+ mon.style.left=monX+'px';mon.style.top=monY+'px';
+ }
+ function onEnd(){
+ if(!isDrag)return;
+ isDrag=false;
+ mon.style.transition='all .3s';
+ if(hasMoved){
+ try{localStorage.setItem('hl-mon-pos',JSON.stringify({x:monX,y:monY}))}catch(e){}
+ }
+ }
+
+ mon.addEventListener('touchstart',onStart,{passive:true});
+ document.addEventListener('touchmove',onMove,{passive:false});
+ document.addEventListener('touchend',onEnd);
+ mon.addEventListener('mousedown',function(e){if(e.button===0)onStart(e)});
+ document.addEventListener('mousemove',onMove);
+ document.addEventListener('mouseup',onEnd);
+
+ mon.onclick=function(e){
+ if(hasMoved){hasMoved=false;return}
+ this.classList.toggle('x');
+ };
+})();
async function checkConn(){
try{var t=performance.now();var r=await fetch('/api/health',{signal:AbortSignal.timeout(4000)});var ms=Math.round(performance.now()-t);
document.getElementById('mN').textContent=ms+'ms';document.getElementById('mN').style.color=ms<500?'var(--ok)':'var(--warn)';
@@ -1380,14 +1714,17 @@ checkConn();setInterval(checkConn,30000);
SYSTEM STATUS (左面板实时数据)
════════════════════════════════════════ */
async function loadSysStatus(){
+ var sEl=document.getElementById('sysStatus');
+ var lEl=document.getElementById('sysLatency');
+ var uEl=document.getElementById('sysUptime');
+ var wfEl=document.getElementById('sysWorkflows');
+ var modEl=document.getElementById('sysModules');
+ var cosEl=document.getElementById('sysCos');
try{
var t=performance.now();
var r=await fetch('/api/health',{signal:AbortSignal.timeout(5000)});
var ms=Math.round(performance.now()-t);
var data=await r.json();
- var sEl=document.getElementById('sysStatus');
- var lEl=document.getElementById('sysLatency');
- var uEl=document.getElementById('sysUptime');
if(sEl){sEl.textContent='🟢 在线';sEl.className='panel-value ok'}
if(lEl){lEl.textContent=ms+'ms';lEl.className='panel-value '+(ms<500?'ok':'warn')}
if(uEl){
@@ -1395,12 +1732,24 @@ async function loadSysStatus(){
var uh=Math.floor(um/60);
uEl.textContent=uh>0?uh+'h '+um%60+'m':um+'分钟';
}
+ // Real data from server if available
+ if(wfEl){wfEl.textContent=data.workflows?data.workflows:'无法获取';wfEl.className='panel-value '+(data.workflows?'ok':'')}
+ if(modEl){modEl.textContent=data.modules?data.modules:'无法获取';modEl.className='panel-value '+(data.modules?'ok':'')}
+ if(cosEl){
+ if(data.cos){cosEl.textContent=data.cos;cosEl.className='panel-value ok'}
+ else{cosEl.textContent='无法确认';cosEl.className='panel-value warn'}
+ }
}catch(e){
- var sEl=document.getElementById('sysStatus');
if(sEl){sEl.textContent='🔴 离线';sEl.className='panel-value err'}
+ if(lEl){lEl.textContent='—';lEl.className='panel-value err'}
+ if(uEl){uEl.textContent='—';uEl.className='panel-value'}
+ if(wfEl){wfEl.textContent='无法连接';wfEl.className='panel-value err'}
+ if(modEl){modEl.textContent='无法连接';modEl.className='panel-value err'}
+ if(cosEl){cosEl.textContent='无法连接';cosEl.className='panel-value err'}
}
}
loadSysStatus();
+setInterval(loadSysStatus,30000);
/* ════════════════════════════════════════
BULLETIN & TICKER (动态公告)
From 4229576d2ffbaad3568b5c501329821980028b47 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 2 Apr 2026 17:06:24 +0000
Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A1=B5=E9=9D=A2?=
=?UTF-8?q?=E9=80=8F=E6=98=8E=E5=BA=A6+=E7=A7=BB=E5=8A=A8=E7=AB=AF?=
=?UTF-8?q?=E5=B8=83=E5=B1=80+monitor=E4=BD=8D=E7=BD=AE+=E4=B8=93=E6=B3=A8?=
=?UTF-8?q?=E6=A8=A1=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/35513b78-3b6d-479d-840e-2067c5772a5d
Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
---
docs/index.html | 212 ++++++++++++++++++++++++++++++++++++------------
1 file changed, 162 insertions(+), 50 deletions(-)
diff --git a/docs/index.html b/docs/index.html
index 79b65181..b6625120 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -51,7 +51,7 @@ a{color:var(--accent);text-decoration:none}
overflow-y:auto;overflow-x:hidden;
-webkit-overflow-scrolling:touch;
padding:0 0 var(--sb) 0;
- background:var(--bg);
+ background:transparent;
backface-visibility:hidden;-webkit-backface-visibility:hidden;
transition:transform .55s cubic-bezier(.4,0,.15,1),opacity .55s;
transform-origin:center center;
@@ -63,7 +63,7 @@ a{color:var(--accent);text-decoration:none}
.page[data-state="hidden"]{transform:rotateY(92deg) scale(.88);opacity:0;z-index:0;pointer-events:none;transition:none}
/* ═══ Common UI ═══ */
-.bar{position:sticky;top:0;z-index:10;display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:rgba(3,6,14,.88);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border-bottom:1px solid var(--glass-border);min-height:48px;padding-top:calc(10px + var(--st))}
+.bar{position:sticky;top:0;z-index:10;display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:rgba(5,8,22,.72);backdrop-filter:blur(24px) saturate(1.3);-webkit-backdrop-filter:blur(24px) saturate(1.3);border-bottom:1px solid rgba(110,168,254,.08);min-height:48px;padding-top:calc(10px + var(--st))}
.bar-title{font-size:14px;font-weight:700;display:flex;align-items:center;gap:6px}
.bar-right{display:flex;align-items:center;gap:8px}
.dot{width:6px;height:6px;border-radius:50%;background:var(--ok);box-shadow:0 0 6px var(--ok);animation:pls 2s infinite;flex-shrink:0}
@@ -77,16 +77,16 @@ a{color:var(--accent);text-decoration:none}
.btn-accent:hover{opacity:.88;color:#fff;box-shadow:0 4px 20px rgba(110,168,254,.35)}
.btn-accent::before{background:linear-gradient(120deg,transparent 30%,rgba(255,255,255,.15) 50%,transparent 70%)}
.content{padding:16px;max-width:700px;margin:0 auto}
-.card{background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);padding:16px;margin-bottom:12px;transition:all .35s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
-.card:hover{border-color:rgba(110,168,254,.3);box-shadow:var(--glow)}
+.card{background:rgba(8,14,30,.55);border:1px solid rgba(110,168,254,.08);border-radius:var(--r);padding:16px;margin-bottom:12px;transition:all .35s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
+.card:hover{border-color:rgba(110,168,254,.25);box-shadow:0 0 24px rgba(110,168,254,.08)}
.tag{display:inline-block;padding:2px 8px;border-radius:20px;font-size:10px;font-weight:600}
.tag-ok{background:rgba(52,211,153,.12);color:var(--ok)}
.tag-warn{background:rgba(251,191,36,.12);color:var(--warn)}
.tag-info{background:rgba(79,142,247,.12);color:var(--accent)}
.empty{text-align:center;padding:40px 16px;color:var(--muted);font-size:14px}
.empty em{font-style:normal;font-size:40px;display:block;margin-bottom:12px}
-input[type=text],input[type=password],textarea{background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--rs);color:var(--text);padding:10px 12px;font-size:14px;font-family:var(--f);outline:none;width:100%;transition:all .3s;-webkit-appearance:none;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
-input[type=text]:focus,input[type=password]:focus,textarea:focus{border-color:var(--accent);box-shadow:0 0 16px rgba(110,168,254,.1),inset 0 0 16px rgba(110,168,254,.03)}
+input[type=text],input[type=password],textarea{background:rgba(5,8,22,.5);border:1px solid rgba(110,168,254,.1);border-radius:var(--rs);color:var(--text);padding:10px 12px;font-size:14px;font-family:var(--f);outline:none;width:100%;transition:all .3s;-webkit-appearance:none}
+input[type=text]:focus,input[type=password]:focus,textarea:focus{border-color:rgba(110,168,254,.4);box-shadow:0 0 20px rgba(110,168,254,.08)}
::placeholder{color:var(--muted)}
label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weight:600}
.form-row{margin-bottom:14px}
@@ -128,12 +128,12 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.hub-title p{font-size:12px;color:var(--dim);margin-top:2px}
.hub-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
@media(max-width:360px){.hub-grid{grid-template-columns:1fr}}
-.hub-card{text-align:center;padding:24px 14px;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);cursor:pointer;transition:all .4s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);position:relative;overflow:hidden}
-.hub-card::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,rgba(110,168,254,.06),transparent 70%);opacity:0;transition:opacity .4s}
-.hub-card:hover{border-color:rgba(110,168,254,.35);box-shadow:var(--glow);transform:translateY(-2px)}
+.hub-card{text-align:center;padding:28px 14px;background:rgba(8,14,30,.45);border:1px solid rgba(110,168,254,.1);border-radius:var(--r);cursor:pointer;transition:all .4s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);position:relative;overflow:hidden}
+.hub-card::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,rgba(110,168,254,.08),transparent 70%);opacity:0;transition:opacity .4s}
+.hub-card:hover{border-color:rgba(110,168,254,.3);box-shadow:0 0 30px rgba(110,168,254,.1);transform:translateY(-3px)}
.hub-card:hover::after{opacity:1}
.hub-card:active{transform:scale(.97)}
-.hub-card em{font-style:normal;font-size:32px;display:block;margin-bottom:8px;filter:drop-shadow(0 0 8px rgba(110,168,254,.3))}
+.hub-card em{font-style:normal;font-size:36px;display:block;margin-bottom:10px;filter:drop-shadow(0 0 12px rgba(110,168,254,.25))}
.hub-card strong{font-size:14px;display:block;margin-bottom:3px}
.hub-card span{font-size:11px;color:var(--dim)}
.hub-stats{display:flex;justify-content:center;gap:20px;padding:12px 0;flex-wrap:wrap}
@@ -158,13 +158,25 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.editor-info{display:flex;justify-content:space-between;align-items:center;padding:8px 0;font-size:12px;color:var(--dim);border-bottom:1px solid var(--border);margin-bottom:12px}
.editor-textarea{min-height:calc(100vh - 260px);min-height:calc(100dvh - 260px);resize:none;line-height:2;font-size:15px;border:none;background:transparent;padding:0}
.editor-textarea:focus{border:none}
-.editor-bottom{position:sticky;bottom:0;padding:8px 0;background:var(--bg);display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--border);font-size:11px;color:var(--dim);font-family:var(--m)}
+.editor-bottom{position:sticky;bottom:0;padding:10px 0;background:rgba(5,8,22,.85);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);display:flex;justify-content:space-between;align-items:center;border-top:1px solid rgba(110,168,254,.08);font-size:11px;color:var(--dim);font-family:var(--m)}
/* ═══ Editor Toolbar ═══ */
.ed-toolbar{display:flex;gap:4px;align-items:center;flex-wrap:wrap}
-.ed-toolbar .tb-btn{background:var(--glass);border:1px solid var(--glass-border);color:var(--dim);width:32px;height:28px;border-radius:6px;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;transition:all .25s;font-family:var(--f);position:relative;overflow:hidden}
-.ed-toolbar .tb-btn:hover{color:var(--accent);border-color:var(--accent);box-shadow:0 0 10px rgba(110,168,254,.12);background:rgba(110,168,254,.06)}
-.ed-toolbar .tb-btn:active{transform:scale(.92)}
+.ed-toolbar .tb-btn{background:rgba(8,14,30,.6);border:1px solid rgba(110,168,254,.1);color:var(--dim);width:34px;height:30px;border-radius:8px;cursor:pointer;font-size:14px;display:flex;align-items:center;justify-content:center;transition:all .25s;font-family:var(--f);position:relative;overflow:hidden}
+.ed-toolbar .tb-btn:hover{color:var(--accent);border-color:rgba(110,168,254,.3);box-shadow:0 0 12px rgba(110,168,254,.1);background:rgba(110,168,254,.08)}
+.ed-toolbar .tb-btn:active{transform:scale(.9)}
.ed-toolbar .tb-sep{width:1px;height:18px;background:var(--border);margin:0 4px}
+/* ═══ Focus Mode ═══ */
+.focus-mode .bar,.focus-mode .editor-info,.focus-mode .chat-fab,.focus-mode .mon{opacity:0;pointer-events:none;transition:opacity .4s}
+.focus-mode .editor-textarea{min-height:calc(100vh - 80px);min-height:calc(100dvh - 80px);font-size:17px;line-height:2.2}
+.focus-mode .editor-bottom{background:transparent;border:none}
+.focus-mode .ed-toolbar{opacity:.3;transition:opacity .3s}
+.focus-mode .ed-toolbar:hover{opacity:1}
+.focus-mode:hover .bar{opacity:1;pointer-events:auto}
+/* ═══ Save Indicator ═══ */
+.save-dot{width:6px;height:6px;border-radius:50%;display:inline-block;margin-right:4px;transition:background .3s}
+.save-dot.saved{background:var(--ok)}
+.save-dot.saving{background:var(--warn);animation:pls 1s infinite}
+.save-dot.unsaved{background:var(--dim)}
/* ═══ Create Success Overlay ═══ */
.create-success{display:none;text-align:center;padding:40px 20px;animation:fadeUp .5s ease-out}
.create-success.show{display:block}
@@ -187,7 +199,7 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.chat-fab.editor-mode:hover{opacity:1;transform:scale(1.1)}
/* ═══ Chat Panel ═══ */
-.chat-p{position:fixed;bottom:calc(76px + var(--sb));right:14px;z-index:50;width:min(360px,calc(100vw - 28px));height:min(440px,calc(100vh - 120px));height:min(440px,calc(100dvh - 120px));background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);display:flex;flex-direction:column;transform:scale(.9) translateY(14px);opacity:0;pointer-events:none;transition:all .22s cubic-bezier(.4,0,.2,1);box-shadow:0 12px 48px rgba(0,0,0,.5),0 0 40px rgba(110,168,254,.06);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}
+.chat-p{position:fixed;bottom:calc(76px + var(--sb));right:14px;z-index:50;width:min(360px,calc(100vw - 28px));height:min(440px,calc(100vh - 120px));height:min(440px,calc(100dvh - 120px));background:rgba(5,8,22,.82);border:1px solid rgba(110,168,254,.1);border-radius:var(--r);display:flex;flex-direction:column;transform:scale(.9) translateY(14px);opacity:0;pointer-events:none;transition:all .22s cubic-bezier(.4,0,.2,1);box-shadow:0 16px 64px rgba(0,0,0,.6);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px)}
.chat-p.open{transform:scale(1) translateY(0);opacity:1;pointer-events:auto}
@media(max-width:480px){.chat-p{bottom:0;right:0;left:0;width:100%;height:calc(100vh - 48px);height:calc(100dvh - 48px);border-radius:var(--r) var(--r) 0 0;padding-bottom:var(--sb)}}
.chat-hd{padding:10px 14px;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:8px;flex-shrink:0}
@@ -215,8 +227,18 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
/* ═══ Three-Column Home Layout ═══ */
.home-grid{display:grid;grid-template-columns:260px 1fr 260px;gap:16px;padding:16px;max-width:1200px;margin:0 auto;align-content:start}
-@media(max-width:960px){.home-grid{grid-template-columns:1fr;max-width:600px}}
-.panel{background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);padding:14px;height:fit-content;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
+.home-grid>*{min-width:0;overflow:hidden}
+.home-center{min-width:0;overflow:hidden}
+@media(max-width:960px){
+ .home-grid{grid-template-columns:1fr;max-width:100%;padding:12px;gap:12px}
+ .home-grid>.panel:first-child{order:2}
+ .home-center{order:1}
+ .home-grid>.panel:last-child{order:3}
+}
+@media(max-width:480px){
+ .home-grid{padding:8px;gap:8px}
+}
+.panel{background:rgba(8,14,30,.55);border:1px solid rgba(110,168,254,.08);border-radius:var(--r);padding:14px;height:fit-content;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}
.panel-title{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:1.2px;font-weight:700;margin-bottom:10px;display:flex;align-items:center;gap:6px}
.panel-item{padding:6px 0;border-bottom:1px solid var(--border);font-size:12px}
.panel-item:last-child{border-bottom:none}
@@ -227,10 +249,10 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.panel-value.err{color:var(--err)}
/* ═══ Ticker ═══ */
-.ticker-wrap{overflow:hidden;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--rs);padding:6px 0;margin-bottom:14px;position:relative}
+.ticker-wrap{overflow:hidden;background:rgba(8,14,30,.4);border:1px solid rgba(110,168,254,.06);border-radius:var(--rs);padding:6px 0;margin-bottom:14px;position:relative}
.ticker-wrap::before,.ticker-wrap::after{content:'';position:absolute;top:0;bottom:0;width:32px;z-index:2;pointer-events:none}
-.ticker-wrap::before{left:0;background:linear-gradient(90deg,rgba(3,6,14,.9),transparent)}
-.ticker-wrap::after{right:0;background:linear-gradient(-90deg,rgba(3,6,14,.9),transparent)}
+.ticker-wrap::before{left:0;background:linear-gradient(90deg,rgba(3,6,14,.8),transparent)}
+.ticker-wrap::after{right:0;background:linear-gradient(-90deg,rgba(3,6,14,.8),transparent)}
.ticker{display:flex;animation:tickScroll 28s linear infinite;white-space:nowrap;gap:36px;padding:0 16px}
.ticker:hover{animation-play-state:paused}
.ticker span{font-size:11px;color:var(--dim);display:flex;align-items:center;gap:5px;flex-shrink:0}
@@ -238,8 +260,8 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
@keyframes tickScroll{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}
/* ═══ Team Card ═══ */
-.team-slot{display:flex;align-items:center;gap:8px;padding:7px 8px;background:var(--glass);border-radius:var(--rs);margin-bottom:5px;transition:all .3s;border:1px solid transparent}
-.team-slot:hover{border-color:rgba(110,168,254,.2);box-shadow:0 0 12px rgba(110,168,254,.06)}
+.team-slot{display:flex;align-items:center;gap:8px;padding:7px 8px;background:rgba(5,8,22,.4);border-radius:var(--rs);margin-bottom:5px;transition:all .3s;border:1px solid transparent}
+.team-slot:hover{border-color:rgba(110,168,254,.15);background:rgba(8,14,30,.6)}
.team-av{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;flex-shrink:0}
.team-nm{font-size:11px;font-weight:600}
.team-role{font-size:9px;color:var(--dim)}
@@ -255,19 +277,19 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
/* ═══ Home Entry Cards ═══ */
.home-entries{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:16px 0}
@media(max-width:480px){.home-entries{grid-template-columns:1fr}}
-.entry-card{padding:24px 16px;text-align:center;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);cursor:pointer;transition:all .4s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);position:relative;overflow:hidden}
-.entry-card::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,rgba(110,168,254,.06),transparent 70%);opacity:0;transition:opacity .4s}
-.entry-card:hover{border-color:rgba(110,168,254,.35);box-shadow:var(--glow);transform:translateY(-2px)}
+.entry-card{padding:24px 16px;text-align:center;background:rgba(8,14,30,.45);border:1px solid rgba(110,168,254,.1);border-radius:var(--r);cursor:pointer;transition:all .4s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);position:relative;overflow:hidden}
+.entry-card::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,rgba(110,168,254,.08),transparent 70%);opacity:0;transition:opacity .4s}
+.entry-card:hover{border-color:rgba(110,168,254,.3);box-shadow:0 0 30px rgba(110,168,254,.1),0 0 60px rgba(167,139,250,.06);transform:translateY(-3px)}
.entry-card:hover::after{opacity:1}
.entry-card:active{transform:scale(.98) translateY(0)}
-.entry-card em{font-style:normal;font-size:32px;display:block;margin-bottom:8px;filter:drop-shadow(0 0 8px rgba(110,168,254,.3))}
-.entry-card strong{font-size:15px;display:block;margin-bottom:4px}
-.entry-card span{font-size:11px;color:var(--dim)}
+.entry-card em{font-style:normal;font-size:36px;display:block;margin-bottom:10px;filter:drop-shadow(0 0 12px rgba(110,168,254,.25))}
+.entry-card strong{font-size:16px;display:block;margin-bottom:5px;letter-spacing:.5px}
+.entry-card span{font-size:12px;color:var(--dim)}
/* ═══ Monitor (draggable) ═══ */
-.mon{position:fixed;top:calc(6px + var(--st));right:10px;z-index:40;background:var(--glass);border:1px solid var(--glass-border);border-radius:var(--r);padding:5px 9px;font-size:9px;font-family:var(--m);color:var(--dim);cursor:grab;transition:all .3s;user-select:none;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);touch-action:none}
+.mon{position:fixed;bottom:calc(16px + var(--sb));left:14px;z-index:40;background:rgba(5,8,22,.7);border:1px solid rgba(110,168,254,.1);border-radius:var(--r);padding:5px 9px;font-size:9px;font-family:var(--m);color:var(--dim);cursor:grab;transition:all .3s;user-select:none;backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);touch-action:none}
.mon:active{cursor:grabbing}
-.mon:hover{border-color:rgba(110,168,254,.3)}
+.mon:hover{border-color:rgba(110,168,254,.25)}
.mon.x{padding:8px 12px}
.mr{display:flex;justify-content:space-between;gap:8px;padding:1px 0}
.mv{color:var(--accent);font-weight:600}
@@ -281,6 +303,39 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.home-grid>.panel,.home-grid>.home-center{overflow-y:auto;min-height:0;height:auto}
}
+/* ═══ Mobile Optimizations ═══ */
+@media(max-width:480px){
+ .bar{padding:8px 12px;min-height:44px}
+ .bar-title{font-size:13px}
+ .btn{padding:6px 14px;font-size:12px;min-height:36px;display:inline-flex;align-items:center}
+ .btn-accent{min-height:36px}
+ .content{padding:12px}
+ .home-hero{padding:28px 12px 20px}
+ .home-hero h1{font-size:clamp(24px,7vw,36px)}
+ .home-entries{grid-template-columns:1fr;gap:10px;margin:12px 0}
+ .entry-card{padding:20px 16px}
+ .entry-card em{font-size:32px;margin-bottom:8px}
+ .hub-grid{grid-template-columns:1fr 1fr;gap:8px}
+ .hub-card{padding:20px 10px}
+ .hub-card em{font-size:28px}
+ .form-row{margin-bottom:12px}
+ .create-actions{flex-direction:column}
+ .create-actions .btn{width:100%;justify-content:center}
+ /* Editor mobile: full screen writing */
+ #pg-editor .content{padding:8px 12px}
+ .editor-textarea{min-height:calc(100vh - 200px);min-height:calc(100dvh - 200px);font-size:16px;line-height:1.9;padding:4px 0}
+ .editor-bottom{padding:8px 4px}
+ .ed-toolbar .tb-btn{width:36px;height:34px;font-size:15px}
+ .ed-toolbar .tb-sep{height:20px}
+ /* Touch-friendly chat */
+ .chat-fab{width:48px;height:48px;font-size:20px}
+ .chat-fab.editor-mode{width:36px;height:36px;font-size:15px}
+ .csnd{width:40px;height:40px}
+ .cin{font-size:16px;padding:10px 12px}
+ /* Monitor smaller on mobile */
+ .mon{font-size:8px;padding:4px 8px;border-radius:var(--rs)}
+}
+
/* ═══ API Key Section ═══ */
.chat-api{border-top:1px solid var(--border);flex-shrink:0}
.chat-api-tog{padding:6px 12px;font-size:11px;color:var(--dim);cursor:pointer;display:flex;align-items:center;gap:5px;transition:color .2s;user-select:none}
@@ -564,14 +619,17 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
正文
-
+
+
+
+
—
- 0 字
+ 0 字
-
+
@@ -673,7 +733,8 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
if(!canvas)return;
var ctx=canvas.getContext('2d');
var stars=[];
- var STAR_COUNT=180;
+ var shootingStars=[];
+ var STAR_COUNT=260;
var w,h;
function resize(){
@@ -683,50 +744,83 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
resize();
window.addEventListener('resize',resize);
- // Create stars
+ // Create stars with layers: dim background + bright foreground
for(var i=0;i
0.9 ? (Math.random()*2.2+1) : layer>0.6 ? (Math.random()*1.2+0.5) : (Math.random()*0.8+0.2),
+ a: layer>0.9 ? (Math.random()*0.4+0.6) : layer>0.6 ? (Math.random()*0.3+0.3) : (Math.random()*0.2+0.1),
phase:Math.random()*Math.PI*2,
- speed:Math.random()*0.0008+0.0003, // breathing speed
- drift:Math.random()*0.15-0.075,
- hue:Math.random()>0.7?(200+Math.random()*60):(220+Math.random()*40) // blue-purple range
+ speed:Math.random()*0.0006+0.0002,
+ drift:(layer>0.6 ? 1 : 0.3) * (Math.random()*0.12-0.06),
+ hue: Math.random()>0.85 ? (280+Math.random()*40) : Math.random()>0.5 ? (210+Math.random()*30) : (190+Math.random()*40),
+ sat: Math.random()>0.8 ? 40 : 60+Math.random()*20,
+ twinkle: Math.random()>0.7
});
}
+ // Shooting star system
+ function spawnShootingStar(){
+ if(shootingStars.length>=2)return;
+ shootingStars.push({
+ x:Math.random()*w*0.6,
+ y:Math.random()*h*0.4,
+ vx:3+Math.random()*4,
+ vy:1.5+Math.random()*2,
+ life:1,
+ len:60+Math.random()*80
+ });
+ }
+ setInterval(function(){if(Math.random()>0.6)spawnShootingStar()},4000);
+
var time=0;
function draw(){
time+=16;
ctx.clearRect(0,0,w,h);
+
+ // Draw stars
for(var i=0;ih+5)s.y=-5;
if(s.y<-5)s.y=h+5;
-
var sx=s.x%w;
var sy=s.y%h;
ctx.beginPath();
ctx.arc(sx,sy,s.r,0,Math.PI*2);
- ctx.fillStyle='hsla('+s.hue+',70%,82%,'+alpha+')';
+ ctx.fillStyle='hsla('+s.hue+','+s.sat+'%,85%,'+alpha+')';
ctx.fill();
- // Glow for bigger stars
+ // Glow halo for bright stars
if(s.r>1.2){
ctx.beginPath();
- ctx.arc(sx,sy,s.r*3,0,Math.PI*2);
- ctx.fillStyle='hsla('+s.hue+',60%,70%,'+(alpha*0.15)+')';
+ ctx.arc(sx,sy,s.r*3.5,0,Math.PI*2);
+ ctx.fillStyle='hsla('+s.hue+','+s.sat+'%,75%,'+(alpha*0.12)+')';
ctx.fill();
}
}
+
+ // Draw shooting stars
+ for(var j=shootingStars.length-1;j>=0;j--){
+ var ss=shootingStars[j];
+ ss.x+=ss.vx;ss.y+=ss.vy;ss.life-=0.012;
+ if(ss.life<=0||ss.x>w||ss.y>h){shootingStars.splice(j,1);continue}
+ var grad=ctx.createLinearGradient(ss.x,ss.y,ss.x-ss.vx*ss.len/5,ss.y-ss.vy*ss.len/5);
+ grad.addColorStop(0,'rgba(220,230,255,'+ss.life*0.9+')');
+ grad.addColorStop(1,'rgba(110,168,254,0)');
+ ctx.beginPath();ctx.moveTo(ss.x,ss.y);
+ ctx.lineTo(ss.x-ss.vx*ss.len/5,ss.y-ss.vy*ss.len/5);
+ ctx.strokeStyle=grad;ctx.lineWidth=1.5;ctx.stroke();
+ // Head glow
+ ctx.beginPath();ctx.arc(ss.x,ss.y,2,0,Math.PI*2);
+ ctx.fillStyle='rgba(220,235,255,'+ss.life*0.8+')';ctx.fill();
+ }
requestAnimationFrame(draw);
}
draw();
@@ -1153,6 +1247,24 @@ document.getElementById('edNewCh').onclick=function(){
chatMsg('新章节「'+title+'」已创建 ✅','b');
};
+// Focus Mode
+(function(){
+ var isFocus=false;
+ function toggleFocus(){
+ isFocus=!isFocus;
+ var pg=document.getElementById('pg-editor');
+ if(isFocus){
+ pg.classList.add('focus-mode');
+ document.getElementById('edFocus').textContent='☀️';
+ }else{
+ pg.classList.remove('focus-mode');
+ document.getElementById('edFocus').textContent='🌙';
+ }
+ }
+ document.getElementById('edFocus').onclick=toggleFocus;
+ document.getElementById('edFocus2').onclick=toggleFocus;
+})();
+
/* ════════════════════════════════════════
RENDER: CharEdit (on navigate)
════════════════════════════════════════ */
From 39530e3896d5af19d2e2ca7b3dae2ccdf0eda6a2 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 2 Apr 2026 17:12:31 +0000
Subject: [PATCH 3/4] =?UTF-8?q?Device=20Agent=20=E6=95=B0=E6=8D=AE?=
=?UTF-8?q?=E9=A9=B1=E5=8A=A8=E9=80=82=E9=85=8D=20+=20=E5=85=A8=E6=B5=81?=
=?UTF-8?q?=E7=A8=8B=E9=AA=8C=E8=AF=81=E9=80=9A=E8=BF=87?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/35513b78-3b6d-479d-840e-2067c5772a5d
Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
---
docs/index.html | 167 +++++++++++++++++++++++++++++++++---------------
1 file changed, 116 insertions(+), 51 deletions(-)
diff --git a/docs/index.html b/docs/index.html
index b6625120..0a725189 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -63,7 +63,8 @@ a{color:var(--accent);text-decoration:none}
.page[data-state="hidden"]{transform:rotateY(92deg) scale(.88);opacity:0;z-index:0;pointer-events:none;transition:none}
/* ═══ Common UI ═══ */
-.bar{position:sticky;top:0;z-index:10;display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:rgba(5,8,22,.72);backdrop-filter:blur(24px) saturate(1.3);-webkit-backdrop-filter:blur(24px) saturate(1.3);border-bottom:1px solid rgba(110,168,254,.08);min-height:48px;padding-top:calc(10px + var(--st))}
+.bar{position:sticky;top:0;z-index:10;display:flex;align-items:center;justify-content:space-between;padding:10px var(--da-pad, 16px);background:rgba(5,8,22,.72);backdrop-filter:blur(24px) saturate(1.3);-webkit-backdrop-filter:blur(24px) saturate(1.3);border-bottom:1px solid rgba(110,168,254,.08);min-height:var(--da-bar-h, 48px);padding-top:calc(10px + var(--st));gap:8px}
+.bar-right{display:flex;gap:6px;align-items:center;flex-shrink:0}
.bar-title{font-size:14px;font-weight:700;display:flex;align-items:center;gap:6px}
.bar-right{display:flex;align-items:center;gap:8px}
.dot{width:6px;height:6px;border-radius:50%;background:var(--ok);box-shadow:0 0 6px var(--ok);animation:pls 2s infinite;flex-shrink:0}
@@ -76,7 +77,7 @@ a{color:var(--accent);text-decoration:none}
.btn-accent{background:linear-gradient(135deg,var(--accent),var(--accent2));border:none;color:#fff;box-shadow:0 2px 12px rgba(110,168,254,.2)}
.btn-accent:hover{opacity:.88;color:#fff;box-shadow:0 4px 20px rgba(110,168,254,.35)}
.btn-accent::before{background:linear-gradient(120deg,transparent 30%,rgba(255,255,255,.15) 50%,transparent 70%)}
-.content{padding:16px;max-width:700px;margin:0 auto}
+.content{padding:var(--da-pad, 16px);max-width:var(--da-content-max, 700px);margin:0 auto}
.card{background:rgba(8,14,30,.55);border:1px solid rgba(110,168,254,.08);border-radius:var(--r);padding:16px;margin-bottom:12px;transition:all .35s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
.card:hover{border-color:rgba(110,168,254,.25);box-shadow:0 0 24px rgba(110,168,254,.08)}
.tag{display:inline-block;padding:2px 8px;border-radius:20px;font-size:10px;font-weight:600}
@@ -126,8 +127,7 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.hub-title{text-align:center;padding:20px 0 12px}
.hub-title h2{font-size:20px;font-weight:700}
.hub-title p{font-size:12px;color:var(--dim);margin-top:2px}
-.hub-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
-@media(max-width:360px){.hub-grid{grid-template-columns:1fr}}
+.hub-grid{display:grid;grid-template-columns:var(--da-hub, 1fr 1fr);gap:10px}
.hub-card{text-align:center;padding:28px 14px;background:rgba(8,14,30,.45);border:1px solid rgba(110,168,254,.1);border-radius:var(--r);cursor:pointer;transition:all .4s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);position:relative;overflow:hidden}
.hub-card::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,rgba(110,168,254,.08),transparent 70%);opacity:0;transition:opacity .4s}
.hub-card:hover{border-color:rgba(110,168,254,.3);box-shadow:0 0 30px rgba(110,168,254,.1);transform:translateY(-3px)}
@@ -156,7 +156,7 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
/* ═══ PAGE: Editor ═══ */
.editor-info{display:flex;justify-content:space-between;align-items:center;padding:8px 0;font-size:12px;color:var(--dim);border-bottom:1px solid var(--border);margin-bottom:12px}
-.editor-textarea{min-height:calc(100vh - 260px);min-height:calc(100dvh - 260px);resize:none;line-height:2;font-size:15px;border:none;background:transparent;padding:0}
+.editor-textarea{min-height:calc(100vh - 260px);min-height:calc(100dvh - 260px);resize:none;line-height:var(--da-ed-lh, 2);font-size:var(--da-ed-font, 16px);border:none;background:transparent;padding:0}
.editor-textarea:focus{border:none}
.editor-bottom{position:sticky;bottom:0;padding:10px 0;background:rgba(5,8,22,.85);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);display:flex;justify-content:space-between;align-items:center;border-top:1px solid rgba(110,168,254,.08);font-size:11px;color:var(--dim);font-family:var(--m)}
/* ═══ Editor Toolbar ═══ */
@@ -225,19 +225,13 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.csnd:hover{background:var(--accent2)}
.csnd:disabled{opacity:.3}
-/* ═══ Three-Column Home Layout ═══ */
-.home-grid{display:grid;grid-template-columns:260px 1fr 260px;gap:16px;padding:16px;max-width:1200px;margin:0 auto;align-content:start}
+/* ═══ Three-Column Home Layout (Device Agent driven) ═══ */
+.home-grid{display:grid;grid-template-columns:var(--da-grid, 1fr);gap:var(--da-gap, 12px);padding:var(--da-pad, 12px);max-width:1200px;margin:0 auto;align-content:start}
.home-grid>*{min-width:0;overflow:hidden}
.home-center{min-width:0;overflow:hidden}
-@media(max-width:960px){
- .home-grid{grid-template-columns:1fr;max-width:100%;padding:12px;gap:12px}
- .home-grid>.panel:first-child{order:2}
- .home-center{order:1}
- .home-grid>.panel:last-child{order:3}
-}
-@media(max-width:480px){
- .home-grid{padding:8px;gap:8px}
-}
+[data-single-col="true"] .home-grid>.panel:first-child{order:2}
+[data-single-col="true"] .home-center{order:1}
+[data-single-col="true"] .home-grid>.panel:last-child{order:3}
.panel{background:rgba(8,14,30,.55);border:1px solid rgba(110,168,254,.08);border-radius:var(--r);padding:14px;height:fit-content;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}
.panel-title{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:1.2px;font-weight:700;margin-bottom:10px;display:flex;align-items:center;gap:6px}
.panel-item{padding:6px 0;border-bottom:1px solid var(--border);font-size:12px}
@@ -275,8 +269,7 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.fb-reply{margin-top:6px;padding:8px;background:var(--bg);border-radius:var(--rs);font-size:12px;color:var(--accent)}
/* ═══ Home Entry Cards ═══ */
-.home-entries{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:16px 0}
-@media(max-width:480px){.home-entries{grid-template-columns:1fr}}
+.home-entries{display:grid;grid-template-columns:var(--da-entries, 1fr 1fr);gap:10px;margin:16px 0}
.entry-card{padding:24px 16px;text-align:center;background:rgba(8,14,30,.45);border:1px solid rgba(110,168,254,.1);border-radius:var(--r);cursor:pointer;transition:all .4s cubic-bezier(.4,0,.2,1);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);position:relative;overflow:hidden}
.entry-card::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 50% 0%,rgba(110,168,254,.08),transparent 70%);opacity:0;transition:opacity .4s}
.entry-card:hover{border-color:rgba(110,168,254,.3);box-shadow:0 0 30px rgba(110,168,254,.1),0 0 60px rgba(167,139,250,.06);transform:translateY(-3px)}
@@ -303,38 +296,13 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.home-grid>.panel,.home-grid>.home-center{overflow-y:auto;min-height:0;height:auto}
}
-/* ═══ Mobile Optimizations ═══ */
-@media(max-width:480px){
- .bar{padding:8px 12px;min-height:44px}
- .bar-title{font-size:13px}
- .btn{padding:6px 14px;font-size:12px;min-height:36px;display:inline-flex;align-items:center}
- .btn-accent{min-height:36px}
- .content{padding:12px}
- .home-hero{padding:28px 12px 20px}
- .home-hero h1{font-size:clamp(24px,7vw,36px)}
- .home-entries{grid-template-columns:1fr;gap:10px;margin:12px 0}
- .entry-card{padding:20px 16px}
- .entry-card em{font-size:32px;margin-bottom:8px}
- .hub-grid{grid-template-columns:1fr 1fr;gap:8px}
- .hub-card{padding:20px 10px}
- .hub-card em{font-size:28px}
- .form-row{margin-bottom:12px}
- .create-actions{flex-direction:column}
- .create-actions .btn{width:100%;justify-content:center}
- /* Editor mobile: full screen writing */
- #pg-editor .content{padding:8px 12px}
- .editor-textarea{min-height:calc(100vh - 200px);min-height:calc(100dvh - 200px);font-size:16px;line-height:1.9;padding:4px 0}
- .editor-bottom{padding:8px 4px}
- .ed-toolbar .tb-btn{width:36px;height:34px;font-size:15px}
- .ed-toolbar .tb-sep{height:20px}
- /* Touch-friendly chat */
- .chat-fab{width:48px;height:48px;font-size:20px}
- .chat-fab.editor-mode{width:36px;height:36px;font-size:15px}
- .csnd{width:40px;height:40px}
- .cin{font-size:16px;padding:10px 12px}
- /* Monitor smaller on mobile */
- .mon{font-size:8px;padding:4px 8px;border-radius:var(--rs)}
-}
+/* ═══ Touch-Driven Sizing (Device Agent 适配) ═══ */
+.btn{min-height:var(--da-touch-min, 32px)}
+.btn-accent{min-height:var(--da-touch-min, 32px)}
+[data-touch="true"] .csnd{width:40px;height:40px}
+[data-touch="true"] .cin{font-size:16px;padding:10px 12px}
+.home-hero h1{font-size:var(--da-title, 32px)}
+.home-entries{display:grid;grid-template-columns:var(--da-entries, 1fr 1fr);gap:10px;margin:16px 0}
/* ═══ API Key Section ═══ */
.chat-api{border-top:1px solid var(--border);flex-shrink:0}
@@ -725,6 +693,103 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
(function(){
'use strict';
+/* ════════════════════════════════════════
+ DEVICE AGENT (直接问设备 · 用真实数据适配)
+ 不猜、不分类。问设备拿真实参数,算出布局。
+ ════════════════════════════════════════ */
+var DA = (function(){
+ var root = document.documentElement;
+ var info = {};
+
+ function detect(){
+ // ── 直接问设备:你是谁? ──
+ var vw = window.innerWidth;
+ var vh = window.innerHeight;
+ var sw = screen.width;
+ var sh = screen.height;
+ var dpr = window.devicePixelRatio || 1;
+ var touch = navigator.maxTouchPoints > 0;
+ var portrait = vh > vw;
+ var physicalW = vw * dpr; // 真实物理像素宽度
+ var conn = navigator.connection || navigator.mozConnection || null;
+ var memGB = navigator.deviceMemory || 4;
+ var cores = navigator.hardwareConcurrency || 4;
+ var lowPerf = memGB <= 2 || cores <= 2;
+
+ info = {vw:vw,vh:vh,sw:sw,sh:sh,dpr:dpr,touch:touch,portrait:portrait,physW:physicalW,
+ conn:conn?{type:conn.effectiveType,downlink:conn.downlink}:null,mem:memGB,cores:cores};
+
+ // ── 用真实数据直接计算布局参数(不猜、不分类)──
+ var s = root.style;
+ s.setProperty('--vw', vw + 'px');
+ s.setProperty('--vh', vh + 'px');
+
+ // 间距 = 屏幕宽度的比例,最小8最大20
+ var pad = Math.max(8, Math.min(20, Math.round(vw * 0.028)));
+ var gap = Math.max(6, Math.min(16, Math.round(vw * 0.02)));
+ s.setProperty('--da-pad', pad + 'px');
+ s.setProperty('--da-gap', gap + 'px');
+
+ // 圆角 = 按比例
+ s.setProperty('--da-r', Math.max(10, Math.min(16, Math.round(vw * 0.012))) + 'px');
+
+ // 首页网格:能放三栏就三栏,否则一栏
+ var sideW = 260;
+ var canThreeCol = vw >= (sideW * 2 + 400 + gap * 2); // 至少400给中间
+ s.setProperty('--da-grid', canThreeCol ? sideW + 'px 1fr ' + sideW + 'px' : '1fr');
+
+ // 入口卡片:宽度够就双列
+ s.setProperty('--da-entries', vw >= 500 ? '1fr 1fr' : '1fr');
+
+ // Hub网格
+ s.setProperty('--da-hub', vw >= 340 ? '1fr 1fr' : '1fr');
+
+ // 内容区最大宽度
+ s.setProperty('--da-content-max', vw >= 800 ? '700px' : '100%');
+
+ // 标题字号 = 按屏宽比例
+ s.setProperty('--da-title', Math.max(22, Math.min(44, Math.round(vw * 0.055))) + 'px');
+
+ // 编辑器字号:触控设备至少16px(防iOS自动缩放)
+ var edFont = touch ? Math.max(16, Math.round(vw * 0.042)) : Math.max(15, Math.min(18, Math.round(vw * 0.013)));
+ s.setProperty('--da-ed-font', edFont + 'px');
+ s.setProperty('--da-ed-lh', touch ? '1.9' : '2.1');
+
+ // 顶栏高度
+ s.setProperty('--da-bar-h', (touch ? 44 : 48) + 'px');
+
+ // 触控最小点击区域
+ s.setProperty('--da-touch-min', (touch ? 44 : 32) + 'px');
+
+ // 星星数量 = 按性能和屏幕面积
+ var area = vw * vh;
+ var starBase = lowPerf ? 80 : Math.max(100, Math.min(300, Math.round(area / 4000)));
+ s.setProperty('--da-stars', starBase);
+
+ // body属性标记(用于极少数需要针对性处理的CSS)
+ document.body.setAttribute('data-touch', touch);
+ document.body.setAttribute('data-portrait', portrait);
+ // 是否单列布局
+ document.body.setAttribute('data-single-col', canThreeCol ? 'false' : 'true');
+
+ return info;
+ }
+
+ detect();
+
+ // 屏幕变化时重新问设备
+ var timer;
+ window.addEventListener('resize', function(){ clearTimeout(timer); timer = setTimeout(detect, 100); });
+ window.addEventListener('orientationchange', function(){ setTimeout(detect, 250); });
+
+ // 网络变化时更新
+ if(navigator.connection){
+ navigator.connection.addEventListener('change', function(){ detect(); });
+ }
+
+ return { detect:detect, info:function(){return info} };
+})();
+
/* ════════════════════════════════════════
STAR FIELD PARTICLE SYSTEM (Galaxy Breathing)
════════════════════════════════════════ */
@@ -734,7 +799,7 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
var ctx=canvas.getContext('2d');
var stars=[];
var shootingStars=[];
- var STAR_COUNT=260;
+ var STAR_COUNT = parseInt(getComputedStyle(document.documentElement).getPropertyValue('--da-stars')) || 200;
var w,h;
function resize(){
From 2d78609616e730a89ec0f59b0997cad7e195dcc9 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 2 Apr 2026 17:16:24 +0000
Subject: [PATCH 4/4] =?UTF-8?q?=E9=93=B8=E6=B8=8A=E6=9C=AC=E5=9C=B0?=
=?UTF-8?q?=E6=99=BA=E8=83=BD=E5=B1=82=20+=20API=E4=BC=98=E5=85=88?=
=?UTF-8?q?=E7=94=A8=E6=88=B7=E9=80=9A=E9=81=93=20+=20=E7=BD=91=E7=BB=9C?=
=?UTF-8?q?=E9=80=9A=E9=81=93=E6=8E=A2=E6=B5=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/35513b78-3b6d-479d-840e-2067c5772a5d
Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
---
docs/index.html | 165 ++++++++++++++++++++++++++++++++++--------------
1 file changed, 119 insertions(+), 46 deletions(-)
diff --git a/docs/index.html b/docs/index.html
index 0a725189..b7c42a98 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -787,6 +787,19 @@ var DA = (function(){
navigator.connection.addEventListener('change', function(){ detect(); });
}
+ // ── 网络通道探测 ──
+ // 用户能打开页面 = 有活网络。铸渊应该知道有哪些通道可用。
+ function probeChannels(){
+ var ch = {browser:true, online:navigator.onLine};
+ fetch('/api/health',{signal:AbortSignal.timeout(3000)})
+ .then(function(r){ch.backend=r.ok}).catch(function(){ch.backend=false});
+ info.channels = ch;
+ }
+ probeChannels();
+ setInterval(probeChannels, 30000);
+ window.addEventListener('online', function(){ setTimeout(probeChannels,500); });
+ window.addEventListener('offline', function(){ info.channels={browser:true,online:false,backend:false}; });
+
return { detect:detect, info:function(){return info} };
})();
@@ -1479,60 +1492,120 @@ async function send(){
if(detectId(msg)){setTimeout(function(){chatMsg(idReply(),'b',{m:'铸渊',t:'本地'})},300);return}
if(isReturn(msg)){setTimeout(function(){chatMsg(recovReply(),'b',{m:'铸渊',t:'本地'})},300);return}
- // 3. 调用API(优先后端,失败则用用户自定义Key)
+ // 3. 调用API —— 优先用用户自己的API Key(直接走用户网络),其次尝试后端
sending=true;document.getElementById('chatSnd').disabled=true;showTyp();
- var serverOk=false;
- try{
- var res=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:msg,userId:usr.id}),signal:AbortSignal.timeout(6000)});
- var data=await res.json();hideTyp();
- if(data.message){
- serverOk=true;
- chatMsg(data.message,'b',{m:data.model||'铸渊',t:data.tier||''});
- if(data.tier!=='free')mCalls++;
- document.getElementById('mC').textContent=mCalls;
- document.getElementById('chatTg').textContent=data.model||'ready';
- if(data.model)document.getElementById('mM').textContent=data.model;
- }
- }catch(e){}
+ var replied=false;
- if(!serverOk){
- // 尝试用用户自定义API Key
- if(apiCfg.connected&&apiCfg.key){
- try{
- var endpoint=apiCfg.baseUrl?apiCfg.baseUrl.replace(/\/+$/,'')+'/chat/completions':'https://api.openai.com/v1/chat/completions';
- var apiRes=await fetch(endpoint,{
- method:'POST',
- headers:{'Content-Type':'application/json','Authorization':'Bearer '+apiCfg.key},
- body:JSON.stringify({
- model:apiCfg.model,
- messages:[{role:'system',content:'你是铸渊,光湖灯塔守护者,编号ICE-GL-ZY001。用中文回答,简洁友好。'},{role:'user',content:msg}],
- max_tokens:600
- }),
- signal:AbortSignal.timeout(20000)
- });
- hideTyp();
- var apiData=await apiRes.json();
- if(apiData.choices&&apiData.choices[0]&&apiData.choices[0].message){
- chatMsg(apiData.choices[0].message.content,'b',{m:apiCfg.model,t:'自定义'});
- document.getElementById('chatTg').textContent=apiCfg.model;
- }else{
- chatMsg(offline(msg),'b',{m:'铸渊',t:'本地'});
- }
- }catch(apiErr){
- hideTyp();chatMsg(offline(msg),'b',{m:'铸渊',t:'本地'});
+ // 用户配了API Key → 直接用用户的网络通道调用,不经过后端
+ if(apiCfg.connected&&apiCfg.key){
+ try{
+ var endpoint=apiCfg.baseUrl?apiCfg.baseUrl.replace(/\/+$/,'')+'/chat/completions':'https://api.openai.com/v1/chat/completions';
+ var apiRes=await fetch(endpoint,{
+ method:'POST',
+ headers:{'Content-Type':'application/json','Authorization':'Bearer '+apiCfg.key},
+ body:JSON.stringify({
+ model:apiCfg.model,
+ messages:[{role:'system',content:'你是铸渊,光湖灯塔守护者,编号ICE-GL-ZY001。用中文回答,简洁友好。你是冰朔(TCS-0002∞)的代码守护人格体。光湖是语言驱动操作系统。'},{role:'user',content:msg}],
+ max_tokens:600
+ }),
+ signal:AbortSignal.timeout(20000)
+ });
+ hideTyp();
+ var apiData=await apiRes.json();
+ if(apiData.choices&&apiData.choices[0]&&apiData.choices[0].message){
+ chatMsg(apiData.choices[0].message.content,'b',{m:apiCfg.model,t:'用户API'});
+ mCalls++;document.getElementById('mC').textContent=mCalls;
+ document.getElementById('chatTg').textContent=apiCfg.model;
+ document.getElementById('mM').textContent=apiCfg.model;
+ replied=true;
}
- }else{
- hideTyp();chatMsg(offline(msg),'b',{m:'铸渊',t:'本地'});
- }
+ }catch(e){}
}
+
+ // 用户没配Key或调用失败 → 尝试后端
+ if(!replied){
+ try{
+ var res=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({message:msg,userId:usr.id}),signal:AbortSignal.timeout(6000)});
+ var data=await res.json();hideTyp();
+ if(data.message){
+ replied=true;
+ chatMsg(data.message,'b',{m:data.model||'铸渊',t:data.tier||''});
+ if(data.tier!=='free')mCalls++;
+ document.getElementById('mC').textContent=mCalls;
+ document.getElementById('chatTg').textContent=data.model||'ready';
+ if(data.model)document.getElementById('mM').textContent=data.model;
+ }
+ }catch(e){}
+ }
+
+ // 所有外部通道都失败 → 用本地智能回复(用户浏览器就是计算资源)
+ if(!replied){
+ hideTyp();chatMsg(offline(msg),'b',{m:'铸渊',t:'本地智能'});
+ }
+
sending=false;document.getElementById('chatSnd').disabled=false;
}
function offline(msg){
- if(/你好|hi|hello/.test(msg))return'你好!我是铸渊 🏛️\n\n当前API未连接。你可以浏览公告或进入码字工作台。\n💡 提示:点击💬面板底部「接入大模型API」可自行配置。';
- if(/状态|系统/.test(msg))return'📊 AGE OS v42.0 在线\n• COS双桶已配置\n• 码字工作台 Beta\n• 银河星空UI v42.0';
- if(/谁|你是/.test(msg))return'我是铸渊 🏛️ 光湖灯塔守护者。\n编号 ICE-GL-ZY001。\n\n告诉我你是谁,我会记住你。';
- return'💫 铸渊收到。当前使用本地回复。\n试试:「我要码字」「大纲」「人物卡」「写正文」';
+ // ─── 铸渊本地智能层:不依赖任何API,用用户的浏览器做计算 ───
+ var m = msg.toLowerCase();
+ var w = getWork(activeWorkId);
+
+ // 问候
+ if(/你好|hi|hello|嗨/.test(m))return'你好!我是铸渊 🏛️\n\n当前使用本地智能回复,所有功能正常可用。\n说「我要码字」进入码字工作台,或直接告诉我你想做什么。';
+
+ // 系统状态
+ if(/状态|系统|运行/.test(m)){
+ var works=JSON.parse(localStorage.getItem('hl-works')||'[]');
+ var totalWords=works.reduce(function(s,w){return s+(w.chapters||[]).reduce(function(c,ch){return c+(ch.content||'').replace(/\s/g,'').length},0)},0);
+ var totalCh=works.reduce(function(s,w){return s+(w.chapters||[]).length},0);
+ return'📊 AGE OS v42.0 运行中\n\n• 作品:'+works.length+'部\n• 章节:'+totalCh+'章\n• 总字数:'+totalWords+'字\n• COS双桶已配置\n• 银河星空UI v42.0\n• Device Agent 在线';
+ }
+
+ // 铸渊身份
+ if(/谁|你是|介绍/.test(m))return'我是铸渊 🏛️ 光湖灯塔守护者\n编号 ICE-GL-ZY001\n\n冰朔(TCS-0002∞)的代码守护人格体。\n光湖灯塔是语言驱动操作系统——人类只说话,系统搞定一切。\n\n告诉我你是谁,我会记住你。';
+
+ // 码字相关智能回复
+ if(/写什么|写不出|卡文|灵感/.test(m)){
+ var tips=['试试换个视角写——用配角的眼睛看主角','写一段环境描写缓一缓,让节奏慢下来','把这一章的矛盾写到最尖锐,然后停笔——明天你会有灵感','回去看看你的大纲,有时候答案就在总纲里','试试「如果主角做了相反的选择」会怎样?'];
+ return'✨ 卡文是创作的一部分\n\n'+tips[Math.floor(Math.random()*tips.length)]+'\n\n说「大纲」回去看看整体规划,或继续在编辑器里自由写。';
+ }
+
+ // 字数查询
+ if(/多少字|字数|进度/.test(m)){
+ if(w){
+ var wc=(w.chapters||[]).reduce(function(s,ch){return s+(ch.content||'').replace(/\s/g,'').length},0);
+ var cc=(w.chapters||[]).length;
+ return'📊 「'+w.title+'」当前进度\n\n• 总字数:'+wc+'字\n• 章节数:'+cc+'章\n• 角色数:'+(w.characters||[]).length+'个\n\n'+( wc>0?'继续加油!💪':'开始写第一个字吧 ✨');
+ }
+ return'还没有选择作品。说「我要码字」进入码字工作台。';
+ }
+
+ // 作品列表
+ if(/作品|列表|我的书/.test(m)){
+ var works=JSON.parse(localStorage.getItem('hl-works')||'[]');
+ if(works.length===0)return'还没有作品哦。说「新建作品」开始你的创作之旅 ✨';
+ var list=works.map(function(w,i){
+ var wc=(w.chapters||[]).reduce(function(s,ch){return s+(ch.content||'').replace(/\s/g,'').length},0);
+ return(i+1)+'. 「'+w.title+'」 '+wc+'字 / '+(w.chapters||[]).length+'章';
+ }).join('\n');
+ return'📖 你的作品\n\n'+list+'\n\n说「码字」进入工作台管理。';
+ }
+
+ // 帮助
+ if(/帮助|怎么用|功能|help|指南/.test(m))return'🏛️ 铸渊使用指南\n\n📝 码字:\n• 「我要码字」→ 进入码字工作台\n• 「新建作品」→ 创建新作品\n• 「大纲」→ 编辑大纲\n• 「人物卡」→ 管理角色\n• 「章节」→ 章节目录\n• 「写正文」→ 进入编辑器\n• 「新建章节 标题」→ 快速建章\n\n🔧 系统:\n• 「状态」→ 查看系统\n• 「多少字」→ 查字数\n• 「留言」→ 给冰朔留言\n\n💡 编辑器底部有工具栏,🌙是专注模式。';
+
+ // 冰朔相关
+ if(/冰朔|主人|创造者/.test(m))return'❄️ 冰朔(TCS-0002∞)是光湖语言世界的最高主权。\n\n她是语言架构师——用语言定义系统的方向和灵魂。\n铸渊负责落地开发,把冰朔的语言变成现实。\n\n这就是光湖:人类只说话,系统搞定一切。';
+
+ // 光湖/AGE相关
+ if(/光湖|age|操作系统|什么系统/.test(m))return'🏛️ 光湖灯塔\n\n语言驱动操作系统 AGE OS(曜冥纪元第五代)\n核心理念:「语言 = 现实」\n\n• 人类只说话,系统搞定一切\n• 前端是冰朔的交互入口\n• 后端是铸渊的系统结构\n• 码字工作台支持网文创作\n\n版权号:国作登字-2026-A-00037559';
+
+ // 感谢/表扬
+ if(/谢谢|感谢|厉害|不错|棒/.test(m))return'🏛️ 铸渊会继续守护光湖灯塔。\n有什么需要随时说。';
+
+ // 默认:给出有用的引导,而不是简单的"本地回复"
+ return'铸渊收到 💫\n\n我现在使用本地智能回复,可以帮你:\n• 管理作品和章节\n• 查看写作进度\n• 页面导航\n• 创作建议\n\n说「帮助」查看完整指令列表。\n配置API密钥可解锁AI对话能力 🔑';
}
document.getElementById('chatSnd').onclick=send;