agent-Specialization/demo/workspace_menu_redesign/style.css
JOJO b593d63856 feat(frontend): 侧边栏紧凑化与挤压式重设计,移除工作区面板功能拆分
- 对话侧边栏:行高/字号/圆角紧凑化,fixed 覆盖式改为文档流挤压式展开,移除工作区/虚拟显示器按钮
- 新增 WorkspaceSwitcher 浮层组件:列表即切换器,内联重命名/删除确认/新建表单动画,「…」菜单 fixed 逃逸裁切,刚好 7 行内部滚动
- 移除 LeftPanel 及两个旧工作区对话框:管理工作区迁入侧边栏,文件管理迁入输入栏 + 菜单(最多 4 项滚动)
- 个人空间移除默认隐藏工作区/隐藏快捷窗口设置项;删除 panelMode 门控轮询(QuickDock 常驻轮询 + socket 推送替代)
- 修复 flex 压缩导致菜单行高失效、分组对话 viewport 裁切最后一行、action-wrap 撑高对话项、/new 残留最近对话待办(无对话 id 不再请求 todo-list)
- 工作区入口按钮改内联 layers 图标并统一 18px,host/docker 模式 localStorage 缓存避免按钮首屏延迟出现
2026-07-23 16:47:49 +08:00

667 lines
17 KiB
CSS
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.

