[split-upload 5/6] f2fd4fa backup via proxy
This commit is contained in:
@@ -0,0 +1,637 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>工具栏统一设计 v0.6 - 图标与坐席头像突破</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: linear-gradient(135deg, #e0e7ff 0%, #f3e8ff 50%, #fce7f3 100%);
|
||||
color: #1a1a1a;
|
||||
padding: 32px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
min-height: 100vh;
|
||||
}
|
||||
h1 { font-size: 24px; font-weight: 600; letter-spacing: -0.02em; margin-bottom: 8px; color: #1a1a1a; }
|
||||
h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 40px 0 12px; color: #1a1a1a; }
|
||||
h3 { font-size: 14px; font-weight: 600; margin: 16px 0 8px; color: #333; }
|
||||
.meta { color: #6b7280; font-size: 12.5px; margin-bottom: 24px; }
|
||||
|
||||
.glass-toolbar {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding: 6px 8px;
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
backdrop-filter: blur(28px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(28px) saturate(180%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.7);
|
||||
border-radius: 18px;
|
||||
box-shadow:
|
||||
0 1px 0 rgba(255, 255, 255, 0.9) inset,
|
||||
0 -1px 0 rgba(99, 102, 241, 0.08) inset,
|
||||
0 2px 4px rgba(99, 102, 241, 0.05),
|
||||
0 8px 16px rgba(99, 102, 241, 0.08),
|
||||
0 24px 48px rgba(99, 102, 241, 0.05);
|
||||
position: relative;
|
||||
}
|
||||
.glass-toolbar::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 18px;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.1) 40%, transparent 60%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.glass-toolbar::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 18px;
|
||||
background: radial-gradient(circle at 20% 20%, rgba(99, 102, 241, 0.15) 0%, transparent 50%),
|
||||
radial-gradient(circle at 80% 80%, rgba(236, 72, 153, 0.12) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
.glass-divider {
|
||||
width: 1px;
|
||||
height: 24px;
|
||||
background: linear-gradient(180deg, transparent 0%, rgba(99, 102, 241, 0.2) 50%, transparent 100%);
|
||||
margin: 0 4px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.glass-btn {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.6);
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
box-shadow:
|
||||
0 1px 0 rgba(255, 255, 255, 0.9) inset,
|
||||
0 -1px 0 rgba(0, 0, 0, 0.04) inset,
|
||||
0 1px 2px rgba(0, 0, 0, 0.04),
|
||||
0 2px 4px rgba(0, 0, 0, 0.04);
|
||||
overflow: hidden;
|
||||
}
|
||||
.glass-btn:hover {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
transform: translateY(-1px) scale(1.04);
|
||||
}
|
||||
.glass-btn:active { transform: translateY(0) scale(0.95); }
|
||||
.glass-btn svg { width: 22px; height: 22px; }
|
||||
|
||||
.agent-btn { width: 42px; height: 42px; }
|
||||
|
||||
.agent-btn.is-active {
|
||||
background: linear-gradient(135deg, rgba(99, 102, 241, 0.95) 0%, rgba(168, 85, 247, 0.95) 50%, rgba(236, 72, 153, 0.95) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
.agent-btn.is-active::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 1px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.35) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.agent-btn.is-urgent {
|
||||
background: linear-gradient(135deg, rgba(239, 68, 68, 0.95) 0%, rgba(220, 38, 38, 0.95) 50%, rgba(185, 28, 28, 0.95) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
animation: agentGlow 1.6s ease-in-out infinite;
|
||||
}
|
||||
@keyframes agentGlow {
|
||||
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0), 0 1px 0 rgba(255, 255, 255, 0.9) inset; }
|
||||
50% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0.18), 0 1px 0 rgba(255, 255, 255, 0.9) inset; }
|
||||
}
|
||||
.agent-btn.is-waiting { background: linear-gradient(135deg, rgba(245, 158, 11, 0.95) 0%, rgba(217, 119, 6, 0.95) 50%, rgba(180, 83, 9, 0.95) 100%); border-color: rgba(255, 255, 255, 0.4); }
|
||||
.agent-btn.is-end { background: linear-gradient(135deg, rgba(16, 185, 129, 0.95) 0%, rgba(5, 150, 105, 0.95) 50%, rgba(4, 120, 87, 0.95) 100%); border-color: rgba(255, 255, 255, 0.4); }
|
||||
.agent-btn.is-reopen { background: linear-gradient(135deg, rgba(59, 130, 246, 0.95) 0%, rgba(37, 99, 235, 0.95) 50%, rgba(29, 78, 216, 0.95) 100%); border-color: rgba(255, 255, 255, 0.4); }
|
||||
.agent-btn.is-disabled { opacity: 0.4; cursor: not-allowed; }
|
||||
.agent-btn.is-disabled:hover { transform: none; background: rgba(255, 255, 255, 0.5); }
|
||||
.agent-btn.is-disabled svg { filter: grayscale(1); }
|
||||
|
||||
.demo-block {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.7);
|
||||
border-radius: 18px;
|
||||
padding: 32px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 8px 16px rgba(99, 102, 241, 0.06);
|
||||
}
|
||||
.demo-label { font-size: 11.5px; color: #6b7280; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 14px; font-weight: 500; }
|
||||
.demo-stage-bg {
|
||||
background: linear-gradient(135deg, #e0e7ff 0%, #f3e8ff 50%, #fce7f3 100%);
|
||||
border-radius: 14px;
|
||||
padding: 48px 32px;
|
||||
min-height: 140px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.state-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid rgba(99, 102, 241, 0.12); }
|
||||
.state-tab {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid rgba(99, 102, 241, 0.2);
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 12.5px;
|
||||
color: #4b5563;
|
||||
transition: all 0.15s;
|
||||
font-family: inherit;
|
||||
}
|
||||
.state-tab:hover { background: rgba(255, 255, 255, 0.8); }
|
||||
.state-tab.active { background: linear-gradient(135deg, #6366f1, #8b5cf6); color: #fff; border-color: transparent; }
|
||||
|
||||
.state-desc { color: #4b5563; font-size: 12.5px; line-height: 1.7; background: rgba(255, 255, 255, 0.5); padding: 12px 14px; border-radius: 10px; border-left: 2px solid #6366f1; margin-top: 12px; backdrop-filter: blur(10px); }
|
||||
.state-desc strong { color: #1a1a1a; }
|
||||
|
||||
/* 坐席头像风格对比 */
|
||||
.avatar-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.avatar-card {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border: 1px solid rgba(255, 255, 255, 0.8);
|
||||
border-radius: 16px;
|
||||
padding: 24px 16px 16px;
|
||||
text-align: center;
|
||||
backdrop-filter: blur(20px);
|
||||
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 8px 16px rgba(99, 102, 241, 0.08);
|
||||
transition: all 0.2s;
|
||||
cursor: pointer;
|
||||
}
|
||||
.avatar-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 1px 0 rgba(255, 255, 255, 1) inset, 0 12px 24px rgba(99, 102, 241, 0.15);
|
||||
}
|
||||
.avatar-card.recommend { border: 2px solid #6366f1; }
|
||||
.avatar-card .stage {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 0 auto 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.avatar-card .stage svg { width: 100%; height: 100%; }
|
||||
.avatar-card h4 { font-size: 13px; font-weight: 600; margin-bottom: 4px; color: #1a1a1a; }
|
||||
.avatar-card p { font-size: 11.5px; color: #6b7280; line-height: 1.5; }
|
||||
.avatar-card .badge {
|
||||
display: inline-block;
|
||||
margin-top: 8px;
|
||||
padding: 2px 8px;
|
||||
background: linear-gradient(135deg, #6366f1, #8b5cf6);
|
||||
color: #fff;
|
||||
font-size: 10.5px;
|
||||
border-radius: 10px;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<svg width="0" height="0" style="position: absolute;">
|
||||
<defs>
|
||||
<linearGradient id="g-active" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#6366f1"/><stop offset="50%" stop-color="#a855f7"/><stop offset="100%" stop-color="#ec4899"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-urgent" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fca5a5"/><stop offset="100%" stop-color="#dc2626"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-waiting" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fcd34d"/><stop offset="100%" stop-color="#f59e0b"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-success" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#6ee7b7"/><stop offset="100%" stop-color="#10b981"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-reopen" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#93c5fd"/><stop offset="100%" stop-color="#3b82f6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-head-warm" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fde68a"/><stop offset="100%" stop-color="#fbbf24"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-head-cool" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#a5b4fc"/><stop offset="100%" stop-color="#6366f1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-body-cool" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#c7d2fe"/><stop offset="100%" stop-color="#818cf8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-earphone" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#475569"/><stop offset="100%" stop-color="#1e293b"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-earphone-soft" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#cbd5e1"/><stop offset="100%" stop-color="#64748b"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-doc-body" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#ffffff"/><stop offset="100%" stop-color="#dbeafe"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-doc-fold" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#c7d2fe"/><stop offset="100%" stop-color="#818cf8"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-mic-body" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#a78bfa"/><stop offset="50%" stop-color="#8b5cf6"/><stop offset="100%" stop-color="#6d28d9"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-emoji-face" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fef3c7"/><stop offset="100%" stop-color="#fbbf24"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-highlight" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="white" stop-opacity="0.95"/>
|
||||
<stop offset="100%" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-deep" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="white" stop-opacity="0"/>
|
||||
<stop offset="100%" stop-color="black" stop-opacity="0.15"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<h1>工具栏统一设计 v0.6 — 图标与坐席头像突破</h1>
|
||||
<p class="meta">整体玻璃工具栏保留 + 4 工具图标升级(高质感几何)+ 坐席头像 3 套风格对比 · 2026-08-04 凌晨</p>
|
||||
|
||||
<div class="note">
|
||||
📌 本版核心改动(对比 v0.5):<br>
|
||||
• 整体水晶玻璃工具栏✅ 沿用 v0.5<br>
|
||||
• 4 工具图标<strong>高质感升级</strong>:<br>
|
||||
- 😊 表情:渐变圆脸 + 立体眼睛(双高光点) + 弧形嘴 + 阴影<br>
|
||||
- 📎 文件:立体文档(白色→浅蓝渐变 + 折角 + 文字行)<br>
|
||||
- 🎤 语音:专业录音棚麦克风(深紫渐变 + 高光条 + 弧形底座)<br>
|
||||
• <strong>坐席头像 3 套风格</strong>对比(点击下方 tab 切换查看):<br>
|
||||
- A. 几何抽象 IP(Linear/Notion 风)— 极简专业<br>
|
||||
- B. Q 版拟人客服(Apple 风)— 圆脸 + 戴耳机,亲和力强<br>
|
||||
- C. 3D 立体拟人(Spotify 风)— 多层渐变 + 立体光影<br>
|
||||
</div>
|
||||
|
||||
<h2>🎨 整体工具栏(玻璃拟态 + 升级图标)</h2>
|
||||
<div class="demo-block">
|
||||
<div class="demo-label">4 按钮工具栏完整效果(点击下方 tab 切换坐席头像风格 A/B/C)</div>
|
||||
<div class="demo-stage-bg">
|
||||
<div class="glass-toolbar">
|
||||
<!-- 表情(升级版) -->
|
||||
<button class="glass-btn" title="表情">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="12" cy="12" r="9" fill="url(#g-emoji-face)"/>
|
||||
<ellipse cx="12" cy="6" rx="6" ry="2" fill="url(#g-highlight)"/>
|
||||
<ellipse cx="8.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<ellipse cx="15.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<circle cx="8.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<circle cx="15.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<path d="M8 15 Q12 18 16 15" fill="none" stroke="#1e1b4b" stroke-width="1.4" stroke-linecap="round"/>
|
||||
<path d="M3 12 Q3 21 12 21 Q21 21 21 12 Q21 3 12 3 Q3 3 3 12" fill="url(#g-deep)" opacity="0.3"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- 文件(升级版) -->
|
||||
<button class="glass-btn" title="文件">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="url(#g-doc-body)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
|
||||
<path d="M14 2 L14 8 L20 8" fill="url(#g-doc-fold)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
|
||||
<ellipse cx="12" cy="4" rx="5" ry="0.8" fill="url(#g-highlight)"/>
|
||||
<line x1="7" y1="12" x2="17" y2="12" stroke="#6366f1" stroke-width="0.8" opacity="0.5"/>
|
||||
<line x1="7" y1="15" x2="15" y2="15" stroke="#6366f1" stroke-width="0.8" opacity="0.5"/>
|
||||
<line x1="7" y1="18" x2="13" y2="18" stroke="#6366f1" stroke-width="0.8" opacity="0.5"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="glass-divider"></div>
|
||||
<!-- 语音(升级版) -->
|
||||
<button class="glass-btn" title="语音">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<rect x="8" y="2" width="8" height="13" rx="4" fill="url(#g-mic-body)"/>
|
||||
<ellipse cx="10" cy="3.5" rx="1.2" ry="3" fill="white" opacity="0.55"/>
|
||||
<line x1="10" y1="6" x2="10" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="14" y1="6" x2="14" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="12" y1="18" x2="12" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="8" y1="22" x2="16" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- 坐席(动态切换) -->
|
||||
<div id="agent-stage"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>👤 坐席头像 3 套风格对比(突破方向)</h2>
|
||||
<div class="demo-block">
|
||||
<div class="state-tabs">
|
||||
<button class="state-tab active" data-style="A">A. 几何抽象 IP(Linear 风)</button>
|
||||
<button class="state-tab" data-style="B">B. Q 版拟人(Apple 风)</button>
|
||||
<button class="state-tab" data-style="C">C. 3D 立体拟人(Spotify 风)</button>
|
||||
</div>
|
||||
|
||||
<div class="avatar-grid">
|
||||
<div class="avatar-card recommend" data-style="A">
|
||||
<div class="stage">
|
||||
<svg viewBox="0 0 100 100" fill="none">
|
||||
<defs>
|
||||
<linearGradient id="aA-bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#6366f1"/><stop offset="100%" stop-color="#8b5cf6"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- 圆形渐变背景 -->
|
||||
<circle cx="50" cy="50" r="48" fill="url(#aA-bg)"/>
|
||||
<ellipse cx="50" cy="30" rx="30" ry="8" fill="white" opacity="0.25"/>
|
||||
<!-- 抽象几何"听筒"符号 -->
|
||||
<circle cx="50" cy="55" r="22" fill="none" stroke="white" stroke-width="3" opacity="0.9"/>
|
||||
<path d="M28 55 Q28 35 50 35 Q72 35 72 55" fill="none" stroke="white" stroke-width="3" opacity="0.9"/>
|
||||
<circle cx="28" cy="55" r="5" fill="white"/>
|
||||
<circle cx="72" cy="55" r="5" fill="white"/>
|
||||
<circle cx="50" cy="55" r="3" fill="white" opacity="0.6"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h4>A. 几何抽象 IP</h4>
|
||||
<p>Linear / Notion 风<br>极简专业 · 抽象听筒<br>不拟人 · 品牌色强</p>
|
||||
<div class="badge">推荐专业 SaaS</div>
|
||||
</div>
|
||||
|
||||
<div class="avatar-card" data-style="B">
|
||||
<div class="stage">
|
||||
<svg viewBox="0 0 100 100" fill="none">
|
||||
<defs>
|
||||
<linearGradient id="aB-bg" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fde68a"/><stop offset="100%" stop-color="#fb923c"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="aB-head" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fef3c7"/><stop offset="100%" stop-color="#fde68a"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- 圆形背景 -->
|
||||
<circle cx="50" cy="50" r="48" fill="url(#aB-bg)"/>
|
||||
<ellipse cx="50" cy="20" rx="35" ry="8" fill="white" opacity="0.3"/>
|
||||
<!-- 拟人客服 -->
|
||||
<ellipse cx="50" cy="68" rx="22" ry="14" fill="white" opacity="0.4"/>
|
||||
<circle cx="50" cy="48" r="18" fill="url(#aB-head)"/>
|
||||
<ellipse cx="50" cy="40" rx="12" ry="3" fill="white" opacity="0.6"/>
|
||||
<!-- 耳罩(渐变) -->
|
||||
<ellipse cx="32" cy="48" rx="5" ry="8" fill="url(#g-earphone-soft)"/>
|
||||
<ellipse cx="68" cy="48" rx="5" ry="8" fill="url(#g-earphone-soft)"/>
|
||||
<ellipse cx="32" cy="48" rx="2.5" ry="4" fill="#475569"/>
|
||||
<ellipse cx="68" cy="48" rx="2.5" ry="4" fill="#475569"/>
|
||||
<!-- 眼睛 -->
|
||||
<ellipse cx="42" cy="48" rx="2" ry="2.5" fill="#1e1b4b"/>
|
||||
<ellipse cx="58" cy="48" rx="2" ry="2.5" fill="#1e1b4b"/>
|
||||
<circle cx="42.6" cy="47.2" r="0.7" fill="white"/>
|
||||
<circle cx="58.6" cy="47.2" r="0.7" fill="white"/>
|
||||
<!-- 嘴(微笑) -->
|
||||
<path d="M44 56 Q50 60 56 56" fill="none" stroke="#1e1b4b" stroke-width="2" stroke-linecap="round"/>
|
||||
<!-- 颈 -->
|
||||
<rect x="44" y="64" width="12" height="6" fill="#fde68a"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h4>B. Q 版拟人客服</h4>
|
||||
<p>Apple 风格<br>圆脸 + 戴耳罩 + 颈<br>亲和力强 · 易识别</p>
|
||||
<div class="badge">推荐</div>
|
||||
</div>
|
||||
|
||||
<div class="avatar-card" data-style="C">
|
||||
<div class="stage">
|
||||
<svg viewBox="0 0 100 100" fill="none">
|
||||
<defs>
|
||||
<radialGradient id="aC-bg" cx="30%" cy="30%" r="80%">
|
||||
<stop offset="0%" stop-color="#a78bfa"/><stop offset="50%" stop-color="#6366f1"/><stop offset="100%" stop-color="#312e81"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="aC-skin" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fef3c7"/><stop offset="100%" stop-color="#fcd34d"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="aC-jacket" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#7c3aed"/><stop offset="100%" stop-color="#4c1d95"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- 3D 渐变背景(径向光) -->
|
||||
<circle cx="50" cy="50" r="48" fill="url(#aC-bg)"/>
|
||||
<ellipse cx="35" cy="20" rx="25" ry="12" fill="white" opacity="0.3"/>
|
||||
<!-- 肩(西装) -->
|
||||
<path d="M22 80 Q22 70 32 65 L68 65 Q78 70 78 80 L78 92 L22 92 Z" fill="url(#aC-jacket)"/>
|
||||
<!-- 衬衣领 -->
|
||||
<path d="M40 65 L50 75 L60 65 L60 60 L50 65 L40 60 Z" fill="white" opacity="0.9"/>
|
||||
<!-- 颈 -->
|
||||
<rect x="44" y="55" width="12" height="14" fill="url(#aC-skin)"/>
|
||||
<!-- 头部(3D 立体) -->
|
||||
<circle cx="50" cy="40" r="20" fill="url(#aC-skin)"/>
|
||||
<ellipse cx="50" cy="28" rx="14" ry="6" fill="white" opacity="0.4"/>
|
||||
<!-- 头发(深色渐变) -->
|
||||
<path d="M30 38 Q30 22 50 20 Q70 22 70 38 L70 32 Q70 28 65 26 L60 28 Q55 24 50 24 Q45 24 40 28 L35 26 Q30 28 30 32 Z" fill="#1e1b4b" opacity="0.9"/>
|
||||
<!-- 耳罩(3D 立体金属感) -->
|
||||
<ellipse cx="28" cy="42" rx="6" ry="9" fill="url(#g-earphone)"/>
|
||||
<ellipse cx="72" cy="42" rx="6" ry="9" fill="url(#g-earphone)"/>
|
||||
<ellipse cx="28" cy="42" rx="3" ry="5" fill="#0f172a"/>
|
||||
<ellipse cx="72" cy="42" rx="3" ry="5" fill="#0f172a"/>
|
||||
<ellipse cx="28" cy="40" rx="1" ry="2" fill="white" opacity="0.4"/>
|
||||
<ellipse cx="72" cy="40" rx="1" ry="2" fill="white" opacity="0.4"/>
|
||||
<!-- 麦克风臂 -->
|
||||
<path d="M28 50 Q28 56 35 58" fill="none" stroke="url(#g-earphone)" stroke-width="2" stroke-linecap="round"/>
|
||||
<circle cx="35" cy="58" r="2" fill="#dc2626"/>
|
||||
<!-- 眼睛(锐利) -->
|
||||
<ellipse cx="42" cy="40" rx="2" ry="2.5" fill="#1e1b4b"/>
|
||||
<ellipse cx="58" cy="40" rx="2" ry="2.5" fill="#1e1b4b"/>
|
||||
<circle cx="42.7" cy="39.2" r="0.7" fill="white"/>
|
||||
<circle cx="58.7" cy="39.2" r="0.7" fill="white"/>
|
||||
<!-- 眉(浓) -->
|
||||
<path d="M38 35 Q42 33 46 35" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M54 35 Q58 33 62 35" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<!-- 鼻 -->
|
||||
<path d="M50 42 L48 48 L52 48" fill="none" stroke="#d97706" stroke-width="1" stroke-linecap="round" opacity="0.6"/>
|
||||
<!-- 嘴(专业微笑) -->
|
||||
<path d="M44 52 Q50 56 56 52" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h4>C. 3D 立体拟人</h4>
|
||||
<p>Spotify / Cuberto 风<br>西装 + 头发 + 锐利五官<br>高级感最强 · 品牌化</p>
|
||||
<div class="badge">推荐</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>🎬 客服按钮 6 态(风格 A 演示)</h2>
|
||||
<div class="demo-block">
|
||||
<div class="state-tabs">
|
||||
<button class="state-tab active" data-state="active">active</button>
|
||||
<button class="state-tab" data-state="disabled">disabled</button>
|
||||
<button class="state-tab" data-state="urgent">urgent</button>
|
||||
<button class="state-tab" data-state="waiting">waiting</button>
|
||||
<button class="state-tab" data-state="end">end</button>
|
||||
<button class="state-tab" data-state="reopen">reopen</button>
|
||||
</div>
|
||||
|
||||
<div class="demo-stage-bg">
|
||||
<div class="glass-toolbar">
|
||||
<div id="state-stage"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="state-desc" id="state-desc"></div>
|
||||
</div>
|
||||
|
||||
<h2>📊 3 套坐席头像风格对比</h2>
|
||||
<table class="cmp-table" style="width:100%; border-collapse: collapse; font-size: 12.5px;">
|
||||
<thead>
|
||||
<tr style="background: rgba(255,255,255,0.6);">
|
||||
<th style="border:1px solid rgba(99,102,241,0.15); padding:8px; text-align:left;">维度</th>
|
||||
<th style="border:1px solid rgba(99,102,241,0.15); padding:8px; text-align:left;">A. 几何抽象 IP</th>
|
||||
<th style="border:1px solid rgba(99,102,241,0.15); padding:8px; text-align:left;">B. Q 版拟人</th>
|
||||
<th style="border:1px solid rgba(99,102,241,0.15); padding:8px; text-align:left;">C. 3D 立体拟人</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">对标产品</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">Linear / Notion</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">Apple 拟人助手</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">Spotify / Cuberto</td></tr>
|
||||
<tr><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">识别度</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">中(抽象)</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">高(拟人亲和)</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">高(品牌感)</td></tr>
|
||||
<tr><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">专业感</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">★★★★★</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">★★★★</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">★★★★★(顶级)</td></tr>
|
||||
<tr><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">亲和感</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">★★(冷)</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">★★★★★(暖)</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">★★★★(平衡)</td></tr>
|
||||
<tr><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">实施难度</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">低</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">中</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">高(SVG 复杂)</td></tr>
|
||||
<tr><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">品牌延展性</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">中(几何简洁)</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">中(角色化)</td><td style="border:1px solid rgba(99,102,241,0.15); padding:8px;">高(可做更多表情/姿态)</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>❓ 待你拍板</h2>
|
||||
<ol style="margin-left: 20px; line-height: 1.8;">
|
||||
<li><strong>坐席头像选 A / B / C 哪套</strong>?或需要混合(如默认 A,排队/紧急用 C 增加情感)?</li>
|
||||
<li><strong>4 工具图标升级版</strong>(高质感几何)OK 吗?如仍需调整(比如简化或更抽象),告诉我</li>
|
||||
<li>坐席头像 <strong>大小</strong>:42px(当前,比工具按钮大)还是 38px(与其他一致)?</li>
|
||||
<li>如果选 C(3D 立体),需<strong>请专业设计师</strong>重画吗?我做的 SVG 复杂度有限,实际效果可能不如设计稿精美</li>
|
||||
</ol>
|
||||
|
||||
<p style="margin-top: 32px; padding-top: 16px; border-top: 1px solid rgba(99, 102, 241, 0.15); color: #6b7280; font-size: 11.5px;">
|
||||
v0.6 图标与坐席头像突破 · 2026-08-04 · Duckula 主理人 · 等待用户拍板
|
||||
</p>
|
||||
|
||||
<script>
|
||||
const agentSvgs = {
|
||||
A: `<svg viewBox="0 0 100 100" fill="none">
|
||||
<circle cx="50" cy="50" r="48" fill="url(#g-active)"/>
|
||||
<ellipse cx="50" cy="30" rx="30" ry="8" fill="white" opacity="0.25"/>
|
||||
<circle cx="50" cy="55" r="22" fill="none" stroke="white" stroke-width="3" opacity="0.9"/>
|
||||
<path d="M28 55 Q28 35 50 35 Q72 35 72 55" fill="none" stroke="white" stroke-width="3" opacity="0.9"/>
|
||||
<circle cx="28" cy="55" r="5" fill="white"/>
|
||||
<circle cx="72" cy="55" r="5" fill="white"/>
|
||||
<circle cx="50" cy="55" r="3" fill="white" opacity="0.6"/>
|
||||
</svg>`,
|
||||
B: `<svg viewBox="0 0 100 100" fill="none">
|
||||
<circle cx="50" cy="50" r="48" fill="url(#g-head-warm)"/>
|
||||
<ellipse cx="50" cy="20" rx="35" ry="8" fill="white" opacity="0.3"/>
|
||||
<ellipse cx="50" cy="68" rx="22" ry="14" fill="white" opacity="0.4"/>
|
||||
<circle cx="50" cy="48" r="18" fill="url(#aB-head)"/>
|
||||
<ellipse cx="50" cy="40" rx="12" ry="3" fill="white" opacity="0.6"/>
|
||||
<ellipse cx="32" cy="48" rx="5" ry="8" fill="url(#g-earphone-soft)"/>
|
||||
<ellipse cx="68" cy="48" rx="5" ry="8" fill="url(#g-earphone-soft)"/>
|
||||
<ellipse cx="32" cy="48" rx="2.5" ry="4" fill="#475569"/>
|
||||
<ellipse cx="68" cy="48" rx="2.5" ry="4" fill="#475569"/>
|
||||
<ellipse cx="42" cy="48" rx="2" ry="2.5" fill="#1e1b4b"/>
|
||||
<ellipse cx="58" cy="48" rx="2" ry="2.5" fill="#1e1b4b"/>
|
||||
<circle cx="42.6" cy="47.2" r="0.7" fill="white"/>
|
||||
<circle cx="58.6" cy="47.2" r="0.7" fill="white"/>
|
||||
<path d="M44 56 Q50 60 56 56" fill="none" stroke="#1e1b4b" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>`,
|
||||
C: `<svg viewBox="0 0 100 100" fill="none">
|
||||
<circle cx="50" cy="50" r="48" fill="url(#aC-bg)"/>
|
||||
<ellipse cx="35" cy="20" rx="25" ry="12" fill="white" opacity="0.3"/>
|
||||
<path d="M22 80 Q22 70 32 65 L68 65 Q78 70 78 80 L78 92 L22 92 Z" fill="url(#aC-jacket)"/>
|
||||
<path d="M40 65 L50 75 L60 65 L60 60 L50 65 L40 60 Z" fill="white" opacity="0.9"/>
|
||||
<rect x="44" y="55" width="12" height="14" fill="url(#aC-skin)"/>
|
||||
<circle cx="50" cy="40" r="20" fill="url(#aC-skin)"/>
|
||||
<ellipse cx="50" cy="28" rx="14" ry="6" fill="white" opacity="0.4"/>
|
||||
<path d="M30 38 Q30 22 50 20 Q70 22 70 38 L70 32 Q70 28 65 26 L60 28 Q55 24 50 24 Q45 24 40 28 L35 26 Q30 28 30 32 Z" fill="#1e1b4b" opacity="0.9"/>
|
||||
<ellipse cx="28" cy="42" rx="6" ry="9" fill="url(#g-earphone)"/>
|
||||
<ellipse cx="72" cy="42" rx="6" ry="9" fill="url(#g-earphone)"/>
|
||||
<ellipse cx="28" cy="42" rx="3" ry="5" fill="#0f172a"/>
|
||||
<ellipse cx="72" cy="42" rx="3" ry="5" fill="#0f172a"/>
|
||||
<path d="M28 50 Q28 56 35 58" fill="none" stroke="url(#g-earphone)" stroke-width="2" stroke-linecap="round"/>
|
||||
<circle cx="35" cy="58" r="2" fill="#dc2626"/>
|
||||
<ellipse cx="42" cy="40" rx="2" ry="2.5" fill="#1e1b4b"/>
|
||||
<ellipse cx="58" cy="40" rx="2" ry="2.5" fill="#1e1b4b"/>
|
||||
<circle cx="42.7" cy="39.2" r="0.7" fill="white"/>
|
||||
<circle cx="58.7" cy="39.2" r="0.7" fill="white"/>
|
||||
<path d="M38 35 Q42 33 46 35" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M54 35 Q58 33 62 35" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M50 42 L48 48 L52 48" fill="none" stroke="#d97706" stroke-width="1" stroke-linecap="round" opacity="0.6"/>
|
||||
<path d="M44 52 Q50 56 56 52" fill="none" stroke="#1e1b4b" stroke-width="1.5" stroke-linecap="round"/>
|
||||
</svg>`
|
||||
};
|
||||
|
||||
const stateMap = {
|
||||
active: { cls: 'is-active', desc: '<strong>active</strong>: 紫粉渐变 + 立体感头像 — 默认"客服在线"。点击切换风格对比 3 套设计' },
|
||||
disabled: { cls: 'is-disabled', desc: '<strong>disabled</strong>: 半透明白 + 灰度滤镜 + opacity 0.4 — 表达"不可用"' },
|
||||
urgent: { cls: 'is-urgent', desc: '<strong>urgent</strong>: 红色渐变 + 1.6s 发光呼吸(光晕扩散) — 表达"紧急"' },
|
||||
waiting: { cls: 'is-waiting', desc: '<strong>waiting</strong>: 橙黄渐变 — 表达"排队中"' },
|
||||
end: { cls: 'is-end', desc: '<strong>end</strong>: 绿色渐变 — 表达"已接入坐席,通话中"' },
|
||||
reopen: { cls: 'is-reopen', desc: '<strong>reopen</strong>: 蓝色渐变 — 表达"会话已关闭,可重新打开"' }
|
||||
};
|
||||
|
||||
let currentStyle = 'A';
|
||||
let currentState = 'active';
|
||||
|
||||
function renderAgent() {
|
||||
const stage = document.getElementById('agent-stage');
|
||||
const stateCls = stateMap[currentState].cls;
|
||||
const svg = agentSvgs[currentStyle];
|
||||
stage.innerHTML = `<button class="glass-btn agent-btn ${stateCls}">${svg}</button>`;
|
||||
}
|
||||
|
||||
function renderState() {
|
||||
const stage = document.getElementById('state-stage');
|
||||
const desc = document.getElementById('state-desc');
|
||||
const s = stateMap[currentState];
|
||||
const svg = agentSvgs.A;
|
||||
stage.innerHTML = `<button class="glass-btn agent-btn ${s.cls}">${svg}</button>`;
|
||||
desc.innerHTML = s.desc;
|
||||
}
|
||||
|
||||
// 风格切换
|
||||
document.querySelectorAll('.avatar-card').forEach(card => {
|
||||
card.addEventListener('click', () => {
|
||||
document.querySelectorAll('.avatar-card').forEach(c => c.classList.remove('recommend'));
|
||||
card.classList.add('recommend');
|
||||
currentStyle = card.dataset.style;
|
||||
document.querySelectorAll('.state-tab[data-style]').forEach(t => {
|
||||
t.classList.toggle('active', t.dataset.style === currentStyle);
|
||||
});
|
||||
renderAgent();
|
||||
});
|
||||
});
|
||||
|
||||
// 风格 tab
|
||||
document.querySelectorAll('.state-tab[data-style]').forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
currentStyle = tab.dataset.style;
|
||||
document.querySelectorAll('.state-tab[data-style]').forEach(t => t.classList.remove('active'));
|
||||
tab.classList.add('active');
|
||||
document.querySelectorAll('.avatar-card').forEach(c => {
|
||||
c.classList.toggle('recommend', c.dataset.style === currentStyle);
|
||||
});
|
||||
renderAgent();
|
||||
});
|
||||
});
|
||||
|
||||
// 状态切换
|
||||
document.querySelectorAll('.state-tab[data-state]').forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
currentState = tab.dataset.state;
|
||||
document.querySelectorAll('.state-tab[data-state]').forEach(t => t.classList.remove('active'));
|
||||
tab.classList.add('active');
|
||||
renderState();
|
||||
});
|
||||
});
|
||||
|
||||
renderAgent();
|
||||
renderState();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,862 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>工具栏统一设计 v1.2 - 状态徽标 + 展开面板</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: linear-gradient(135deg, #e0e7ff 0%, #f3e8ff 50%, #fce7f3 100%);
|
||||
color: #1a1a1a;
|
||||
padding: 24px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
min-height: 100vh;
|
||||
}
|
||||
h1 { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin-bottom: 8px; color: #1a1a1a; }
|
||||
h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 32px 0 12px; color: #1a1a1a; }
|
||||
h3 { font-size: 14px; font-weight: 600; margin: 12px 0 8px; color: #333; }
|
||||
.meta { color: #6b7280; font-size: 12.5px; margin-bottom: 20px; }
|
||||
|
||||
/* === ChatPanel 整体 === */
|
||||
.chatpanel-mock {
|
||||
width: 100%;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.9);
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 8px 32px rgba(99, 102, 241, 0.1);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.chatpanel-mock-header {
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid rgba(99, 102, 241, 0.1);
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
font-size: 13px;
|
||||
color: #6b7280;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.chatpanel-mock-header .dot { width: 8px; height: 8px; border-radius: 50%; background: #10b981; }
|
||||
|
||||
/* === 消息流区域 === */
|
||||
.chatpanel-mock-messages {
|
||||
min-height: 200px;
|
||||
padding: 20px 16px;
|
||||
background: linear-gradient(180deg, #fafbfc 0%, #f5f7fa 100%);
|
||||
}
|
||||
.mock-msg {
|
||||
max-width: 70%;
|
||||
padding: 8px 12px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.mock-msg.user {
|
||||
margin-left: auto;
|
||||
background: linear-gradient(135deg, #6366f1, #8b5cf6);
|
||||
color: #fff;
|
||||
}
|
||||
.mock-msg.ai {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
color: #1a1a1a;
|
||||
border: 1px solid rgba(99, 102, 241, 0.1);
|
||||
}
|
||||
.mock-msg .meta { font-size: 10.5px; opacity: 0.7; margin-bottom: 2px; color: #6b7280; }
|
||||
.mock-msg.user .meta { color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
/* === InputBar(消息发送框) === */
|
||||
.inputbar-mock {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
border-top: 1px solid rgba(99, 102, 241, 0.15);
|
||||
padding: 12px 16px 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* === 4 按钮工具栏(InputBar 内上方居中) === */
|
||||
.glass-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
padding: 8px 16px;
|
||||
margin: 0 auto 12px;
|
||||
width: fit-content;
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
backdrop-filter: blur(28px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(28px) saturate(180%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.7);
|
||||
border-radius: 20px;
|
||||
box-shadow:
|
||||
0 1px 0 rgba(255, 255, 255, 0.9) inset,
|
||||
0 -1px 0 rgba(99, 102, 241, 0.08) inset,
|
||||
0 2px 4px rgba(99, 102, 241, 0.05),
|
||||
0 8px 16px rgba(99, 102, 241, 0.08),
|
||||
0 24px 48px rgba(99, 102, 241, 0.05);
|
||||
position: relative;
|
||||
}
|
||||
.glass-toolbar::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0.1) 40%, transparent 60%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.glass-toolbar::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 20px;
|
||||
background: radial-gradient(circle at 20% 20%, rgba(99, 102, 241, 0.15) 0%, transparent 50%),
|
||||
radial-gradient(circle at 80% 80%, rgba(236, 72, 153, 0.12) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* === 4 按钮(40px 圆形玻璃) === */
|
||||
.glass-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.6);
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
box-shadow:
|
||||
0 1px 0 rgba(255, 255, 255, 0.9) inset,
|
||||
0 -1px 0 rgba(0, 0, 0, 0.04) inset,
|
||||
0 1px 2px rgba(0, 0, 0, 0.04),
|
||||
0 2px 4px rgba(0, 0, 0, 0.04);
|
||||
overflow: visible;
|
||||
}
|
||||
.glass-btn:hover {
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
transform: translateY(-1px) scale(1.06);
|
||||
box-shadow:
|
||||
0 1px 0 rgba(255, 255, 255, 1) inset,
|
||||
0 -1px 0 rgba(0, 0, 0, 0.04) inset,
|
||||
0 2px 4px rgba(0, 0, 0, 0.06),
|
||||
0 8px 16px rgba(99, 102, 241, 0.15);
|
||||
}
|
||||
.glass-btn:active { transform: translateY(0) scale(0.95); }
|
||||
.glass-btn svg { width: 22px; height: 22px; display: block; }
|
||||
|
||||
/* === 表情激活(黄橙渐变) === */
|
||||
.glass-btn.is-active-emoji {
|
||||
background: linear-gradient(135deg, rgba(251, 191, 36, 0.9) 0%, rgba(245, 158, 11, 0.9) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
.glass-btn.is-active-emoji::before {
|
||||
content: ""; position: absolute; inset: 1px; border-radius: 50%;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.35) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
}
|
||||
/* === 文件激活(蓝紫渐变) === */
|
||||
.glass-btn.is-active-file {
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.9) 0%, rgba(37, 99, 235, 0.9) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
.glass-btn.is-active-file::before {
|
||||
content: ""; position: absolute; inset: 1px; border-radius: 50%;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.35) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* === 语音:颜色+形态双变 === */
|
||||
.glass-btn.is-voice-recording {
|
||||
background: linear-gradient(135deg, rgba(239, 68, 68, 0.95) 0%, rgba(220, 38, 38, 0.95) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
animation: recordingPulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
@keyframes recordingPulse {
|
||||
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0), 0 1px 0 rgba(255, 255, 255, 0.9) inset; }
|
||||
50% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0.15), 0 1px 0 rgba(255, 255, 255, 0.9) inset; }
|
||||
}
|
||||
.glass-btn.is-voice-recognized {
|
||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.95) 0%, rgba(5, 150, 105, 0.95) 100%);
|
||||
border-color: rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
/* === 坐席按钮(图片头像 44px + 状态徽标) === */
|
||||
.agent-btn {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid transparent;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
background: linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%) padding-box;
|
||||
}
|
||||
.agent-btn::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -2px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%);
|
||||
z-index: -1;
|
||||
}
|
||||
.agent-btn img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
object-position: center 15%;
|
||||
display: block;
|
||||
}
|
||||
.agent-btn:hover { transform: translateY(-1px) scale(1.05); }
|
||||
|
||||
/* === 状态徽标(头像右下角小圆点) === */
|
||||
.agent-badge {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid white;
|
||||
z-index: 3;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
||||
}
|
||||
.agent-badge.is-online { background: #10b981; } /* 绿 = 在线 */
|
||||
.agent-badge.is-urgent { background: #ef4444; } /* 红 = 紧急 */
|
||||
.agent-badge.is-waiting { background: #f59e0b; } /* 橙 = 等待 */
|
||||
.agent-badge.is-offline { background: #9ca3af; } /* 灰 = 离线 */
|
||||
.agent-badge.is-end { background: #3b82f6; } /* 蓝 = 结束/重连 */
|
||||
|
||||
/* 紧急状态 - 徽标呼吸 */
|
||||
.agent-btn.is-urgent .agent-badge { animation: badgePulse 1.5s ease-in-out infinite; }
|
||||
@keyframes badgePulse {
|
||||
0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.6), 0 1px 2px rgba(0,0,0,0.2); }
|
||||
50% { box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.3), 0 1px 2px rgba(0,0,0,0.2); }
|
||||
}
|
||||
|
||||
/* === InputBar 输入框 === */
|
||||
.inputbar-mock-field {
|
||||
width: 100%;
|
||||
min-height: 60px;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border: 1px solid rgba(99, 102, 241, 0.12);
|
||||
border-radius: 12px;
|
||||
padding: 10px 14px;
|
||||
font-size: 13px;
|
||||
color: #9ca3af;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* === 演示容器 === */
|
||||
.demo-block {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.7);
|
||||
border-radius: 18px;
|
||||
padding: 24px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9) inset, 0 8px 16px rgba(99, 102, 241, 0.06);
|
||||
}
|
||||
.demo-label { font-size: 11.5px; color: #6b7280; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 14px; font-weight: 500; }
|
||||
|
||||
.state-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid rgba(99, 102, 241, 0.12); }
|
||||
.state-tab {
|
||||
padding: 6px 12px;
|
||||
border: 1px solid rgba(99, 102, 241, 0.2);
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 12.5px;
|
||||
color: #4b5563;
|
||||
transition: all 0.15s;
|
||||
font-family: inherit;
|
||||
}
|
||||
.state-tab:hover { background: rgba(255, 255, 255, 0.8); }
|
||||
.state-tab.active { background: linear-gradient(135deg, #6366f1, #8b5cf6); color: #fff; border-color: transparent; }
|
||||
|
||||
.state-desc { color: #4b5563; font-size: 12.5px; line-height: 1.7; background: rgba(255, 255, 255, 0.5); padding: 12px 14px; border-radius: 10px; border-left: 2px solid #6366f1; margin-top: 12px; backdrop-filter: blur(10px); }
|
||||
.state-desc strong { color: #1a1a1a; }
|
||||
|
||||
.note { background: rgba(254, 243, 199, 0.6); border-left: 3px solid #d97706; padding: 12px 16px; border-radius: 4px; font-size: 12.5px; color: #78350f; margin: 16px 0; backdrop-filter: blur(10px); }
|
||||
|
||||
/* === 表情面板(从 InputBar 顶部上滑展开) === */
|
||||
.emoji-panel {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
border: 1px solid rgba(99, 102, 241, 0.15);
|
||||
border-radius: 14px;
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 -4px 16px rgba(99, 102, 241, 0.1);
|
||||
animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
@keyframes slideUp {
|
||||
from { opacity: 0; transform: translateY(20px); max-height: 0; }
|
||||
to { opacity: 1; transform: translateY(0); max-height: 400px; }
|
||||
}
|
||||
.emoji-panel-tabs {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-bottom: 10px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid rgba(99, 102, 241, 0.1);
|
||||
}
|
||||
.emoji-panel-tab {
|
||||
padding: 4px 10px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
color: #6b7280;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.emoji-panel-tab.active { background: linear-gradient(135deg, #6366f1, #8b5cf6); color: white; }
|
||||
.emoji-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(8, 1fr);
|
||||
gap: 4px;
|
||||
max-height: 180px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.emoji-cell {
|
||||
aspect-ratio: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
.emoji-cell:hover { background: rgba(99, 102, 241, 0.1); }
|
||||
|
||||
/* === 文件面板 === */
|
||||
.file-panel {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
border: 1px solid rgba(99, 102, 241, 0.15);
|
||||
border-radius: 14px;
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 -4px 16px rgba(99, 102, 241, 0.1);
|
||||
animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
.file-panel-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
.file-panel-item {
|
||||
aspect-ratio: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
background: rgba(99, 102, 241, 0.05);
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
font-size: 11.5px;
|
||||
color: #4b5563;
|
||||
}
|
||||
.file-panel-item:hover { background: rgba(99, 102, 241, 0.12); transform: translateY(-1px); }
|
||||
.file-panel-item .icon { font-size: 26px; }
|
||||
|
||||
/* === InputBar 扩展演示容器 === */
|
||||
.inputbar-stage {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
border: 1px solid rgba(99, 102, 241, 0.15);
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
overflow: hidden;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
/* === 4 状态网格(坐席徽标+语音形态) === */
|
||||
.status-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
.status-card {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border: 1px solid rgba(99, 102, 241, 0.15);
|
||||
border-radius: 12px;
|
||||
padding: 20px 12px;
|
||||
text-align: center;
|
||||
}
|
||||
.status-card .label { font-size: 11px; color: #6b7280; margin-top: 10px; font-weight: 500; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<svg width="0" height="0" style="position: absolute;">
|
||||
<defs>
|
||||
<linearGradient id="g-emoji" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fde68a"/><stop offset="60%" stop-color="#fbbf24"/><stop offset="100%" stop-color="#d97706"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="g-emoji-blush" cx="50%" cy="50%" r="50%">
|
||||
<stop offset="0%" stop-color="rgba(244, 63, 94, 0.4)"/>
|
||||
<stop offset="100%" stop-color="rgba(244, 63, 94, 0)"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="g-highlight" x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
<stop offset="0%" stop-color="white" stop-opacity="0.7"/>
|
||||
<stop offset="100%" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-doc-body" x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
<stop offset="0%" stop-color="#ffffff"/><stop offset="100%" stop-color="#dbeafe"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-doc-fold" x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
<stop offset="0%" stop-color="#c7d2fe"/><stop offset="100%" stop-color="#6366f1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-doc-text" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#6366f1"/><stop offset="100%" stop-color="#a855f7"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-mic-body" x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
<stop offset="0%" stop-color="#c4b5fd"/><stop offset="50%" stop-color="#8b5cf6"/><stop offset="100%" stop-color="#6d28d9"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-mic-shine" x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
<stop offset="0%" stop-color="white" stop-opacity="0.65"/><stop offset="100%" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<h1>工具栏统一设计 v1.2 — 状态徽标 + 颜色&形态双变 + 展开面板</h1>
|
||||
<p class="meta">v1.1 基础 + 3 项关键决策 · 坐席徽标(头像右下角) · 语音形态双变 · 表情/文件面板从 InputBar 顶部上滑展开 · 2026-08-04</p>
|
||||
|
||||
<div class="note">
|
||||
📌 <strong>v1.2 三大升级</strong>(基于你的 3 项决策):<br>
|
||||
• 🎭 <strong>坐席状态:只用头像+徽标</strong>(绿/红/橙/灰/蓝 5 色徽标,圆角头像不变色)<br>
|
||||
• 🎙️ <strong>语音状态:颜色+形态双变</strong>(话筒→红色脉动声波→绿色对勾)<br>
|
||||
• 📤 <strong>展开面板:从 InputBar 顶部上滑</strong>(表情网格 / 文件选择面板)
|
||||
</div>
|
||||
|
||||
<h2>🎨 ChatPanel 完整布局(工具栏在 InputBar 内)</h2>
|
||||
<div class="chatpanel-mock">
|
||||
<div class="chatpanel-mock-header">
|
||||
<span class="dot"></span>
|
||||
<span>IT 智能服务台 · 在线 · 客服小王</span>
|
||||
</div>
|
||||
<div class="chatpanel-mock-messages">
|
||||
<div class="mock-msg user">
|
||||
<div class="meta">我 10:23</div>
|
||||
你好,我电脑经常蓝屏
|
||||
</div>
|
||||
<div class="mock-msg ai">
|
||||
<div class="meta">AI 10:23</div>
|
||||
您好!电脑蓝屏可能由驱动/内存/温度等问题引起。建议先尝试安全模式启动...
|
||||
</div>
|
||||
<div class="mock-msg user">
|
||||
<div class="meta">我 10:25</div>
|
||||
还有其他办法吗?紧急,需要尽快恢复
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- InputBar(消息发送框) -->
|
||||
<div class="inputbar-mock">
|
||||
<!-- 4 按钮工具栏(InputBar 内上方居中) -->
|
||||
<div class="glass-toolbar" id="toolbar-stage">
|
||||
<!-- 1. 表情 -->
|
||||
<button class="glass-btn" title="表情">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="12" cy="12" r="9" fill="url(#g-emoji)"/>
|
||||
<ellipse cx="12" cy="6" rx="6" ry="2.5" fill="url(#g-highlight)"/>
|
||||
<ellipse cx="6.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
|
||||
<ellipse cx="17.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
|
||||
<ellipse cx="8.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<ellipse cx="15.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<circle cx="8.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<circle cx="15.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<path d="M8 15 Q12 18 16 15" fill="none" stroke="#1e1b4b" stroke-width="1.6" stroke-linecap="round"/>
|
||||
<path d="M8 15 Q12 17 16 15" fill="rgba(244, 63, 94, 0.2)"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- 2. 文件 -->
|
||||
<button class="glass-btn" title="文件">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="url(#g-doc-body)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
|
||||
<path d="M14 2 L14 8 L20 8" fill="url(#g-doc-fold)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
|
||||
<ellipse cx="10" cy="4" rx="5" ry="0.8" fill="url(#g-highlight)"/>
|
||||
<rect x="7" y="11.5" width="10" height="0.8" rx="0.4" fill="url(#g-doc-text)"/>
|
||||
<rect x="7" y="14" width="8" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.7"/>
|
||||
<rect x="7" y="16.5" width="6" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.5"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- 3. 语音 -->
|
||||
<button class="glass-btn" title="语音输入">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<rect x="8" y="2" width="8" height="13" rx="4" fill="url(#g-mic-body)"/>
|
||||
<rect x="9" y="3" width="2" height="11" rx="1" fill="url(#g-mic-shine)"/>
|
||||
<line x1="10.5" y1="6" x2="10.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="12" y1="5" x2="12" y2="12" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="13.5" y1="6" x2="13.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="12" y1="18" x2="12" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="8" y1="22" x2="16" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- 4. 坐席(图片头像 + 状态徽标) -->
|
||||
<button class="agent-btn" title="客服在线">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="客服" />
|
||||
<span class="agent-badge is-online"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 输入框 -->
|
||||
<div class="inputbar-mock-field">
|
||||
请输入消息...(输入框在工具栏下方,用户打字区)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>🎙️ 语音按钮 - 颜色+形态双变(3 状态)</h2>
|
||||
<div class="demo-block">
|
||||
<div class="demo-label">点击下方 Tab 切换语音按钮形态</div>
|
||||
<div class="state-tabs" id="voice-tabs">
|
||||
<button class="state-tab active" data-voice="default">① 默认(话筒)</button>
|
||||
<button class="state-tab" data-voice="recording">② 录音中(红色脉动声波)</button>
|
||||
<button class="state-tab" data-voice="recognized">③ 已识别(绿色对勾)</button>
|
||||
</div>
|
||||
<div class="inputbar-stage">
|
||||
<div class="glass-toolbar" id="voice-stage" style="margin: 0 auto;"></div>
|
||||
</div>
|
||||
<div class="state-desc" id="voice-desc"></div>
|
||||
</div>
|
||||
|
||||
<h2>🎭 坐席按钮 - 头像 + 状态徽标(5 色)</h2>
|
||||
<div class="demo-block">
|
||||
<div class="demo-label">徽标颜色映射坐席状态,头像本体不变色</div>
|
||||
<div class="status-grid">
|
||||
<div class="status-card">
|
||||
<div class="glass-toolbar" style="margin: 0 auto; padding: 16px 24px;">
|
||||
<button class="agent-btn" style="cursor: default;">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="客服" />
|
||||
<span class="agent-badge is-online"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="label">在线 🟢</div>
|
||||
</div>
|
||||
<div class="status-card">
|
||||
<div class="glass-toolbar" style="margin: 0 auto; padding: 16px 24px;">
|
||||
<button class="agent-btn is-urgent" style="cursor: default;">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="客服" />
|
||||
<span class="agent-badge is-urgent"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="label">紧急 🔴 (徽标呼吸)</div>
|
||||
</div>
|
||||
<div class="status-card">
|
||||
<div class="glass-toolbar" style="margin: 0 auto; padding: 16px 24px;">
|
||||
<button class="agent-btn" style="cursor: default;">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="客服" />
|
||||
<span class="agent-badge is-waiting"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="label">等待 🟠</div>
|
||||
</div>
|
||||
<div class="status-card">
|
||||
<div class="glass-toolbar" style="margin: 0 auto; padding: 16px 24px;">
|
||||
<button class="agent-btn" style="cursor: default;">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="客服" />
|
||||
<span class="agent-badge is-end"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="label">结束/重连 🔵</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="status-grid" style="grid-template-columns: 1fr; margin-top: 16px;">
|
||||
<div class="status-card" style="padding: 16px 12px;">
|
||||
<div class="glass-toolbar" style="margin: 0 auto; padding: 12px 16px;">
|
||||
<button class="agent-btn" style="cursor: default; opacity: 0.4; filter: grayscale(0.7);">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="客服" />
|
||||
<span class="agent-badge is-offline"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="label">离线 ⚫ (灰度+灰色徽标)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>📤 表情面板 - 从 InputBar 顶部上滑展开</h2>
|
||||
<div class="demo-block">
|
||||
<div class="demo-label">点击表情按钮 → 表情网格从工具栏下方(InputBar 内)向上滑出</div>
|
||||
<div class="inputbar-stage" style="padding: 0;">
|
||||
<div class="inputbar-mock" style="border-radius: 12px;">
|
||||
<!-- 表情面板 -->
|
||||
<div class="emoji-panel">
|
||||
<div class="emoji-panel-tabs">
|
||||
<span class="emoji-panel-tab active">😀 表情</span>
|
||||
<span class="emoji-panel-tab">🐶 动物</span>
|
||||
<span class="emoji-panel-tab">🍔 食物</span>
|
||||
<span class="emoji-panel-tab">⚽ 活动</span>
|
||||
<span class="emoji-panel-tab">🚗 旅行</span>
|
||||
<span class="emoji-panel-tab">💡 物品</span>
|
||||
<span class="emoji-panel-tab">❤️ 符号</span>
|
||||
</div>
|
||||
<div class="emoji-grid">
|
||||
<div class="emoji-cell">😀</div><div class="emoji-cell">😃</div><div class="emoji-cell">😄</div><div class="emoji-cell">😁</div>
|
||||
<div class="emoji-cell">😆</div><div class="emoji-cell">😅</div><div class="emoji-cell">🤣</div><div class="emoji-cell">😂</div>
|
||||
<div class="emoji-cell">🙂</div><div class="emoji-cell">🙃</div><div class="emoji-cell">😉</div><div class="emoji-cell">😊</div>
|
||||
<div class="emoji-cell">😇</div><div class="emoji-cell">🥰</div><div class="emoji-cell">😍</div><div class="emoji-cell">🤩</div>
|
||||
<div class="emoji-cell">😘</div><div class="emoji-cell">😗</div><div class="emoji-cell">☺️</div><div class="emoji-cell">😚</div>
|
||||
<div class="emoji-cell">😙</div><div class="emoji-cell">🥲</div><div class="emoji-cell">😋</div><div class="emoji-cell">😛</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 4 按钮工具栏 -->
|
||||
<div class="glass-toolbar" style="margin-bottom: 8px;">
|
||||
<button class="glass-btn is-active-emoji" title="表情">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="12" cy="12" r="9" fill="url(#g-emoji)"/>
|
||||
<ellipse cx="12" cy="6" rx="6" ry="2.5" fill="url(#g-highlight)"/>
|
||||
<ellipse cx="6.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
|
||||
<ellipse cx="17.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
|
||||
<ellipse cx="8.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<ellipse cx="15.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<circle cx="8.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<circle cx="15.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<path d="M8 15 Q12 18 16 15" fill="none" stroke="#1e1b4b" stroke-width="1.6" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="glass-btn" title="文件">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="url(#g-doc-body)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
|
||||
<path d="M14 2 L14 8 L20 8" fill="url(#g-doc-fold)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
|
||||
<ellipse cx="10" cy="4" rx="5" ry="0.8" fill="url(#g-highlight)"/>
|
||||
<rect x="7" y="11.5" width="10" height="0.8" rx="0.4" fill="url(#g-doc-text)"/>
|
||||
<rect x="7" y="14" width="8" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.7"/>
|
||||
<rect x="7" y="16.5" width="6" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.5"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="glass-btn" title="语音输入">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<rect x="8" y="2" width="8" height="13" rx="4" fill="url(#g-mic-body)"/>
|
||||
<rect x="9" y="3" width="2" height="11" rx="1" fill="url(#g-mic-shine)"/>
|
||||
<line x1="10.5" y1="6" x2="10.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="12" y1="5" x2="12" y2="12" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="13.5" y1="6" x2="13.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="12" y1="18" x2="12" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="8" y1="22" x2="16" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="agent-btn" title="客服在线">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="客服" />
|
||||
<span class="agent-badge is-online"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="inputbar-mock-field" style="min-height: 40px; padding: 6px 12px; font-size: 12px;">输入框</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>📁 文件面板 - 从 InputBar 顶部上滑展开</h2>
|
||||
<div class="demo-block">
|
||||
<div class="demo-label">点击文件按钮 → 文件选择面板从工具栏下方(InputBar 内)向上滑出</div>
|
||||
<div class="inputbar-stage" style="padding: 0;">
|
||||
<div class="inputbar-mock" style="border-radius: 12px;">
|
||||
<!-- 文件面板 -->
|
||||
<div class="file-panel">
|
||||
<div class="file-panel-grid">
|
||||
<div class="file-panel-item"><div class="icon">🖼️</div>图片</div>
|
||||
<div class="file-panel-item"><div class="icon">📄</div>文档</div>
|
||||
<div class="file-panel-item"><div class="icon">🎬</div>视频</div>
|
||||
<div class="file-panel-item"><div class="icon">🎵</div>音频</div>
|
||||
<div class="file-panel-item"><div class="icon">📷</div>拍照</div>
|
||||
<div class="file-panel-item"><div class="icon">📁</div>文件夹</div>
|
||||
<div class="file-panel-item"><div class="icon">📎</div>其他</div>
|
||||
<div class="file-panel-item"><div class="icon">📊</div>表格</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 4 按钮工具栏 -->
|
||||
<div class="glass-toolbar" style="margin-bottom: 8px;">
|
||||
<button class="glass-btn" title="表情">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="12" cy="12" r="9" fill="url(#g-emoji)"/>
|
||||
<ellipse cx="12" cy="6" rx="6" ry="2.5" fill="url(#g-highlight)"/>
|
||||
<ellipse cx="8.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<ellipse cx="15.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<circle cx="8.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<circle cx="15.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<path d="M8 15 Q12 18 16 15" fill="none" stroke="#1e1b4b" stroke-width="1.6" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="glass-btn is-active-file" title="文件">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="url(#g-doc-body)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
|
||||
<path d="M14 2 L14 8 L20 8" fill="url(#g-doc-fold)" stroke="#818cf8" stroke-width="0.8" stroke-linejoin="round"/>
|
||||
<ellipse cx="10" cy="4" rx="5" ry="0.8" fill="url(#g-highlight)"/>
|
||||
<rect x="7" y="11.5" width="10" height="0.8" rx="0.4" fill="url(#g-doc-text)"/>
|
||||
<rect x="7" y="14" width="8" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.7"/>
|
||||
<rect x="7" y="16.5" width="6" height="0.8" rx="0.4" fill="url(#g-doc-text)" opacity="0.5"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="glass-btn" title="语音输入">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<rect x="8" y="2" width="8" height="13" rx="4" fill="url(#g-mic-body)"/>
|
||||
<rect x="9" y="3" width="2" height="11" rx="1" fill="url(#g-mic-shine)"/>
|
||||
<line x1="10.5" y1="6" x2="10.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="12" y1="5" x2="12" y2="12" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="13.5" y1="6" x2="13.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="12" y1="18" x2="12" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="8" y1="22" x2="16" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="agent-btn" title="客服在线">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="客服" />
|
||||
<span class="agent-badge is-online"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="inputbar-mock-field" style="min-height: 40px; padding: 6px 12px; font-size: 12px;">输入框</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>📊 v1.1 vs v1.2 关键差异</h2>
|
||||
<table style="width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12.5px;">
|
||||
<thead>
|
||||
<tr style="background: rgba(255, 255, 255, 0.6);">
|
||||
<th style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px; text-align: left;">维度</th>
|
||||
<th style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px; text-align: left;">v1.1</th>
|
||||
<th style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px; text-align: left;"><strong>v1.2</strong></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;">坐席状态</td>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;">按钮边框变色(紫粉/红/橙/绿/蓝)</td>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;"><strong>头像右下角徽标(5 色)</strong> 简洁不喧宾夺主</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;">语音形态</td>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;">只换颜色(灰/紫/红)</td>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;"><strong>颜色+形态双变</strong>(话筒→红色脉动声波→绿色对勾)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;">展开面板</td>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;">未实现(占位)</td>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;"><strong>表情网格 / 文件选择器</strong>,从 InputBar 顶部上滑(slideUp 0.3s)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;">离线坐席</td>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;">灰色边框</td>
|
||||
<td style="border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px;"><strong>整体灰度 + 灰色徽标</strong>(完全弱化)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p style="margin-top: 32px; padding-top: 16px; border-top: 1px solid rgba(99, 102, 241, 0.15); color: #6b7280; font-size: 11.5px;">
|
||||
v1.2 状态徽标 + 颜色&形态双变 + 展开面板 · 2026-08-04 · Duckula 主理人 · 等待用户最终拍板进入开发
|
||||
</p>
|
||||
|
||||
<script>
|
||||
// === 语音状态切换 ===
|
||||
const voiceMap = {
|
||||
'default': {
|
||||
cls: '',
|
||||
svg: `<svg viewBox="0 0 24 24" fill="none">
|
||||
<rect x="8" y="2" width="8" height="13" rx="4" fill="url(#g-mic-body)"/>
|
||||
<rect x="9" y="3" width="2" height="11" rx="1" fill="url(#g-mic-shine)"/>
|
||||
<line x1="10.5" y1="6" x2="10.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="12" y1="5" x2="12" y2="12" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<line x1="13.5" y1="6" x2="13.5" y2="11" stroke="white" stroke-width="0.3" opacity="0.4"/>
|
||||
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="12" y1="18" x2="12" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="8" y1="22" x2="16" y2="22" stroke="url(#g-mic-body)" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>`,
|
||||
desc: '<strong>① 默认状态</strong>:话筒图标 + 紫粉渐变。等待用户长按或点击开始录音'
|
||||
},
|
||||
'recording': {
|
||||
cls: 'is-voice-recording',
|
||||
svg: `<svg viewBox="0 0 24 24" fill="none">
|
||||
<rect x="8" y="2" width="8" height="13" rx="4" fill="white"/>
|
||||
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="12" y1="18" x2="12" y2="22" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="8" y1="22" x2="16" y2="22" stroke="white" stroke-width="2" stroke-linecap="round"/>
|
||||
<circle cx="5" cy="12" r="1.5" fill="white" opacity="0.8">
|
||||
<animate attributeName="r" values="1.5;2.5;1.5" dur="1s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
<circle cx="19" cy="12" r="1.5" fill="white" opacity="0.8">
|
||||
<animate attributeName="r" values="1.5;2.5;1.5" dur="1s" repeatCount="indefinite"/>
|
||||
</circle>
|
||||
</svg>`,
|
||||
desc: '<strong>② 录音中</strong>:白色话筒 + 红色背景 + 1.5s 呼吸光环。两侧脉动声波提示正在收音,点击停止'
|
||||
},
|
||||
'recognized': {
|
||||
cls: 'is-voice-recognized',
|
||||
svg: `<svg viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="12" cy="12" r="9" fill="none" stroke="white" stroke-width="2"/>
|
||||
<path d="M7 12 L11 16 L17 9" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>`,
|
||||
desc: '<strong>③ 已识别</strong>:绿色背景 + 白色对勾。语音识别成功,文本已填入输入框,可继续编辑发送'
|
||||
}
|
||||
};
|
||||
|
||||
const voiceTabs = document.querySelectorAll('#voice-tabs .state-tab');
|
||||
const voiceStage = document.getElementById('voice-stage');
|
||||
const voiceDesc = document.getElementById('voice-desc');
|
||||
|
||||
function renderVoice(state) {
|
||||
const s = voiceMap[state];
|
||||
voiceStage.innerHTML = `
|
||||
<button class="glass-btn ${s.cls}" title="语音">${s.svg}</button>
|
||||
<button class="glass-btn" title="表情" style="opacity: 0.5;">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="12" cy="12" r="9" fill="url(#g-emoji)"/>
|
||||
<ellipse cx="8.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<ellipse cx="15.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<path d="M8 15 Q12 18 16 15" fill="none" stroke="#1e1b4b" stroke-width="1.6" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="glass-btn" title="文件" style="opacity: 0.5;">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="url(#g-doc-body)" stroke="#818cf8" stroke-width="0.8"/>
|
||||
<path d="M14 2 L14 8 L20 8" fill="url(#g-doc-fold)" stroke="#818cf8" stroke-width="0.8"/>
|
||||
<rect x="7" y="11.5" width="10" height="0.8" rx="0.4" fill="url(#g-doc-text)"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="agent-btn" title="客服">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="客服"/>
|
||||
<span class="agent-badge is-online"></span>
|
||||
</button>
|
||||
`;
|
||||
voiceDesc.innerHTML = s.desc;
|
||||
}
|
||||
|
||||
voiceTabs.forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
voiceTabs.forEach(t => t.classList.remove('active'));
|
||||
tab.classList.add('active');
|
||||
renderVoice(tab.dataset.voice);
|
||||
});
|
||||
});
|
||||
|
||||
renderVoice('default');
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,420 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>工具栏统一设计 v1.8 - 融合会话窗口 · 圆润顶端</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body {
|
||||
font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: linear-gradient(135deg, #e0e7ff 0%, #f3e8ff 50%, #fce7f3 100%);
|
||||
color: #1a1a1a;
|
||||
padding: 24px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
min-height: 100vh;
|
||||
}
|
||||
h1 { font-size: 22px; font-weight: 600; letter-spacing: -0.02em; margin-bottom: 8px; color: #1a1a1a; }
|
||||
h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 32px 0 12px; color: #1a1a1a; }
|
||||
.meta { color: #6b7280; font-size: 12.5px; margin-bottom: 20px; }
|
||||
|
||||
/* === ChatPanel 整体(员工端会话窗口容器) === */
|
||||
.chatpanel-mock {
|
||||
width: 100%;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.9);
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 8px 32px rgba(99, 102, 241, 0.1);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.chatpanel-mock-header {
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid rgba(99, 102, 241, 0.1);
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
font-size: 13px;
|
||||
color: #374151;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.chatpanel-mock-header .dot { width: 8px; height: 8px; border-radius: 50%; background: #10b981; }
|
||||
.chatpanel-mock-header .title { font-weight: 600; }
|
||||
.chatpanel-mock-header .sub { color: #9ca3af; font-size: 11.5px; }
|
||||
|
||||
/* === 消息流区域(会话窗口) === */
|
||||
.chatpanel-mock-messages {
|
||||
min-height: 260px;
|
||||
padding: 20px 16px;
|
||||
background: linear-gradient(180deg, #fafbfc 0%, #f5f7fa 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.mock-msg {
|
||||
max-width: 74%;
|
||||
padding: 9px 13px;
|
||||
border-radius: 14px;
|
||||
font-size: 13px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.mock-msg .who { font-size: 10.5px; opacity: 0.65; margin-bottom: 3px; }
|
||||
.mock-msg.user {
|
||||
align-self: flex-end;
|
||||
background: linear-gradient(135deg, #6366f1, #8b5cf6);
|
||||
color: #fff;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
.mock-msg.ai {
|
||||
align-self: flex-start;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
color: #1a1a1a;
|
||||
border: 1px solid rgba(99, 102, 241, 0.12);
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.mock-msg.ai .quick {
|
||||
margin-top: 8px; display: flex; gap: 6px; flex-wrap: wrap;
|
||||
}
|
||||
.mock-msg.ai .quick span {
|
||||
font-size: 11.5px; padding: 4px 10px; border-radius: 12px;
|
||||
background: rgba(99, 102, 241, 0.08); color: #4f46e5; border: 1px solid rgba(99, 102, 241, 0.15);
|
||||
}
|
||||
|
||||
/* === gem 工具栏 band(位于会话窗口与消息窗口之间) === */
|
||||
.gem-band {
|
||||
background: rgba(255, 255, 255, 0.35);
|
||||
border-top: 1px solid rgba(99, 102, 241, 0.1);
|
||||
border-bottom: 1px solid rgba(99, 102, 241, 0.1);
|
||||
padding: 6px 0 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.gem-toolbar {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 16px;
|
||||
width: fit-content;
|
||||
height: 84px;
|
||||
}
|
||||
.gem-toolbar-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
overflow: visible;
|
||||
}
|
||||
.gem-row { position: relative; z-index: 2; display: flex; align-items: center; justify-content: center; gap: 12px; }
|
||||
.gem-toolbar .agent-btn.gem {
|
||||
width: 60px; height: 60px; margin: 0 6px; z-index: 3; box-shadow: none;
|
||||
}
|
||||
.gem-toolbar .glass-btn { z-index: 2; }
|
||||
|
||||
/* === InputBar(消息窗口) === */
|
||||
.inputbar-mock {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
border-top: 1px solid rgba(99, 102, 241, 0.15);
|
||||
padding: 12px 16px 16px;
|
||||
position: relative;
|
||||
}
|
||||
.inputbar-mock-field {
|
||||
width: 100%;
|
||||
min-height: 56px;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
border: 1px solid rgba(99, 102, 241, 0.12);
|
||||
border-radius: 12px;
|
||||
padding: 10px 14px;
|
||||
font-size: 13px;
|
||||
color: #9ca3af;
|
||||
line-height: 1.6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.inputbar-mock-field .send {
|
||||
margin-left: 12px;
|
||||
padding: 7px 18px;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(135deg, #6366f1, #8b5cf6);
|
||||
color: #fff; font-size: 13px; font-weight: 600;
|
||||
box-shadow: 0 2px 6px rgba(99,102,241,0.25);
|
||||
}
|
||||
|
||||
/* === 通用按钮样式(玻璃圆形 + 坐席头像) === */
|
||||
.glass-btn {
|
||||
width: 40px; height: 40px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.6);
|
||||
background: rgba(255, 255, 255, 0.55);
|
||||
backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
position: relative; z-index: 2;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 2px 4px rgba(0,0,0,0.04);
|
||||
}
|
||||
.glass-btn:hover { background: rgba(255,255,255,0.75); transform: translateY(-1px) scale(1.06); }
|
||||
.glass-btn:active { transform: translateY(0) scale(0.95); }
|
||||
.glass-btn svg { width: 22px; height: 22px; display: block; }
|
||||
.agent-btn {
|
||||
border-radius: 50%;
|
||||
border: 2px solid transparent;
|
||||
cursor: pointer;
|
||||
position: relative; z-index: 2;
|
||||
padding: 0;
|
||||
background: linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%) padding-box;
|
||||
}
|
||||
.agent-btn::before {
|
||||
content: ""; position: absolute; inset: -2px; border-radius: 50%;
|
||||
background: linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%); z-index: -1;
|
||||
}
|
||||
.agent-btn img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; object-position: center 15%; display: block; }
|
||||
.agent-badge { position: absolute; bottom: 0; right: 0; width: 12px; height: 12px; border-radius: 50%; border: 2px solid white; z-index: 3; box-shadow: 0 1px 2px rgba(0,0,0,0.2); }
|
||||
.agent-badge.is-online { background: #10b981; }
|
||||
|
||||
/* === 演示容器 / 提示块 === */
|
||||
.demo-block {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.7);
|
||||
border-radius: 18px;
|
||||
padding: 24px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 1px 0 rgba(255,255,255,0.9) inset, 0 8px 16px rgba(99,102,241,0.06);
|
||||
}
|
||||
.note { background: rgba(254, 243, 199, 0.6); border-left: 3px solid #d97706; padding: 12px 16px; border-radius: 4px; font-size: 12.5px; color: #78350f; margin: 16px 0; backdrop-filter: blur(10px); }
|
||||
.note-success { background: rgba(209, 250, 229, 0.6); border-left: 3px solid #10b981; padding: 12px 16px; border-radius: 4px; font-size: 12.5px; color: #064e3b; margin: 16px 0; backdrop-filter: blur(10px); }
|
||||
.note-info { background: rgba(219, 234, 254, 0.6); border-left: 3px solid #3b82f6; padding: 12px 16px; border-radius: 4px; font-size: 12.5px; color: #1e3a8a; margin: 16px 0; backdrop-filter: blur(10px); }
|
||||
.arch-compare { display: flex; gap: 24px; flex-wrap: wrap; margin: 12px 0; }
|
||||
.arch-compare figure { text-align: center; font-size: 11.5px; color: #6b7280; }
|
||||
.arch-compare svg { background: rgba(255,255,255,0.5); border: 1px solid rgba(99,102,241,0.12); border-radius: 10px; }
|
||||
table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12.5px; }
|
||||
thead tr { background: rgba(255, 255, 255, 0.6); }
|
||||
th { border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px; text-align: left; font-weight: 600; }
|
||||
td { border: 1px solid rgba(99, 102, 241, 0.15); padding: 8px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<svg width="0" height="0" style="position: absolute;">
|
||||
<defs>
|
||||
<linearGradient id="g-emoji" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#fde68a"/><stop offset="60%" stop-color="#fbbf24"/><stop offset="100%" stop-color="#d97706"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="g-emoji-blush" cx="50%" cy="50%" r="50%">
|
||||
<stop offset="0%" stop-color="rgba(244, 63, 94, 0.4)"/>
|
||||
<stop offset="100%" stop-color="rgba(244, 63, 94, 0)"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="g-highlight" x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
<stop offset="0%" stop-color="white" stop-opacity="0.7"/>
|
||||
<stop offset="100%" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-doc-body" x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
<stop offset="0%" stop-color="#ffffff"/><stop offset="100%" stop-color="#dbeafe"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-doc-fold" x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
<stop offset="0%" stop-color="#c7d2fe"/><stop offset="100%" stop-color="#6366f1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-doc-text" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#6366f1"/><stop offset="100%" stop-color="#a855f7"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-mic-body" x1="50%" y1="0%" x2="50%" y2="100%">
|
||||
<stop offset="0%" stop-color="#c4b5fd"/><stop offset="50%" stop-color="#8b5cf6"/><stop offset="100%" stop-color="#6d28d9"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-group" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#a5b4fc"/><stop offset="100%" stop-color="#c4b5fd"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="g-group-strong" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#6366f1"/><stop offset="50%" stop-color="#a855f7"/><stop offset="100%" stop-color="#ec4899"/>
|
||||
</linearGradient>
|
||||
<!-- 圆角长方形轨道渐变 -->
|
||||
<linearGradient id="g-rail" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#818cf8" stop-opacity="0.5"/>
|
||||
<stop offset="50%" stop-color="#c4b5fd" stop-opacity="0.9"/>
|
||||
<stop offset="100%" stop-color="#818cf8" stop-opacity="0.5"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
<h1>工具栏统一设计 v1.8 — 融合会话窗口 · 圆润顶端</h1>
|
||||
<p class="meta">v1.7 演进:① 顶端拱肩水平缓出 + 顶点大半径圆顶(更圆润);② 将 gem 工具栏作为独立 band 融入员工端「会话消息区 ↔ 消息输入区」之间 · 2026-08-05</p>
|
||||
|
||||
<div class="note-info">
|
||||
📐 <strong>v1.8 两处改动</strong>:<br>
|
||||
① <strong>顶端更圆润</strong>:拱肩由「直线段立刻上抬(控制点 120,14)」改为「先水平缓出、再均匀升起(控制点 128,16)」,消除直线段与拱之间的折角;顶点控制点由 (144,8)/(168,8) 外推至 (138,9)/(174,9),顶点曲率半径更大 → 顶端更圆、更柔<br>
|
||||
② <strong>融入会话窗口</strong>:gem 工具栏作为一条独立 band,置于「会话消息区」与「消息输入区(InputBar)」之间,配真实 IT 工单对话气泡,呈现实际融合效果(不再孤立展示)
|
||||
</div>
|
||||
|
||||
<h2>🎯 v1.8 实战融合效果(员工端会话窗口)</h2>
|
||||
<div class="demo-block">
|
||||
<!-- 完整员工端会话窗口 -->
|
||||
<div class="chatpanel-mock">
|
||||
<!-- 头部 -->
|
||||
<div class="chatpanel-mock-header">
|
||||
<span class="dot"></span>
|
||||
<span class="title">IT 智能服务台</span>
|
||||
<span class="sub">· 在线 · 工单 #SR-20260805-0392</span>
|
||||
</div>
|
||||
|
||||
<!-- 会话窗口:消息流 -->
|
||||
<div class="chatpanel-mock-messages">
|
||||
<div class="mock-msg user">
|
||||
<div class="who">我</div>
|
||||
你好,我的 VPN 连不上,提示 691 错误,影响今天远程办公。
|
||||
</div>
|
||||
<div class="mock-msg ai">
|
||||
<div class="who">智能助手</div>
|
||||
您好,VPN 691 通常是账号密码错误或账号被锁定。已为您查询:账号状态正常、未过期。<br>
|
||||
建议先自助排查:① 确认密码未过期;② 在 portal 重置密码后重试。
|
||||
<div class="quick">
|
||||
<span>重置 VPN 密码</span><span>查看排障指引</span><span>转人工坐席</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mock-msg user">
|
||||
<div class="who">我</div>
|
||||
重置了还是不行,麻烦转人工。
|
||||
</div>
|
||||
<div class="mock-msg ai">
|
||||
<div class="who">智能助手</div>
|
||||
已为您转接人工坐席,请稍候。也可点击下方工具栏「人工坐席」按钮随时发起通话。
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- gem 工具栏 band(位于会话窗口与消息窗口之间) -->
|
||||
<div class="gem-band">
|
||||
<div class="gem-toolbar">
|
||||
<svg class="gem-toolbar-bg" viewBox="0 0 312 84" preserveAspectRatio="xMidYMid meet">
|
||||
<!-- 圆角长方形轨道:两端(两侧图标处)保持直线,仅中央坐席处连续圆顶拱起;顶端圆肩缓出、顶点大半径更圆润 -->
|
||||
<path d="M 18 18
|
||||
L 108 18
|
||||
C 128 16, 138 9, 156 6
|
||||
C 174 9, 184 16, 204 18
|
||||
L 294 18
|
||||
C 302 18, 312 26, 312 34
|
||||
L 312 50
|
||||
C 312 58, 302 66, 294 66
|
||||
L 204 66
|
||||
C 184 68, 174 75, 156 78
|
||||
C 138 75, 128 68, 108 66
|
||||
L 18 66
|
||||
C 0 66, 0 58, 0 50
|
||||
L 0 34
|
||||
C 0 26, 10 18, 18 18 Z"
|
||||
fill="url(#g-rail)" stroke="rgba(255,255,255,0.85)" stroke-width="1.2"/>
|
||||
</svg>
|
||||
<div class="gem-row">
|
||||
<button class="glass-btn" title="表情">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="12" cy="12" r="9" fill="url(#g-emoji)"/>
|
||||
<ellipse cx="12" cy="6" rx="6" ry="2.5" fill="url(#g-highlight)"/>
|
||||
<ellipse cx="6.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
|
||||
<ellipse cx="17.5" cy="14" rx="1.5" ry="1" fill="url(#g-emoji-blush)"/>
|
||||
<ellipse cx="8.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<ellipse cx="15.5" cy="11" rx="1.4" ry="1.6" fill="#1e1b4b"/>
|
||||
<circle cx="8.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<circle cx="15.9" cy="10.4" r="0.5" fill="white"/>
|
||||
<path d="M8 15 Q12 18 16 15" fill="none" stroke="#1e1b4b" stroke-width="1.6" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="glass-btn" title="文件">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="url(#g-doc-body)" stroke="#818cf8" stroke-width="0.8"/>
|
||||
<path d="M14 2 L14 8 L20 8" fill="url(#g-doc-fold)" stroke="#818cf8" stroke-width="0.8"/>
|
||||
<rect x="7" y="11.5" width="10" height="0.8" rx="0.4" fill="url(#g-doc-text)"/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- 人工坐席按钮:增大 50%(60px),居中,不探出,无光晕 -->
|
||||
<button class="agent-btn gem" title="人工坐席">
|
||||
<img src="./agent-avatar-v0.8.jpg" alt="人工坐席"/>
|
||||
<span class="agent-badge is-online"></span>
|
||||
</button>
|
||||
<button class="glass-btn" title="语音输入">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<rect x="8" y="2" width="8" height="13" rx="4" fill="url(#g-mic-body)"/>
|
||||
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="url(#g-mic-body)" stroke-width="2"/>
|
||||
<line x1="12" y1="18" x2="12" y2="22" stroke="url(#g-mic-body)" stroke-width="2"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="glass-btn" title="群聊">
|
||||
<svg viewBox="0 0 24 24" fill="none">
|
||||
<circle cx="8" cy="9" r="2.2" fill="url(#g-group)"/>
|
||||
<path d="M5 16 Q5 13 8 13 Q11 13 11 16 Z" fill="url(#g-group)"/>
|
||||
<circle cx="16" cy="9" r="2.2" fill="url(#g-group)"/>
|
||||
<path d="M13 16 Q13 13 16 13 Q19 13 19 16 Z" fill="url(#g-group)"/>
|
||||
<circle cx="12" cy="10.5" r="2.8" fill="url(#g-group-strong)"/>
|
||||
<path d="M8.5 18.5 Q8.5 14 12 14 Q15.5 14 15.5 18.5 Z" fill="url(#g-group-strong)"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 消息窗口:InputBar -->
|
||||
<div class="inputbar-mock">
|
||||
<div class="inputbar-mock-field">
|
||||
<span>描述您的问题,或点击上方工具栏发起操作…</span>
|
||||
<span class="send">发送</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>🔍 顶端弧度对比(v1.7 → v1.8)</h2>
|
||||
<div class="note">
|
||||
左为 v1.7「渐升圆顶」、右为 v1.8「圆润顶端」:v1.8 的拱肩从直线段水平缓出(不再立刻上抬),顶点控制点外推加宽、曲率半径更大,肉眼可见顶端更圆、与直线段衔接更柔。
|
||||
</div>
|
||||
<div class="arch-compare">
|
||||
<figure>
|
||||
<svg width="312" height="84" viewBox="0 0 312 84">
|
||||
<path d="M 18 18 L 108 18 C 120 14, 144 8, 156 6 C 168 8, 192 14, 204 18 L 294 18 C 302 18, 312 26, 312 34 L 312 50 C 312 58, 302 66, 294 66 L 204 66 C 192 70, 168 76, 156 78 C 144 76, 120 70, 108 66 L 18 66 C 0 66, 0 58, 0 50 L 0 34 C 0 26, 10 18, 18 18 Z"
|
||||
fill="none" stroke="#f59e0b" stroke-width="1.4"/>
|
||||
</svg>
|
||||
<div>v1.7(拱肩直抬 · 顶点较尖)</div>
|
||||
</figure>
|
||||
<figure>
|
||||
<svg width="312" height="84" viewBox="0 0 312 84">
|
||||
<path d="M 18 18 L 108 18 C 128 16, 138 9, 156 6 C 174 9, 184 16, 204 18 L 294 18 C 302 18, 312 26, 312 34 L 312 50 C 312 58, 302 66, 294 66 L 204 66 C 184 68, 174 75, 156 78 C 138 75, 128 68, 108 66 L 18 66 C 0 66, 0 58, 0 50 L 0 34 C 0 26, 10 18, 18 18 Z"
|
||||
fill="none" stroke="#10b981" stroke-width="1.4"/>
|
||||
</svg>
|
||||
<div>v1.8(圆肩缓出 · 顶点更圆)</div>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<h2>📊 v1.7 vs v1.8</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>维度</th><th>v1.7</th><th><strong>v1.8</strong></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>顶端弧度</td><td>渐升圆顶(拱肩直抬,顶点中等半径)</td><td><strong>圆润顶端(拱肩水平缓出,顶点大半径更圆)</strong></td></tr>
|
||||
<tr><td>顶部首控制点</td><td>120,14(立刻上抬)</td><td><strong>128,16(水平缓出)</strong></td></tr>
|
||||
<tr><td>顶点控制点</td><td>144,8 / 168,8</td><td><strong>138,9 / 174,9(外推加宽、更圆)</strong></td></tr>
|
||||
<tr><td>融合场景</td><td>孤立展示工具栏</td><td><strong>嵌入员工端会话窗口(消息区 ↔ 输入区之间)</strong></td></tr>
|
||||
<tr><td>坐席按钮 / 两端直线 / 不探出 / 无光晕</td><td>60px / 保持 / 保持 / 保持</td><td><strong>60px / 保持 / 保持 / 保持(不变)</strong></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>⚠️ 注意事项与待确认点</h2>
|
||||
<ol style="margin-left: 20px; line-height: 1.8; font-size: 13px;">
|
||||
<li><strong>顶端圆润度</strong>:若还嫌顶点偏尖,可继续外推顶点控制点(如 134,10 / 178,10)或略降顶点(y 6→8)让拱更扁更圆;若觉得过圆想更挺,回收即可</li>
|
||||
<li><strong>50% 口径</strong>:坐席按「较 40px 工具图标大 50%」= 60px。若指 v1.6 的 54px 再 +50%(=81px),告知即改</li>
|
||||
<li><strong>融合位置</strong>:当前 gem 工具栏是介于「消息区」与「InputBar」之间的独立 band。若你想让它直接嵌进 InputBar 顶部(如 v1.3 那样),也可调整</li>
|
||||
<li><strong>头像占位图</strong>:<code>./agent-avatar-v0.8.jpg</code> 为占位路径,实际集成时替换</li>
|
||||
</ol>
|
||||
|
||||
<p style="margin-top: 32px; padding-top: 16px; border-top: 1px solid rgba(99, 102, 241, 0.15); color: #6b7280; font-size: 11.5px;">
|
||||
v1.8 融合会话窗口 · 圆润顶端 · 2026-08-05 · Duckula 主理人 · 等待用户拍板进入开发
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user