/* ============================================================ 工作区菜单重设计 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; } }