/* ============================================================
工作区菜单重设计 Demo — 样式
颜色全部走三主题语义 token与 static/src/styles/base/_tokens.scss 对齐)
============================================================ */
/* ---------- 主题 token取自项目真实值 ---------- */
:root[data-theme='classic'] {
--surface-base: #faf9f5;
--surface-panel: #faf9f5;
--surface-rail: #f5f0e8;
--surface-sidebar: #f5f0e8;
--surface-card: #efe9de;
--surface-raised: #ffffff;
--surface-soft: #f5f0e8;
--surface-muted: #e8e0d2;
--text-primary: #141413;
--text-secondary: #3d3d3a;
--text-tertiary: #6c6a64;
--text-muted: rgba(108, 106, 100, 0.55);
--border-default: #e6dfd8;
--border-strong: #d8cfc4;
--border-card-strong: #e6dfd8;
--accent: #cc785c;
--accent-strong: #a9583e;
--accent-hover: #bd6a4f;
--accent-active: #a9583e;
--on-accent: #ffffff;
--state-success: #10b981;
--state-warning: #f59e0b;
--state-danger: #dc2626;
--state-danger-strong: #b91c1c;
--shadow-pop: 0 1px 2px rgba(60, 50, 40, 0.06), 0 12px 32px rgba(60, 50, 40, 0.1);
--shadow-card: 0 1px 2px rgba(60, 50, 40, 0.05);
}
:root[data-theme='light'] {
--surface-base: #ffffff;
--surface-panel: #ffffff;
--surface-rail: #f9f9f9;
--surface-sidebar: #f9f9f9;
--surface-card: #ffffff;
--surface-raised: #ffffff;
--surface-soft: #f9f9f9;
--surface-muted: #f3f3f3;
--text-primary: #0d0d0d;
--text-secondary: #5d5d5d;
--text-tertiary: #8f8f8f;
--text-muted: rgba(13, 13, 13, 0.35);
--border-default: rgba(13, 13, 13, 0.1);
--border-strong: rgba(13, 13, 13, 0.15);
--border-card-strong: rgba(13, 13, 13, 0.1);
--accent: #181818;
--accent-strong: #181818;
--accent-hover: #303030;
--accent-active: #414141;
--on-accent: #ffffff;
--state-success: #10b981;
--state-warning: #f59e0b;
--state-danger: #dc2626;
--state-danger-strong: #b91c1c;
--shadow-pop: 0 1px 2px rgba(0, 0, 0, 0.05), 0 12px 32px rgba(0, 0, 0, 0.1);
--shadow-card: 0 1px 2px rgba(0, 0, 0, 0.05);
}
:root[data-theme='dark'] {
--surface-base: #1a1a1a;
--surface-panel: #1a1a1a;
--surface-rail: #181818;
--surface-sidebar: #181818;
--surface-card: #0a0a0a;
--surface-raised: #242424;
--surface-soft: #0f0f0f;
--surface-muted: #141414;
--text-primary: #ffffff;
--text-secondary: #a0a0a0;
--text-tertiary: #707070;
--text-muted: rgba(255, 255, 255, 0.3);
--border-default: rgba(255, 255, 255, 0.08);
--border-strong: rgba(255, 255, 255, 0.12);
--border-card-strong: rgba(255, 255, 255, 0.1);
--accent: #606060;
--accent-strong: #505050;
--accent-hover: #707070;
--accent-active: #505050;
--on-accent: #ffffff;
--state-success: #10b981;
--state-warning: #f59e0b;
--state-danger: #dc2626;
--state-danger-strong: #b91c1c;
--shadow-pop: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.5);
--shadow-card: 0 1px 2px rgba(0, 0, 0, 0.35);
}
/* ---------- 基础 ---------- */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Segoe UI', 'Helvetica Neue', sans-serif;
background: var(--surface-base);
color: var(--text-primary);
font-size: 13px;
line-height: 1.45;
-webkit-font-smoothing: antialiased;
transition: background 160ms ease, color 160ms ease;
}
button {
font: inherit;
color: inherit;
background: none;
border: 0;
cursor: pointer;
}
input {
font: inherit;
color: var(--text-primary);
background: transparent;
border: 0;
outline: none;
}
svg { display: block; width: 100%; height: 100%; }
/* ============================================================
Demo 外框(非产品部分)
============================================================ */
.demo-chrome {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 14px 20px;
border-bottom: 1px solid var(--border-default);
}
.demo-chrome-title { display: flex; flex-direction: column; gap: 2px; }
.demo-chrome-title strong { font-size: 14px; font-weight: 600; }
.demo-chrome-title span { font-size: 12px; color: var(--text-tertiary); }
.demo-chrome-controls { display: flex; align-items: center; gap: 10px; }
.demo-theme-switch {
display: flex;
gap: 2px;
padding: 2px;
border: 1px solid var(--border-default);
border-radius: 8px;
background: var(--surface-soft);
}
.demo-theme-switch button {
height: 26px;
padding: 0 12px;
border-radius: 6px;
font-size: 12px;
color: var(--text-secondary);
}
.demo-theme-switch button.active {
background: var(--surface-raised);
color: var(--text-primary);
box-shadow: var(--shadow-card);
}
.demo-stage {
display: grid;
grid-template-columns: minmax(0, 1fr) 300px;
gap: 24px;
padding: 24px;
align-items: start;
}
.stage-canvas {
position: relative;
min-height: 560px;
border: 1px solid var(--border-default);
border-radius: 12px;
background: var(--surface-panel);
overflow: hidden;
}
.stage-status {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 34px;
display: flex;
align-items: center;
padding: 0 14px;
border-top: 1px solid var(--border-default);
background: var(--surface-soft);
color: var(--text-tertiary);
font-size: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* ============================================================
侧边栏 Mock紧凑化后的未来形态
============================================================ */
.sidebar-mock {
width: 232px;
height: 526px; /* 560 - 状态条 34 */
display: flex;
flex-direction: column;
background: var(--surface-sidebar);
border-right: 1px solid var(--border-default);
}
.side-nav { padding: 8px; display: flex; flex-direction: column; gap: 1px; }
.side-nav-row {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
height: 30px; /* 紧凑化:原 ~36px */
padding: 0 8px;
border-radius: 6px; /* 紧凑化:原 ~10px */
color: var(--text-secondary);
font-size: 12.5px;
text-align: left;
}
.side-nav-row:hover { background: color-mix(in srgb, var(--text-primary) 5%, transparent); }
.side-nav-row.active {
background: color-mix(in srgb, var(--text-primary) 7%, transparent);
color: var(--text-primary);
}
.side-icon {
flex: none;
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.side-icon svg { width: 15px; height: 15px; }
.side-label { flex: none; }
.side-current {
margin-left: auto;
min-width: 0;
max-width: 88px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 11px;
color: var(--text-tertiary);
}
.side-search {
display: flex;
align-items: center;
gap: 7px;
margin: 0 8px;
height: 28px;
padding: 0 8px;
border: 1px solid var(--border-default);
border-radius: 6px;
color: var(--text-tertiary);
}
.side-search .side-icon svg { width: 13px; height: 13px; }
.side-search input { flex: 1; min-width: 0; font-size: 12px; }
.side-search input::placeholder { color: var(--text-muted); }
.side-list {
flex: 1;
min-height: 0;
overflow-y: auto;
padding: 8px; /* 与左右间距一致hover 圆角四边均匀 */
display: flex;
flex-direction: column;
gap: 1px;
}
.conv-row {
display: flex;
align-items: center;
gap: 6px;
height: 27px; /* 紧凑化:原 ~34px */
padding: 0 8px;
border-radius: 6px;
font-size: 12px;
color: var(--text-secondary);
cursor: pointer;
}
.conv-row:hover { background: color-mix(in srgb, var(--text-primary) 4%, transparent); }
.conv-row.active {
background: color-mix(in srgb, var(--text-primary) 7%, transparent);
color: var(--text-primary);
}
.conv-title {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.conv-dot {
flex: none;
width: 5px;
height: 5px;
border-radius: 50%;
background: var(--state-success);
}
.side-footer { padding: 8px; border-top: 1px solid var(--border-default); }
/* ============================================================
工作区浮层(重设计主体)
============================================================ */
.ws-popover {
--ws-row-h: 50px;
position: absolute;
width: 300px;
display: flex;
flex-direction: column;
border: 1px solid var(--border-default);
border-radius: 12px;
background: var(--surface-raised);
box-shadow: var(--shadow-pop);
overflow: hidden;
opacity: 0;
transform: translateY(-4px) scale(0.98);
transform-origin: top left;
pointer-events: none;
transition: opacity 120ms ease, transform 150ms cubic-bezier(0.22, 1, 0.36, 1);
}
.ws-popover.open {
opacity: 1;
transform: translateY(0) scale(1);
pointer-events: auto;
}
.ws-popover.docker { --ws-row-h: 38px; }
/* 头部:安静的类型标题,发丝线分隔 */
.ws-header {
flex: none;
display: flex;
align-items: center;
justify-content: space-between;
height: 42px;
padding: 0 14px;
border-bottom: 1px solid var(--border-default);
}
.ws-header-title { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.ws-header-count { font-size: 11px; color: var(--text-tertiary); }
/* 列表:最多显示 5 个工作区超出内部滚动padding 四边一致保证 hover 圆角均匀 */
.ws-list {
flex: none;
max-height: calc(var(--ws-row-h) * 5 + 16px); /* 5行 + 4条1px间隔 + 上下各6px padding */
overflow-y: auto;
padding: 6px;
display: flex;
flex-direction: column;
gap: 1px;
scrollbar-width: thin;
scrollbar-color: var(--border-strong) transparent;
}
.ws-list::-webkit-scrollbar { width: 8px; }
.ws-list::-webkit-scrollbar-thumb {
background: var(--border-strong);
border-radius: 4px;
border: 2px solid var(--surface-raised);
}
.ws-list::-webkit-scrollbar-track { background: transparent; }
/* 工作区行:可选项,固定高度,宿主机两行 / Docker 单行 */
.ws-row {
position: relative;
display: flex;
align-items: center;
gap: 10px;
width: 100%;
height: var(--ws-row-h);
padding: 0 8px;
border-radius: 8px;
text-align: left;
cursor: pointer;
}
.ws-row:hover { background: color-mix(in srgb, var(--text-primary) 4%, transparent); }
.ws-row.current { background: color-mix(in srgb, var(--text-primary) 6%, transparent); }
.ws-row.current:hover { background: color-mix(in srgb, var(--text-primary) 7%, transparent); }
.ws-row-icon {
flex: none;
width: 17px;
height: 17px;
margin-top: -13px; /* 与首行文字视觉对齐,而非两行整体居中 */
color: var(--text-tertiary);
}
.ws-row.docker .ws-row-icon { margin-top: 0; }
.ws-row.current .ws-row-icon { color: var(--text-secondary); }
.ws-row-text {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 1px;
}
.ws-row-name {
font-size: 13px;
font-weight: 500;
color: var(--text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ws-row-path {
font-size: 11.5px;
color: var(--text-tertiary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ws-row-meta {
flex: none;
display: flex;
align-items: center;
gap: 8px;
}
.ws-tag {
font-size: 11px;
color: var(--text-tertiary);
white-space: nowrap;
}
/* 行尾「…」:仅 hover / 菜单展开时出现 */
.ws-more {
flex: none;
width: 24px;
height: 24px;
display: none;
align-items: center;
justify-content: center;
border-radius: 6px;
color: var(--text-tertiary);
}
.ws-more svg { width: 15px; height: 15px; }
.ws-more:hover { color: var(--text-primary); background: color-mix(in srgb, var(--text-primary) 7%, transparent); }
.ws-row:hover .ws-more,
.ws-row.menu-open .ws-more { display: flex; }
/* 「…」二级菜单fixed 浮层,逃逸浮层裁切(同个人空间二级菜单方案) */
.ws-menu-floating {
position: fixed;
z-index: 3000;
min-width: 136px;
padding: 4px;
border: 1px solid var(--border-default);
border-radius: 10px;
background: var(--surface-raised);
box-shadow: var(--shadow-pop);
display: none;
flex-direction: column;
opacity: 0;
transform: translateY(-3px) scale(0.98);
transform-origin: top right;
transition: opacity 110ms ease, transform 140ms cubic-bezier(0.22, 1, 0.36, 1);
}
.ws-menu-floating.open { opacity: 1; transform: translateY(0) scale(1); }
.ws-menu-floating button {
display: flex;
align-items: center;
width: 100%;
height: 30px;
padding: 0 10px;
border-radius: 6px;
font-size: 12.5px;
color: var(--text-secondary);
text-align: left;
white-space: nowrap;
}
.ws-menu-floating button:hover { background: color-mix(in srgb, var(--text-primary) 5%, transparent); color: var(--text-primary); }
.ws-menu-floating button.danger { color: var(--state-danger); }
.ws-menu-floating button.danger:hover { background: color-mix(in srgb, var(--state-danger) 8%, transparent); }
.ws-menu-floating button:disabled { color: var(--text-muted); cursor: default; }
.ws-menu-floating button:disabled:hover { background: none; color: var(--text-muted); }
.ws-menu-sep { height: 1px; margin: 4px 6px; background: var(--border-default); }
/* 重命名内联输入:替换名称文字 */
.ws-rename-input {
font-size: 13px;
font-weight: 500;
color: var(--text-primary);
border-bottom: 1px solid var(--accent);
padding: 1px 0;
width: 100%;
}
/* 删除确认内联:整行内容替换 */
.ws-confirm {
display: flex;
flex-direction: column;
gap: 5px;
width: 100%;
padding: 2px 0;
}
.ws-confirm-text {
font-size: 12px;
color: var(--text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ws-confirm-actions { display: flex; gap: 8px; }
/* 通用小按钮 */
.ws-btn {
height: 26px;
padding: 0 10px;
border-radius: 6px;
font-size: 12px;
border: 1px solid var(--border-strong);
color: var(--text-secondary);
white-space: nowrap;
}
.ws-btn:hover { background: color-mix(in srgb, var(--text-primary) 5%, transparent); }
.ws-btn.primary {
background: var(--accent);
border-color: var(--accent);
color: var(--on-accent);
}
.ws-btn.primary:hover { background: var(--accent-hover); }
.ws-btn.danger {
background: var(--state-danger);
border-color: var(--state-danger);
color: #ffffff;
}
.ws-btn.danger:hover { background: var(--state-danger-strong); }
.ws-btn.ghost { border-color: var(--border-default); }
/* 底部区域:新建按钮 ⇄ 新建表单,容器高度动画 */
.ws-bottom {
flex: none;
border-top: 1px solid var(--border-default);
overflow: hidden;
transition: height 200ms cubic-bezier(0.22, 1, 0.36, 1);
}
.ws-footer { padding: 6px; transition: opacity 130ms ease; }
.ws-footer.fading { opacity: 0; }
.ws-create-btn {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
height: 34px;
padding: 0 8px;
border-radius: 8px;
font-size: 12.5px;
color: var(--text-secondary);
}
.ws-create-btn:hover { background: color-mix(in srgb, var(--text-primary) 4%, transparent); color: var(--text-primary); }
.ws-create-icon { flex: none; width: 15px; height: 15px; color: var(--text-tertiary); }
.ws-create-btn:hover .ws-create-icon { color: var(--text-secondary); }
/* 新建表单:内联,平铺无卡片 */
.ws-create-form {
display: flex;
flex-direction: column;
gap: 8px;
padding: 10px;
transition: opacity 150ms ease;
}
.ws-create-form.fading { opacity: 0; }
.ws-create-form input {
height: 32px;
padding: 0 10px;
border: 1px solid var(--border-default);
border-radius: 8px;
font-size: 12.5px;
background: var(--surface-soft);
}
.ws-create-form input:focus { border-color: var(--accent); }
.ws-create-form input::placeholder { color: var(--text-muted); }
.ws-create-actions { display: flex; justify-content: flex-end; gap: 8px; }
/* 隐藏互斥切换 */
.ws-footer[hidden], .ws-create-form[hidden] { display: none; }
/* ============================================================
设计说明栏
============================================================ */
.stage-notes {
border: 1px solid var(--border-default);
border-radius: 12px;
background: var(--surface-soft);
padding: 16px 18px;
font-size: 12.5px;
color: var(--text-secondary);
}
.stage-notes h2 {
font-size: 12px;
font-weight: 600;
color: var(--text-tertiary);
margin: 14px 0 8px;
letter-spacing: 0.02em;
}
.stage-notes h2:first-child { margin-top: 0; }
.stage-notes ul { list-style: none; display: flex; flex-direction: column; gap: 7px; }
.stage-notes li { padding-left: 12px; position: relative; line-height: 1.55; }
.stage-notes li::before {
content: '';
position: absolute;
left: 0;
top: 8px;
width: 4px;
height: 4px;
border-radius: 50%;
background: var(--text-muted);
}
.stage-notes li b { color: var(--text-primary); font-weight: 600; }
.notes-compare li { color: var(--text-tertiary); }
@media (max-width: 980px) {
.demo-stage { grid-template-columns: 1fr; }
}