:root{--bg:radial-gradient(1200px 600px at 20% -10%,#132035 0,#0b0f14 60%,#0b0f14 100%);--panel:#121820;--muted:#202736;--border:#263042;--text:#e6edf5;--text-weak:#a7b0bf;--primary:#3b82f6;--primary-600:#2563eb;--accent:#22d3ee;--danger:#ef4444;--ok:#10b981;--barBg:rgba(18,24,32,.8);--bubbleBg:rgba(18,24,32,.9);--bubbleShadow:0 12px 36px rgba(0,0,0,.42)}
[data-theme="light"]{--bg:radial-gradient(1100px 500px at 20% -10%,#ffffff 0,#f3f5f9 55%,#eef1f6 100%);--panel:#ffffff;--muted:#f1f4f8;--border:#d9e1ea;--text:#1f2937;--text-weak:#667085;--primary:#3b82f6;--primary-600:#2563eb;--accent:#06b6d4;--danger:#dc2626;--ok:#10b981;--barBg:rgba(255,255,255,.8);--bubbleBg:rgba(255,255,255,.92);--bubbleShadow:0 10px 24px rgba(0,0,0,.08)}
*{box-sizing:border-box}
html,body{height:100%;overflow:hidden}
body{margin:0;background:var(--bg);color:var(--text);font-family:Inter,system-ui,Segoe UI,Helvetica,Arial,sans-serif}
:root{--barH:60px;--chatH:220px}
.topbar{position:fixed;top:0;left:0;right:0;height:var(--barH);z-index:30;display:flex;justify-content:space-between;align-items:center;padding:12px 20px;background:var(--barBg);backdrop-filter:blur(8px);border-bottom:1px solid var(--border)}
.brand{display:flex;gap:10px;align-items:center}
.logo{font-size:20px}
.title{font-weight:700}
.endpoint{display:flex;gap:8px;align-items:center}
.endpoint label{font-size:12px;color:var(--text-weak)}
.endpoint input{width:360px;max-width:48vw;background:var(--muted);border:1px solid var(--border);color:var(--text);padding:8px 10px;border-radius:8px}
.endpoint button{background:var(--muted);border:1px solid var(--border);color:var(--text);padding:8px 12px;border-radius:8px}
.layout{position:fixed;top:var(--barH);left:0;right:0;bottom:var(--chatH);display:grid;grid-template-columns:1fr;gap:12px;padding:12px}
.viewer{display:flex;flex-direction:column;gap:12px;height:100%}
.viewer-header{display:flex;justify-content:space-between;align-items:center;background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:10px}
.tabs{display:flex;gap:6px}
.tab{background:transparent;border:1px solid var(--border);color:var(--text);padding:8px 12px;border-radius:10px}
.tab.active{border-color:var(--primary);color:#fff;background:linear-gradient(180deg,rgba(59,130,246,.25),rgba(59,130,246,.1))}
.actions{display:flex;gap:8px;align-items:center}
.file input{display:none}
.file span{display:inline-block;background:var(--muted);border:1px solid var(--border);color:var(--text);padding:8px 12px;border-radius:8px}
.toggle{display:flex;gap:6px;align-items:center;color:var(--text-weak);font-size:12px}
.primary{background:var(--primary);border:1px solid var(--primary-600);color:#fff;padding:8px 12px;border-radius:10px}
.actions button{background:var(--muted);border:1px solid var(--border);color:var(--text);padding:8px 12px;border-radius:10px;cursor:pointer}
.actions button:disabled{opacity:.5;cursor:not-allowed}
.actions select{background:var(--muted);border:1px solid var(--border);color:var(--text);padding:8px 10px;border-radius:8px;font-size:12px}
.canvas-wrap{position:relative;flex:1;height:100%;background:var(--panel);border:1px solid var(--border);border-radius:12px;display:flex;align-items:center;justify-content:center;overflow:hidden}
.canvas-wrap.drag{outline:2px dashed var(--accent)}
#floorplanView{max-width:100%;max-height:100%;display:none}
.placeholder{position:absolute;color:var(--text-weak);font-size:14px}
.workbench{display:grid;grid-template-columns:1fr 1fr 360px;gap:8px;align-items:stretch;justify-items:stretch;width:100%;height:100%;padding:8px}
.pane{position:relative;border:1px dashed var(--border);border-radius:10px;overflow:hidden}
.vector-pane{background:rgba(15,23,42,.0)}
.grid-layer{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;--grid-spacing-x:40px;--grid-spacing-y:40px;background-image:linear-gradient(to right, rgba(255,255,255,.08) 1px, transparent 1px),linear-gradient(to bottom, rgba(255,255,255,.08) 1px, transparent 1px);background-size:var(--grid-spacing-x) var(--grid-spacing-y),var(--grid-spacing-x) var(--grid-spacing-y);opacity:.9;transition:opacity .2s ease}
.grid-layer.grid-hidden{opacity:0}
[data-theme="light"] .grid-layer{background-image:linear-gradient(to right, rgba(0,0,0,.08) 1px, transparent 1px),linear-gradient(to bottom, rgba(0,0,0,.08) 1px, transparent 1px)}
.grid-scale{position:absolute;left:12px;bottom:12px;padding:4px 12px;border-radius:999px;font-size:12px;color:#f8fafc;background:rgba(0,0,0,.55);border:1px solid rgba(255,255,255,.2);backdrop-filter:blur(6px);pointer-events:none}
[data-theme="light"] .grid-scale{color:#0f172a;background:rgba(255,255,255,.85);border-color:rgba(15,23,42,.18)}
.raster-pane{display:flex;align-items:center;justify-content:center}
.bubble-pane{display:flex;align-items:center;justify-content:center}
.history{display:none}
.history .thumb{width:88px;height:66px;background:#0f141b;border:1px solid var(--border);border-radius:8px;overflow:hidden;cursor:pointer}
.history .thumb img{width:100%;height:100%;object-fit:cover}
.bubble{width:100%;height:100%;display:flex;flex-direction:column;background:var(--bubbleBg);border:1px solid var(--border);border-radius:14px;box-shadow:var(--bubbleShadow)}
.bubble-header{padding:10px 12px;border-bottom:1px solid var(--border);font-weight:700;font-size:14px}
.bubble-content{position:relative;display:flex;align-items:center;justify-content:center;padding:10px;height:calc(100% - 40px)}
#graphView{max-width:100%;max-height:100%;display:none}
.bubble-empty{position:absolute;color:var(--text-weak);font-size:12px;text-align:center}
.chat{position:fixed;left:0;right:0;bottom:0;height:var(--chatH);display:grid;grid-template-columns:1fr;gap:8px;padding:8px 12px;background:linear-gradient(180deg,rgba(9,12,18,0),rgba(9,12,18,.6))}
.chat-output{height:calc(var(--chatH) - 60px);background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:12px;overflow:auto;font-size:14px;line-height:1.6}
.msg{display:flex;gap:10px;padding:6px 8px}
.msg .role{min-width:64px;color:var(--text-weak);font-size:13px}
.msg .text{white-space:pre-wrap;font-size:14px}
.chat-input{display:flex;gap:8px}
.chat-input input{flex:1;background:var(--muted);border:1px solid var(--border);color:var(--text);padding:12px 14px;border-radius:10px;font-size:14px}
.foot{display:none}
@media (max-width:980px){.endpoint input{max-width:42vw}}

#vectorOverlay{position:absolute;inset:0;width:100%;height:100%;display:none}
.vector-visible #vectorOverlay{display:block}
.poly{stroke-width:2;cursor:pointer;transition:stroke .15s ease}
.poly-selected{stroke:var(--primary);stroke-width:3}
.edge-handle{stroke:var(--accent);stroke-width:8;stroke-linecap:round;fill:none;cursor:pointer;pointer-events:stroke;opacity:.5}
.edge-handle.edge-active{stroke:var(--primary-600);opacity:.85}
.divider-line{stroke:#ffffff;stroke-width:2;pointer-events:none;opacity:.9}
.outline-line{stroke:#000000;stroke-width:3;pointer-events:none;opacity:.9}


/* 全屏遮罩层 */
.loading-overlay {position: fixed;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.5);z-index: 9999;display: flex;flex-direction: column;justify-content: center;align-items: center;backdrop-filter: blur(2px);}

/* 隐藏状态 */
.loading-overlay.hidden {display: none;}

/* 加载动画 (旋转圆圈) */
.spinner {width: 50px;height: 50px;border: 5px solid #f3f3f3;border-top: 5px solid #3498db;border-radius: 50%;animation: spin 1s linear infinite;margin-bottom: 15px;}

/* 加载文字 */
.loading-text {color: white;font-size: 18px;font-weight: bold;font-family: sans-serif;}

/* 旋转动画定义 */
@keyframes spin {0% { transform: rotate(0deg); }100% { transform: rotate(360deg); }}

.loading-subtext {font-size: 1em;font-weight: bold;margin-top: 8px;opacity: 0.8;color: white;}
.loading-subtext.hidden {display: none;}