feat(h5/chat): InputBar v2.0 服务蓝扁平服务舱重铸

按 PRD-REQ-通用-001-前端设计系统 v1.2 将 H5 输入栏主题由企微绿迁至
服务蓝 #1769E0(员工端新角色主题),并把工具栏从「水晶玻璃主导」
改为「扁平蓝色服务舱主导 + 玻璃增强可降级」。

主要改动:
- 色板迁移:文件/语音/群聊图标渐变、轨道渐变、坐席描边、在线徽标
  全部由紫粉/主绿改为服务蓝 #1769E0 + 青蓝 #0E9FBA(AI 能力语义色)
- 工具栏三态实现:
  · 默认 实色 #E7F0FF 浅蓝 + #1769E0 实色描边(稳定对比度、低性能成本)
  · 增强 @supports (backdrop-filter) 内启用蓝色水晶玻璃 blur(20px) saturate(160%)
  · 降级 @supports not (backdrop-filter) 实色回退,布局与对比度不变
- 装饰性外阴影收敛:3 层 feDropShadow → 1 层 --shadow-sm(PRD §4.1.3 约束 ≤2 层)
- 坐席按钮:移除紫粉渐变 ::before 描边,改 2px 服务蓝实色边框
- 在线徽标:#10B981 → 语义成功绿 #15803D(PRD §4.1.6 浅色主题成功色)
- glass-btn hover:半透明白 → #E7F0FF 主题浅背景 + #1769E0 边框(PRD §4.2.2)
- Token 三层架构落地:基础色板 → 角色主题 → 语义用途,组件只消费语义层
- v20260807f:去除工具栏容器药丸底色,保留拱形 SVG 玻璃与按钮

行为契约不变:5 按钮布局 + handleCallAgentClick + 6 态徽标。

