Polish web workspace visual foundation
This commit is contained in:
parent
ff3bc75fed
commit
07eba5c402
|
|
@ -5,6 +5,10 @@
|
|||
> 所以不是每个版本号都有条目。条目格式 `## <版本> — <日期>`,新条目加在最上面。
|
||||
> 工程口径的完整记录见 `PROGRESS.md` / git log。
|
||||
|
||||
## 0.60.8 — 2026-07-29
|
||||
|
||||
- 网页工作台完成一轮整体视觉优化:任务、对话和文件三栏层级更清晰,长回复阅读更舒适,按钮、输入框、弹窗、状态反馈及手机端触控尺寸也更加统一。
|
||||
|
||||
## 0.60.7 — 2026-07-29
|
||||
|
||||
- 新对话的目录选择框现在也能直接创建工作目录:输入新名称后选择创建即可,不再需要旁边的额外按钮和第二个输入框。
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
> 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9`。
|
||||
|
||||
最后更新:2026-07-29(组合框内直接新建目录,bump 0.60.7)
|
||||
最后更新:2026-07-29(Web 工作台 Visual Polish v1,bump 0.60.8)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
### 2026-07-29
|
||||
|
||||
- **07-29 / 0.60.8 / Web 工作台 Visual Polish v1**:新增零构建 `web/static/ui.css` 作为内部轻量视觉基础层,集中颜色、间距、圆角、阴影与 focus/disabled 等控件状态;收敛三栏层级、任务/资源导航、对话正文与工具过程块、输入区、文件栏、modal/toast 及 ≤640px 触控尺寸,不改 DOM 契约、API 或业务交互。新增 CSS 文件接入、MIME 与 `no-cache` 回归测试;相关 Python 20 项 + Node 5 项通过,浏览器连接不可用故截图级视觉验收留真实页面复核。
|
||||
- **07-29 / 0.60.7 / 组合框内直接新建工作目录**:新对话目录 combobox 增加 allow-create 语义:输入时继续过滤已有目录,无完全同名项时在同一下拉内提供“创建工作目录「名称」”,明确选择后才进入新建状态,失焦搜索词不会误提交;删除外部新建按钮与二级输入框。纯前端改动,无 API、schema、migration 或目录绑定语义变化;全量 387 测试通过(17 项按环境跳过)。
|
||||
- **07-29 / 0.60.6 / 新对话目录选择改可搜索组合框**:将上一版独立搜索框 + 原生 select 合并为单一 combobox,同一输入区完成已选目录展示、即时过滤和下拉选择,并补方向键、Enter、Esc、失焦恢复与 ARIA 状态;最近目录置顶、明确选择 working_dir 和新建目录入口均保持不变。纯前端改动,无依赖、API、schema 或 migration;全量 387 测试通过(17 项按环境跳过)。
|
||||
- **07-29 / 0.60.5 / 新对话目录选择提速**:保留首发前明确选择 working_dir 的归档约束;本机最近实际使用目录在候选中自动选中、置顶并标记,目录达到 6 个时按需显示搜索框,目录较少时维持原有简洁界面;同步精简“文件保存位置”文案。纯前端改动,无 API、schema、migration 或目录绑定语义变化;相关静态资源与无 DB 路由 18 项测试通过。
|
||||
|
|
@ -268,7 +269,7 @@ web/{background,scheduler_runner,wechat_runner}.py ← lifespan 后台协程按
|
|||
web/{runs,common,schemas,model_gate,userfiles}.py ← BG worker/共享 helper/请求体/档位门控/路径安全
|
||||
web/auth.py ~190 ← 邮箱密码 + platform_key → JWT
|
||||
web/broker.py / sinks.py / pptx_render.py / admin.py
|
||||
web/static/dev.html + js/*.js ← dev SPA 零构建 ES module(main.js 入口;skills.js=技能 modal;kb.js=知识库 modal)
|
||||
web/static/dev.html + ui.css + js/*.js ← dev SPA 零构建;ui.css=轻量视觉基础层,main.js=入口
|
||||
web/static/vendor/ ~1 MB ← jszip / docx-preview / xlsx
|
||||
tests/ 360 项 ← golden/rendering 基线 + 路由两套(nodb/db)+ DB 套件(ZCBOT_TEST_DB_URL 门控)
|
||||
─────────────────────────────────
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# zcbot 版本号单一事实源:web/app.py 的 FastAPI version、/healthz 返回、前端展示都引这里。
|
||||
# 改版本只动这一行。
|
||||
__version__ = "0.60.7"
|
||||
__version__ = "0.60.8"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from web.static_files import NoCacheStaticFiles
|
|||
ROOT = Path(__file__).resolve().parents[1]
|
||||
STATIC_DIR = ROOT / "web" / "static"
|
||||
DEV_HTML = STATIC_DIR / "dev.html"
|
||||
UI_CSS = STATIC_DIR / "ui.css"
|
||||
JS_DIR = STATIC_DIR / "js"
|
||||
VENDOR_DIR = STATIC_DIR / "vendor" / "markdown"
|
||||
|
||||
|
|
@ -42,6 +43,16 @@ class StaticVendorTests(unittest.TestCase):
|
|||
self.assertTrue(path.exists(), f"missing vendored asset: {path}")
|
||||
self.assertGreater(path.stat().st_size, 0, f"empty vendored asset: {path}")
|
||||
|
||||
def test_dev_html_uses_local_ui_foundation(self) -> None:
|
||||
html = DEV_HTML.read_text(encoding="utf-8")
|
||||
|
||||
self.assertIn('href="ui.css"', html)
|
||||
self.assertTrue(UI_CSS.exists(), f"missing UI foundation: {UI_CSS}")
|
||||
css = UI_CSS.read_text(encoding="utf-8")
|
||||
self.assertIn("--accent:", css)
|
||||
self.assertIn(":focus-visible", css)
|
||||
self.assertIn("@media (max-width: 640px)", css)
|
||||
|
||||
def test_frontend_surfaces_context_and_cache_stats(self) -> None:
|
||||
src = _frontend_source()
|
||||
|
||||
|
|
@ -62,6 +73,18 @@ class StaticVendorTests(unittest.TestCase):
|
|||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(resp.headers.get("cache-control"), "no-cache")
|
||||
|
||||
def test_ui_css_is_served_as_css_with_revalidation(self) -> None:
|
||||
app = FastAPI()
|
||||
app.mount("/static", NoCacheStaticFiles(directory=str(STATIC_DIR)), name="static")
|
||||
client = TestClient(app)
|
||||
|
||||
resp = client.get("/static/ui.css")
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertTrue(resp.headers.get("content-type", "").startswith("text/css"))
|
||||
self.assertEqual(resp.headers.get("cache-control"), "no-cache")
|
||||
self.assertIn("--accent:", resp.text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -13,35 +13,6 @@
|
|||
<link rel="stylesheet" href="vendor/markdown/github.min.css" />
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f7f7f7;
|
||||
--panel: #ffffff;
|
||||
--border: #e3e3e3;
|
||||
--border-soft: #ececec;
|
||||
--text: #222;
|
||||
--muted: #888;
|
||||
--accent: #c0392b;
|
||||
--accent-soft: #fde9e7;
|
||||
--hover: #f0f0f0;
|
||||
--code-bg: #f4f4f4;
|
||||
--user-bg: #eef4fb;
|
||||
--asst-bg: #ffffff;
|
||||
/* 语义色组:done/export/clear/abandon/delete 按钮 + dd-item + badge 共用 */
|
||||
--c-green: #27ae60; --c-green-bg: #e9f7ef; --c-green-bd: #a9dfbf;
|
||||
--c-blue: #2980b9; --c-blue-bg: #ebf5fb; --c-blue-bd: #aed6f1;
|
||||
--c-purple: #8e44ad; --c-purple-bg: #f5eef8; --c-purple-bd: #d2b4de;
|
||||
--c-orange: #e67e22; --c-orange-bg: #fef5e7; --c-orange-bd: #f5cba7;
|
||||
--c-red: #c0392b; --c-red-bg: #fdedec; --c-red-bd: #f5b7b1;
|
||||
/* 圆角:各档下调一档(没那么圆润) */
|
||||
--r-sm: 3px; /* code / 小标签 */
|
||||
--r-md: 4px; /* button / input / 消息气泡 / 卡片元素 */
|
||||
--r-lg: 6px; /* modal card / 中型容器 */
|
||||
--r-xl: 8px; /* 大 modal card(登录卡) */
|
||||
--shadow-card: 0 12px 32px rgba(0,0,0,.18);
|
||||
--shadow-card-lg: 0 20px 60px rgba(0,0,0,.12), 0 2px 6px rgba(0,0,0,.04);
|
||||
--mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace;
|
||||
--t: all .15s;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
html, body { height: 100%; margin: 0; }
|
||||
body {
|
||||
|
|
@ -1518,6 +1489,7 @@
|
|||
button:active:not(:disabled) { transform: none; }
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="ui.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,589 @@
|
|||
/*
|
||||
* zcbot UI foundation
|
||||
*
|
||||
* The application intentionally stays build-free. This file is the shared
|
||||
* visual layer for the main SPA: tokens, control states and restrained
|
||||
* workspace polish. Feature-specific layout remains next to dev.html until
|
||||
* it is reused by a second surface.
|
||||
*/
|
||||
|
||||
:root {
|
||||
color-scheme: light;
|
||||
|
||||
/* Neutral workspace palette */
|
||||
--bg: #f3f5f7;
|
||||
--panel: #ffffff;
|
||||
--panel-subtle: #f8f9fb;
|
||||
--panel-muted: #f4f6f8;
|
||||
--border: #dde2e7;
|
||||
--border-soft: #e9edf1;
|
||||
--text: #20242a;
|
||||
--text-strong: #15181d;
|
||||
--muted: #6f7782;
|
||||
|
||||
/* Institute red is deliberately reserved for primary emphasis. */
|
||||
--accent: #b83a31;
|
||||
--accent-hover: #a9322a;
|
||||
--accent-soft: #fbecea;
|
||||
--accent-ring: rgba(184, 58, 49, 0.16);
|
||||
|
||||
--hover: #f0f3f5;
|
||||
--code-bg: #f3f5f7;
|
||||
--user-bg: #f1f5fa;
|
||||
--asst-bg: #ffffff;
|
||||
|
||||
--c-green: #238653;
|
||||
--c-green-bg: #eaf6ef;
|
||||
--c-green-bd: #a9d9bd;
|
||||
--c-blue: #2d6f9f;
|
||||
--c-blue-bg: #edf5fa;
|
||||
--c-blue-bd: #b5d5e7;
|
||||
--c-purple: #7c5192;
|
||||
--c-purple-bg: #f5eff8;
|
||||
--c-purple-bd: #d8c4e1;
|
||||
--c-orange: #bf6a20;
|
||||
--c-orange-bg: #fdf3e8;
|
||||
--c-orange-bd: #ebc79f;
|
||||
--c-red: #b83a31;
|
||||
--c-red-bg: #fbecea;
|
||||
--c-red-bd: #e7b3ae;
|
||||
|
||||
/* One compact radius and spacing vocabulary. */
|
||||
--r-sm: 4px;
|
||||
--r-md: 6px;
|
||||
--r-lg: 8px;
|
||||
--r-xl: 10px;
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 24px;
|
||||
--space-6: 32px;
|
||||
|
||||
--shadow-float: 0 10px 30px rgba(24, 32, 41, 0.12);
|
||||
--shadow-card: 0 18px 48px rgba(24, 32, 41, 0.16);
|
||||
--shadow-card-lg:
|
||||
0 24px 72px rgba(24, 32, 41, 0.14),
|
||||
0 2px 8px rgba(24, 32, 41, 0.06);
|
||||
--mono: ui-monospace, "Cascadia Code", "SF Mono", Consolas, monospace;
|
||||
--t: background-color 0.15s ease, border-color 0.15s ease,
|
||||
color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 14px;
|
||||
line-height: 1.55;
|
||||
color: var(--text);
|
||||
background: var(--bg);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
textarea,
|
||||
select {
|
||||
transition: var(--t);
|
||||
}
|
||||
|
||||
button {
|
||||
min-height: 32px;
|
||||
padding: 5px 11px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
button.small {
|
||||
min-height: 28px;
|
||||
}
|
||||
|
||||
button:hover:not(:disabled) {
|
||||
border-color: #cbd2d9;
|
||||
}
|
||||
|
||||
button.primary {
|
||||
background: var(--accent);
|
||||
border-color: var(--accent);
|
||||
box-shadow: 0 1px 2px rgba(73, 25, 21, 0.16);
|
||||
}
|
||||
|
||||
button.primary:hover:not(:disabled) {
|
||||
background: var(--accent-hover);
|
||||
border-color: var(--accent-hover);
|
||||
filter: none;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
opacity: 0.46;
|
||||
}
|
||||
|
||||
button:focus-visible,
|
||||
a:focus-visible,
|
||||
input:focus-visible,
|
||||
textarea:focus-visible,
|
||||
select:focus-visible,
|
||||
[tabindex]:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
|
||||
textarea,
|
||||
select {
|
||||
min-height: 34px;
|
||||
border-color: var(--border);
|
||||
}
|
||||
|
||||
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):hover,
|
||||
textarea:hover,
|
||||
select:hover {
|
||||
border-color: #c7ced5;
|
||||
}
|
||||
|
||||
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent);
|
||||
box-shadow: 0 0 0 3px var(--accent-ring);
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: #9aa1aa;
|
||||
}
|
||||
|
||||
/* Application shell */
|
||||
|
||||
#app.ready {
|
||||
background: var(--bg);
|
||||
}
|
||||
|
||||
header {
|
||||
min-height: 48px;
|
||||
padding: 9px 16px;
|
||||
border-bottom-color: var(--border);
|
||||
box-shadow: 0 1px 0 rgba(24, 32, 41, 0.02);
|
||||
}
|
||||
|
||||
header .brand {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
header .brand .logo {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
box-shadow: 0 2px 8px rgba(184, 58, 49, 0.2);
|
||||
}
|
||||
|
||||
header .title {
|
||||
color: var(--text-strong);
|
||||
font-size: 15px;
|
||||
letter-spacing: 0.1px;
|
||||
}
|
||||
|
||||
header .who {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.pane {
|
||||
border-color: var(--border);
|
||||
}
|
||||
|
||||
#pane-left,
|
||||
#pane-right {
|
||||
background: var(--panel-subtle);
|
||||
}
|
||||
|
||||
#pane-mid {
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.splitter {
|
||||
background: var(--bg);
|
||||
}
|
||||
|
||||
.splitter::before {
|
||||
background: #d7dde3;
|
||||
}
|
||||
|
||||
.pane-head {
|
||||
min-height: 44px;
|
||||
padding: 8px 12px;
|
||||
background: rgba(248, 249, 251, 0.96);
|
||||
border-bottom-color: var(--border-soft);
|
||||
}
|
||||
|
||||
.pane-head .label {
|
||||
color: var(--text-strong);
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
#pane-left .pane-head + .pane-head {
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
#task-scroll,
|
||||
#file-list {
|
||||
scrollbar-color: #cbd1d7 transparent;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
/* Task and resource navigation */
|
||||
|
||||
#channel-cards {
|
||||
padding: 8px 10px 4px;
|
||||
}
|
||||
|
||||
.channel-card {
|
||||
border-color: rgba(7, 158, 82, 0.26);
|
||||
background: rgba(7, 158, 82, 0.045);
|
||||
}
|
||||
|
||||
#task-list {
|
||||
padding: 4px 8px 8px;
|
||||
}
|
||||
|
||||
.task-row {
|
||||
margin: 3px 0;
|
||||
padding: 9px 10px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--r-md);
|
||||
}
|
||||
|
||||
.task-row:hover {
|
||||
background: var(--panel);
|
||||
border-color: var(--border-soft);
|
||||
box-shadow: 0 1px 3px rgba(24, 32, 41, 0.04);
|
||||
}
|
||||
|
||||
.task-row.active {
|
||||
padding-left: 8px;
|
||||
background: var(--accent-soft);
|
||||
border-color: #f0d2cf;
|
||||
border-left: 3px solid var(--accent);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.task-row .desc {
|
||||
color: var(--text-strong);
|
||||
}
|
||||
|
||||
.task-row .meta {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.task-row .badge,
|
||||
.sk-badge {
|
||||
border-radius: var(--r-sm);
|
||||
}
|
||||
|
||||
#rail-resources {
|
||||
padding: 8px;
|
||||
border-top-color: var(--border-soft);
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
#rail-resources > button {
|
||||
min-height: 48px;
|
||||
border-color: transparent;
|
||||
color: #59616b;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#rail-resources > button:hover {
|
||||
color: var(--accent);
|
||||
border-color: #f0d2cf;
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
|
||||
/* Menus and lightweight cards */
|
||||
|
||||
#floating-menu,
|
||||
#media-model-pop {
|
||||
border-color: var(--border);
|
||||
border-radius: var(--r-lg);
|
||||
box-shadow: var(--shadow-float);
|
||||
}
|
||||
|
||||
.dd-item {
|
||||
padding: 7px 14px;
|
||||
}
|
||||
|
||||
.dd-item:hover {
|
||||
background: var(--panel-muted);
|
||||
}
|
||||
|
||||
.sk-item {
|
||||
padding: 9px 10px;
|
||||
border-color: var(--border-soft);
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.sk-item:hover {
|
||||
border-color: #d2a09b;
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
|
||||
.sk-item.active {
|
||||
border-color: var(--accent);
|
||||
background: var(--accent-soft);
|
||||
}
|
||||
|
||||
.empty,
|
||||
.sk-empty {
|
||||
color: var(--muted);
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* Conversation: assistant content reads like a document, not a bubble stack. */
|
||||
|
||||
#chat-meta {
|
||||
min-height: 40px;
|
||||
padding: 8px 16px;
|
||||
background: var(--panel);
|
||||
border-bottom-color: var(--border-soft);
|
||||
}
|
||||
|
||||
#chat-stream {
|
||||
gap: 14px;
|
||||
padding: 20px clamp(16px, 3vw, 36px) 24px;
|
||||
background: var(--panel);
|
||||
scrollbar-color: #cbd1d7 transparent;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.msg {
|
||||
padding: 10px 13px;
|
||||
border-color: var(--border-soft);
|
||||
border-radius: var(--r-lg);
|
||||
}
|
||||
|
||||
.msg.user {
|
||||
background: var(--user-bg);
|
||||
border-color: #dce6f0;
|
||||
}
|
||||
|
||||
.msg.assistant {
|
||||
padding: 8px 0;
|
||||
border-color: transparent;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.msg.assistant.live-run {
|
||||
padding: 12px 14px;
|
||||
border-color: rgba(184, 58, 49, 0.2);
|
||||
border-radius: var(--r-lg);
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(184, 58, 49, 0.05),
|
||||
0 8px 24px rgba(184, 58, 49, 0.06);
|
||||
}
|
||||
|
||||
.msg .role {
|
||||
margin-bottom: 4px;
|
||||
color: #7d858f;
|
||||
font-family: inherit;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.2px;
|
||||
}
|
||||
|
||||
.msg .body {
|
||||
color: var(--text);
|
||||
font-size: 15px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.msg .body p {
|
||||
margin: 0.65em 0;
|
||||
}
|
||||
|
||||
.msg .body h1,
|
||||
.msg .body h2,
|
||||
.msg .body h3 {
|
||||
color: var(--text-strong);
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.msg-actions {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.tool-call,
|
||||
.reasoning {
|
||||
color: #4f5863;
|
||||
}
|
||||
|
||||
.tool-call summary,
|
||||
.reasoning summary {
|
||||
padding: 6px 8px;
|
||||
border: 1px solid var(--border-soft);
|
||||
border-radius: var(--r-md);
|
||||
background: var(--panel-muted);
|
||||
}
|
||||
|
||||
.tool-call summary:hover,
|
||||
.reasoning summary:hover {
|
||||
background: var(--hover);
|
||||
}
|
||||
|
||||
.tool-call pre {
|
||||
border: 1px solid var(--border-soft);
|
||||
background: var(--code-bg);
|
||||
}
|
||||
|
||||
#chat-form {
|
||||
gap: 8px;
|
||||
padding: 12px 16px 14px;
|
||||
border-top-color: var(--border-soft);
|
||||
background: var(--panel);
|
||||
box-shadow: 0 -8px 24px rgba(24, 32, 41, 0.035);
|
||||
}
|
||||
|
||||
#chat-input {
|
||||
min-height: 72px;
|
||||
padding: 10px 12px;
|
||||
line-height: 1.6;
|
||||
border-radius: var(--r-lg);
|
||||
background: #fcfcfd;
|
||||
}
|
||||
|
||||
#chat-form .row {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#chat-action {
|
||||
min-width: 64px;
|
||||
}
|
||||
|
||||
/* File pane */
|
||||
|
||||
.crumbs {
|
||||
min-height: 38px;
|
||||
padding: 9px 12px;
|
||||
background: var(--panel);
|
||||
border-bottom-color: var(--border-soft);
|
||||
}
|
||||
|
||||
.file-row {
|
||||
min-height: 38px;
|
||||
padding: 7px 12px;
|
||||
border-bottom-color: var(--border-soft);
|
||||
}
|
||||
|
||||
.file-row:hover {
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.file-row .name {
|
||||
color: #30363d;
|
||||
}
|
||||
|
||||
.storage-foot {
|
||||
padding: 8px 12px;
|
||||
border-top-color: var(--border-soft);
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.storage-foot .bar {
|
||||
height: 5px;
|
||||
background: #e5e9ed;
|
||||
}
|
||||
|
||||
/* Dialogs and notifications */
|
||||
|
||||
.modal {
|
||||
padding: 16px;
|
||||
background: rgba(22, 28, 35, 0.46);
|
||||
}
|
||||
|
||||
.modal > .card {
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.72);
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
#chpw-modal h3,
|
||||
#app-dialog h3,
|
||||
#changelog-modal h3,
|
||||
#skills-modal h3,
|
||||
#wechat-modal h3,
|
||||
#crons-modal h3,
|
||||
#memory-modal h3,
|
||||
#kb-modal h3 {
|
||||
min-height: 48px;
|
||||
padding: 13px 18px;
|
||||
color: var(--text-strong);
|
||||
border-bottom-color: var(--border-soft);
|
||||
}
|
||||
|
||||
#app-dialog .body,
|
||||
#chpw-modal .body {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
#app-dialog .actions,
|
||||
#chpw-modal .actions,
|
||||
#src-picker-modal .actions {
|
||||
padding: 12px 18px;
|
||||
border-top-color: var(--border-soft);
|
||||
background: var(--panel-subtle);
|
||||
}
|
||||
|
||||
.toast,
|
||||
.app-msg {
|
||||
border: 1px solid var(--border-soft);
|
||||
border-radius: var(--r-lg);
|
||||
box-shadow: var(--shadow-float);
|
||||
}
|
||||
|
||||
/* Respect system motion preferences for polish-only transitions too. */
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
button,
|
||||
input,
|
||||
textarea,
|
||||
select {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
header {
|
||||
min-height: 46px;
|
||||
padding: 7px 10px;
|
||||
}
|
||||
|
||||
.pane-head {
|
||||
min-height: 42px;
|
||||
}
|
||||
|
||||
#chat-stream {
|
||||
gap: 12px;
|
||||
padding: 14px 12px 18px;
|
||||
}
|
||||
|
||||
.msg {
|
||||
max-width: 97%;
|
||||
}
|
||||
|
||||
.msg .body {
|
||||
font-size: 15px;
|
||||
line-height: 1.68;
|
||||
}
|
||||
|
||||
#chat-form {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#chat-input {
|
||||
min-height: 64px;
|
||||
}
|
||||
|
||||
#chat-form .row button {
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
.modal {
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue