Files
wecom_it_smart_desk/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-工具栏统一设计v1.9-融合无边框圆润顶端.html
T
Simon facc04aa65 chore: docs 结构整改 + compose 双目录对齐(合并重建提交)
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交
(5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。

一、docs 结构整改(整改 #14)
根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入,
随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录
树并存于 docs/,共 791 文件、双分类体系冲突。

修复动作:
- b2 同名异主题文件改名迁移保全 9 个
- C 类 39 个孤立文件按主题正确归类
- A/B1 类 222 个重复文件删除(新结构已有内容副本)
- 9 个旧独有空目录删除
- 270 处内部引用按 verified 映射改写
- 整改记录 #14 登记于 04-运维文档/部署运维

结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。
残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。

二、compose 双目录对齐(消除踩坑 A)
- docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist
  改为 src/frontend-*/dist(h5 / agent / admin / terminal)
- docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/
- 效果:本地 docker compose up 不再把根目录 stale dist 挂回,
  与线上一致,分叉隐患消除(已 docker compose config 校验通过)

防复发铁律:
- 重构须提交;仓库修复须 git stash -u 或先 commit
- 新结构须 git add 并提交,避免再次 untracked 复活
- H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
2026-08-07 22:31:32 +08:00

461 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>工具栏统一设计 v1.9 - 融合无边框 · 圆润顶端</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: linear-gradient(180deg, rgba(255,255,255,0.95) 0%, rgba(247,248,252,0.95) 100%);
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); /* 仅窗口标题栏分隔,属 chrome 非 zone 分隔 */
background: rgba(255, 255, 255, 0.4);
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: 250px;
padding: 20px 16px;
background: transparent;
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(99, 102, 241, 0.06);
color: #1a1a1a;
border: 1px solid rgba(99, 102, 241, 0.1);
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: transparent;
padding: 8px 0 12px;
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: transparent;
padding: 4px 16px 16px;
position: relative;
}
.inputbar-mock-field {
width: 100%;
min-height: 56px;
background: rgba(255, 255, 255, 0.7);
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;
box-shadow: 0 1px 0 rgba(255,255,255,0.9) inset;
}
.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; }
/* === 专业建议卡片 === */
.advice { background: rgba(255,255,255,0.7); border: 1px solid rgba(99,102,241,0.15); border-radius: 14px; padding: 18px 20px; margin: 16px 0; }
.advice h3 { font-size: 14px; font-weight: 700; color: #4338ca; margin: 14px 0 8px; }
.advice h3:first-child { margin-top: 0; }
.advice p { font-size: 13px; line-height: 1.7; color: #374151; margin-bottom: 8px; }
.advice ul { margin: 6px 0 10px 20px; font-size: 13px; line-height: 1.7; color: #374151; }
.advice li { margin-bottom: 6px; }
.advice .opt { font-weight: 600; }
.advice .rec { color: #047857; font-weight: 600; }
.tag { display: inline-block; font-size: 11px; padding: 2px 8px; border-radius: 8px; background: rgba(99,102,241,0.1); color: #4338ca; margin-left: 6px; }
</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.9 — 融合无边框 · 圆润顶端</h1>
<p class="meta">v1.8 演进:① 坐席顶端圆肩水平缓出 + 顶点大半径(更圆,顶点抬至 y=4 给圆顶 8px 余量);② 隐藏消息区/工具栏/输入区之间全部区隔线,三区融为连续表面 · 2026-08-05</p>
<div class="note-info">
📐 <strong>v1.9 两处改动</strong><br>
<strong>坐席顶端更圆润</strong>:拱肩控制点改为水平缓出(首控制点 y 与直边齐平,切线水平,与直边 C1 连续无折角);顶点控制点外推至 (132,8)/(180,8)、顶点抬至 (156,4),曲率半径更大 → 顶端更圆;坐席按钮上下各留 8px 余量不探出<br>
<strong>三区无边框融合</strong>:删去 gem-band 的上下边框、inputbar 的顶部边框,消息区/工具栏/输入区背景统一为同一连续浅色表面(仅窗口标题栏保留 chrome 分隔)。工具栏(gem 轨道)作为连续表面上唯一浮起的玻璃元素,自然"嵌"在消息区与输入区之间
<br>
<strong>坐席顶端再圆滑(微调)</strong>:穹顶区间由 x 108..204 拓宽至 <strong>x 96..204</strong>(更宽),顶点控制点由 (132,8)/(180,8) 调为 (132,7)/(180,7)、拱肩首控制点 (120,18),使顶点切线更平、曲率半径更大 → 顶端更圆滑、与直线段衔接无折角;坐席上下仍各留 8px 余量不探出
</div>
<h2>🎯 v1.9 实战融合效果(无边框 · 连续表面)</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">
<!-- 圆角长方形轨道:两端(两侧图标处)直线,仅坐席处连续圆顶;穹顶更宽(x 96..204)、顶点切线更平、大半径更圆 -->
<path d="M 18 18
L 96 18
C 120 18, 132 7, 156 4
C 180 7, 192 18, 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 66, 180 77, 156 80
C 132 77, 120 66, 96 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>
<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>
<div class="inputbar-mock">
<div class="inputbar-mock-field">
<span>描述您的问题,或点击上方工具栏发起操作…</span>
<span class="send">发送</span>
</div>
</div>
</div>
</div>
<h2>🔍 顶端弧度对比(v1.8 → v1.9)</h2>
<div class="note">
左 v1.9(穹顶 x 108..204、顶点切线略陡)、右 v1.9 微调(穹顶拓宽至 x 96..204、顶点切线更平、曲率半径更大)。更宽的穹顶 + 更平的顶点,使坐席顶端肉眼更圆滑、与直线段衔接无折角。
</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 124 18, 132 8, 156 4 C 180 8, 188 18, 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 188 66, 180 76, 156 80 C 132 76, 124 66, 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.9(穹顶较窄)</div>
</figure>
<figure>
<svg width="312" height="84" viewBox="0 0 312 84">
<path d="M 18 18 L 96 18 C 120 18, 132 7, 156 4 C 180 7, 192 18, 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 66, 180 77, 156 80 C 132 77, 120 66, 96 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.9 微调(穹顶更宽 · 顶点更平)</div>
</figure>
</div>
<h2>🧭 我的专业建议(Duckula 主理人视角)</h2>
<div class="advice">
<h3>目标复述</h3>
<p>这条工具栏的核心,是让「转人工坐席」成为输入区里最显眼、最可点、又不突兀的主 CTA(召唤按钮)。所有视觉处理都应服务这个目标,而不是反过来让形态喧宾夺主。</p>
<h3>对当前「拱形轨道」方案的评估</h3>
<p><span class="opt">优点</span>:焦点极强、有品牌记忆点,「坐席嵌在工具栏里」的语义很贴切,比普通扁条更有设计感。</p>
<p><span class="opt">风险</span></p>
<ul>
<li><strong>衔接最难做" intentional(看起来是刻意设计)"</strong>:圆形头像 + 拱形轨道的接缝,是整套里对曲率最敏感的地方。曲率差一点,就会从"精致嵌入"变成"渲染 bug / 头像被压扁"。你一路微调"圆润/平滑"恰恰印证了这点。</li>
<li><strong>维护成本高于普通 CSS</strong>:手写 SVG path 在窄屏、不同 DPR、深色模式下都要严格按 viewBox 还原,开发还原时容易走样;而扁条工具栏用 Flex + border-radius 几乎零维护。</li>
<li><strong>响应式更脆</strong>:拱形依赖固定宽度布局,工具按钮增减或文案变化时,path 要重算。</li>
</ul>
<h3>三个可选方向(附优劣)</h3>
<p><span class="opt">A. 扁平胶囊工具栏 <span class="tag">生产稳妥首选</span></span><br>
整条工具栏是一个玻璃胶囊,<strong>不做轨道变形</strong>;坐席按钮靠「更大(60px) + 渐变环 + 轻微投影抬升」形成焦点。<br>
✅ 用户一眼认出是"输入框上方的工具栏",零歧义;响应式最省事;深色模式/窄屏无缝。<br>
⚠️ 视觉个性弱一些,但"清晰 > 炫"的内部工具通常更划算。</p>
<p><span class="opt">B. 当前拱形(v1.9 融合版) <span class="tag">品牌签名</span></span><br>
保留中央隆起,但已做到无边框融合 + 圆润顶端。<br>
✅ 差异化识别度最高,适合产品想有独特视觉语言。<br>
⚠️ 须把曲率锁成设计 token、给出 viewBox 还原规范,开发严格照做;后续增减按钮要重算 path。</p>
<p><span class="opt">C. 悬浮 FAB(浮球)</span><br>
坐席按钮做成半透明浮球,轻轻压在工具栏/输入区交界上。<br>
✅ App 化最强、点击欲最高、天然"破界"焦点。<br>
⚠️ 改动布局最大,与现有 InputBar 结构冲突最多,落地成本最高。</p>
<h3>我的推荐 <span class="rec">(拍板前请先看这段)</span></h3>
<p>如果这是<strong>面向大量员工的生产工具、以"清晰优先"为原则</strong> → 选 <span class="rec">A(扁平胶囊)</span>;拱形(B)只作为视觉点缀,不靠它传达层级。若<strong>产品经理想有独特识别度、且愿承担 SVG 维护成本</strong> → 选 <span class="rec">Bv1.9</span></p>
<p>无论选哪个,以下可访问性底线保持不变:坐席按钮 <strong>60px(≥44px 触控区)</strong>、清晰的 <code>title</code>/<code>aria-label</code>、可见的 <code>focus</code> 态、轨道 SVG 标 <code>aria-hidden</code>(装饰性)。</p>
<p><strong>下一步</strong>:你定方向后,我把已列好的 <code>InputBar.vue</code> 改动清单 + 这份原型一并交付开发,进入实现。</p>
</div>
<h2>📊 版本演进一览</h2>
<table>
<thead>
<tr><th>维度</th><th>v1.8</th><th><strong>v1.9</strong></th></tr>
</thead>
<tbody>
<tr><td>坐席顶端</td><td>顶点 y=6,控制点 138,9/174,9(中等半径)</td><td><strong>顶点 y=4,控制点 132,8/180,8(大半径更圆)</strong></td></tr>
<tr><td>拱肩与直边衔接</td><td>近水平(轻微折角)</td><td><strong>水平切线,C1 连续无折角</strong></td></tr>
<tr><td>坐席按钮余量</td><td>上下各 6px</td><td><strong>上下各 8px(更宽松不探出)</strong></td></tr>
<tr><td>三区区隔线</td><td>gem-band 有上下边框</td><td><strong>全部隐藏,融为连续表面</strong></td></tr>
<tr><td>融合方式</td><td>独立 band(仍有边界感)</td><td><strong>连续浅色表面,轨道为唯一浮起元素</strong></td></tr>
</tbody>
</table>
<h2>⚠️ 待确认点</h2>
<ol style="margin-left: 20px; line-height: 1.8; font-size: 13px;">
<li><strong>方向拍板</strong>A 扁平胶囊 / B 拱形(v1.9) / C 悬浮 FAB,三者选一(见上方专业建议)</li>
<li><strong>坐席 60px 口径</strong>:按「较 40px 工具图标大 50%」= 60px;若指 v1.6 的 54px 再 +50%=81px),告知即改</li>
<li><strong>顶端圆润度</strong>:若 v1.9 仍偏尖,可继续外推顶点控制点(如 128,9/184,9)或降顶点 y 更扁更圆</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.9 融合无边框 · 圆润顶端 · 2026-08-05 · Duckula 主理人 · 等待用户拍板方向进入开发
</p>
</body>
</html>