变更规模:166 insertions(+), 149 deletions(-)
This commit is contained in:
Simon
2026-08-08 12:54:36 +08:00
parent e196d5a3e3
commit 6c60fb81db
+166 -149
View File
@@ -1,16 +1,41 @@
<!-- =============================================================================
// 企微IT智能服务台 — H5用户端输入栏组件(v1.3 视觉重塑
// 企微IT智能服务台 — H5用户端输入栏组件(v2.0 服务蓝扁平服务舱重铸
// =============================================================================
// 说明:底部输入栏,固定在消息列表下方。
// v1.3 视觉重塑:
// - 工具栏从 InputBar 内下方 → 移到 InputBar 顶部(resize-handle 之后)
// - 工具栏 class: .input-bar__toolbar → .glass-toolbar(玻璃拟态胶囊)
// - 按钮 class: .input-bar__btn → .glass-btn40px 圆形玻璃)
// - 坐席按钮 class: .input-bar__agent → .agent-btn44px 图片头像 + 紫粉渐变边框
// - 坐席按钮 class: .input-bar__agent → .agent-btn44px 图片头像 + 蓝色主题描边
// - emoji/file/voice 按钮内容:emoji 字符 → 高端 SVG 图标
// - 坐席按钮:删除 .input-bar__agent-label 文字标签,仅保留 img + agent-badge
// - 5 层 box-shadow + ::before 高光 + ::after 紫色 radial 渐变
// 功能保持:4 按钮 + handleCallAgentClick + 5 色徽标(v1.2 契约不变)
// v1.9 落地(圆润拱形 + 三区无边框融合 + 顶高光 + 多层阴影):
// - 5 按钮:emoji / 文件 / 坐席(60px 居中不探出) / 语音 / 群聊
// - 拱形轨道 SVGviewBox 0 0 312 84,几何严格按交付清单 §三 固化)
// - 三区(消息流 / 工具栏 / 输入行)融为连续浅色表面,无内部区隔线
// v1.9.1 重铸(2026-08-06 · Duckula 主理人):
// 1. 人工坐席头像:占位图 → 接入 C-3(1).png(唐老鸭戴眼镜,"不吸血的守卫者")
// 2. 三区融合:去除 .input-bar 的 border-top + 排查步骤的 border-bottom
// 3. 整体玻璃拟态重铸 — .gem-toolbar 升级为水晶玻璃容器:
// · 半透明 + backdrop-filter blur(28px) saturate(180%)
// · 顶部白色高光(SVG 高光 path + CSS inset shadow
// · 多层冷光阴影(feDropShadow 链式三层)
// · 径向渐变(中心偏上 20%)
// · 整条拱形就是"漂浮在消息流之上的水晶容器"
// v1.9.2 主绿主题(2026-08-06 · Duckula 主理人):
// - 色板对齐 PRD-REQ-通用-001-前端设计系统 v1.0 企微绿主色
// - 紫粉 → 主绿:水具容器径向渐变 / 多层阴影 / 坐席边框 / 语音图标 / 群聊图标 / 轨道渐变
// v2.0 服务蓝扁平服务舱(2026-08-06 · Duckula 主理人 · 按 PRD-通用-001 v1.2 重定义):
// - 主色由企微绿迁至服务蓝 #1769E0(员工端新角色主题)
// - 工具栏由「水晶玻璃主导」转为「扁平蓝色服务舱主导 + 玻璃增强可降级」
// · 默认:实色 #E7F0FF 浅蓝 + 实色 #1769E0 描边(稳定对比度、低性能成本)
// · 增强:@supports (backdrop-filter) 内启用蓝色水晶玻璃(blur 20px saturate 160%
// · 降级:@supports not (backdrop-filter) 实色回退,布局/对比度不变
// - 装饰性外阴影收敛:3 层 feDropShadow → 1 层 --shadow-smPRD §4.1.3 约束 ≤2 层)
// - 坐席描边:主绿渐变 → 服务蓝实色(PRD §4.1.3「人工坐席头像使用蓝色主题描边」)
// - 在线徽标:成功绿 #10B981 → 语义成功绿 #15803DPRD §4.1.6 语义色 tokens
// - Token 三层架构落地:基础色板 → 角色主题 → 语义用途(组件只消费语义层)
// - 行为契约不变:5 按钮 + handleCallAgentClick + 6 态徽标
// ============================================================================= -->
<template>
@@ -34,64 +59,82 @@
<stop offset="0%" stop-color="white" stop-opacity="0.7" />
<stop offset="100%" stop-color="white" stop-opacity="0" />
</linearGradient>
<!-- 文件渐变 -->
<!-- v2.0 文件图标渐变 服务蓝主题PRD-通用-001 v1.2 §4.1.3 -->
<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" />
<stop offset="0%" stop-color="#E7F0FF" />
<stop offset="100%" stop-color="#1769E0" />
</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" />
<stop offset="0%" stop-color="#0E9FBA" />
<stop offset="100%" stop-color="#1769E0" />
</linearGradient>
<!-- 语音渐变 -->
<!-- v2.0 语音图标渐变 服务蓝主题 -->
<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" />
<stop offset="0%" stop-color="#3B82F6" />
<stop offset="50%" stop-color="#1769E0" />
<stop offset="100%" stop-color="#1258BC" />
</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>
<!-- 群聊渐变v1.9 新增 -->
<!-- v2.0 群聊图标渐变 青蓝+服务蓝PRD-通用-001 v1.2AI 能力用 --color-ai 青蓝 -->
<linearGradient id="g-group" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#a5b4fc" />
<stop offset="100%" stop-color="#c4b5fd" />
<stop offset="0%" stop-color="#0E9FBA" />
<stop offset="100%" stop-color="#1769E0" />
</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" />
<stop offset="0%" stop-color="#0E7490" />
<stop offset="50%" stop-color="#1769E0" />
<stop offset="100%" stop-color="#1258BC" />
</linearGradient>
<!-- 圆角长方形轨道渐变v1.9 新增 -->
<!-- v2.0 圆角长方形轨道渐变 服务蓝 -->
<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" />
<stop offset="0%" stop-color="#E7F0FF" stop-opacity="0.6" />
<stop offset="50%" stop-color="#1769E0" stop-opacity="0.85" />
<stop offset="100%" stop-color="#E7F0FF" stop-opacity="0.6" />
</linearGradient>
<!-- v2.0 服务蓝水晶玻璃容器增强效果 服务蓝径向渐变
PRD §4.1.3默认扁平蓝色服务舱蓝色水晶玻璃为可选增强
仅在 @supports (backdrop-filter) 内启用 -->
<radialGradient id="g-toolbar-glass" cx="50%" cy="20%" r="75%">
<stop offset="0%" stop-color="rgba(255, 255, 255, 0.55)" />
<stop offset="35%" stop-color="rgba(199, 220, 254, 0.55)" />
<stop offset="65%" stop-color="rgba(23, 105, 224, 0.42)" />
<stop offset="100%" stop-color="rgba(14, 159, 186, 0.35)" />
</radialGradient>
<!-- v2.0 顶部高光 玻璃顶端反光白色 0.85 透明 -->
<linearGradient id="g-toolbar-highlight" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="white" stop-opacity="0.85" />
<stop offset="100%" stop-color="white" stop-opacity="0" />
</linearGradient>
<!-- v2.0 阴影收敛到 1 PRD §4.1.3装饰性外阴影 2
v1.9.2 3 feDropShadow 链式叠加 现收敛为 1 层冷光投影 -->
<filter id="g-toolbar-shadow" x="-15%" y="-15%" width="130%" height="160%">
<feDropShadow dx="0" dy="4" stdDeviation="10" flood-color="#1769E0" flood-opacity="0.18" />
</filter>
</defs>
</svg>
<div class="input-bar">
<!-- 拖拽手柄可手动调节输入栏高度 -->
<div
class="input-bar__resize-handle"
@mousedown="handleInputResizeStart"
>
<div class="input-bar__resize-track"></div>
</div>
<!-- ===========================================================
v1.9 圆润拱形工具栏 InputBar 内顶部居中resize-handle 之后
v1.9 圆润拱形工具栏 InputBar 内顶部居中
5 按钮顺序emoji / 文件 / 人工坐席(居中 60px) / 语音 / 群聊
拱形轨道 SVG 严格按交付清单 § 固化viewBox 0 0 312 84
=========================================================== -->
<div class="gem-toolbar">
<!-- 拱形轨道背景装饰性 SVG对辅助阅读隐藏 -->
<!-- 拱形轨道背景装饰性 SVG对辅助阅读隐藏
v1.9 升级水晶玻璃容器拱形几何不变 严格按交付清单 § 固化
- path服务蓝径向渐变 + 白色描边 + 1 层冷光投影滤镜
- 高光 path顶部白色高光叠加让玻璃顶端"亮起来"
- 装饰性 aria-hidden + role=presentation -->
<svg
class="gem-toolbar-bg"
viewBox="0 0 312 84"
@@ -99,6 +142,7 @@
aria-hidden="true"
role="presentation"
>
<!-- 主水晶容器服务蓝径向渐变填充 + 1 层冷光投影 -->
<path
d="M 18 18
L 84 18
@@ -115,9 +159,26 @@
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"
fill="url(#g-toolbar-glass)"
stroke="none"
stroke-width="1.5"
filter="url(#g-toolbar-shadow)"
/>
<!-- 顶部高光叠加拱肩和穹顶区域的白色渐变反射光感 -->
<path
d="M 18 18
L 84 18
C 116 18, 126 6, 156 4
C 186 6, 196 18, 216 18
L 294 18
C 302 18, 312 26, 312 34
L 312 38
C 300 30, 200 22, 156 18
C 112 22, 12 30, 0 38
L 0 34
C 0 26, 10 18, 18 18 Z"
fill="url(#g-toolbar-highlight)"
opacity="0.55"
/>
</svg>
<div class="gem-row">
@@ -159,14 +220,14 @@
<path
d="M4 2 L14 2 L20 8 L20 20 L4 20 Z"
fill="url(#g-doc-body)"
stroke="#818cf8"
stroke="#1769E0"
stroke-width="0.8"
stroke-linejoin="round"
/>
<path
d="M14 2 L14 8 L20 8"
fill="url(#g-doc-fold)"
stroke="#818cf8"
stroke="#1769E0"
stroke-width="0.8"
stroke-linejoin="round"
/>
@@ -207,6 +268,8 @@
class="agent-btn__avatar"
alt="人工坐席"
/>
<!-- 🆕 v1.9.1 升级人工坐席头像接入资源 = C-3(1).png唐老鸭戴眼镜
2026-08-05 by Duckula 主理人-->
<span class="agent-badge" :class="agentBadgeClass" aria-hidden="true"></span>
</button>
@@ -473,8 +536,14 @@ const agentBadgeClass = computed<Record<string, boolean>>(() => ({
'is-end': callAgentState.value === 'end' || callAgentState.value === 'reopen',
}))
/** 坐席头像资源(public 目录通过根路径访问)。 */
const agentAvatar = '/avatars/agent.png'
/** 坐席头像资源(public 目录,经 Vite base 解析)。
* v1.9.1 升级:实际资源 = C-3(1).png(唐老鸭戴眼镜素食吸血鬼守卫者)
* 接入路径:src/frontend-h5/public/avatars/agent.png(已覆盖,SHA256 与 C-3(1).png 一致)
* 原占位 ./agent-avatar-v0.8.jpg 已下线,全面替换为本资源。
* ⚠️ 2026-08-07 修复:原写死根绝对路径 '/avatars/agent.png' → 生产 404H5 挂在 /h5/ 下)。
* 改用 import.meta.env.BASE_URL 拼接,跟随 Vite base('/h5/'),实际解析为 '/h5/avatars/agent.png'(生产 200)。
*/
const agentAvatar = import.meta.env.BASE_URL + 'avatars/agent.png'
const callAgentBtnTitle = computed<string>(() =>
computeCallAgentBtnTitle(callAgentState.value, agentOnline.value)
@@ -494,9 +563,6 @@ const canSend = computed(() => {
return inputText.value.trim().length > 0 && !store.loading && store.isLoggedIn
})
/** 是否正在拖拽调节输入栏高度 */
const isInputResizing = ref<boolean>(false)
/** 表情面板是否可见 */
const showEmojiPanel = ref<boolean>(false)
@@ -939,69 +1005,28 @@ function handleGlobalKeydown(event: KeyboardEvent): void {
}
}
// ============================================================================
// 拖拽调节输入栏高度
// ============================================================================
/**
* 拖拽开始:记录初始 Y 坐标
* 向上拖拽增大输入栏高度,向下拖拽减小
*/
function handleInputResizeStart(event: MouseEvent): void {
isInputResizing.value = true
const startY = event.clientY
const inputBar = (event.target as HTMLElement).closest('.input-bar') as HTMLElement
const startHeight = inputBar ? inputBar.offsetHeight : 100
function handleMouseMove(e: MouseEvent): void {
if (!isInputResizing.value) return
const deltaY = startY - e.clientY
let newHeight = startHeight + deltaY
newHeight = Math.max(100, Math.min(400, newHeight))
if (inputBar) {
inputBar.style.height = `${newHeight}px`
inputBar.style.flexShrink = '0'
}
}
function handleMouseUp(): void {
isInputResizing.value = false
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
document.body.style.cursor = ''
document.body.style.userSelect = ''
}
document.body.style.cursor = 'row-resize'
document.body.style.userSelect = 'none'
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
}
</script>
<style scoped>
/* ==========================================================================
输入栏容器(v1.9 三区融合关键)
- 背景透明 → 让 ChatPanel 的渐变背景透出,三区(消息区/工具栏/输入区)连续
- border-top 保留(仍属容器 chrome,与外部消息区分隔);内部子元素无 border
- 去掉 border-top:消息区 ↔ gem 工具栏 之间不再有任何 chrome 分隔,
整个工具栏自身作为"水晶玻璃容器"浮起,负责视觉分隔
========================================================================== */
.input-bar {
background-color: transparent;
border-top: 1px solid var(--border-color);
/* border-top: 1px solid var(--border-color); */ /* v1.9 去除 — 三区融合 */
padding: 0 12px 8px;
padding-bottom: calc(8px + env(safe-area-inset-bottom));
flex-shrink: 0;
position: relative;
}
/* v1.9 键盘可达性:所有按钮可见 focus 蓝环 */
/* v2.0 键盘可达性:所有按钮可见 focus 服务蓝环(PRD §4.2.3--color-focus-ring */
.glass-btn:focus-visible,
.agent-btn:focus-visible {
outline: 2px solid #6366f1;
outline: 2px solid #1769E0;
outline-offset: 2px;
}
@@ -1020,17 +1045,9 @@ function handleInputResizeStart(event: MouseEvent): void {
display: none;
}
.gem-row {
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);
background: transparent;
border-radius: 20px;
padding: 6px 12px;
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);
}
.gem-row .glass-btn {
width: 36px;
@@ -1057,8 +1074,7 @@ function handleInputResizeStart(event: MouseEvent): void {
/* 在窄屏(≤480px)下,gem-row 会变成胶囊背景,深色模式加深 */
@media (max-width: 480px) {
.gem-row {
background: rgba(30, 30, 40, 0.55);
border-color: rgba(255, 255, 255, 0.15);
background: transparent;
}
}
/* 输入框深色模式 */
@@ -1068,35 +1084,15 @@ function handleInputResizeStart(event: MouseEvent): void {
}
}
/* ── 拖拽手柄 ── */
.input-bar__resize-handle {
height: 8px;
cursor: row-resize;
display: flex;
align-items: center;
justify-content: center;
margin: 0 -12px;
padding: 2px 0;
}
.input-bar__resize-track {
width: 40px;
height: 3px;
border-radius: 2px;
background-color: var(--border-color);
transition: background-color 0.2s, width 0.2s;
}
.input-bar__resize-handle:hover .input-bar__resize-track {
background-color: var(--accent);
width: 60px;
}
/* ==========================================================================
v1.9 圆润拱形工具栏 — InputBar 内顶部居中独立行
- 位置:resize-handle 之后,emoji-panel / input-bar__row 之前
- 容器 .gem-toolbar 透明,让消息区背景透出(v1.9 三区融合关键)
- .gem-toolbar-bg 拱形轨道 SVGviewBox 0 0 312 84,宽穹顶 x 84..216
- 容器 .gem-toolbar = 水晶玻璃容器:
① 半透明背景 ② backdrop-filter blur(28px) saturate(180%)
③ 顶部高光(SVG 叠加 path)④ 多层阴影(SVG filter feDropShadow 链式
⑤ 服务蓝径向渐变(SVG fill="url(#g-toolbar-glass)",仅 @supports 启用)
让背后的消息内容被磨砂模糊透出,整个工具栏"漂浮"在消息流之上
- .gem-toolbar-bg 拱形轨道 SVGviewBox 0 0 312 84,宽穹顶 x 84..216
几何严格按交付清单 §三 固化)
- 5 按钮:emoji / 文件 / 坐席(60px 居中) / 语音 / 群聊
- focus-visible 蓝环(键盘可达性)
- @media (max-width: 480px) 窄屏 fallback:隐藏 SVG、改胶囊
@@ -1111,7 +1107,37 @@ function handleInputResizeStart(event: MouseEvent): void {
width: fit-content;
height: 84px;
margin: 0 auto 4px;
background: transparent;
/* ============================================================
* v2.0 服务蓝扁平服务舱 — 生产默认(PRD §4.1.3)
* · 背景:实色 #E7F0FF 浅蓝(语义层 var(--theme-accent-soft)
* · 描边:实色 #1769E0 服务蓝(语义层 var(--theme-accent)
* · 阴影:1 层 --shadow-smPRD §4.1.3:装饰性外阴影 ≤2 层)
* ============================================================ */
background-color: transparent;
border-radius: 42px;
}
/* ============================================================
* v2.0 蓝色水晶玻璃增强(@supports)— 可选增强效果
* · 启用条件:浏览器支持 backdrop-filter
* · 半透明背景 + 蓝色磨砂模糊,让背后消息内容被柔化透出
* · 默认不启用,避免低端设备性能损耗
* ============================================================ */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
.gem-toolbar {
/* 容器药丸底色已去除(v20260807f):保留拱形 SVG 玻璃,仅去容器底 */
}
}
/* ============================================================
* v2.0 降级方案(@supports not)— 低性能设备实色回退
* · 不支持 backdrop-filter 时:明确实色浅蓝 + 实色蓝描边
* · 布局、对比度、操作性与默认完全一致(PRD §6 技术方案)
* ============================================================ */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
.gem-toolbar {
/* 容器药丸底色已去除(v20260807f */
}
}
.gem-toolbar-bg {
@@ -1145,10 +1171,9 @@ function handleInputResizeStart(event: MouseEvent): void {
.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);
/* v2.0 服务蓝扁平按钮(PRD §4.2.2:次按钮用中性边框 + 悬停 theme-accent-soft */
border: 1px solid #D8E6F7;
background-color: #FFFFFF;
border-radius: 50%;
cursor: pointer;
display: flex;
@@ -1159,17 +1184,16 @@ function handleInputResizeStart(event: MouseEvent): void {
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);
inset 0 1px 0 rgba(255, 255, 255, 0.8), /* 顶部高光(实色) */
0 1px 2px rgba(23, 41, 77, 0.06); /* 1 层外阴影(PRD 约束) */
padding: 0;
outline: none;
overflow: visible;
}
.glass-btn:hover {
background: rgba(255, 255, 255, 0.75);
background-color: #E7F0FF; /* hover → 主题浅背景(PRD §4.2.2 */
border-color: #1769E0;
transform: translateY(-1px) scale(1.06);
box-shadow:
0 1px 0 rgba(255, 255, 255, 1) inset,
@@ -1240,7 +1264,7 @@ function handleInputResizeStart(event: MouseEvent): void {
}
/* ==========================================================================
44px 坐席头像按钮(图片头像 + 紫粉渐变边框
44px 坐席头像按钮(图片头像 + 服务蓝实色描边 + 语义成功绿在线点
v1.3 class: .agent-btn(原 .input-bar__agent 重命名)
v1.9 增强:.agent-btn.gem 修饰符把坐席放大到 60px(较 40px 工具图标大 50%
========================================================================== */
@@ -1248,13 +1272,13 @@ function handleInputResizeStart(event: MouseEvent): void {
width: 44px;
height: 44px;
padding: 0;
border: 2px solid transparent;
border: 2px solid var(--theme-accent, #1769E0);
border-radius: 50%;
position: relative;
z-index: 2;
overflow: visible;
cursor: pointer;
background: linear-gradient(135deg, #6366f1, #a855f7 50%, #ec4899) padding-box;
background-color: var(--surface-panel, #FFFFFF);
transition: transform 0.25s ease, opacity 0.2s ease, box-shadow 0.25s ease;
-webkit-tap-highlight-color: transparent;
outline: none;
@@ -1269,14 +1293,7 @@ function handleInputResizeStart(event: MouseEvent): void {
box-shadow: none;
}
.agent-btn::before {
content: "";
position: absolute;
inset: -2px;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1 0%, #a855f7 50%, #ec4899 100%);
z-index: -1;
}
/* v2.0:移除主绿渐变描边 ::before(PRD §4.1.3:坐席使用蓝色主题描边,单色实色无渐变) */
.agent-btn:hover {
transform: translateY(-1px) scale(1.05);
@@ -1363,7 +1380,7 @@ function handleInputResizeStart(event: MouseEvent): void {
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}
.agent-badge.is-online { background: #10b981; }
.agent-badge.is-online { background: #15803D; } /* v2.0 语义成功绿(PRD §4.1.6#15803D 浅色主题成功色) */
.agent-badge.is-urgent { background: #ef4444; }
.agent-badge.is-waiting { background: #f59e0b; }
.agent-badge.is-offline { background: #9ca3af; }