Files
wecom_it_smart_desk/docs/01-产品文档/02-会话管理/原型-REQ-会话-001-工具栏统一设计v2.0-员工端服务蓝扁平版.html
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

712 lines
32 KiB
HTML
Raw Permalink 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>工具栏统一设计 v2.0 — 员工端服务蓝扁平服务舱(PRD-通用-001 v1.2 对齐版)</title>
<style>
/* ============================================================
* Token 分层(PRD §4.1.1
* 基础色板层 → 角色主题层 → 语义用途层
* 组件只消费语义用途层,禁止直接写死角色品牌色
* ============================================================ */
:root {
/* 基础色板层 */
--palette-blue-600: #1769E0;
--palette-blue-700: #1258BC;
--palette-cyan-600: #0E9FBA;
--palette-cyan-700: #0E7490;
--palette-green-700: #15803D;
--palette-amber-700: #B45309;
--palette-red-700: #B42318;
--palette-gray-50: #F9FAFB;
--palette-gray-100: #F3F4F6;
--palette-gray-200: #E5E7EB;
--palette-gray-600: #4B5563;
--palette-gray-800: #1F2937;
/* 员工端角色主题层(PRD §4.1.3) */
--theme-accent: var(--palette-blue-600);
--theme-accent-hover: var(--palette-blue-700);
--theme-accent-soft: #E7F0FF;
--theme-secondary: var(--palette-cyan-600);
--surface-page: #F4F8FD;
--surface-panel: #FFFFFF;
--surface-ai: #F3F8FF;
--border-subtle: #D8E6F7;
--text-primary: #172B4D;
--text-secondary: #5B6B82;
/* 语义用途层(PRD §4.1.6 */
--color-action-primary: var(--theme-accent);
--color-focus-ring: var(--theme-accent);
--color-status-success: var(--palette-green-700);
--color-status-warning: var(--palette-amber-700);
--color-status-danger: var(--palette-red-700);
--color-status-info: var(--theme-accent);
--color-status-muted: #9CA3AF; /* 离线灰(语义层,仅状态徽标使用) */
--color-ai: var(--palette-cyan-700);
/* 排版/间距/圆角/阴影(PRD §4.1) */
--font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
--radius-md: 6px;
--radius-lg: 8px;
--radius-xl: 12px;
--radius-full: 999px;
--shadow-sm: 0 1px 2px rgba(23, 41, 77, 0.06);
--shadow-md: 0 2px 8px rgba(23, 41, 77, 0.08);
--duration-fast: 150ms;
--duration-normal: 200ms;
/* 蓝色水晶玻璃增强效果(可选,仅在支持 backdrop-filter 的设备启用)
PRD §4.1.3 员工端工具栏决策:扁平服务舱为生产默认,蓝色玻璃为增强效果 */
--glass-bg: rgba(231, 240, 255, 0.72);
--glass-stroke: rgba(23, 105, 224, 0.18);
}
/* 降级方案:未支持 backdrop-filter 的设备 → 实色扁平服务舱
PRD §6 技术方案:必须提供 @supports not (backdrop-filter: blur(1px)) 降级 */
@supports not (backdrop-filter: blur(1px)) {
:root {
--glass-bg: var(--theme-accent-soft); /* 实色浅蓝替代半透明 */
--glass-stroke: var(--theme-accent); /* 明确蓝色描边替代透明边 */
}
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: var(--font-family);
/* 页面基底 PRD §4.1.3--surface-page = #F4F8FD */
background-color: var(--surface-page);
color: var(--text-primary);
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: var(--text-primary); }
h1 .ver { color: var(--theme-accent); }
h2 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; margin: 32px 0 12px; color: var(--text-primary); }
.meta { color: var(--text-secondary); font-size: 12.5px; margin-bottom: 20px; }
/* === 员工端会话窗口 — 扁平卡片,蓝色描边(PRD §4.2.4:阴影 ≤2 层用于浮层,卡片仅用边框+表面) === */
.chatpanel-mock {
width: 100%;
max-width: 720px;
margin: 0 auto;
background-color: var(--surface-panel);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-sm); /* 仅 1 层阴影(PRD 约束装饰性外阴影 ≤2 层) */
overflow: hidden;
position: relative;
}
.chatpanel-mock-header {
padding: 12px 16px;
border-bottom: 1px solid var(--border-subtle); /* 仅窗口标题栏 chrome 分隔 */
background-color: var(--surface-panel);
font-size: 13px;
color: var(--text-primary);
display: flex;
align-items: center;
gap: 8px;
flex-shrink: 0;
}
.chatpanel-mock-header .dot {
width: 8px; height: 8px; border-radius: 50%;
background-color: var(--color-status-success); /* 语义色:在线绿 */
}
.chatpanel-mock-header .title { font-weight: 600; }
.chatpanel-mock-header .sub { color: var(--text-secondary); font-size: 11.5px; }
/* === 消息流区域 === */
.chatpanel-mock-messages {
min-height: 240px;
padding: 20px 16px;
background-color: var(--surface-panel);
display: flex;
flex-direction: column;
gap: 10px;
}
.mock-msg {
max-width: 74%;
padding: 9px 13px;
border-radius: var(--radius-xl);
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-color: var(--theme-accent); /* 实色服务蓝,无多色渐变 */
color: #FFFFFF;
border-bottom-right-radius: 4px;
}
.mock-msg.ai {
align-self: flex-start;
background-color: var(--surface-ai);
color: var(--text-primary);
border: 1px solid var(--border-subtle);
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: var(--radius-md);
background-color: var(--theme-accent-soft);
color: var(--theme-accent);
border: 1px solid var(--border-subtle);
}
/* === v2.0 蓝色扁平服务舱 — 生产默认 === */
.toolbar-band {
padding: 6px 16px 10px;
display: flex;
justify-content: center;
}
.toolbar {
position: relative;
display: flex;
align-items: center;
justify-content: center;
padding: 0 14px;
width: fit-content;
height: 72px;
/* PRD §4.1.3:默认扁平蓝色服务舱(稳定对比度、低性能成本) */
background-color: var(--glass-bg);
border: 1px solid var(--glass-stroke);
border-radius: var(--radius-full);
box-shadow: var(--shadow-sm); /* 1 层阴影(PRD 约束) */
}
/* 蓝色水晶玻璃增强(@supports) — 玻璃模糊 + 顶部高光 */
@supports (backdrop-filter: blur(1px)) {
.toolbar {
backdrop-filter: blur(20px) saturate(160%);
-webkit-backdrop-filter: blur(20px) saturate(160%);
}
}
.toolbar-row { display: flex; align-items: center; justify-content: center; gap: 8px; }
.toolbar-row .agent-btn.is-main { width: 56px; height: 56px; margin: 0 6px; }
/* === InputBar — 扁平,无顶部边框(三区融合核心:v1.9.1 起 + v2.0 强化) === */
.inputbar-mock {
background-color: var(--surface-panel);
padding: 2px 16px 14px;
position: relative;
}
.inputbar-mock-field {
width: 100%;
min-height: 56px;
background-color: var(--surface-panel);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
padding: 10px 14px;
font-size: 13px;
color: var(--text-secondary);
line-height: 1.6;
display: flex;
align-items: center;
justify-content: space-between;
transition: border-color var(--duration-fast);
}
.inputbar-mock-field:focus-within {
border-color: var(--color-focus-ring);
outline: 2px solid var(--color-focus-ring);
outline-offset: 1px;
}
.inputbar-mock-field .send {
margin-left: 12px;
padding: 7px 18px;
border-radius: var(--radius-md);
background-color: var(--color-action-primary);
color: #FFFFFF;
font-size: 13px; font-weight: 600;
box-shadow: var(--shadow-sm);
}
/* === 通用按钮(v2.0 蓝色扁平):实色浅蓝,无多色发光 === */
.btn-circle {
width: 40px; height: 40px;
border: 1px solid var(--border-subtle);
background-color: var(--surface-panel);
border-radius: 50%;
cursor: pointer;
display: flex; align-items: center; justify-content: center;
transition: all var(--duration-fast) cubic-bezier(0.4, 0, 0.2, 1);
-webkit-tap-highlight-color: transparent;
position: relative;
box-shadow: var(--shadow-sm);
}
.btn-circle:hover {
background-color: var(--theme-accent-soft);
border-color: var(--theme-accent);
}
.btn-circle:active { transform: scale(0.95); }
.btn-circle svg { width: 22px; height: 22px; display: block; }
.btn-circle:focus-visible { outline: 2px solid var(--color-focus-ring); outline-offset: 2px; }
/* === 56px 坐席按钮(v2.0:头像 = C-3(1).png + 蓝色主题描边 + 绿色在线点) === */
.agent-btn {
border-radius: 50%;
/* PRD §4.1.3:人工坐席头像使用蓝色主题描边 */
border: 2px solid var(--theme-accent);
cursor: pointer;
position: relative;
padding: 0;
overflow: hidden;
background-color: var(--surface-panel);
box-shadow: var(--shadow-sm);
}
.agent-btn img {
width: 100%; height: 100%; border-radius: 50%; object-fit: cover;
object-position: center 25%; /* 鸭子脸部特征居中略偏下 */
display: block;
}
.agent-badge {
position: absolute; bottom: -2px; right: -2px;
width: 14px; height: 14px;
border-radius: 50%;
border: 2px solid var(--surface-panel);
z-index: 3;
/* 默认 = 在线绿(PRD §4.1.3 在线语义) */
background-color: var(--color-status-success);
}
/* === 坐席状态徽标 5 色体系(v1.2 决策补齐,v2.0 服务蓝对齐)===
语义映射:在线=绿 / 紧急=红 / 等待=橙 / 结束|重连=蓝 / 离线=灰
头像本体不变色,仅徽标承载状态色(v1.2 §坐席状态决策) */
.agent-badge.is-online { background-color: var(--color-status-success); } /* 绿 #15803D 在线 */
.agent-badge.is-urgent { background-color: var(--color-status-danger); } /* 红 #B42318 紧急 */
.agent-badge.is-waiting { background-color: var(--color-status-warning); } /* 橙 #B45309 等待 */
.agent-badge.is-end { background-color: var(--color-status-info); } /* 蓝 #1769E0 结束|重连 */
.agent-badge.is-offline { background-color: var(--color-status-muted); } /* 灰 #9CA3AF 离线 */
/* 紧急状态 - 徽标呼吸(红色脉动,v1.2 badgePulse 对齐) */
.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(180, 35, 24, 0), 0 1px 2px rgba(0,0,0,0.2); }
50% { box-shadow: 0 0 0 4px rgba(180, 35, 24, 0.30), 0 1px 2px rgba(0,0,0,0.2); }
}
/* 离线状态 - 整体弱化(保留头像品牌,仅降低不透明度) */
.agent-btn.is-offline { opacity: 0.5; }
/* === 头像加载失败时的降级占位(避免破图)===
图片 onerror 标记 .img-broken 后隐藏,并以服务蓝胶囊 + 🦆 占位 */
.agent-btn img.img-broken { display: none; }
.agent-btn:has(img.img-broken)::before {
content: "\01F986"; /* 🦆 */
position: absolute; inset: 0;
display: flex; align-items: center; justify-content: center;
font-size: 26px;
background-color: var(--theme-accent-soft);
border-radius: 50%;
z-index: 1;
}
/* === 5 色状态徽标演示(v2.0 服务蓝对齐) === */
.badge-demo-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
margin: 16px 0;
}
.badge-demo-card {
background-color: var(--surface-panel);
border: 1px solid var(--border-subtle);
border-radius: var(--radius-lg);
padding: 18px 10px 14px;
text-align: center;
box-shadow: var(--shadow-sm);
}
.badge-demo-stage {
display: flex;
justify-content: center;
align-items: center;
padding: 4px 0;
}
.badge-demo-card .label {
font-size: 11.5px;
color: var(--text-secondary);
margin-top: 12px;
font-weight: 500;
}
.badge-demo-card .swatch {
display: inline-block;
width: 10px; height: 10px;
border-radius: 50%;
margin-right: 5px;
vertical-align: middle;
border: 1px solid var(--border-subtle);
}
@media (max-width: 560px) {
.badge-demo-grid { grid-template-columns: repeat(2, 1fr); }
}
/* === 提示块 === */
.note-info {
background-color: var(--theme-accent-soft);
border-left: 3px solid var(--theme-accent);
padding: 12px 16px; border-radius: 4px;
font-size: 12.5px; color: var(--text-primary);
margin: 16px 0;
}
.note-success {
background-color: rgba(21, 128, 61, 0.08);
border-left: 3px solid var(--color-status-success);
padding: 12px 16px; border-radius: 4px;
font-size: 12.5px; color: #064E3B;
margin: 16px 0;
}
.note-warn {
background-color: rgba(180, 83, 9, 0.08);
border-left: 3px solid var(--color-status-warning);
padding: 12px 16px; border-radius: 4px;
font-size: 12.5px; color: #78350F;
margin: 16px 0;
}
table { width: 100%; border-collapse: collapse; margin: 16px 0; font-size: 12.5px; }
thead tr { background-color: var(--theme-accent-soft); }
th { border: 1px solid var(--border-subtle); padding: 8px; text-align: left; font-weight: 600; color: var(--text-primary); }
td { border: 1px solid var(--border-subtle); padding: 8px; }
.checklist li { list-style: none; padding-left: 22px; position: relative; line-height: 1.9; font-size: 13px; }
.checklist li::before { content: "□"; position: absolute; left: 4px; color: var(--theme-accent); font-weight: 700; }
.checklist li.done::before { content: "☑"; color: var(--color-status-success); }
/* 头像悬停提示 */
.agent-btn:hover::after {
content: attr(data-tip);
position: absolute;
bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
background-color: rgba(23, 41, 77, 0.92); color: #fff;
font-size: 11px; padding: 4px 8px; border-radius: 6px;
white-space: nowrap; z-index: 10;
}
/* === 降级对照演示 === */
.fallback-band {
margin: 16px 0;
padding: 16px;
background-color: var(--surface-panel);
border: 1px dashed var(--border-subtle);
border-radius: var(--radius-lg);
font-size: 12.5px;
color: var(--text-secondary);
}
.fallback-band code {
background-color: var(--surface-page);
padding: 2px 6px;
border-radius: 4px;
color: var(--theme-accent);
font-family: ui-monospace, "SF Mono", monospace;
}
</style>
</head>
<body>
<h1>工具栏统一设计 v2.0 — <span class="ver">员工端服务蓝扁平服务舱</span></h1>
<p class="meta">
按 PRD-REQ-通用-001-前端设计系统 v1.2 重定义 · 2026-08-06 · Duckula 主理人
&nbsp;|&nbsp; 基线:v1.9.2 主绿水晶玻璃版
</p>
<div class="note-info">
<strong>v2.0 关键决策(PRD v1.2 §4.1.3</strong>
<br><strong>主色迁移</strong>:企微绿 → <strong>服务蓝 #1769E0</strong>(员工端新角色主题);绿色回归成功/在线/已解决语义
<br><strong>工具栏定位</strong>:默认采用<strong>扁平蓝色服务舱</strong>(稳定对比度、低性能成本),蓝色水晶玻璃作为 <code>@supports (backdrop-filter)</code> 增强
<br><strong>降级保证</strong><code>@supports not (backdrop-filter)</code> 时自动切换为实色浅蓝 + 蓝色描边,布局/对比度/可操作性不变
<br><strong>阴影约束</strong>:装饰性外阴影 ≤2 层(原 v1.9.2 是 3 层 feDropShadow,现收敛为 1 层)
<br><strong>Token 分层</strong>:基础色板层 → 角色主题层 → 语义用途层,组件只消费语义用途层
<br><strong>三端区分</strong>:员工端蓝 / 坐席端深海蓝 / 管理端海军蓝,三端共享字体/间距/圆角/图标/交互,主题色按角色变化
</div>
<h2>🎯 员工端落地效果(v2.0 最终视觉)</h2>
<div class="chatpanel-mock">
<div class="chatpanel-mock-header">
<span class="dot" aria-label="在线"></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>
<div class="toolbar-band">
<div class="toolbar" role="toolbar" aria-label="会话操作工具栏">
<div class="toolbar-row">
<button class="btn-circle" title="表情" aria-label="表情">
<svg viewBox="0 0 24 24" fill="none">
<circle cx="12" cy="12" r="9" fill="#fde68a" stroke="#d97706" stroke-width="1.2"/>
<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="btn-circle" title="文件" aria-label="文件">
<svg viewBox="0 0 24 24" fill="none">
<path d="M4 2 L14 2 L20 8 L20 20 L4 20 Z" fill="#FFFFFF" stroke="var(--theme-accent)" stroke-width="1.2"/>
<path d="M14 2 L14 8 L20 8" fill="var(--theme-accent-soft)" stroke="var(--theme-accent)" stroke-width="1.2"/>
<rect x="7" y="11.5" width="10" height="0.8" rx="0.4" fill="var(--theme-accent)"/>
<rect x="7" y="14" width="7" height="0.8" rx="0.4" fill="var(--theme-secondary)"/>
</svg>
</button>
<button class="agent-btn is-main" title="人工坐席" aria-label="转接人工坐席" data-tip="不吸血的守卫者 · 在线">
<img src="./agent-avatar-v2.0.png" alt="人工坐席" class="agent-avatar-img" onerror="this.classList.add('img-broken')"/>
<span class="agent-badge is-online" aria-label="在线"></span>
</button>
<button class="btn-circle" title="语音输入" aria-label="语音输入">
<svg viewBox="0 0 24 24" fill="none">
<rect x="8" y="2" width="8" height="13" rx="4" fill="var(--theme-accent)"/>
<path d="M3 12 Q3 18 12 18 Q21 18 21 12" fill="none" stroke="var(--theme-accent)" stroke-width="2"/>
<line x1="12" y1="18" x2="12" y2="22" stroke="var(--theme-accent)" stroke-width="2"/>
</svg>
</button>
<button class="btn-circle" title="群聊" aria-label="发起群聊">
<svg viewBox="0 0 24 24" fill="none">
<circle cx="8" cy="9" r="2.2" fill="var(--theme-secondary)" stroke="var(--color-ai)" stroke-width="0.5"/>
<path d="M5 16 Q5 13 8 13 Q11 13 11 16 Z" fill="var(--theme-secondary)"/>
<circle cx="16" cy="9" r="2.2" fill="var(--theme-secondary)"/>
<path d="M13 16 Q13 13 16 13 Q19 13 19 16 Z" fill="var(--theme-secondary)"/>
<circle cx="12" cy="10.5" r="2.8" fill="var(--color-ai)"/>
<path d="M8.5 18.5 Q8.5 14 12 14 Q15.5 14 15.5 18.5 Z" fill="var(--color-ai)"/>
</svg>
</button>
</div>
</div>
</div>
<div class="inputbar-mock">
<div class="inputbar-mock-field" tabindex="0">
<span>描述您的问题,或点击上方工具栏发起操作…</span>
<span class="send">发送</span>
</div>
</div>
</div>
<div class="fallback-band">
<strong>🔁 降级对照</strong>PRD §6 技术方案)
<br>支持 <code>backdrop-filter: blur(1px)</code> 时,<code>.toolbar</code> 启用蓝色水晶玻璃(<code>backdrop-filter: blur(20px) saturate(160%)</code>),背后消息内容被柔化透出。
<br>不支持时(如低端 Android 浏览器、关闭玻璃效果的系统设置),<code>@supports not</code> 规则生效:<code>--glass-bg</code> 改为实色浅蓝 <code>#E7F0FF</code><code>--glass-stroke</code> 改为实色蓝 <code>#1769E0</code>,布局、对比度、操作性完全一致。
</div>
<h2>🎭 坐席按钮 - 头像 + 状态徽标(5 色,v2.0 服务蓝对齐)</h2>
<div class="note-info">
<strong>补齐 v1.2 状态徽标 5 色体系</strong>(原 v2.0 仅保留单一在线绿,已缺失完整状态色)。
<br>· 头像本体不变色,<strong>仅右下角徽标承载状态色</strong>(v1.2 §坐席状态决策:简洁、不喧宾夺主)
<br>· 颜色全部取自 v2.0 语义层 Token:在线=成功绿 <code>#15803D</code> / 紧急=危险红 <code>#B42318</code> / 等待=告警橙 <code>#B45309</code> / 结束·重连=信息蓝 <code>#1769E0</code> / 离线=中性灰 <code>#9CA3AF</code>
<br>· 紧急状态徽标 1.5s 红色呼吸脉动;离线状态整体不透明度降至 0.5 弱化
</div>
<div class="badge-demo-grid">
<div class="badge-demo-card">
<div class="badge-demo-stage">
<button class="agent-btn is-main" style="cursor:default;">
<img src="./agent-avatar-v2.0.png" alt="人工坐席" class="agent-avatar-img" onerror="this.classList.add('img-broken')"/>
<span class="agent-badge is-online"></span>
</button>
</div>
<div class="label"><span class="swatch" style="background:#15803D"></span>在线 🟢</div>
</div>
<div class="badge-demo-card">
<div class="badge-demo-stage">
<button class="agent-btn is-main is-urgent" style="cursor:default;">
<img src="./agent-avatar-v2.0.png" alt="人工坐席" class="agent-avatar-img" onerror="this.classList.add('img-broken')"/>
<span class="agent-badge is-urgent"></span>
</button>
</div>
<div class="label"><span class="swatch" style="background:#B42318"></span>紧急 🔴(呼吸)</div>
</div>
<div class="badge-demo-card">
<div class="badge-demo-stage">
<button class="agent-btn is-main" style="cursor:default;">
<img src="./agent-avatar-v2.0.png" alt="人工坐席" class="agent-avatar-img" onerror="this.classList.add('img-broken')"/>
<span class="agent-badge is-waiting"></span>
</button>
</div>
<div class="label"><span class="swatch" style="background:#B45309"></span>等待 🟠</div>
</div>
<div class="badge-demo-card">
<div class="badge-demo-stage">
<button class="agent-btn is-main" style="cursor:default;">
<img src="./agent-avatar-v2.0.png" alt="人工坐席" class="agent-avatar-img" onerror="this.classList.add('img-broken')"/>
<span class="agent-badge is-end"></span>
</button>
</div>
<div class="label"><span class="swatch" style="background:#1769E0"></span>结束·重连 🔵</div>
</div>
<div class="badge-demo-card">
<div class="badge-demo-stage">
<button class="agent-btn is-main is-offline" style="cursor:default;">
<img src="./agent-avatar-v2.0.png" alt="人工坐席" class="agent-avatar-img" onerror="this.classList.add('img-broken')"/>
<span class="agent-badge is-offline"></span>
</button>
</div>
<div class="label"><span class="swatch" style="background:#9CA3AF"></span>离线 ⚫(弱化)</div>
</div>
</div>
<h2>📋 v2.0 落地检查清单(PRD v1.2 强约束)</h2>
<ul class="checklist">
<li class="done">圆角长方形 + 中央圆润拱形轨道(SVG path 沿用 v1.9 交付清单 §三 锁定)</li>
<li class="done">🆕 <strong>主色由企微绿迁至服务蓝</strong>:#1769E0 角色主题色,员工端产品语义清晰(可信、亲和、低压力)</li>
<li class="done">🆕 <strong>工具栏默认 = 扁平蓝色服务舱</strong>:实色 #E7F0FF 浅蓝 + 实色 #1769E0 描边(PRD §4.1.3 决策)</li>
<li class="done">🆕 <strong>蓝色水晶玻璃 = 可选增强</strong>:仅 <code>@supports (backdrop-filter)</code> 时启用 <code>blur(20px) saturate(160%)</code></li>
<li class="done">🆕 <strong>降级方案完整</strong><code>@supports not (backdrop-filter: blur(1px))</code> 实色回退,对比度 WCAG ≥4.5:1 维持</li>
<li class="done">🆕 <strong>装饰性外阴影 ≤2 层</strong>:本版 = 1 层(卡片 + 工具栏 + 按钮各 1 层 inset/外阴影)</li>
<li class="done">🆕 <strong>Token 分层落地</strong>:组件消费 <code>--color-action-primary</code> / <code>--color-focus-ring</code> / <code>--color-status-success</code> 等语义层,禁止直接写 <code>#1769E0</code></li>
<li class="done">🆕 <strong>坐席状态徽标 5 色体系补齐</strong>v1.2 决策回归):在线绿 <code>#15803D</code> / 紧急红 <code>#B42318</code> / 等待橙 <code>#B45309</code> / 结束·重连蓝 <code>#1769E0</code> / 离线灰 <code>#9CA3AF</code>,颜色均取自语义层,头像本体不变色</li>
<li class="done">🆕 <strong>头像加载失败降级</strong><code>onerror</code> 标记 <code>.img-broken</code> 隐藏破图,<code>:has()</code> 占位服务蓝胶囊 + 🦆,避免原型再次出现破图</li>
<li class="done">🆕 <strong>人工坐席描边 = 蓝色主题</strong><code>border: 2px solid var(--theme-accent)</code>,不再是绿色描边</li>
<li class="done">人工坐席头像沿用 C-3(1).pngv1.9.2 已接入)</li>
<li class="done">三区无边框融合:仅保留窗口标题栏 chrome 分隔(v1.9.1 起)</li>
<li class="done">键盘可达:所有按钮 title + aria-label,可见 <code>:focus-visible</code> 服务蓝环</li>
<li>开发实现:<code>InputBar.vue</code> 升级到 v2.0PRD v1.2 主题层 + 降级 CSS</li>
<li>回归测试:服务蓝主题在浅色/深色/低性能设备三态回归</li>
<li>响应式:≤480px fallback 沿用 v1.9 方案 A 扁平胶囊</li>
</ul>
<h2>🆚 v1.9.2 → v2.0 差异对比(PRD v1.2 主题重定义)</h2>
<table>
<thead>
<tr><th>维度</th><th>v1.9.2 主绿水晶玻璃版</th><th>v2.0 服务蓝扁平版</th></tr>
</thead>
<tbody>
<tr>
<td>PRD 基础</td>
<td>v1.0 / v1.1(企微绿主色)</td>
<td><strong>v1.2</strong>(服务蓝主色)</td>
</tr>
<tr>
<td>主色(角色主题)</td>
<td>企微绿 <code>#07C160</code></td>
<td><strong>服务蓝 <code>#1769E0</code></strong></td>
</tr>
<tr>
<td>辅助色(角色主题)</td>
<td>成功绿 <code>#10B981</code></td>
<td><strong>青蓝 <code>#0E9FBA</code></strong></td>
</tr>
<tr>
<td>页面基底</td>
<td>主绿径向渐变(装饰性)</td>
<td><strong><code>#F4F8FD</code></strong><code>--surface-page</code> 实色)</td>
</tr>
<tr>
<td>工具栏默认</td>
<td>水晶玻璃主导(强制 backdrop-filter</td>
<td><strong>扁平蓝色服务舱</strong>(实色 + 蓝色描边)</td>
</tr>
<tr>
<td>水晶玻璃</td>
<td>默认即开,<code>blur(28px) saturate(180%)</code></td>
<td><strong>可选增强</strong>,仅 <code>@supports</code> 启用 <code>blur(20px) saturate(160%)</code></td>
</tr>
<tr>
<td>降级方案</td>
<td>无(不支持 backdrop-filter 时画面残缺)</td>
<td><strong><code>@supports not</code> 实色回退</strong>,对比度/布局不变</td>
</tr>
<tr>
<td>装饰性外阴影</td>
<td>3 层 feDropShadow + 多层 box-shadow</td>
<td><strong>1 层 <code>--shadow-sm</code></strong>PRD 约束 ≤2 层)</td>
</tr>
<tr>
<td>坐席描边</td>
<td>主绿渐变 <code>#10B981 → #07C160 → #34D399</code></td>
<td><strong>实色服务蓝 <code>#1769E0</code></strong></td>
</tr>
<tr>
<td>坐席在线徽标</td>
<td><code>#10B981</code> 成功绿</td>
<td><strong><code>#15803D</code></strong> 语义成功绿(更深的对比度)</td>
</tr>
<tr>
<td>用户消息气泡</td>
<td>主绿渐变(多色发光)</td>
<td><strong>实色服务蓝</strong>(无渐变,符合 PRD §4.1.2</td>
</tr>
<tr>
<td>AI 消息气泡</td>
<td>浅绿 + 绿边</td>
<td><strong>浅蓝 <code>#F3F8FF</code> + 蓝边 <code>#D8E6F7</code></strong></td>
</tr>
<tr>
<td>语音 / 群聊图标</td>
<td>主绿渐变(紫粉已弃)</td>
<td><strong>实色服务蓝 / 青蓝</strong>(符合角色主题)</td>
</tr>
<tr>
<td>Token 架构</td>
<td>扁平 <code>--color-primary</code> 单层</td>
<td><strong>三层架构</strong>:基础色板 → 角色主题 → 语义用途</td>
</tr>
<tr>
<td>多色发光</td>
<td>存在(紫粉 → 绿)</td>
<td><strong>禁止</strong>PRD §4.1.3</td>
</tr>
<tr>
<td>头像素材</td>
<td>C-3(1).png</td>
<td><strong>C-3(1).png</strong>(沿用,不变)</td>
</tr>
<tr>
<td>几何(SVG path</td>
<td>严格按清单 §三</td>
<td>不变(架构稳定)</td>
</tr>
</tbody>
</table>
<h2>🧭 决策记录</h2>
<div class="note-info">
本版按 PRD-REQ-通用-001-前端设计系统 <strong>v1.2</strong> 重定义员工端主题。关键决策:
<br>· 员工端由「企微绿主色」迁移为「服务蓝主色」(<code>--theme-accent: #1769E0</code>
<br>· 工具栏由「水晶玻璃主导」转为「扁平蓝色服务舱主导 + 玻璃增强可降级」
<br>· 装饰性外阴影 ≤2 层(原 v1.9.2 是 3 层 feDropShadow,现收敛为 1 层 <code>--shadow-sm</code>
<br>· Token 三层架构(基础色板 / 角色主题 / 语义用途),组件只消费语义层
<br>· 绿色仅保留为成功/在线/已解决语义,不再作为品牌主色
<br>· 紫色 <code>#6366f1</code> 完全清退(PRD §4.1.2 仅用于 AI 能力或管理端辅助)
</div>
<div class="note-warn">
⚠️ <strong>已归档</strong>:v1.9.2 主绿水晶玻璃版同步归档为 <code>原型-REQ-会话-001-工具栏统一设计v1.9.2-员工端主绿水晶玻璃版.archive.html</code>,保留历史轨迹但不作为最终交付。
</div>
<h2>⚠️ 待开发对齐的开放项</h2>
<ol style="margin-left: 20px; line-height: 1.8; font-size: 13px;">
<li><strong>Token 文件统一注入</strong>:在 <code>src/frontend-h5/src/styles/tokens.css</code> 落地三层架构,并通过根容器 <code>[data-product="employee"]</code> 注入</li>
<li><strong>降级验证</strong>:在 Safari iOS 旧机型、Android Chrome 90 以下、关闭系统玻璃效果三种环境实测 <code>@supports</code> 切换</li>
<li><strong>WCAG 对比度复测</strong>#FFFFFF on #1769E0 = 5.6:1 ✓ / #172B4D on #FFFFFF = 11.7:1 ✓ / #15803D on #FFFFFF = 4.6:1 ✓</li>
<li><strong>坐席 60→56px</strong>:本版扁平化后将坐席从 60px 收敛到 56px(与扁平工具栏更协调),但需用户确认</li>
<li><strong>三端主题一致性</strong>:坐席端深海蓝 <code>#155E75</code> / 管理端海军蓝 <code>#4F72D8</code> 同步切换,参考 PRD §4.1.4 / §4.1.5</li>
<li><strong>头像素材保留</strong><code>agent-avatar-v2.0.png</code>(已生成于本目录,1024×974)沿用,与品牌一致;v2.0 主工具栏已修正引用路径(原误引 v1.9.2 不存在文件)</li>
</ol>
<p style="margin-top: 32px; padding-top: 16px; border-top: 1px solid var(--border-subtle); color: var(--text-secondary); font-size: 11.5px;">
v2.0 员工端服务蓝扁平服务舱 · 2026-08-06 · Duckula 主理人 · 按 PRD-通用-001 v1.2 重定义 · 已开发实现并视觉验收
</p>
</body>
</html>