feat: polish logo card with svg transitions

This commit is contained in:
JOJO 2025-11-22 00:14:40 +08:00
parent 411cbf71ee
commit 6e8321cf7e
4 changed files with 110 additions and 56 deletions

View File

@ -71,7 +71,8 @@ const ICONS = Object.freeze({
triangleAlert: '/static/icons/triangle-alert.svg',
user: '/static/icons/user.svg',
wrench: '/static/icons/wrench.svg',
x: '/static/icons/x.svg'
x: '/static/icons/x.svg',
zap: '/static/icons/zap.svg'
});
const TOOL_ICON_MAP = Object.freeze({
@ -219,12 +220,12 @@ async function bootstrapApp() {
autoScrollEnabled: true,
// 面板宽度控制
leftWidth: 280,
leftWidth: 350,
rightWidth: 420,
rightCollapsed: true,
isResizing: false,
resizingPanel: null,
minPanelWidth: 200,
minPanelWidth: 350,
maxPanelWidth: 600,
// 工具状态跟踪

13
static/icons/zap.svg Normal file
View File

@ -0,0 +1,13 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M13 2L3 14h9l-1 8 10-12h-9z" />
</svg>

After

Width:  |  Height:  |  Size: 251 B

View File

@ -168,21 +168,30 @@
<aside class="sidebar left-sidebar" :style="{ width: leftWidth + 'px' }">
<div class="sidebar-status">
<div class="compact-status-card">
<div class="status-top">
<span class="logo icon-label">
<span class="icon icon-md"
<div class="status-line">
<div class="status-brand">
<span class="icon icon-lg status-logo"
:style="iconStyle('bot')"
aria-hidden="true"></span>
<span>AI Agent</span>
</span>
<div class="brand-text">
<span class="brand-name">AI Agent</span>
<span class="agent-version" v-if="agentVersion">{{ agentVersion }}</span>
</div>
<div class="status-bottom">
<span class="thinking-chip">{{ thinkingMode ? '思考模式' : '快速模式' }}</span>
<span class="connection-chip" :class="{ connected: isConnected }">
<span class="status-dot" :class="{ active: isConnected }"></span>
{{ isConnected ? '已连接' : '未连接' }}
</div>
<div class="status-indicators">
<span class="mode-indicator"
:class="{ thinking: thinkingMode, fast: !thinkingMode }">
<transition name="mode-icon" mode="out-in">
<span class="icon icon-sm"
:style="iconStyle(thinkingMode ? 'brain' : 'zap')"
:key="thinkingMode ? 'brain' : 'zap'"
aria-hidden="true"></span>
</transition>
</span>
<span class="connection-dot"
:class="{ active: isConnected }"
:title="isConnected ? '已连接' : '未连接'"></span>
</div>
</div>
</div>
</div>

View File

@ -108,7 +108,7 @@ body {
.agent-version {
color: var(--claude-text-secondary);
font-size: 14px;
font-size: 16px;
}
.header-right {
@ -135,19 +135,6 @@ body {
gap: 6px;
}
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--claude-muted);
transition: all 0.3s ease;
}
.status-dot.active {
background: var(--claude-success);
box-shadow: 0 0 8px rgba(118, 176, 134, 0.45);
}
/* 主容器 */
.main-container {
display: flex;
@ -650,47 +637,91 @@ o-conversations {
padding: 14px 16px;
box-shadow: 0 12px 30px rgba(61, 57, 41, 0.12);
display: flex;
flex-direction: column;
gap: 10px;
align-items: center;
}
.status-top {
.status-line {
display: flex;
align-items: center;
justify-content: space-between;
align-items: center;
font-size: 15px;
width: 100%;
gap: 18px;
}
.status-bottom {
.status-brand {
display: flex;
align-items: center;
gap: 12px;
}
.status-logo {
color: var(--claude-accent);
}
.brand-text {
display: flex;
align-items: baseline;
gap: 8px;
font-weight: 600;
color: var(--claude-text);
}
.brand-name {
font-size: 16px;
}
.status-indicators {
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.thinking-chip {
background: var(--claude-accent);
color: #fffef8;
padding: 4px 14px;
border-radius: 999px;
font-size: 12px;
letter-spacing: 0.02em;
}
.connection-chip {
.mode-indicator {
width: 36px;
height: 36px;
border-radius: 18px;
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 12px;
border-radius: 999px;
border: 1px solid rgba(118, 103, 84, 0.3);
font-size: 12px;
color: var(--claude-text-secondary);
justify-content: center;
background: var(--claude-accent);
color: #fffef8;
box-shadow: 0 8px 20px rgba(189, 93, 58, 0.25);
transition: background 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
}
.connection-chip.connected {
border-color: rgba(94, 159, 109, 0.5);
color: var(--claude-text);
.mode-indicator.fast {
background: #ffcc4d;
box-shadow: 0 8px 20px rgba(255, 204, 77, 0.35);
}
.mode-indicator .icon {
--icon-size: 18px;
color: inherit;
}
.connection-dot {
width: 12px;
height: 12px;
border-radius: 6px;
background: var(--claude-muted);
box-shadow: 0 0 0 4px rgba(121, 109, 94, 0.18);
transition: background 0.2s ease, box-shadow 0.2s ease;
}
.connection-dot.active {
background: var(--claude-success);
box-shadow: 0 0 0 6px rgba(118, 176, 134, 0.25);
}
.mode-icon-enter-active,
.mode-icon-leave-active {
transition: opacity 0.2s ease, transform 0.2s ease;
}
.mode-icon-enter-from,
.mode-icon-leave-to {
opacity: 0;
transform: scale(0.5) rotate(8deg);
}
.sidebar-header {