Device Agent 数据驱动适配 + 全流程验证通过

Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/35513b78-3b6d-479d-840e-2067c5772a5d

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-04-02 17:12:31 +00:00 committed by GitHub
parent 4229576d2f
commit 39530e3896
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 116 additions and 51 deletions

View File

@ -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(){