wezard 2.1.4 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -8
- package/dist/daemon/cc-session.js +14 -1
- package/dist/daemon/cc-session.js.map +1 -1
- package/dist/daemon/detail.js +28 -7
- package/dist/daemon/detail.js.map +1 -1
- package/dist/daemon/handoff.js +132 -0
- package/dist/daemon/handoff.js.map +1 -0
- package/dist/daemon/inbound.js +2 -1
- package/dist/daemon/inbound.js.map +1 -1
- package/dist/daemon/index.js +191 -99
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/mirror-bridge.js +136 -12
- package/dist/daemon/mirror-bridge.js.map +1 -1
- package/dist/daemon/peers.js +114 -34
- package/dist/daemon/peers.js.map +1 -1
- package/dist/daemon/receipts.js +190 -0
- package/dist/daemon/receipts.js.map +1 -0
- package/dist/daemon/route.js +92 -0
- package/dist/daemon/route.js.map +1 -0
- package/dist/daemon/wizard.js +38 -19
- package/dist/daemon/wizard.js.map +1 -1
- package/dist/mcp/server.js +60 -25
- package/dist/mcp/server.js.map +1 -1
- package/dist/shared/chat-http.js +101 -21
- package/dist/shared/chat-http.js.map +1 -1
- package/dist/shared/chat-render.js +0 -1
- package/dist/shared/chat-render.js.map +1 -1
- package/dist/shared/chat-view.js +2 -9
- package/dist/shared/chat-view.js.map +1 -1
- package/dist/shared/config.js +6 -0
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/detail-render.js +3 -2
- package/dist/shared/detail-render.js.map +1 -1
- package/dist/shared/detail-store.js +1 -1
- package/dist/shared/detail-store.js.map +1 -1
- package/dist/shared/keepalive.js +46 -0
- package/dist/shared/keepalive.js.map +1 -0
- package/dist/shared/reminder.js +13 -0
- package/dist/shared/reminder.js.map +1 -1
- package/dist/shared/role-render.js +2 -1
- package/dist/shared/role-render.js.map +1 -1
- package/dist/shared/role-search.js +100 -0
- package/dist/shared/role-search.js.map +1 -0
- package/dist/shared/role-view.js +85 -26
- package/dist/shared/role-view.js.map +1 -1
- package/dist/shared/world.js +38 -8
- package/dist/shared/world.js.map +1 -1
- package/dist/svr/index.js +1 -1
- package/dist/svr/index.js.map +1 -1
- package/package.json +1 -1
- package/web/chat.css +407 -327
- package/web/chat.js +897 -726
package/web/chat.css
CHANGED
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
--mine-line: #c9d7f3;
|
|
19
19
|
--accent: #2f55c9; /* 视角色: 名字的点、选中态、自己的气泡描边 */
|
|
20
20
|
--priv: #9a5b10; /* 私聊 */
|
|
21
|
+
/* 头像底: 不透明, 且由 card/accent 推出 —— 叠在选中/高亮/关系图任何底色上都不变色, 换主题时随 token 走。 */
|
|
22
|
+
--av-bg: var(--card);
|
|
23
|
+
--av-line: var(--line);
|
|
24
|
+
--av-hot: color-mix(in srgb, var(--accent) 14%, var(--card));
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
html { height: 100% }
|
|
@@ -47,59 +51,73 @@ button { font: inherit; color: inherit }
|
|
|
47
51
|
|
|
48
52
|
/* ── 左栏顶: 当前 role 的名片 (身份); 关系/日程入口是名片下、会话列表上的一排 ──── */
|
|
49
53
|
.rolebar {
|
|
50
|
-
|
|
54
|
+
/* margin 归零: 通用 header 规则带着 8px 下边距, 会把下面的入口条顶得上宽下窄。 */
|
|
55
|
+
position: relative; flex: none; margin: 0; padding: 16px 16px 14px; border-bottom: 1px solid var(--line);
|
|
51
56
|
display: flex; flex-direction: column; gap: 8px; background: var(--card);
|
|
57
|
+
/* 通用 header 规则带着 flex-wrap:wrap + align-items:baseline —— 竖轴上那会让名片按内容撑宽 (max-content),
|
|
58
|
+
长名字 / 长路径就冲出侧栏。 */
|
|
59
|
+
flex-wrap: nowrap; align-items: stretch;
|
|
52
60
|
}
|
|
61
|
+
.rolebar > .who { min-width: 0 }
|
|
53
62
|
.rolebar .id { display: flex; gap: 10px; align-items: center; min-width: 0 }
|
|
54
63
|
.rolebar .id .av { font-size: 26px; line-height: 1; flex: none }
|
|
55
64
|
.rolebar .id .l { min-width: 0; display: flex; flex-direction: column; gap: 2px }
|
|
56
65
|
.rolebar .id .nm { font-size: 18px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
57
|
-
.rolebar .id .k { font-size: 11.5px; color: var(--mute) }
|
|
58
|
-
/*
|
|
59
|
-
.rolebar .
|
|
60
|
-
.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.rolebar .
|
|
66
|
-
.rolebar .st.off { color: var(--faint) }
|
|
67
|
-
.rolebar .st.off::before { background: transparent; box-shadow: inset 0 0 0 1.5px #b1bac4 }
|
|
68
|
-
.rolebar .job { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ink); opacity: .8 }
|
|
69
|
-
.rolebar .facts { display: flex; gap: 6px 12px; flex-wrap: wrap; font-size: 11.5px; color: var(--mute) }
|
|
70
|
-
.rolebar .facts span { white-space: nowrap }
|
|
66
|
+
.rolebar .id .k { font-size: 11.5px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
67
|
+
/* 职责是一句话, 至多两行; 截掉的悬停看全文 (chat.js 的截断提示)。 */
|
|
68
|
+
.rolebar .job {
|
|
69
|
+
margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ink); opacity: .8; word-break: break-word;
|
|
70
|
+
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
|
|
71
|
+
}
|
|
72
|
+
.rolebar .facts { display: flex; gap: 6px 12px; flex-wrap: wrap; font-size: 11.5px; color: var(--mute); min-width: 0 }
|
|
73
|
+
/* 每条事实自身不折行, 一行排不下就落到下一行; 独占一行仍超宽 (长路径 / 长群名) 才省略。 */
|
|
74
|
+
.rolebar .facts span { white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis }
|
|
71
75
|
.rolebar .go { cursor: pointer; color: var(--accent) }
|
|
72
76
|
.rolebar .go:hover { text-decoration: underline }
|
|
73
|
-
|
|
77
|
+
/* 分隔线两端收进来, 与上面搜索框的左右边距对齐, 不顶满侧栏。 */
|
|
78
|
+
.acts { flex: none; display: flex; justify-content: center; align-items: center; gap: 2px; margin: 0 10px; padding: 4px 0 8px; border-bottom: 1px solid var(--line) }
|
|
74
79
|
.acts:empty { display: none }
|
|
75
80
|
/* 旧外壳 (daemon 未重启) 里它还在名片内 —— 那里不需要自己的内边距与分隔线。 */
|
|
76
|
-
.rolebar .acts { padding: 0; border: 0 }
|
|
77
|
-
/*
|
|
81
|
+
.rolebar .acts { margin: 0; padding: 0; border: 0 }
|
|
82
|
+
/* 入口: 图标 + 名字 + 淡色副标题, 无框无底; hover 才浮出一层浅底, 打开着的染视角色。 */
|
|
78
83
|
.bd {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
.bd
|
|
83
|
-
.bd
|
|
84
|
-
.bd
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
flex: none; padding: 1px 4px; border: 0; border-radius: 4px; background: none; cursor: pointer; white-space: nowrap;
|
|
85
|
+
font-size: 12px; color: var(--mute); transition: color .12s;
|
|
86
|
+
}
|
|
87
|
+
.bd:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 3px }
|
|
88
|
+
.bd.on { color: var(--accent); font-weight: 600 }
|
|
89
|
+
.bd.bad { color: #cf222e }
|
|
90
|
+
.acts .sep { color: var(--line); font-size: 12px; user-select: none }
|
|
91
|
+
/* session 切换: name 右边一个小号文字触发器 + 浮层列表。name 先省略, 触发器不让位。 */
|
|
92
|
+
.rolebar .id .l { flex: 1 }
|
|
93
|
+
.rolebar .nl { display: flex; align-items: center; gap: 8px; min-width: 0 }
|
|
94
|
+
#rb-st { flex: none; display: inline-flex }
|
|
95
|
+
.rolebar .nl .nm { min-width: 0; flex: 0 1 auto }
|
|
96
|
+
.rolebar .nl .cp { min-width: 0; flex: 0 1 auto; display: inline-flex; cursor: copy }
|
|
97
|
+
.rolebar .nl .cp:hover .nm { text-decoration: underline dotted var(--faint); text-underline-offset: 3px }
|
|
98
|
+
.toast {
|
|
99
|
+
position: fixed; left: 50%; bottom: 28px; z-index: 1000; transform: translate(-50%, 8px);
|
|
100
|
+
padding: 6px 12px; border-radius: 8px; font-size: 12.5px; color: #fff; background: rgba(28, 36, 48, .88);
|
|
101
|
+
opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s;
|
|
102
|
+
}
|
|
103
|
+
.toast.on { opacity: 1; transform: translate(-50%, 0) }
|
|
104
|
+
#rb-sp { flex: none; display: inline-flex }
|
|
105
|
+
.sp { position: relative; display: inline-flex }
|
|
87
106
|
.sp-btn {
|
|
88
|
-
|
|
89
|
-
font-size:
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
.sp-btn:hover, .sp.open .sp-btn {
|
|
93
|
-
|
|
94
|
-
.sp-btn .lb { font-size: 10px; color: var(--faint); text-transform: uppercase; letter-spacing: .4px; flex: none }
|
|
95
|
-
.sp-btn .v { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums }
|
|
107
|
+
display: inline-flex; align-items: center; gap: 2px; cursor: pointer; white-space: nowrap;
|
|
108
|
+
font-size: 11.5px; color: var(--mute); background: none; border: 0; border-radius: 5px; padding: 1px 4px;
|
|
109
|
+
font-variant-numeric: tabular-nums; transition: background .12s, color .12s;
|
|
110
|
+
}
|
|
111
|
+
.sp-btn:hover, .sp.open .sp-btn { background: var(--paper); color: var(--ink) }
|
|
112
|
+
/* 箭头用边框画, 不用 ▾ 字形 —— 字形贴着基线, 放大后总是偏下。 */
|
|
96
113
|
.sp-btn .car {
|
|
97
|
-
|
|
98
|
-
|
|
114
|
+
width: 0; height: 0; margin-left: 3px; border: 5px solid transparent; border-top: 6px solid var(--faint); border-bottom: 0;
|
|
115
|
+
transition: transform .15s;
|
|
99
116
|
}
|
|
100
|
-
.sp.open .sp-btn .car { transform: rotate(
|
|
117
|
+
.sp.open .sp-btn .car { transform: rotate(180deg) }
|
|
101
118
|
.sp-list {
|
|
102
|
-
|
|
119
|
+
/* 以触发器左下角为锚向右下展开 —— 触发器贴着 name 右边, 朝左开会被侧栏左沿裁掉。 */
|
|
120
|
+
position: absolute; z-index: 20; left: 0; top: calc(100% + 4px); width: 196px; max-width: calc(100vw - 24px);
|
|
103
121
|
max-height: 280px; overflow-y: auto; overscroll-behavior: contain;
|
|
104
122
|
background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 4px;
|
|
105
123
|
box-shadow: 0 8px 24px #1c24301f, 0 2px 6px #1c24300f;
|
|
@@ -107,45 +125,46 @@ button { font: inherit; color: inherit }
|
|
|
107
125
|
}
|
|
108
126
|
.sp.open .sp-list { opacity: 1; transform: none; pointer-events: auto }
|
|
109
127
|
.sp-it {
|
|
110
|
-
width: 100%; display:
|
|
128
|
+
width: 100%; display: flex; gap: 10px; align-items: baseline;
|
|
111
129
|
background: none; border: 0; border-radius: 6px; padding: 6px 8px; cursor: pointer; text-align: left; font-size: 12px;
|
|
112
130
|
}
|
|
113
131
|
.sp-it:hover { background: var(--paper) }
|
|
114
132
|
.sp-it.on { background: var(--mine); color: var(--accent) }
|
|
115
|
-
.sp-it .id {
|
|
116
|
-
.sp-it .
|
|
117
|
-
.sp-it .n { color: var(--faint); font-variant-numeric: tabular-nums; grid-column: 3 }
|
|
133
|
+
.sp-it .id { flex: 1; min-width: 0; font-variant-numeric: tabular-nums }
|
|
134
|
+
.sp-it .n { flex: none; color: var(--faint); font-variant-numeric: tabular-nums }
|
|
118
135
|
.sp-it.all { border-bottom: 1px solid var(--line); border-radius: 6px 6px 0 0; margin-bottom: 3px }
|
|
119
|
-
.sp-it.all .id { font-family: inherit }
|
|
120
|
-
|
|
121
|
-
/* 左栏底: session 切换 —— 轮次的事, 与顶上的身份分开, 钉在会话列表下面。 */
|
|
122
|
-
.sidefoot { flex: none; border-top: 1px solid var(--line); padding: 10px 12px; background: var(--paper) }
|
|
123
|
-
/* 在底部, 浮层往上开。 */
|
|
124
|
-
.sidefoot .sp-list { top: auto; bottom: calc(100% + 4px); transform: translateY(4px) }
|
|
125
|
-
.sidefoot .sp.open .sp-list { transform: none }
|
|
126
136
|
|
|
127
137
|
/* ── 用量条: 一组轮次的总账 ─────────────────────────────────────────
|
|
128
138
|
一个组件两处挂: 整页页脚 (wizard 的总账) / 聊天窗口底 (人与某个 wizard 这段往来的账)。
|
|
129
|
-
|
|
130
|
-
|
|
139
|
+
永远单行: 主人 · 模型 · 指标 · 图例, I/O 分布是贴底的色带。排不下时 chat.js 的 fitUsage
|
|
140
|
+
按容器宽度一级级加 f-* 藏掉次要的 (分布文字 → 名字 → 耗时), 不按视口断点。 */
|
|
131
141
|
.usage {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
142
|
+
/* 整条只有一个字号、一个间隔: 指标、模型名、主人、图例都用它。 */
|
|
143
|
+
--u-gap: 14px;
|
|
144
|
+
flex: none; display: flex; align-items: center; flex-wrap: nowrap; gap: var(--u-gap); overflow: hidden; white-space: nowrap;
|
|
145
|
+
position: relative; padding: 7px 20px 9px; border-top: 1px solid var(--line); background: var(--paper);
|
|
146
|
+
font-family: ui-monospace, Menlo, monospace; font-size: 11.5px; color: var(--mute);
|
|
135
147
|
font-variant-numeric: tabular-nums;
|
|
136
148
|
}
|
|
137
|
-
.usage b { font-weight:
|
|
138
|
-
.usage
|
|
139
|
-
.usage .u-
|
|
140
|
-
.usage .
|
|
141
|
-
.usage .
|
|
142
|
-
.usage .u-
|
|
143
|
-
.usage .
|
|
144
|
-
.usage .
|
|
145
|
-
|
|
149
|
+
.usage b { font-weight: 400; color: var(--ink) }
|
|
150
|
+
.usage > * { flex: none }
|
|
151
|
+
.usage .u-who { display: flex; align-items: center; gap: 4px; max-width: 200px }
|
|
152
|
+
.usage .u-nm { overflow: hidden; text-overflow: ellipsis; color: var(--faint) }
|
|
153
|
+
.usage .u-lb { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; color: var(--accent) }
|
|
154
|
+
.usage .u-ic { font-style: normal; margin-right: 4px }
|
|
155
|
+
.usage .u-kvs, .usage .leg { display: flex; gap: var(--u-gap) }
|
|
156
|
+
.usage .kv { white-space: nowrap }
|
|
157
|
+
/* I/O 分布 = bar 的底边: 横跨整宽的细色带, 不占行; 悬停加粗一点好瞄准某一段。 */
|
|
158
|
+
.usage .bar {
|
|
159
|
+
position: absolute; left: 0; right: 0; bottom: 0; height: 3px; display: flex;
|
|
160
|
+
background: var(--line); transition: height .12s;
|
|
161
|
+
}
|
|
162
|
+
.usage .bar:hover { height: 6px }
|
|
163
|
+
.usage .bar .seg { flex: 1 1 0; min-width: 2px; height: 100% }
|
|
164
|
+
.usage .leg { margin-left: auto }
|
|
146
165
|
.usage .lg { display: flex; align-items: center; gap: 4px; white-space: nowrap }
|
|
147
|
-
.usage .lg i { width:
|
|
148
|
-
.usage .
|
|
166
|
+
.usage .lg i { width: 7px; height: 7px; border-radius: 50%; flex: none }
|
|
167
|
+
.usage.f-leg .leg, .usage.f-nm .u-nm, .usage.f-time .kv-time { display: none }
|
|
149
168
|
|
|
150
169
|
/* 群聊头像 = 参与者头像拼图: 1 格居中, 2 格左右, 3/4 格田字。 */
|
|
151
170
|
.mosaic {
|
|
@@ -153,7 +172,7 @@ button { font: inherit; color: inherit }
|
|
|
153
172
|
background: #eef1f6; border: 1px solid var(--line); gap: 1px; padding: 1px;
|
|
154
173
|
font-size: 13px !important; line-height: 1 !important;
|
|
155
174
|
}
|
|
156
|
-
.mosaic i { font-style: normal; display: grid; place-items: center; background:
|
|
175
|
+
.mosaic i { font-style: normal; display: grid; place-items: center; background: var(--av-bg); min-width: 0; min-height: 0 }
|
|
157
176
|
.mosaic.n1 { grid-template: 1fr / 1fr; font-size: 20px !important }
|
|
158
177
|
.mosaic.n2 { grid-template: 1fr / 1fr 1fr; font-size: 14px !important }
|
|
159
178
|
.mosaic.n3, .mosaic.n4 { grid-template: 1fr 1fr / 1fr 1fr }
|
|
@@ -167,50 +186,42 @@ button { font: inherit; color: inherit }
|
|
|
167
186
|
.convs h2:first-child { margin-top: 6px }
|
|
168
187
|
.convs h2 span { font-weight: 400; color: var(--faint); font-variant-numeric: tabular-nums }
|
|
169
188
|
|
|
170
|
-
.ci
|
|
171
|
-
|
|
189
|
+
/* 群下的子项 (.si) 与私聊项 (.ci) 同一套尺寸 —— 只有一份。 */
|
|
190
|
+
.ci, .si {
|
|
191
|
+
display: flex; gap: 10px; align-items: center; width: 100%; text-align: left; overflow: hidden;
|
|
172
192
|
padding: 8px 10px; border: 0; border-radius: 9px; background: transparent; cursor: pointer;
|
|
173
193
|
}
|
|
174
|
-
.ci
|
|
175
|
-
|
|
176
|
-
.ci {
|
|
177
|
-
.ci
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
.ci .
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
.ci .
|
|
194
|
+
.ci.on, .si.on { background: #eaf0fc }
|
|
195
|
+
/* 下分割线: 每一项自己的下边线 (侧栏项、群下子项、关系图卡片一律), 两端收到内容边距。 */
|
|
196
|
+
.ci, .si { position: relative }
|
|
197
|
+
.ci::after, .si::after {
|
|
198
|
+
content: ""; position: absolute; left: 10px; right: 10px; bottom: 0; height: 1px;
|
|
199
|
+
background: var(--line); opacity: .6; pointer-events: none;
|
|
200
|
+
}
|
|
201
|
+
.ci > .av, .si > .av {
|
|
202
|
+
flex: none; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px;
|
|
203
|
+
background: var(--av-bg); box-shadow: inset 0 0 0 1px var(--av-line); font-size: 20px; line-height: 1;
|
|
204
|
+
}
|
|
205
|
+
.ci .b, .si .b { min-width: 0; flex: 1; overflow: hidden }
|
|
206
|
+
.ci .l1, .si .l1 { display: flex; align-items: baseline; gap: 6px; overflow: hidden; white-space: nowrap }
|
|
207
|
+
.ci .t, .si .t { font-size: 13.5px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
208
|
+
.ci .ts, .si .ts { margin-left: auto; flex: none; font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums }
|
|
209
|
+
.ci .pv, .si .pv { display: block; font-size: 12px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
210
|
+
.ci .pv:empty, .si .pv:empty { display: none }
|
|
186
211
|
.ci .tag { font-size: 10.5px; border-radius: 4px; padding: 0 4px; flex: none }
|
|
187
212
|
/* 头像与名字是进入那个 role 视角的入口 —— 侧栏项、会话头、消息行同一种读法。
|
|
188
|
-
|
|
189
|
-
让位 (:has), 否则读起来像是要选中这一行。z-index 保证没有兄弟盖住命中区。 */
|
|
213
|
+
它们嵌在整行那颗按钮里; 行本身悬停不变底色, 只有入口自己亮起。z-index 保证没有兄弟盖住命中区。 */
|
|
190
214
|
.nm.go, .av.go { position: relative; z-index: 1; cursor: pointer }
|
|
191
215
|
.nm.go:hover { color: var(--accent); text-decoration: underline; text-underline-offset: 2px }
|
|
192
216
|
span.av.go { border-radius: 8px; transition: background .12s, box-shadow .12s }
|
|
193
|
-
span.av.go:hover { background:
|
|
194
|
-
.ci:not(.on):has(.go:hover), .si:not(.on):has(.go:hover) { background: transparent }
|
|
217
|
+
span.av.go:hover { background: var(--av-hot); box-shadow: 0 0 0 3px var(--av-hot) }
|
|
195
218
|
.ci .tag.priv { color: var(--priv); background: #9a5b1014 }
|
|
196
219
|
|
|
197
|
-
/* 群里的其他 role —— 挂在群下,
|
|
220
|
+
/* 群里的其他 role —— 挂在群下, 与会话项同一种读法、同一套尺寸 (名字 · 时刻 / 最近一句), 只靠缩进分层级。
|
|
198
221
|
点开是「我与它在这个群里」的往来。 */
|
|
199
|
-
|
|
200
|
-
.
|
|
201
|
-
|
|
202
|
-
padding: 5px 8px; border: 0; border-radius: 8px; background: transparent; cursor: pointer; color: var(--ink);
|
|
203
|
-
}
|
|
204
|
-
.si:hover { background: #f4f6f9 }
|
|
205
|
-
.si.on { background: #eaf0fc }
|
|
206
|
-
.si > .av { font-size: 17px; line-height: 1; flex: none; width: 24px; text-align: center }
|
|
207
|
-
.si .b { min-width: 0; flex: 1; overflow: hidden }
|
|
208
|
-
.si .l1 { display: flex; align-items: baseline; gap: 6px }
|
|
209
|
-
.si .t { font-size: 12.5px; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
210
|
-
.si.on .t { color: var(--accent) }
|
|
211
|
-
.si .ts { margin-left: auto; flex: none; font-size: 10.5px; color: var(--faint); font-variant-numeric: tabular-nums }
|
|
212
|
-
.si .pv { display: block; font-size: 11.5px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
213
|
-
.si .pv:empty { display: none }
|
|
222
|
+
/* 竖线的 x 与关系图里的竖向连线对齐: 都在项左缘 +10px (关系树 ul 缩进 20 - 线距 li 10)。 */
|
|
223
|
+
.subs { margin: 0 0 6px 10px; border-left: 1px solid var(--line); padding-left: 2px }
|
|
224
|
+
.si { color: var(--ink) }
|
|
214
225
|
.si-more {
|
|
215
226
|
display: block; width: 100%; text-align: center; padding: 4px 8px; border: 0;
|
|
216
227
|
background: transparent; cursor: pointer; font-size: 11.5px; color: var(--mute);
|
|
@@ -226,16 +237,11 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
226
237
|
font-variant-numeric: tabular-nums;
|
|
227
238
|
}
|
|
228
239
|
|
|
229
|
-
/* 执行中的 wizard: 名字右边一盏呼吸灯, 会话与子项同一位置, 与回复头上的 .tg-dot 同大。 */
|
|
230
|
-
.ci .l1 .live, .si .l1 .live {
|
|
231
|
-
flex: none; align-self: center; width: 7px; height: 7px;
|
|
232
|
-
border-radius: 50%; background: #1a7f37; animation: pulse 1.4s infinite;
|
|
233
|
-
}
|
|
234
240
|
|
|
235
241
|
/* ── 右栏头: 这个群聊 / 私聊是什么 ───────────────────────────────── */
|
|
236
242
|
.main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; background: var(--card) }
|
|
237
243
|
.chathead {
|
|
238
|
-
flex: none; display: flex; align-items: center; gap: 12px; padding: 10px 20px; min-height: 58px;
|
|
244
|
+
flex: none; display: flex; align-items: center; gap: 12px; margin: 0; padding: 10px 20px; min-height: 58px;
|
|
239
245
|
background: var(--card); border-bottom: 1px solid var(--line);
|
|
240
246
|
}
|
|
241
247
|
.chathead .back { display: none; border: 0; background: none; font-size: 22px; color: var(--mute); cursor: pointer; padding: 0 4px }
|
|
@@ -249,10 +255,13 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
249
255
|
.ch-who .pair .av + .av { margin-left: -8px; box-shadow: -2px 0 0 var(--card) }
|
|
250
256
|
.ch-who .pair .av.go { cursor: pointer }
|
|
251
257
|
.ch-who .pair .av.go:hover { border-color: var(--accent) }
|
|
252
|
-
|
|
253
|
-
.ch-who
|
|
254
|
-
.ch-who
|
|
255
|
-
.ch-
|
|
258
|
+
/* 标题先让位 (min-width:0), 两端头像与右侧按钮不让。 */
|
|
259
|
+
.ch-who .t { min-width: 0; font-size: 16px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
260
|
+
.ch-who > .t:not(:only-child) { flex: 0 1 auto }
|
|
261
|
+
.ch-who .sub { min-width: 0; font-size: 11.5px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
262
|
+
.ch-acts { display: flex; gap: 8px; align-items: center; flex: 0 1 auto; min-width: 0; font-size: 12px; color: var(--mute) }
|
|
263
|
+
.ch-acts .with { min-width: 0; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
264
|
+
.ch-acts .vb { flex: none }
|
|
256
265
|
.vb {
|
|
257
266
|
font-size: 12.5px; background: var(--card); border: 1px solid var(--line); border-radius: 7px;
|
|
258
267
|
padding: 4px 11px; cursor: pointer; white-space: nowrap;
|
|
@@ -287,7 +296,8 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
287
296
|
.mrow.mine { flex-direction: row-reverse }
|
|
288
297
|
.mrow.mine .mcol { align-items: flex-end }
|
|
289
298
|
.mwho { font-size: 11.5px; color: var(--mute); display: flex; gap: 6px; align-items: center; flex-wrap: wrap }
|
|
290
|
-
.mwho .to { color: var(--faint); display: inline-flex; gap: 6px; align-items: center }
|
|
299
|
+
.mwho .to { color: var(--faint); display: inline-flex; gap: 6px; align-items: center; min-width: 0; max-width: 100% }
|
|
300
|
+
.mwho .nm { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
291
301
|
.mwho .ch { font-size: 10.5px; border-radius: 4px; padding: 0 4px }
|
|
292
302
|
.mwho .ch.priv { color: var(--priv); background: #9a5b1014 }
|
|
293
303
|
/* 时刻只此一处 —— 气泡外, 跟着名字走。等宽数字让一列时间对得齐。 */
|
|
@@ -352,8 +362,40 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
352
362
|
.mrow.mine .flip .fi { flex-direction: row-reverse }
|
|
353
363
|
.mrow.mine .flip .fc { transform: scaleX(-1) }
|
|
354
364
|
.flip .fc { flex: none }
|
|
365
|
+
.flip .fi { min-width: 0; max-width: 100%; box-sizing: border-box; padding: 4px 8px; gap: 6px }
|
|
366
|
+
/* 要去谁那里: 名字可以折行, 不撑出门外。 */
|
|
367
|
+
.flip .fn { min-width: 0; overflow-wrap: anywhere }
|
|
355
368
|
.flip:hover, .flip:focus-visible { background: #2f55c90d; color: var(--accent) }
|
|
356
369
|
.flip[disabled] { cursor: default; background: transparent !important; color: transparent !important }
|
|
370
|
+
/* 说给谁: 贴着气泡写在门里, 与气泡首行对齐。不吃点击 —— 点到它就是点门。
|
|
371
|
+
门竖排: 描述在上、换视角箭头在下, 描述折几行箭头就跟着往下让, 两者不叠。
|
|
372
|
+
contain: size —— 门的内容不参与这一行的高度, 描述再长也不撑高一行。 */
|
|
373
|
+
.flip:has(.dest) {
|
|
374
|
+
flex-direction: column; justify-content: flex-start; gap: 6px; contain: size;
|
|
375
|
+
padding: calc(var(--av) + 12px) 4px 0;
|
|
376
|
+
}
|
|
377
|
+
/* 只留向下的吸附: 原先的 bottom 吸附会把箭头往上拽到视窗中线, 越过上面的描述。 */
|
|
378
|
+
.flip:has(.dest) .fi { bottom: auto; flex: none }
|
|
379
|
+
/* 门比描述矮 (一行短气泡) 时不许把描述压扁, 宁可溢到行外。 */
|
|
380
|
+
.flip:has(.dest) .dest { flex: none }
|
|
381
|
+
/* 压过 .mrow.mine .flip 的 flex-end: 竖排后那条是纵轴, 会把描述推到行底。 */
|
|
382
|
+
.mrow .flip:has(.dest) { justify-content: flex-start }
|
|
383
|
+
.mrow.them .flip:has(.dest) { align-items: flex-start }
|
|
384
|
+
.mrow.mine .flip:has(.dest) { align-items: flex-end }
|
|
385
|
+
.flip .dest {
|
|
386
|
+
max-width: 100%; font-size: 11px; line-height: 1.45; color: var(--faint); pointer-events: none;
|
|
387
|
+
display: flex; align-items: center; gap: 4px; max-height: calc(3 * 1.45em); overflow: hidden;
|
|
388
|
+
}
|
|
389
|
+
.flip .dest .arr { font-style: normal; flex: none }
|
|
390
|
+
.flip .dest .dav {
|
|
391
|
+
flex: none; width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--line); background: var(--card);
|
|
392
|
+
display: grid; place-items: center; font-size: 11px; line-height: 1;
|
|
393
|
+
}
|
|
394
|
+
.flip .dest .dn { min-width: 0; overflow-wrap: anywhere }
|
|
395
|
+
.mrow.them .flip .dest { text-align: left }
|
|
396
|
+
.mrow.mine .flip .dest { text-align: right; justify-content: flex-end }
|
|
397
|
+
.flip[disabled] .dest { color: var(--faint) }
|
|
398
|
+
.mwho .to { display: none }
|
|
357
399
|
.mwho .av.go { cursor: pointer }
|
|
358
400
|
.mwho .av.go:hover { border-color: var(--accent); background: #2f55c914 }
|
|
359
401
|
|
|
@@ -392,6 +434,8 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
392
434
|
保温 ping 不是对话, 但它是真花销 —— 所以留在时间轴上, 只是收成一行虚线。 */
|
|
393
435
|
/* summary 的灰底 / 底线是 SHARED_CSS 里通用 details 的 —— 圆角得自己裁, 底线只在展开时才是分割线。 */
|
|
394
436
|
.ping-fold { border: 1px dashed #d8dee4; border-radius: 10px; background: #fff; overflow: hidden }
|
|
437
|
+
/* 暂时整条藏起来 —— 行仍折在 details 里, 折叠 / FLIP 逻辑照旧, 删掉这行即恢复。 */
|
|
438
|
+
.ping-fold { display: none }
|
|
395
439
|
.ping-fold:not([open]) > .ping-sum { border-bottom: 0 }
|
|
396
440
|
.ping-fold > .ping-sum {
|
|
397
441
|
display: flex; align-items: center; gap: 8px; padding: 6px 12px; background: #fff;
|
|
@@ -414,6 +458,7 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
414
458
|
}
|
|
415
459
|
.ping-fold .mcol { max-width: 100% }
|
|
416
460
|
.ping-fold .flip { display: none }
|
|
461
|
+
.ping-fold .mwho .to { display: inline-flex }
|
|
417
462
|
/* 折叠里的气泡同是白底 —— 描一圈虚线跟对话气泡分开, 与外框一个语气。 */
|
|
418
463
|
.ping-fold .mb :is(.bubble.mq, .say > .bubble) { border: 1px dashed var(--bub-line) }
|
|
419
464
|
|
|
@@ -428,11 +473,10 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
428
473
|
.thread { padding: 12px }
|
|
429
474
|
.mcol { max-width: calc(86% + var(--av)) }
|
|
430
475
|
.flip { min-width: 16px; padding: 0 4px; font-size: 0 }
|
|
476
|
+
.flip .dest { display: none }
|
|
477
|
+
.mwho .to { display: inline-flex }
|
|
431
478
|
.thread { padding-bottom: calc(12px + env(safe-area-inset-bottom)) }
|
|
432
|
-
.usage { padding: 8px 12px
|
|
433
|
-
.usage .u-kvs, .usage .leg { flex-wrap: wrap }
|
|
434
|
-
.usage .u-io { flex: 1 1 100%; flex-wrap: wrap; gap: 6px 12px }
|
|
435
|
-
.usage .bar { flex: 1 1 100%; width: auto }
|
|
479
|
+
.usage { padding: 8px 12px }
|
|
436
480
|
.usage.page { padding-bottom: calc(8px + env(safe-area-inset-bottom)) }
|
|
437
481
|
}
|
|
438
482
|
|
|
@@ -448,139 +492,12 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
448
492
|
padding: 8px 20px; background: #fff; border-bottom: 1px solid #d0d7de;
|
|
449
493
|
font-size: 11.5px; color: #57606a;
|
|
450
494
|
}
|
|
451
|
-
.
|
|
452
|
-
|
|
453
|
-
只会让人在两处之间对照颜色。 */
|
|
454
|
-
.wtools .chip {
|
|
455
|
-
display: flex; align-items: center; gap: 5px; font: inherit; cursor: pointer;
|
|
456
|
-
background: #fff; border: 1px solid #d0d7de; border-radius: 13px; padding: 2px 10px;
|
|
457
|
-
color: #8c959f;
|
|
458
|
-
}
|
|
459
|
-
.wtools .chip i { width: 14px; height: 0; border-top: 2px solid var(--c); opacity: .35 }
|
|
460
|
-
.wtools .chip b { font-variant-numeric: tabular-nums; font-weight: 700 }
|
|
461
|
-
.wtools .chip.on { color: #1f2328; border-color: var(--c) }
|
|
462
|
-
.wtools .chip.on i { opacity: 1 }
|
|
463
|
-
.wtools .chip.clear, .wtools .chip.only { border-color: #d0d7de; color: #57606a }
|
|
464
|
-
.wtools .chip.only.on { border-color: #0969da; color: #0550ae; background: #ddf4ff }
|
|
465
|
-
.wtools .wstat { margin-left: auto; color: #8c959f; font-variant-numeric: tabular-nums }
|
|
466
|
-
.wtools .wstat b { color: #0969da }
|
|
495
|
+
.wtools .wstat { flex: 1; display: flex; gap: 6px; align-items: baseline; color: #8c959f }
|
|
496
|
+
.wtools .rng { color: var(--ink) }
|
|
467
497
|
.wtools .warn { color: #9a6700 }
|
|
468
|
-
.wtools .hint { margin-left:
|
|
469
|
-
|
|
470
|
-
/* position 不是装饰: 力导向的画布是 `position:absolute; inset:0`, 没有这一行它
|
|
471
|
-
就贴到更外层的定位祖先上去 —— 坐标原点跑到顶栏, 节点飘到工具条上面, 而
|
|
472
|
-
overflow:hidden 也拦不住一个容器块在自己之外的绝对定位子元素。 */
|
|
498
|
+
.wtools .hint { margin-left: auto; color: #b1bac4 }
|
|
473
499
|
.wscroll { position: relative; flex: 1; min-height: 0; overflow: auto; -webkit-overflow-scrolling: touch }
|
|
474
500
|
.wmap { position: relative; padding: 18px 20px 28px; min-width: min-content }
|
|
475
|
-
/* 有关系的节点带一道左侧色条 —— 76 个会话里哪几个真的在协作, 不点开也看得见。 */
|
|
476
|
-
.wnode.rel::before {
|
|
477
|
-
content: ""; position: absolute; left: 1px; top: 8px; bottom: 8px;
|
|
478
|
-
width: 2px; border-radius: 1px; background: #0969da66;
|
|
479
|
-
}
|
|
480
|
-
/* 连线层铺满整张图并且不吃事件 —— 节点的点击/双击必须照常穿过去。
|
|
481
|
-
z-index 把它抬到卡片之上: 卡片是不透明的, 压在下面时一条跨卡片的边会被中途
|
|
482
|
-
吃掉半截, 读出来像是断的。.wgrid 不设 z-index (保持 auto) 才不会自成一个层叠
|
|
483
|
-
上下文 —— 那样悬停/聚焦的节点就再也抬不过这条线了。 */
|
|
484
|
-
.wedges { position: absolute; inset: 0; pointer-events: none; overflow: visible; z-index: 2 }
|
|
485
|
-
/* 反过来: 正在看的那个节点要压过连线, 否则文字被线划着读。只抬这两种 —— 一直
|
|
486
|
-
抬着某个节点等于把"线被卡片吃掉"这个毛病在它身上留一份。 */
|
|
487
|
-
.wnode:hover, .wnode.sel { z-index: 3 }
|
|
488
|
-
/* 多列流式而不是 grid: 聊天卡片的高度天差地别 (一个群 2 个 wizard, 另一个 20 个),
|
|
489
|
-
grid 的行高按本行最高的那张对齐, 于是矮卡片下面全是空白 —— 图看着比实际稀疏
|
|
490
|
-
一倍。CSS columns 是砌砖式的: 卡片顺着列往下码, 码满了换列, 没有行的概念。
|
|
491
|
-
列宽钉在 320 附近也顺带收住了"两张卡片各占半个屏"的过度拉伸。 */
|
|
492
|
-
.wgrid { position: relative; columns: 320px; column-gap: 16px }
|
|
493
|
-
|
|
494
|
-
.wchat {
|
|
495
|
-
background: #fff; border: 1px solid #d0d7de; border-radius: 12px; overflow: hidden;
|
|
496
|
-
/* 一张卡片不能被切成两列 —— 断在半截的家谱读不出父子关系。 */
|
|
497
|
-
break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid;
|
|
498
|
-
margin-bottom: 16px;
|
|
499
|
-
}
|
|
500
|
-
/* 卡片头可点 = 进那个群 (见 chat.js 的 openNode)。 */
|
|
501
|
-
.wch.go { cursor: pointer }
|
|
502
|
-
.wch.go:hover .nm { color: #0969da; text-decoration: underline }
|
|
503
|
-
/* 当前聊天是读图的锚点, 给它一道明确的边 —— 其余的群一律等价, 不再分轻重。 */
|
|
504
|
-
.wchat.self { border-color: #0969da66; box-shadow: 0 0 0 3px #0969da10 }
|
|
505
|
-
.wch {
|
|
506
|
-
display: flex; align-items: baseline; gap: 8px; padding: 9px 13px;
|
|
507
|
-
border-bottom: 1px solid #eaeef2; background: #f6f8fa;
|
|
508
|
-
}
|
|
509
|
-
.wchat.self .wch { background: #f0f6ff }
|
|
510
|
-
.wch .nm {
|
|
511
|
-
font-size: 13px; font-weight: 700; min-width: 0; overflow: hidden;
|
|
512
|
-
text-overflow: ellipsis; white-space: nowrap;
|
|
513
|
-
}
|
|
514
|
-
.wch .here {
|
|
515
|
-
font-size: 10px; color: #0969da; background: #0969da14; border-radius: 4px; padding: 1px 5px;
|
|
516
|
-
}
|
|
517
|
-
.wch .ct {
|
|
518
|
-
margin-left: auto; font-size: 11px; color: #8c959f; flex: none;
|
|
519
|
-
font-family: ui-monospace, Menlo, monospace;
|
|
520
|
-
}
|
|
521
|
-
.wch .ct em { color: #1a7f37; font-style: normal; font-weight: 700 }
|
|
522
|
-
/* 左内边距是同卡片内连线的车道 —— 一条 `#a → #b` 的派活边从这里绕过去, 不必
|
|
523
|
-
拐出卡片 (拐出去就会被滚动容器裁掉)。 */
|
|
524
|
-
.wrows { padding: 7px 10px 10px 22px; display: flex; flex-direction: column; gap: 3px }
|
|
525
|
-
|
|
526
|
-
.wnode {
|
|
527
|
-
position: relative; display: flex; gap: 8px; align-items: flex-start;
|
|
528
|
-
padding: 6px 8px; border-radius: 8px; cursor: pointer;
|
|
529
|
-
border: 1px solid transparent; transition: opacity .15s, background .12s;
|
|
530
|
-
}
|
|
531
|
-
.wnode:hover { background: #f6f8fa }
|
|
532
|
-
.wnode.self { background: #fffbe8 }
|
|
533
|
-
.wnode.sel { background: #eef4fc; border-color: #0969da55 }
|
|
534
|
-
/* 聚焦时无关节点压暗而不是移除 —— 位置不动, 连点几个节点版面也不跳。 */
|
|
535
|
-
.wnode.dim { opacity: .3 }
|
|
536
|
-
/* 双击能走进去的那些 —— 外聊天的节点现在也算 (整页跳过去)。 */
|
|
537
|
-
.wnode.go { cursor: pointer }
|
|
538
|
-
.wnode.cold .wav { filter: grayscale(1); opacity: .55 }
|
|
539
|
-
/* 缩进本身就是家谱; 这道折线只是把"缩给谁看"指实。 */
|
|
540
|
-
.wnode .lin {
|
|
541
|
-
position: absolute; left: -9px; top: 0; bottom: 50%; width: 9px;
|
|
542
|
-
border-left: 1.5px solid #d8cdf0; border-bottom: 1.5px solid #d8cdf0;
|
|
543
|
-
border-bottom-left-radius: 6px;
|
|
544
|
-
}
|
|
545
|
-
/* 子 wizard 不是 fork: 折线换成虚线、换色, 与分身一眼分开 (同关系图的 spawn 边)。 */
|
|
546
|
-
.wnode .lin.sp { border-style: dashed; border-color: #f0d2bd }
|
|
547
|
-
.wav {
|
|
548
|
-
position: relative; width: 26px; height: 26px; flex: none; border-radius: 8px;
|
|
549
|
-
background: #f1f3f6; border: 1px solid #eaeef2;
|
|
550
|
-
display: flex; align-items: center; justify-content: center; font-size: 14px;
|
|
551
|
-
}
|
|
552
|
-
.wav .live {
|
|
553
|
-
position: absolute; right: -3px; bottom: -3px; width: 9px; height: 9px;
|
|
554
|
-
border-radius: 50%; background: #1a7f37; border: 2px solid #fff;
|
|
555
|
-
animation: pulse 1.4s infinite;
|
|
556
|
-
}
|
|
557
|
-
.wbody { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px }
|
|
558
|
-
.wl1 { display: flex; align-items: baseline; gap: 6px; min-width: 0 }
|
|
559
|
-
.wname {
|
|
560
|
-
font-size: 12.5px; font-weight: 600; min-width: 0; overflow: hidden;
|
|
561
|
-
text-overflow: ellipsis; white-space: nowrap;
|
|
562
|
-
}
|
|
563
|
-
.wnode.run .wname { color: #1a7f37 }
|
|
564
|
-
.wtag {
|
|
565
|
-
flex: none; font-size: 10.5px; color: #57606a; background: #f1f3f6;
|
|
566
|
-
border-radius: 4px; padding: 0 5px; font-family: ui-monospace, Menlo, monospace;
|
|
567
|
-
}
|
|
568
|
-
.wtag.def { color: #8c959f }
|
|
569
|
-
.wih { flex: none; font-size: 11px; color: #6639ba }
|
|
570
|
-
.wts {
|
|
571
|
-
margin-left: auto; flex: none; font-size: 10.5px; color: #8c959f;
|
|
572
|
-
font-family: ui-monospace, Menlo, monospace;
|
|
573
|
-
}
|
|
574
|
-
.wjob { font-size: 11.5px; color: #0550ae; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
575
|
-
.wprev {
|
|
576
|
-
font-size: 11.5px; color: #656d76; overflow: hidden; line-height: 1.4;
|
|
577
|
-
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
|
|
578
|
-
}
|
|
579
|
-
.wmeta {
|
|
580
|
-
font-size: 10.5px; color: #8c959f; font-family: ui-monospace, Menlo, monospace;
|
|
581
|
-
display: flex; gap: 4px; flex-wrap: wrap; margin-top: 1px;
|
|
582
|
-
}
|
|
583
|
-
.wmeta .sep { opacity: .45 }
|
|
584
501
|
|
|
585
502
|
/* ══ 日程 ═══════════════════════════════════════════════════════════ */
|
|
586
503
|
.plan-in { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 20px 28px }
|
|
@@ -615,32 +532,18 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
615
532
|
position: relative; height: 8px; border-radius: 4px; background: #eaeef2; margin: 3px 0 7px;
|
|
616
533
|
}
|
|
617
534
|
.strip .pin {
|
|
618
|
-
position: absolute; top: -
|
|
619
|
-
border-radius: 3px; background: #9a6700; box-shadow: 0 0 0 2px #fff;
|
|
620
|
-
}
|
|
621
|
-
.strip .cap { font-size: 11px; color: #8c959f }
|
|
622
|
-
|
|
623
|
-
.prow {
|
|
624
|
-
display: flex; gap: 16px; background: #fff; border: 1px solid #d0d7de;
|
|
625
|
-
border-radius: 10px; padding: 12px 16px; margin-bottom: 10px;
|
|
626
|
-
}
|
|
627
|
-
.prow .pl { flex: none; width: 152px; border-right: 1px dashed #eaeef2; padding-right: 14px }
|
|
628
|
-
.pwhen { font-size: 11.5px; color: #9a6700; font-weight: 600 }
|
|
629
|
-
.pnext {
|
|
630
|
-
display: flex; align-items: baseline; gap: 6px; margin-top: 5px;
|
|
631
|
-
font-family: ui-monospace, Menlo, monospace;
|
|
535
|
+
position: absolute; top: -4px; width: 10px; height: 16px; margin-left: -5px; padding: 0; cursor: pointer;
|
|
536
|
+
border: 0; border-radius: 3px; background: #9a6700; box-shadow: 0 0 0 2px #fff;
|
|
632
537
|
}
|
|
633
|
-
.
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
.ph { display: flex; align-items: center; gap: 7px; flex-wrap: wrap }
|
|
637
|
-
.ph .note { font-size: 11px; color: #57606a }
|
|
638
|
-
.ph .pid {
|
|
639
|
-
margin-left: auto; font-size: 10px; color: #b1bac4;
|
|
640
|
-
font-family: ui-monospace, Menlo, monospace;
|
|
538
|
+
.strip .pin span {
|
|
539
|
+
position: absolute; bottom: 19px; left: 50%; transform: translateX(-50%); white-space: nowrap;
|
|
540
|
+
font: 600 9.5px ui-monospace, Menlo, monospace; color: #9a6700; opacity: 0; transition: opacity .12s; pointer-events: none;
|
|
641
541
|
}
|
|
642
|
-
.
|
|
643
|
-
.
|
|
542
|
+
.strip .pin:hover span, .strip .pin:focus-visible span { opacity: 1 }
|
|
543
|
+
.strip .pin:hover { transform: scaleY(1.15) }
|
|
544
|
+
.strip .pin.bad { background: #cf222e }
|
|
545
|
+
.strip .pin.bad span { color: #cf222e }
|
|
546
|
+
.strip .cap { font-size: 11px; color: #8c959f }
|
|
644
547
|
|
|
645
548
|
/* wizard 徽标 —— 日程/工单里凡是提到一个 wizard 都用它, 同聊天的可点进线程。 */
|
|
646
549
|
.wchip {
|
|
@@ -684,69 +587,15 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
684
587
|
@media (max-width: 760px) {
|
|
685
588
|
.chathead .vb { padding: 3px 8px }
|
|
686
589
|
.wmap { padding: 12px }
|
|
687
|
-
.wgrid { columns: 1 }
|
|
688
590
|
.plan-in { padding: 12px }
|
|
689
|
-
.
|
|
690
|
-
.
|
|
691
|
-
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
/* 相关性筛掉的那些 —— 说一声它们还在, 但不占图的位置 (见 shared/world 的说明)。 */
|
|
695
|
-
.wmore {
|
|
696
|
-
padding: 5px 13px 9px; font-size: 10.5px; color: #b1bac4;
|
|
697
|
-
border-top: 1px dashed #eaeef2; margin-top: 2px;
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
/* ══ 关系视图 · 力导向布局 ═════════════════════════════════════════
|
|
701
|
-
卡片布局之外的另一种读法: 节点只画 wizard, 聊天不再是容器而是节点身上的一
|
|
702
|
-
道色条 + 一行群名。见 web/chat.js 的说明。 */
|
|
703
|
-
.wscroll.fx { overflow: hidden }
|
|
704
|
-
.wmap.force { position: absolute; inset: 0; padding: 0; min-width: 0 }
|
|
705
|
-
.fxn {
|
|
706
|
-
position: absolute; left: 0; top: 0; z-index: 2;
|
|
707
|
-
display: flex; align-items: center; gap: 7px; max-width: 210px;
|
|
708
|
-
padding: 5px 10px 5px 7px; border-radius: 10px;
|
|
709
|
-
background: #fff; border: 1px solid #d0d7de; border-left: 3px solid var(--c);
|
|
710
|
-
box-shadow: 0 1px 3px #1b1f2412; cursor: grab; touch-action: none;
|
|
711
|
-
user-select: none; -webkit-user-select: none;
|
|
712
|
-
transition: opacity .15s, box-shadow .12s;
|
|
713
|
-
will-change: transform;
|
|
714
|
-
}
|
|
715
|
-
.fxn .wav { width: 22px; height: 22px; border-radius: 7px; font-size: 12px }
|
|
716
|
-
.fxn .wav .live { width: 8px; height: 8px; right: -2px; bottom: -2px }
|
|
717
|
-
.fxb { min-width: 0; display: flex; flex-direction: column; gap: 0 }
|
|
718
|
-
.fxn .wname { font-size: 12px }
|
|
719
|
-
/* 群名压得比名字轻 —— 它是节点的属性, 不是节点本身。 */
|
|
720
|
-
.fxc {
|
|
721
|
-
font-size: 9.5px; color: var(--c); opacity: .85; overflow: hidden;
|
|
722
|
-
text-overflow: ellipsis; white-space: nowrap;
|
|
723
|
-
}
|
|
724
|
-
.fxn.self { background: #fffbe8 }
|
|
725
|
-
.fxn.cold { opacity: .72 }
|
|
726
|
-
.fxn.cold .wav { filter: grayscale(1); opacity: .55 }
|
|
727
|
-
.fxn.run .wname { color: #1a7f37 }
|
|
728
|
-
.fxn.dim { opacity: .22 }
|
|
729
|
-
.fxn.sel { box-shadow: 0 0 0 3px var(--c), 0 1px 3px #1b1f2412; }
|
|
730
|
-
.fxn.sel .fxc { opacity: 1 }
|
|
731
|
-
.fxn.drag { cursor: grabbing; box-shadow: 0 6px 16px #1b1f2426 }
|
|
732
|
-
/* 钉住 = 这个位置是人摆的, 力不再动它。 */
|
|
733
|
-
.fxn.pin::after {
|
|
734
|
-
content: "📌"; position: absolute; right: -5px; top: -7px; font-size: 9px;
|
|
735
|
-
opacity: .8; pointer-events: none;
|
|
736
|
-
}
|
|
737
|
-
/* 布局开关 —— 两种读法并列, 不是复选。 */
|
|
738
|
-
.wtools .wlay { display: inline-flex; border: 1px solid #d0d7de; border-radius: 7px; overflow: hidden }
|
|
739
|
-
.wtools .lb {
|
|
740
|
-
border: 0; background: #fff; cursor: pointer; padding: 3px 9px;
|
|
741
|
-
font-size: 11.5px; color: #57606a; font-family: inherit;
|
|
742
|
-
}
|
|
743
|
-
.wtools .lb + .lb { border-left: 1px solid #d0d7de }
|
|
744
|
-
.wtools .lb.on { background: #ddf4ff; color: #0550ae; font-weight: 600 }
|
|
591
|
+
.tcard { flex-direction: column; gap: 8px }
|
|
592
|
+
.tc-time { width: auto; flex-direction: row; align-items: baseline; gap: 8px; border-right: 0; padding: 0 }
|
|
593
|
+
}
|
|
745
594
|
|
|
746
595
|
/* ══ 关系 / 日程 ═══════════════════════════════════════════════════ */
|
|
747
596
|
/* 都是当前 role 的另一面, 侧栏 (它的会话) 留着 —— 点一个会话就回到对话。
|
|
748
597
|
会话标题条与页脚总账只属于对话视图。 */
|
|
749
|
-
.pane { flex: 1; min-height: 0; display: flex; flex-direction: column; background: #fafbfc }
|
|
598
|
+
.pane { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; background: #fafbfc }
|
|
750
599
|
|
|
751
600
|
/* 过程框里的工具行是 nowrap 的 —— 不裁一刀会把整列撑出横向滚动。 */
|
|
752
601
|
.mb > .turn-group { overflow: hidden }
|
|
@@ -759,3 +608,234 @@ span.av.go:hover { background: #2f55c924; box-shadow: 0 0 0 3px #2f55c924 }
|
|
|
759
608
|
.rem.raw { flex-basis: 100% }
|
|
760
609
|
.rem.raw .rem-raw { display: block }
|
|
761
610
|
.rem.raw .rem-tag { display: none }
|
|
611
|
+
|
|
612
|
+
/* ══ 忙闲: 名字右边唯一的状态位 (名片 · 关系树 · 侧栏共用 stTag) ══
|
|
613
|
+
只有执行中带颜色与呼吸; 空字 (侧栏) 就只剩那盏灯。 */
|
|
614
|
+
.wst {
|
|
615
|
+
flex: none; align-self: center; display: inline-flex; align-items: center; gap: 4px; font-size: 10px; line-height: 16px;
|
|
616
|
+
padding: 0 6px; border-radius: 8px; background: #eef0f3; color: var(--mute); white-space: nowrap; font-weight: 500;
|
|
617
|
+
}
|
|
618
|
+
.wst::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #b1bac4 }
|
|
619
|
+
.wst.run { background: #dafbe1; color: #1a7f37 }
|
|
620
|
+
.wst.run::before { background: #1a7f37; animation: pulse 1.4s infinite }
|
|
621
|
+
.wst.off { background: transparent; color: var(--faint); box-shadow: inset 0 0 0 1px var(--line) }
|
|
622
|
+
.wst.off::before { background: transparent; box-shadow: inset 0 0 0 1.5px #b1bac4 }
|
|
623
|
+
.wst:empty { padding: 0; background: none; box-shadow: none }
|
|
624
|
+
.wst:empty::before { width: 7px; height: 7px }
|
|
625
|
+
/* ══ 关系图 · 关系树 (家谱与派活合成一棵, 以当前 role 为中心) ══════════
|
|
626
|
+
它替换的是侧栏的会话列表: 标题、图例与会话列表的分组标题同一种读法, 卡片就是会话项 (.ci)。 */
|
|
627
|
+
.tview .tall {
|
|
628
|
+
margin-left: auto; border: 0; background: none; padding: 0 2px; cursor: pointer; font-size: 11px; color: var(--faint);
|
|
629
|
+
text-decoration: underline dotted; text-underline-offset: 3px;
|
|
630
|
+
}
|
|
631
|
+
.tview .tall:hover { color: var(--accent) }
|
|
632
|
+
.tview h2 .warn { color: #9a6700; font-weight: 400 }
|
|
633
|
+
.tree.all > li + li { margin-top: 10px; padding-top: 10px; border-top: 1px dashed #eaeef2 }
|
|
634
|
+
.tfold { flex: none; font-size: 10px; font-weight: 400; color: var(--faint); border: 1px dashed var(--line); border-radius: 8px; padding: 0 5px; line-height: 14px }
|
|
635
|
+
.tsolo { font-size: 11.5px; color: var(--faint); margin: 0 8px 10px }
|
|
636
|
+
.tview .pempty { padding: 18px 8px }
|
|
637
|
+
|
|
638
|
+
/* 树: 每条入边是一道实线, 从父卡片底下一路落到自己卡片的头像旁, 末端一枚箭头, 颜色 = 关系种类。
|
|
639
|
+
兄弟共用的那段竖干上, 后画的 (更下方的节点) 盖住先画的; 竖线往上伸到 ul 顶为止 (clip-path 只裁上边)。 */
|
|
640
|
+
.tree, .tree ul { list-style: none; margin: 0; padding: 0 }
|
|
641
|
+
.tree ul { padding-left: 20px; clip-path: inset(0 -100vw -100vh -100vw) }
|
|
642
|
+
.tree li { position: relative; padding-top: 14px }
|
|
643
|
+
.tree > li { padding-top: 0 }
|
|
644
|
+
.tree ul > li::before {
|
|
645
|
+
content: ""; position: absolute; left: -10px; top: -9999px; height: calc(9999px + 39px); width: 10px;
|
|
646
|
+
border-left: 1.5px solid var(--lc); border-bottom: 1.5px solid var(--lc); border-bottom-left-radius: 7px;
|
|
647
|
+
}
|
|
648
|
+
.tree ul > li::after {
|
|
649
|
+
content: ""; position: absolute; left: -6px; top: 34px; border: 4.5px solid transparent; border-right: 0;
|
|
650
|
+
border-left: 7px solid var(--lc);
|
|
651
|
+
}
|
|
652
|
+
.tree li.spawn { --lc: #d4700f }
|
|
653
|
+
.tree li.clone { --lc: #8250df }
|
|
654
|
+
.tree li.peer { --lc: #0969da }
|
|
655
|
+
.tree li.job { --lc: #bf8700 }
|
|
656
|
+
.tree li.graph { --lc: #0a7d6b }
|
|
657
|
+
/* 卡片 = 会话项; label 骑在它左上角, 紧挨箭头。 */
|
|
658
|
+
.tci { position: relative; overflow: visible }
|
|
659
|
+
.tci.me .t .nm { color: var(--accent) }
|
|
660
|
+
/* 连接用的祖先: 没和视角对过话, 只为把对过话的后代挂回家谱 —— 淡一档。 */
|
|
661
|
+
.tci.via { opacity: .55 }
|
|
662
|
+
.tci.via:hover { opacity: 1 }
|
|
663
|
+
.tlab { position: absolute; left: 4px; top: -8px; display: flex; gap: 3px; z-index: 2 }
|
|
664
|
+
.tlab .ek { box-shadow: 0 0 0 2px var(--card) }
|
|
665
|
+
|
|
666
|
+
/* 边的 label: 辅助信息, 淡色; 一条边可能同时带几种 (既是子 wizard 又被派过活), 各一枚。 */
|
|
667
|
+
.ek {
|
|
668
|
+
flex: none; font-size: 10px; line-height: 15px; padding: 0 5px; border-radius: 4px; white-space: nowrap;
|
|
669
|
+
font-weight: 500; color: var(--mute); background: #f1f3f6;
|
|
670
|
+
}
|
|
671
|
+
.ek.spawn { color: #a8642a; background: #d4700f12 }
|
|
672
|
+
.ek.clone { color: #7a5bb8; background: #8250df12 }
|
|
673
|
+
.ek.peer { color: #4a74b0; background: #0969da10 }
|
|
674
|
+
.ek.job { color: #94741f; background: #bf870014 }
|
|
675
|
+
.ek.graph { color: #3d8577; background: #0a7d6b12 }
|
|
676
|
+
.ek.cross { font-weight: 400; background: #fff; box-shadow: inset 0 0 0 1px var(--line) }
|
|
677
|
+
|
|
678
|
+
/* ══ 日程 · 总览 / 任务卡 ════════════════════════════════════════════ */
|
|
679
|
+
.pstats {
|
|
680
|
+
max-width: 900px; margin: 0 auto 18px; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px;
|
|
681
|
+
}
|
|
682
|
+
.pst {
|
|
683
|
+
background: #fff; border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px;
|
|
684
|
+
display: flex; flex-direction: column; gap: 2px; min-width: 0;
|
|
685
|
+
}
|
|
686
|
+
.pst .k { font-size: 11px; color: var(--mute) }
|
|
687
|
+
.pst b { font-size: 20px; line-height: 26px; font-variant-numeric: tabular-nums; font-family: ui-monospace, Menlo, monospace }
|
|
688
|
+
.pst b small { font-size: 12px; color: var(--faint); font-weight: 400 }
|
|
689
|
+
.pst .s { font-size: 11px; color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
690
|
+
.pst.bad { border-color: #cf222e66; background: #fff6f6 }
|
|
691
|
+
.pst.bad b, .pst.bad .k { color: #cf222e }
|
|
692
|
+
|
|
693
|
+
.tcard {
|
|
694
|
+
display: flex; gap: 16px; background: #fff; border: 1px solid var(--line); border-radius: 12px;
|
|
695
|
+
padding: 12px 16px; margin-bottom: 10px; transition: box-shadow .2s, border-color .2s;
|
|
696
|
+
}
|
|
697
|
+
.tcard:hover { border-color: #b9c3d3 }
|
|
698
|
+
.tcard.bad { border-color: #cf222e55; border-left: 3px solid #cf222e }
|
|
699
|
+
.tcard.flash { animation: flash 1.2s ease-out }
|
|
700
|
+
@keyframes flash { 0% { box-shadow: 0 0 0 4px #9a670055 } 100% { box-shadow: 0 0 0 4px #9a670000 } }
|
|
701
|
+
.tc-time {
|
|
702
|
+
flex: none; width: 92px; display: flex; flex-direction: column; gap: 1px;
|
|
703
|
+
border-right: 1px dashed #eaeef2; padding-right: 14px;
|
|
704
|
+
}
|
|
705
|
+
.tc-time b { font: 700 22px/28px ui-monospace, Menlo, monospace; font-variant-numeric: tabular-nums; color: var(--ink) }
|
|
706
|
+
.tc-time span { font-size: 11px; color: var(--mute) }
|
|
707
|
+
.tc-time em { font-style: normal; font-size: 11px; color: #9a6700; font-weight: 600 }
|
|
708
|
+
.tc-main { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 7px }
|
|
709
|
+
.perr {
|
|
710
|
+
font-size: 11.5px; color: #82071e; background: #ffebe9; border: 1px solid #ff818266; border-radius: 8px;
|
|
711
|
+
padding: 6px 10px; line-height: 1.5;
|
|
712
|
+
}
|
|
713
|
+
.perr b { font-weight: 700 }
|
|
714
|
+
.perr code {
|
|
715
|
+
display: block; margin-top: 3px; font: 11px/1.5 ui-monospace, Menlo, monospace; color: #a40e26;
|
|
716
|
+
white-space: pre-wrap; word-break: break-word;
|
|
717
|
+
}
|
|
718
|
+
.prule { display: flex; gap: 5px; flex-wrap: wrap }
|
|
719
|
+
.rl { font-size: 11px; line-height: 18px; padding: 0 7px; border-radius: 9px; white-space: nowrap }
|
|
720
|
+
.rl.clock { color: #7d4e00; background: #fff8c5; border: 1px solid #d4a72c66; font-weight: 600 }
|
|
721
|
+
.rl.guard { color: var(--mute); background: #f1f3f6; border: 1px solid #e4e8ee }
|
|
722
|
+
.ptitle { font-size: 13px; font-weight: 600; line-height: 1.45; word-break: break-word }
|
|
723
|
+
.pflow { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; font-size: 11.5px }
|
|
724
|
+
.pflow .fl { color: var(--faint) }
|
|
725
|
+
.pflow .ar { color: var(--faint) }
|
|
726
|
+
.pflow .fresh { color: #6639ba; background: #8250df12; border-radius: 10px; padding: 0 7px; line-height: 18px }
|
|
727
|
+
.pprompt { font-size: 11.5px; border-radius: 8px; background: #f6f8fa; border: 1px solid #eaeef2 }
|
|
728
|
+
.pprompt summary {
|
|
729
|
+
text-transform: none; letter-spacing: 0; font-weight: 400; cursor: pointer; padding: 5px 10px; color: var(--mute); display: flex; gap: 8px; min-width: 0; list-style: none;
|
|
730
|
+
}
|
|
731
|
+
.pprompt summary::-webkit-details-marker { display: none }
|
|
732
|
+
.pprompt summary::before { content: "▸"; color: var(--faint); transition: transform .12s }
|
|
733
|
+
.pprompt[open] summary::before { transform: rotate(90deg) }
|
|
734
|
+
.pprompt summary span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); opacity: .75 }
|
|
735
|
+
.pprompt pre {
|
|
736
|
+
margin: 0; padding: 8px 12px 10px; border-top: 1px solid #eaeef2; max-height: 280px; overflow: auto;
|
|
737
|
+
font: 11.5px/1.55 ui-monospace, Menlo, monospace; white-space: pre-wrap; word-break: break-word;
|
|
738
|
+
}
|
|
739
|
+
.pfoot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 10.5px; color: var(--faint) }
|
|
740
|
+
.pfoot .pid { margin-left: auto; font-family: ui-monospace, Menlo, monospace; color: #b1bac4 }
|
|
741
|
+
.gt { border-radius: 4px; padding: 0 6px; line-height: 16px; font-weight: 600 }
|
|
742
|
+
.gt.none { color: var(--faint); background: #f1f3f6; font-weight: 400 }
|
|
743
|
+
.gt.go { color: #1a7f37; background: #dafbe1 }
|
|
744
|
+
.gt.skip { color: #57606a; background: #eaeef2 }
|
|
745
|
+
.gt.err { color: #fff; background: #cf222e }
|
|
746
|
+
.jh .jst { border-radius: 4px; padding: 0 6px; background: #eaeef2 }
|
|
747
|
+
.jrow.open .jh .jst { background: #dafbe1 }
|
|
748
|
+
.jmm .wst { font-size: 9.5px }
|
|
749
|
+
.jmm .tmp, .jmm .wchip { flex: none; white-space: nowrap }
|
|
750
|
+
|
|
751
|
+
/* ── 搜索 (⌘K): 名片下、关系/日程入口上的搜索框 + 居中浮层 ──────────────
|
|
752
|
+
入口与会话项同圆角, 安静的浅灰底; 浮层的结果行沿用会话项的两行读法。 */
|
|
753
|
+
.sbox {
|
|
754
|
+
flex: none; display: flex; align-items: center; gap: 8px; margin: 10px 10px 4px; padding: 7px 10px;
|
|
755
|
+
border: 1px solid var(--line); border-radius: 9px; background: var(--paper); color: var(--faint);
|
|
756
|
+
cursor: pointer; text-align: left; transition: border-color .12s, background .12s, color .12s;
|
|
757
|
+
}
|
|
758
|
+
.sbox:hover { border-color: #c4cbd6; background: var(--card); color: var(--mute) }
|
|
759
|
+
.sbox .ic, .sk-in .ic { flex: none; display: inline-flex }
|
|
760
|
+
.sbox .ic svg, .sk-in .ic svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round }
|
|
761
|
+
.sbox .lb { flex: 1; min-width: 0; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
762
|
+
.sbox kbd, .sk kbd {
|
|
763
|
+
flex: none; font: 500 10.5px/1 ui-sans-serif, system-ui, -apple-system, sans-serif; color: var(--mute);
|
|
764
|
+
padding: 3px 5px; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 5px; background: var(--card);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
.sk {
|
|
768
|
+
position: fixed; inset: 0; z-index: 900; display: flex; justify-content: center; align-items: flex-start;
|
|
769
|
+
padding: 12vh 16px 16px; background: #1c243038; animation: sk-in .12s ease-out;
|
|
770
|
+
}
|
|
771
|
+
.sk[hidden] { display: none }
|
|
772
|
+
@keyframes sk-in { from { opacity: 0 } }
|
|
773
|
+
.sk-panel {
|
|
774
|
+
width: 600px; max-width: 100%; max-height: 70vh; display: flex; flex-direction: column; overflow: hidden;
|
|
775
|
+
background: var(--card); border: 1px solid var(--line); border-radius: 14px;
|
|
776
|
+
box-shadow: 0 24px 64px #1c243033, 0 4px 14px #1c24301a;
|
|
777
|
+
}
|
|
778
|
+
.sk-in { flex: none; display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--line); color: var(--faint) }
|
|
779
|
+
.sk-in .ic svg { width: 17px; height: 17px }
|
|
780
|
+
.sk-in input {
|
|
781
|
+
flex: 1; min-width: 0; border: 0; outline: 0; background: none; font: inherit; font-size: 15px; color: var(--ink);
|
|
782
|
+
}
|
|
783
|
+
.sk-in input::-webkit-search-cancel-button { display: none }
|
|
784
|
+
.sk-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 4px 8px 8px }
|
|
785
|
+
.sk-list h3 {
|
|
786
|
+
margin: 10px 8px 4px; font-size: 11.5px; font-weight: 600; color: var(--mute);
|
|
787
|
+
display: flex; align-items: baseline; gap: 6px;
|
|
788
|
+
}
|
|
789
|
+
.sk-list h3 span { font-weight: 400; color: var(--faint); font-variant-numeric: tabular-nums }
|
|
790
|
+
.sk-it {
|
|
791
|
+
display: flex; gap: 10px; align-items: center; width: 100%; text-align: left; overflow: hidden;
|
|
792
|
+
padding: 7px 10px; border: 0; border-radius: 9px; background: transparent; cursor: pointer;
|
|
793
|
+
}
|
|
794
|
+
.sk-it.on { background: #eaf0fc }
|
|
795
|
+
.sk-it.msg { align-items: flex-start }
|
|
796
|
+
.sk-it.msg > .av { margin-top: 1px }
|
|
797
|
+
.sk-it > .av {
|
|
798
|
+
flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 9px;
|
|
799
|
+
background: #f1f3f6; font-size: 17px; line-height: 1;
|
|
800
|
+
}
|
|
801
|
+
.sk-it .b { min-width: 0; flex: 1; overflow: hidden }
|
|
802
|
+
.sk-it .l1 { display: flex; align-items: baseline; gap: 8px; overflow: hidden; white-space: nowrap }
|
|
803
|
+
.sk-it .nm { font-size: 13.5px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
804
|
+
.sk-it .k { margin-left: auto; flex: none; font-size: 11px; color: var(--faint); opacity: 0 }
|
|
805
|
+
.sk-it.on .k { opacity: 1; color: var(--accent) }
|
|
806
|
+
.sk-it .ts { margin-left: auto; flex: none; font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums }
|
|
807
|
+
.sk-it .pv { display: block; font-size: 12px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
|
|
808
|
+
.sk-it .l1 .nm + .nm, .sk-it .arr + .nm { font-weight: 500; color: var(--mute) }
|
|
809
|
+
.sk-it .arr { flex: none; color: var(--faint); font-size: 11.5px }
|
|
810
|
+
.sk-it .tag { flex: none; font-size: 10.5px; color: var(--mute); background: var(--paper); border-radius: 4px; padding: 1px 5px }
|
|
811
|
+
/* 命中的那一截: 正文色, 最多两行; 命中词是这一页的视角色淡底 —— 与选中态一个色系。 */
|
|
812
|
+
.sk-it .sn {
|
|
813
|
+
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
|
|
814
|
+
margin-top: 2px; font-size: 12.5px; line-height: 1.5; color: var(--ink); word-break: break-word;
|
|
815
|
+
}
|
|
816
|
+
.sk-it mark { background: #2f55c91f; color: var(--accent); font-weight: 600; border-radius: 3px; padding: 0 1px }
|
|
817
|
+
.sk-it.on mark { background: #2f55c92e }
|
|
818
|
+
.sk-it .l3 { display: flex; align-items: center; gap: 8px; margin-top: 3px; min-width: 0 }
|
|
819
|
+
.sk-it .where {
|
|
820
|
+
display: inline-flex; align-items: center; gap: 4px; min-width: 0; max-width: 70%;
|
|
821
|
+
font-size: 11px; color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
822
|
+
}
|
|
823
|
+
.sk-it .where i { font-style: normal; font-size: 12px; line-height: 1 }
|
|
824
|
+
.sk-it .where.priv { color: var(--priv) }
|
|
825
|
+
.sk-it .cnt { flex: none; font-size: 11px; color: var(--faint); font-variant-numeric: tabular-nums }
|
|
826
|
+
.sk-empty { padding: 18px 10px; text-align: center; font-size: 12.5px; color: var(--faint) }
|
|
827
|
+
.sk-foot {
|
|
828
|
+
flex: none; display: flex; gap: 16px; padding: 8px 16px; border-top: 1px solid var(--line);
|
|
829
|
+
font-size: 11px; color: var(--faint); background: #fafbfc;
|
|
830
|
+
}
|
|
831
|
+
.sk-foot span { display: inline-flex; align-items: center; gap: 4px }
|
|
832
|
+
.sk-foot kbd { padding: 2px 4px }
|
|
833
|
+
@media (max-width: 760px) {
|
|
834
|
+
.sk { padding-top: 8px }
|
|
835
|
+
.sk-panel { max-height: calc(100dvh - 16px) }
|
|
836
|
+
.sk-foot { display: none }
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/* 搜索跳到的那一句: 气泡闪一圈视角色。 */
|
|
840
|
+
.mrow.hit .mb > * { animation: hit 1.6s ease-out }
|
|
841
|
+
@keyframes hit { 0%, 30% { box-shadow: 0 0 0 3px #2f55c955 } 100% { box-shadow: 0 0 0 3px #2f55c900 } }
|