@co0ontty/wand 1.35.2 → 1.37.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.
@@ -112,9 +112,21 @@
112
112
  --ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55);
113
113
  }
114
114
 
115
- /* 尊重用户的减少动画偏好 */
115
+ /* 尊重用户的减少动画偏好。
116
+ 但 Android WebView 例外: Chromium 在 Android 上会把系统 Developer
117
+ Options 里的 "Animator duration scale" / "Transition animation scale"
118
+ (设为 0 = 关) 直接映射成 prefers-reduced-motion: reduce — 这俩开关其实
119
+ 是为 Android 原生 UI 转场设计的, 不少老用户为求"启动快"长期关着,
120
+ 省电模式也会强制关掉。结果就是 Wand APK 内所有入场动画 (queueBarEnter、
121
+ messageSlideUser 等) 被压成 0.01ms, 用户看不到"消息已加入排队"这种
122
+ 关键反馈, 跟浏览器版表现不一致。
123
+ html.is-wand-app 由 scripts.js 在 UA 含 WandApp/* 时挂到 <html> 上 ——
124
+ Wand APK 内自己定义动画策略, 不跟 Android 系统级开关绑死; 浏览器 /
125
+ 普通 PWA / 桌面端仍然完整尊重用户偏好 (排除 .is-wand-app 后规则不变)。 */
116
126
  @media (prefers-reduced-motion: reduce) {
117
- *, *::before, *::after {
127
+ html:not(.is-wand-app) *,
128
+ html:not(.is-wand-app) *::before,
129
+ html:not(.is-wand-app) *::after {
118
130
  animation-duration: 0.01ms !important;
119
131
  animation-iteration-count: 1 !important;
120
132
  transition-duration: 0.01ms !important;
@@ -677,18 +689,18 @@
677
689
  display: flex;
678
690
  align-items: center;
679
691
  justify-content: space-between;
680
- padding: 14px 16px;
692
+ padding: 12px 14px;
681
693
  border-bottom: 1px solid var(--border-subtle);
682
694
  background: rgba(255, 251, 245, 0.8);
683
695
  flex-shrink: 0;
684
- min-height: 56px;
685
- gap: 12px;
696
+ min-height: 52px;
697
+ gap: 10px;
686
698
  }
687
699
 
688
700
  .sidebar-header-main {
689
701
  display: flex;
690
702
  align-items: center;
691
- gap: 10px;
703
+ gap: 9px;
692
704
  min-width: 0;
693
705
  flex: 1;
694
706
  }
@@ -696,10 +708,16 @@
696
708
  .sidebar-header-actions {
697
709
  display: flex;
698
710
  align-items: center;
699
- gap: 6px;
711
+ gap: 4px;
700
712
  flex-shrink: 0;
701
713
  }
702
714
 
715
+ /* On desktop pinned mode the close (X) button is redundant — the hamburger
716
+ toggle in the topbar already opens/closes the sidebar. Hide it to declutter. */
717
+ .sidebar.pinned .sidebar-header-actions .sidebar-close {
718
+ display: none;
719
+ }
720
+
703
721
  .sidebar-header-more {
704
722
  position: relative;
705
723
  }
@@ -1260,7 +1278,7 @@
1260
1278
  flex: 1;
1261
1279
  min-height: 0;
1262
1280
  overflow-y: auto;
1263
- padding: 12px;
1281
+ padding: 10px 10px 12px;
1264
1282
  }
1265
1283
 
1266
1284
  .sessions-list:empty::before {
@@ -1282,7 +1300,7 @@
1282
1300
  the "Liquid Glass — sidebar" section below. */
1283
1301
 
1284
1302
  .session-group-title {
1285
- padding: 8px 8px 12px;
1303
+ padding: 4px 6px 10px;
1286
1304
  font-size: 0.6875rem;
1287
1305
  font-weight: 700;
1288
1306
  letter-spacing: 0.08em;
@@ -1296,9 +1314,9 @@
1296
1314
  .session-group-title::before {
1297
1315
  content: '';
1298
1316
  width: 3px;
1299
- height: 14px;
1317
+ height: 12px;
1300
1318
  background: var(--accent);
1301
- opacity: 0.7;
1319
+ opacity: 0.65;
1302
1320
  border-radius: var(--radius-full);
1303
1321
  }
1304
1322
 
@@ -1408,17 +1426,21 @@
1408
1426
  z-index: 1;
1409
1427
  }
1410
1428
 
1429
+ /* Keep content transparent by default so it doesn't paint a second
1430
+ gradient inside the card (which created a visible "white box" in the
1431
+ middle). Only opaque when swiped, so the actions stay hidden behind. */
1411
1432
  .session-item-content {
1412
1433
  position: relative;
1413
1434
  z-index: 2;
1414
- background: inherit;
1435
+ background: transparent;
1415
1436
  border-radius: inherit;
1416
- transition: transform 0.3s var(--ease-out-expo);
1437
+ transition: transform 0.3s var(--ease-out-expo), background 0.18s ease;
1417
1438
  will-change: transform;
1418
1439
  }
1419
1440
 
1420
1441
  .session-item.swiped .session-item-content {
1421
1442
  transform: translateX(-72px);
1443
+ background: linear-gradient(180deg, rgba(255, 252, 247, 0.96) 0%, rgba(252, 246, 237, 0.94) 100%);
1422
1444
  }
1423
1445
 
1424
1446
  .session-manage-check {
@@ -1443,11 +1465,18 @@
1443
1465
  width: 18px;
1444
1466
  height: 18px;
1445
1467
  border-radius: 6px;
1446
- border: 1px solid var(--border-subtle);
1447
- background: var(--bg-surface);
1468
+ border: 1px solid rgba(125, 91, 57, 0.22);
1469
+ background: rgba(255, 251, 245, 0.55);
1470
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4);
1448
1471
  display: inline-flex;
1449
1472
  align-items: center;
1450
1473
  justify-content: center;
1474
+ transition: background 0.15s ease, border-color 0.15s ease;
1475
+ }
1476
+
1477
+ .session-manage-check:hover span {
1478
+ background: rgba(255, 251, 245, 0.8);
1479
+ border-color: rgba(125, 91, 57, 0.35);
1451
1480
  }
1452
1481
 
1453
1482
  .session-manage-check input:checked + span {
@@ -1504,10 +1533,11 @@
1504
1533
  }
1505
1534
 
1506
1535
  .session-main {
1536
+ flex: 1;
1507
1537
  min-width: 0;
1508
1538
  display: flex;
1509
1539
  flex-direction: column;
1510
- gap: 3px;
1540
+ gap: 4px;
1511
1541
  padding-right: 64px;
1512
1542
  }
1513
1543
 
@@ -2220,8 +2250,158 @@
2220
2250
  font-weight: 500;
2221
2251
  }
2222
2252
 
2253
+ /* ===== Sidebar: docked Claude history region =====
2254
+ Lives between .sidebar-body and .sidebar-footer. Collapsed by default —
2255
+ only a slim header row ("历史消息" + 数字气泡) is visible, so the main
2256
+ scrolling area focuses on recent / archived sessions. Expanding it
2257
+ grows the region with a 40% max-height cap so it can never eat the
2258
+ sessions list above. */
2259
+ .sidebar-history-region {
2260
+ flex-shrink: 0;
2261
+ display: flex;
2262
+ flex-direction: column;
2263
+ min-height: 0;
2264
+ max-height: 40%;
2265
+ border-top: 1px solid var(--border-subtle);
2266
+ background: rgba(255, 251, 245, 0.66);
2267
+ transition: max-height 0.28s var(--ease-out-expo);
2268
+ }
2269
+
2270
+ .sidebar-history-header {
2271
+ display: flex;
2272
+ align-items: center;
2273
+ justify-content: space-between;
2274
+ width: 100%;
2275
+ padding: 9px 14px;
2276
+ min-height: 38px;
2277
+ flex-shrink: 0;
2278
+ background: transparent;
2279
+ border: none;
2280
+ border-radius: 0;
2281
+ cursor: pointer;
2282
+ text-align: left;
2283
+ font-family: var(--font-sans);
2284
+ font-size: 0.75rem;
2285
+ font-weight: 600;
2286
+ letter-spacing: 0.005em;
2287
+ color: var(--text-secondary);
2288
+ transition: background var(--transition-fast), color var(--transition-fast);
2289
+ -webkit-tap-highlight-color: transparent;
2290
+ }
2291
+
2292
+ .sidebar-history-header:hover {
2293
+ background: rgba(150, 118, 85, 0.06);
2294
+ color: var(--text-primary);
2295
+ }
2296
+
2297
+ .sidebar-history-header:active {
2298
+ background: rgba(150, 118, 85, 0.1);
2299
+ }
2300
+
2301
+ .sidebar-history-header.expanded {
2302
+ background: rgba(255, 251, 245, 0.85);
2303
+ color: var(--text-primary);
2304
+ border-bottom: 1px solid var(--border-subtle);
2305
+ }
2306
+
2307
+ .sidebar-history-label {
2308
+ display: inline-flex;
2309
+ align-items: center;
2310
+ gap: 6px;
2311
+ }
2312
+
2313
+ .sidebar-history-right {
2314
+ display: inline-flex;
2315
+ align-items: center;
2316
+ gap: 8px;
2317
+ flex-shrink: 0;
2318
+ }
2319
+
2320
+ /* Count bubble — pill shape, tabular numerals, accent-tinted when there
2321
+ are items, muted when empty/loading. */
2322
+ .history-bubble {
2323
+ display: inline-flex;
2324
+ align-items: center;
2325
+ justify-content: center;
2326
+ min-width: 22px;
2327
+ height: 18px;
2328
+ padding: 0 7px;
2329
+ border-radius: 999px;
2330
+ background: var(--accent-muted);
2331
+ color: var(--accent);
2332
+ font-size: 0.6875rem;
2333
+ font-weight: 700;
2334
+ font-variant-numeric: tabular-nums;
2335
+ line-height: 1;
2336
+ letter-spacing: 0;
2337
+ }
2338
+
2339
+ .history-bubble.empty {
2340
+ background: var(--bg-tertiary);
2341
+ color: var(--text-muted);
2342
+ opacity: 0.65;
2343
+ }
2344
+
2345
+ .history-bubble.loading {
2346
+ background: transparent;
2347
+ color: var(--text-muted);
2348
+ letter-spacing: 0.1em;
2349
+ padding: 0 4px;
2350
+ font-weight: 600;
2351
+ }
2352
+
2353
+ .sidebar-history-chevron {
2354
+ flex-shrink: 0;
2355
+ color: var(--text-muted);
2356
+ transition: transform 0.22s var(--ease-out-expo), color var(--transition-fast);
2357
+ }
2358
+
2359
+ .sidebar-history-header.expanded .sidebar-history-chevron {
2360
+ transform: rotate(180deg);
2361
+ color: var(--text-secondary);
2362
+ }
2363
+
2364
+ /* Expanded body — scrollable, capped via parent max-height. */
2365
+ .sidebar-history-body {
2366
+ flex: 1;
2367
+ min-height: 0;
2368
+ overflow-y: auto;
2369
+ padding: 6px 8px 10px;
2370
+ display: flex;
2371
+ flex-direction: column;
2372
+ gap: 4px;
2373
+ animation: historyBodyFadeIn 0.22s var(--ease-out-expo);
2374
+ }
2375
+
2376
+ @keyframes historyBodyFadeIn {
2377
+ from { opacity: 0; transform: translateY(-2px); }
2378
+ to { opacity: 1; transform: translateY(0); }
2379
+ }
2380
+
2381
+ .sidebar-history-toolbar {
2382
+ display: flex;
2383
+ justify-content: flex-end;
2384
+ padding: 2px 4px 6px;
2385
+ flex-shrink: 0;
2386
+ }
2387
+
2388
+ .sidebar-history-clear {
2389
+ color: var(--text-muted);
2390
+ font-weight: 500;
2391
+ }
2392
+ .sidebar-history-clear:hover {
2393
+ color: var(--danger);
2394
+ background: var(--danger-muted);
2395
+ }
2396
+
2397
+ .sidebar-history-scroll {
2398
+ display: flex;
2399
+ flex-direction: column;
2400
+ gap: 2px;
2401
+ }
2402
+
2223
2403
  .sidebar-footer {
2224
- padding: 14px;
2404
+ padding: 12px 12px 14px;
2225
2405
  border-top: 1px solid var(--border-subtle);
2226
2406
  display: flex;
2227
2407
  flex-direction: column;
@@ -2229,10 +2409,13 @@
2229
2409
  background: rgba(255, 251, 245, 0.7);
2230
2410
  }
2231
2411
 
2412
+ /* Auto-fit grid: 3 buttons stretch to fill, extra buttons (PWA install
2413
+ / switch server) drop in without breaking the row. minmax(56px,1fr)
2414
+ guarantees touch-friendly width while not leaving big empty cells. */
2232
2415
  .sidebar-footer-actions {
2233
2416
  display: grid;
2234
- grid-template-columns: repeat(4, 1fr);
2235
- gap: 6px;
2417
+ grid-template-columns: repeat(auto-fit, minmax(56px, 1fr));
2418
+ gap: 4px;
2236
2419
  }
2237
2420
 
2238
2421
  .sidebar-footer-actions .btn {
@@ -2240,19 +2423,22 @@
2240
2423
  flex-direction: column;
2241
2424
  align-items: center;
2242
2425
  justify-content: center;
2243
- gap: 3px;
2426
+ gap: 4px;
2244
2427
  font-size: 0.625rem;
2428
+ font-weight: 500;
2245
2429
  color: var(--text-muted);
2246
- padding: 8px 4px;
2247
- min-height: 48px;
2248
- border-radius: var(--radius-sm);
2249
- transition: all var(--transition-fast);
2430
+ padding: 7px 4px;
2431
+ min-height: 46px;
2432
+ border-radius: 9px;
2433
+ transition: background var(--transition-fast), color var(--transition-fast), transform var(--transition-fast);
2250
2434
  }
2251
2435
 
2252
2436
  .sidebar-footer-actions .btn svg {
2253
2437
  width: 16px;
2254
2438
  height: 16px;
2255
2439
  flex-shrink: 0;
2440
+ opacity: 0.85;
2441
+ transition: opacity var(--transition-fast);
2256
2442
  }
2257
2443
 
2258
2444
  .sidebar-footer-actions .btn:hover {
@@ -2261,6 +2447,10 @@
2261
2447
  transform: translateY(-1px);
2262
2448
  }
2263
2449
 
2450
+ .sidebar-footer-actions .btn:hover svg {
2451
+ opacity: 1;
2452
+ }
2453
+
2264
2454
  .sidebar-footer-actions .btn:active {
2265
2455
  transform: scale(0.95);
2266
2456
  transition-duration: 0.1s;
@@ -2270,6 +2460,30 @@
2270
2460
  display: none;
2271
2461
  }
2272
2462
 
2463
+ /* Subtle visual separation for the destructive "退出" so it doesn't
2464
+ sit visually equal to "文件 / 设置". A hairline divider on the left
2465
+ (collapses gracefully if it lands at the start of a wrapped row). */
2466
+ .sidebar-footer-actions .sidebar-logout {
2467
+ position: relative;
2468
+ }
2469
+ .sidebar-footer-actions .sidebar-logout::before {
2470
+ content: "";
2471
+ position: absolute;
2472
+ left: -3px;
2473
+ top: 22%;
2474
+ bottom: 22%;
2475
+ width: 1px;
2476
+ background: var(--border-subtle);
2477
+ pointer-events: none;
2478
+ }
2479
+ .sidebar-footer-actions .sidebar-logout:hover {
2480
+ color: var(--danger);
2481
+ background: var(--danger-muted);
2482
+ }
2483
+ .sidebar-footer-actions .sidebar-logout:hover svg {
2484
+ color: var(--danger);
2485
+ }
2486
+
2273
2487
  .sidebar-meta {
2274
2488
  display: flex;
2275
2489
  flex-direction: row;
@@ -4178,7 +4392,7 @@
4178
4392
  的 WebView,会把 color-mix(...) 当作 invalid 整条扔掉,导致背景/边框消失。
4179
4393
  下面凡是 color-mix 的属性都先写一条 rgba()/纯色 fallback,再被 color-mix
4180
4394
  覆盖;旧浏览器看到 fallback、新浏览器自动用 color-mix。同一文件里下方
4181
- .chat-handoff-tag / .subagent-reply / .subagent-reply-cycle 等也是同思路。 */
4395
+ .chat-handoff-tag / .subagent-reply / .subagent-reply-toggle 等也是同思路。 */
4182
4396
  .chat-handoff {
4183
4397
  align-self: flex-start;
4184
4398
  margin: 4px 0 2px 4px;
@@ -4264,15 +4478,18 @@
4264
4478
  padding: 14px 16px;
4265
4479
  }
4266
4480
 
4481
+ /* 短内容(error)形态:图标 + body 并列。用 flex 而不是 inline-block + display:inline,
4482
+ 后者在 body 内含块级 markdown(段落 / 代码块)时会塌掉。 */
4483
+ .subagent-reply:not(.collapsible) {
4484
+ display: flex;
4485
+ align-items: flex-start;
4486
+ gap: 6px;
4487
+ }
4267
4488
  .subagent-reply-icon {
4268
- display: inline-block;
4489
+ flex: 0 0 auto;
4269
4490
  color: var(--danger, #e2574c);
4270
- margin-right: 6px;
4271
4491
  font-weight: 700;
4272
- }
4273
-
4274
- .subagent-reply-body {
4275
- display: inline;
4492
+ line-height: 1.55;
4276
4493
  }
4277
4494
 
4278
4495
  .subagent-reply pre,
@@ -4293,98 +4510,250 @@
4293
4510
  min-width: 0;
4294
4511
  }
4295
4512
 
4296
- /* ===== subagent 回复三态折叠 =====
4297
- preview(默认)→ 限高 ~5 + 渐隐 mask + 内部可滚
4298
- expanded 拉到一个比较大的上限,内部可滚
4299
- collapsed → 完全收起,只剩底部一条工具栏,按钮还能再点回来 */
4300
- .subagent-reply.collapsible {
4301
- position: relative;
4302
- padding-right: 14px;
4303
- padding-bottom: 28px;
4304
- }
4305
-
4306
- .subagent-reply-scroll {
4513
+ /* ===== subagent panel(整段输出统一折叠面板)=====
4514
+ 结构:header(handoff + 展开按钮)+ body(max-height 22em 滚动)+ footer(同款按钮)
4515
+ 状态:data-expanded="false" 预览 / "true" 展开(body 拉到 70vh 仍可滚)
4516
+ 色彩:跟随 --agent-color(外层 inline style 注入),同 agent 跨 turn 颜色稳定 */
4517
+ .subagent-panel {
4518
+ margin: 8px 0;
4519
+ border: 1px solid color-mix(in srgb, var(--agent-color, var(--accent)) 25%, transparent);
4520
+ border-left: 3px solid color-mix(in srgb, var(--agent-color, var(--accent)) 55%, transparent);
4521
+ border-radius: 10px;
4307
4522
  overflow: hidden;
4308
- transition: max-height 0.32s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
4309
- min-width: 0;
4310
- max-width: 100%;
4523
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 3%, var(--bg-surface));
4524
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
4311
4525
  }
4312
- .subagent-reply-scroll > :first-child { margin-top: 0; }
4313
- .subagent-reply-scroll > :last-child { margin-bottom: 0; }
4314
4526
 
4315
- .subagent-reply.collapsible[data-collapse-mode="preview"] .subagent-reply-scroll {
4316
- max-height: 7.5em; /* ~5 行 */
4317
- overflow-y: auto;
4318
- -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent 100%);
4319
- mask-image: linear-gradient(to bottom, #000 70%, transparent 100%);
4527
+ .subagent-panel-header {
4528
+ display: flex;
4529
+ align-items: center;
4530
+ gap: 8px;
4531
+ padding: 8px 12px;
4532
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 10%, var(--bg-surface));
4533
+ border-bottom: 1px solid color-mix(in srgb, var(--agent-color, var(--accent)) 16%, transparent);
4534
+ cursor: pointer;
4535
+ user-select: none;
4536
+ font-size: 0.78rem;
4537
+ line-height: 1.35;
4538
+ transition: background 0.15s ease;
4539
+ }
4540
+ .subagent-panel-header:hover {
4541
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 14%, var(--bg-surface));
4542
+ }
4543
+ .subagent-panel-header:focus-visible {
4544
+ outline: 2px solid color-mix(in srgb, var(--agent-color, var(--accent)) 55%, transparent);
4545
+ outline-offset: -2px;
4320
4546
  }
4321
4547
 
4322
- .subagent-reply.collapsible[data-collapse-mode="expanded"] .subagent-reply-scroll {
4323
- max-height: 360px;
4324
- overflow-y: auto;
4548
+ .subagent-panel-avatar {
4549
+ flex: 0 0 auto;
4550
+ width: 22px;
4551
+ height: 22px;
4552
+ border-radius: 5px;
4553
+ overflow: hidden;
4554
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 18%, transparent);
4555
+ display: inline-flex;
4556
+ align-items: center;
4557
+ justify-content: center;
4558
+ }
4559
+ .subagent-panel-avatar svg,
4560
+ .subagent-panel-avatar img {
4561
+ width: 100%;
4562
+ height: 100%;
4563
+ display: block;
4325
4564
  }
4326
4565
 
4327
- .subagent-reply.collapsible[data-collapse-mode="collapsed"] {
4328
- padding-top: 6px;
4329
- padding-bottom: 26px;
4566
+ .subagent-panel-arrow {
4567
+ flex: 0 0 auto;
4568
+ color: color-mix(in srgb, var(--agent-color, var(--accent)) 65%, var(--text-primary));
4569
+ opacity: 0.8;
4570
+ font-weight: 600;
4330
4571
  }
4331
- .subagent-reply.collapsible[data-collapse-mode="collapsed"] .subagent-reply-scroll {
4332
- max-height: 0;
4572
+
4573
+ .subagent-panel-attribution {
4574
+ flex: 1 1 auto;
4575
+ min-width: 0;
4576
+ color: var(--text-primary);
4333
4577
  overflow: hidden;
4334
- margin: 0;
4578
+ text-overflow: ellipsis;
4579
+ white-space: nowrap;
4580
+ }
4581
+ .subagent-panel-name {
4582
+ color: color-mix(in srgb, var(--agent-color, var(--accent)) 88%, var(--text-primary));
4583
+ font-weight: 600;
4584
+ }
4585
+ .subagent-panel-tag {
4586
+ display: inline-block;
4587
+ margin: 0 6px;
4588
+ padding: 0 6px;
4589
+ font-size: 0.62rem;
4590
+ font-weight: 500;
4591
+ letter-spacing: 0.04em;
4592
+ color: var(--agent-color, var(--accent));
4593
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 12%, transparent);
4594
+ border: 1px solid color-mix(in srgb, var(--agent-color, var(--accent)) 30%, transparent);
4595
+ border-radius: 4px;
4596
+ vertical-align: 1px;
4597
+ line-height: 1.4;
4598
+ white-space: nowrap;
4599
+ /* 注意:不要加 text-transform: uppercase。之前用 lowercase "subagent" + uppercase 强转
4600
+ 出来 "SUBAGENT",结果中文 UI 里冒出来一个英文大写词跟用户配置语言(中文)对不上。
4601
+ 现在文案直接走 i18n(t("subagent.tag") = "子代理" / "Subagent"),无需大小写强制。 */
4602
+ }
4603
+ .subagent-panel-task-desc {
4604
+ color: var(--text-muted);
4605
+ font-weight: 400;
4335
4606
  }
4336
4607
 
4337
- /* 三态循环按钮:固定在气泡右下角,三种模式下都可见 */
4338
- .subagent-reply-cycle {
4339
- position: absolute;
4340
- right: 8px;
4341
- bottom: 6px;
4608
+ .subagent-panel-toggle {
4609
+ flex: 0 0 auto;
4342
4610
  display: inline-flex;
4343
4611
  align-items: center;
4344
- gap: 3px;
4345
- padding: 2px 8px;
4612
+ gap: 4px;
4613
+ padding: 3px 10px;
4346
4614
  font-size: 0.7rem;
4347
4615
  font-weight: 500;
4348
- line-height: 1.4;
4349
- color: var(--accent);
4350
- color: var(--agent-color, var(--accent));
4351
- background: rgba(255, 248, 240, 0.95);
4352
- background: color-mix(in srgb, var(--agent-color, var(--accent)) 8%, var(--bg-surface, #fff));
4353
- border: 1px solid rgba(197, 101, 61, 0.28);
4354
- border: 1px solid color-mix(in srgb, var(--agent-color, var(--accent)) 28%, transparent);
4616
+ line-height: 1.3;
4617
+ color: color-mix(in srgb, var(--agent-color, var(--accent)) 78%, var(--text-primary));
4618
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 8%, var(--bg-surface));
4619
+ border: 1px solid color-mix(in srgb, var(--agent-color, var(--accent)) 30%, transparent);
4355
4620
  border-radius: 999px;
4356
4621
  cursor: pointer;
4357
4622
  user-select: none;
4358
- transition: background 0.15s ease, transform 0.1s ease, border-color 0.15s ease;
4623
+ transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
4359
4624
  }
4360
- .subagent-reply-cycle:hover {
4361
- background: rgba(248, 226, 210, 1);
4362
- background: color-mix(in srgb, var(--agent-color, var(--accent)) 16%, var(--bg-surface, #fff));
4363
- border-color: rgba(197, 101, 61, 0.45);
4625
+ .subagent-panel-toggle:hover {
4626
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 18%, var(--bg-surface));
4364
4627
  border-color: color-mix(in srgb, var(--agent-color, var(--accent)) 45%, transparent);
4365
4628
  }
4366
- .subagent-reply-cycle:active {
4629
+ .subagent-panel-toggle:active {
4367
4630
  transform: translateY(1px);
4368
4631
  }
4369
- .subagent-reply-cycle-icon {
4370
- font-size: 0.7rem;
4371
- line-height: 1;
4632
+ .subagent-panel-toggle-icon {
4633
+ transition: transform 0.2s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
4634
+ }
4635
+ .subagent-panel[data-expanded="true"] .subagent-panel-toggle-icon {
4636
+ transform: rotate(180deg);
4372
4637
  }
4373
4638
 
4374
- /* 内部滚动条做小一点,别抢戏 */
4375
- .subagent-reply-scroll::-webkit-scrollbar {
4376
- width: 6px;
4377
- height: 6px;
4639
+ /* body:默认 max-height 22em(≈14 行),内部滚动;展开后拉到 70vh 仍内部可滚,
4640
+ 避免一个超长 subagent 把整页撑爆。展开过渡只动 max-height,body 内的卡片
4641
+ 不动,不会有抖动。 */
4642
+ .subagent-panel-body {
4643
+ padding: 10px 14px;
4644
+ overflow-y: auto;
4645
+ overflow-x: hidden;
4646
+ min-width: 0;
4647
+ max-width: 100%;
4648
+ transition: max-height 0.28s var(--ease-out-expo, cubic-bezier(0.16, 1, 0.3, 1));
4649
+ scrollbar-gutter: stable;
4378
4650
  }
4379
- .subagent-reply-scroll::-webkit-scrollbar-thumb {
4380
- background: rgba(197, 101, 61, 0.35);
4381
- background: color-mix(in srgb, var(--agent-color, var(--accent)) 35%, transparent);
4382
- border-radius: 3px;
4651
+ .subagent-panel[data-expanded="false"] .subagent-panel-body {
4652
+ max-height: 22em;
4653
+ }
4654
+ .subagent-panel[data-expanded="true"] .subagent-panel-body {
4655
+ max-height: 70vh;
4656
+ }
4657
+ .subagent-panel-body > :first-child { margin-top: 0; }
4658
+ .subagent-panel-body > :last-child { margin-bottom: 0; }
4659
+
4660
+ /* body 里的工具卡 / 文本:缩一点字号 + 减小 margin,让 22em 能装下更多内容 */
4661
+ .subagent-panel-body .tool-use-card,
4662
+ .subagent-panel-body .tool-group,
4663
+ .subagent-panel-body .inline-tool,
4664
+ .subagent-panel-body .inline-terminal,
4665
+ .subagent-panel-body .inline-diff {
4666
+ margin: 4px 0;
4667
+ }
4668
+ .subagent-panel-body .markdown-content {
4669
+ font-size: 0.875rem;
4383
4670
  }
4384
- .subagent-reply-scroll::-webkit-scrollbar-track {
4671
+
4672
+ /* body 滚动条:弱化但仍可见,对应 agent 色 */
4673
+ .subagent-panel-body::-webkit-scrollbar {
4674
+ width: 7px;
4675
+ height: 7px;
4676
+ }
4677
+ .subagent-panel-body::-webkit-scrollbar-thumb {
4678
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 32%, transparent);
4679
+ border-radius: 4px;
4680
+ }
4681
+ .subagent-panel-body::-webkit-scrollbar-thumb:hover {
4682
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 50%, transparent);
4683
+ }
4684
+ .subagent-panel-body::-webkit-scrollbar-track {
4385
4685
  background: transparent;
4386
4686
  }
4387
4687
 
4688
+ /* footer:跟 header 对称,永远可见在 panel 底部。滚到 body 最下时用户能就近点。
4689
+ hint 是个软提示"— 协作猫 —",告诉用户 panel 边界,避免与下一段父消息混淆。 */
4690
+ .subagent-panel-footer {
4691
+ display: flex;
4692
+ align-items: center;
4693
+ gap: 10px;
4694
+ padding: 6px 12px;
4695
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 6%, var(--bg-surface));
4696
+ border-top: 1px solid color-mix(in srgb, var(--agent-color, var(--accent)) 14%, transparent);
4697
+ font-size: 0.7rem;
4698
+ }
4699
+ .subagent-panel-footer-hint {
4700
+ flex: 1 1 auto;
4701
+ min-width: 0;
4702
+ color: var(--text-muted);
4703
+ opacity: 0.7;
4704
+ font-family: var(--font-mono);
4705
+ letter-spacing: 0.04em;
4706
+ overflow: hidden;
4707
+ text-overflow: ellipsis;
4708
+ white-space: nowrap;
4709
+ }
4710
+
4711
+ /* ===== panel 内最终回复的简化标记块(外层 panel 已经管折叠,这里只剩"任务完成"标记)===== */
4712
+ .subagent-reply.collapsible {
4713
+ padding: 0;
4714
+ overflow: hidden;
4715
+ }
4716
+ .subagent-reply.final {
4717
+ margin: 6px 0 0;
4718
+ padding: 10px 12px;
4719
+ border-radius: 8px;
4720
+ border-left: 3px solid color-mix(in srgb, var(--agent-color, var(--accent)) 60%, transparent);
4721
+ background: color-mix(in srgb, var(--agent-color, var(--accent)) 5%, var(--bg-surface));
4722
+ }
4723
+ .subagent-reply.final.error {
4724
+ border-left-color: var(--danger, #e2574c);
4725
+ background: color-mix(in srgb, var(--danger, #e2574c) 5%, var(--bg-surface));
4726
+ }
4727
+ .subagent-reply-marker {
4728
+ display: inline-flex;
4729
+ align-items: center;
4730
+ gap: 4px;
4731
+ margin-bottom: 4px;
4732
+ font-size: 0.68rem;
4733
+ font-weight: 600;
4734
+ letter-spacing: 0.04em;
4735
+ text-transform: uppercase;
4736
+ color: color-mix(in srgb, var(--agent-color, var(--accent)) 78%, var(--text-primary));
4737
+ }
4738
+ .subagent-reply-marker.error {
4739
+ color: var(--danger, #e2574c);
4740
+ }
4741
+ .subagent-reply-marker.pending {
4742
+ color: var(--text-muted);
4743
+ text-transform: none;
4744
+ letter-spacing: 0;
4745
+ font-weight: 500;
4746
+ }
4747
+ .subagent-reply-marker-icon {
4748
+ font-weight: 700;
4749
+ }
4750
+ .subagent-reply.final .subagent-reply-content > :first-child { margin-top: 0; }
4751
+ .subagent-reply.final .subagent-reply-content > :last-child { margin-bottom: 0; }
4752
+
4753
+ /* (旧的 .subagent-reply-header / .subagent-reply-toggle / .subagent-reply-body /
4754
+ .subagent-reply-fade / .subagent-reply-body-inline 系列已移除——现在外层
4755
+ .subagent-panel 接管整段折叠 + 滚动,内层最终回复退化为简化标记块。) */
4756
+
4388
4757
  /* ===== 消息使用量信息 ===== */
4389
4758
  .message-usage {
4390
4759
  margin-top: 8px;
@@ -10521,6 +10890,26 @@
10521
10890
  .tool-use-file { max-width: 100%; }
10522
10891
  .tool-use-body { padding: 10px 12px; }
10523
10892
  .subagent-reply { padding: 9px 12px; }
10893
+ .subagent-reply.collapsible { padding: 0; }
10894
+ .subagent-reply.final { padding: 9px 11px; }
10895
+ /* subagent-panel:窄屏头部不省略 attribution(可换行多行 vs 单行省略),
10896
+ body 高度收紧一点,footer hint 隐掉只留按钮。 */
10897
+ .subagent-panel { margin: 6px 0; }
10898
+ .subagent-panel-header {
10899
+ padding: 7px 10px;
10900
+ gap: 6px;
10901
+ font-size: 0.74rem;
10902
+ }
10903
+ .subagent-panel-attribution {
10904
+ white-space: normal;
10905
+ line-height: 1.4;
10906
+ }
10907
+ .subagent-panel-tag { margin: 0 4px; padding: 0 4px; }
10908
+ .subagent-panel-body { padding: 9px 11px; }
10909
+ .subagent-panel[data-expanded="false"] .subagent-panel-body { max-height: 18em; }
10910
+ .subagent-panel[data-expanded="true"] .subagent-panel-body { max-height: 60vh; }
10911
+ .subagent-panel-footer { padding: 5px 10px; }
10912
+ .subagent-panel-footer-hint { display: none; }
10524
10913
  .markdown-content .code-block { margin: 8px 0; }
10525
10914
  .markdown-content pre,
10526
10915
  .markdown-content .code-block pre,
@@ -15688,4 +16077,191 @@
15688
16077
  }
15689
16078
  .working-dir-indicator-icon > svg { display: block; }
15690
16079
 
16080
+ /* ===== 终端悬浮摇杆遥控器(手机端 PTY 遥控) ===== */
16081
+ .wand-joystick-root {
16082
+ position: fixed;
16083
+ inset: 0;
16084
+ z-index: 40;
16085
+ pointer-events: none;
16086
+ opacity: 0;
16087
+ visibility: hidden;
16088
+ transition: opacity 0.2s ease;
16089
+ }
16090
+ .wand-joystick-root.visible {
16091
+ opacity: 1;
16092
+ visibility: visible;
16093
+ }
16094
+ .wand-joystick-backdrop {
16095
+ position: absolute;
16096
+ inset: 0;
16097
+ background: rgba(20, 15, 12, 0);
16098
+ pointer-events: none;
16099
+ transition: background 0.2s ease;
16100
+ }
16101
+ .wand-joystick-backdrop.active {
16102
+ background: rgba(20, 15, 12, 0.28);
16103
+ pointer-events: auto;
16104
+ }
16105
+ .wand-joystick-ball {
16106
+ position: fixed;
16107
+ right: 18px;
16108
+ bottom: 96px;
16109
+ width: 52px;
16110
+ height: 52px;
16111
+ border-radius: 50%;
16112
+ display: flex;
16113
+ align-items: center;
16114
+ justify-content: center;
16115
+ color: rgba(245, 235, 225, 0.95);
16116
+ background: rgba(32, 25, 21, 0.78);
16117
+ border: 1px solid rgba(197, 101, 61, 0.34);
16118
+ box-shadow:
16119
+ 0 6px 20px rgba(0, 0, 0, 0.36),
16120
+ inset 0 1px 0 rgba(255, 255, 255, 0.1);
16121
+ backdrop-filter: blur(8px);
16122
+ -webkit-backdrop-filter: blur(8px);
16123
+ pointer-events: auto;
16124
+ touch-action: none;
16125
+ -webkit-tap-highlight-color: transparent;
16126
+ user-select: none;
16127
+ -webkit-user-select: none;
16128
+ z-index: 43;
16129
+ cursor: grab;
16130
+ transition: transform 0.18s var(--ease-spring), background 0.2s ease, border-color 0.2s ease;
16131
+ }
16132
+ .wand-joystick-ball:hover { border-color: rgba(197, 101, 61, 0.55); }
16133
+ .wand-joystick-ball:active { background: rgba(44, 34, 28, 0.88); }
16134
+ .wand-joystick-ball.dragging {
16135
+ transform: scale(1.12);
16136
+ cursor: grabbing;
16137
+ box-shadow: 0 10px 28px rgba(0, 0, 0, 0.42);
16138
+ }
16139
+ /* 环形菜单:圆心运行期由 JS 对齐球球中心 */
16140
+ .wand-joystick-ring {
16141
+ position: fixed;
16142
+ left: 0;
16143
+ top: 0;
16144
+ width: 0;
16145
+ height: 0;
16146
+ z-index: 42;
16147
+ pointer-events: none;
16148
+ opacity: 0;
16149
+ transform: scale(0.6);
16150
+ transition: opacity 0.18s var(--ease-out-expo), transform 0.22s var(--ease-spring);
16151
+ }
16152
+ .wand-joystick-ring.active {
16153
+ opacity: 1;
16154
+ transform: scale(1);
16155
+ }
16156
+ .wjr-svg {
16157
+ position: absolute;
16158
+ left: 0;
16159
+ top: 0;
16160
+ transform: translate(-50%, -50%);
16161
+ overflow: visible;
16162
+ pointer-events: none;
16163
+ filter: drop-shadow(0 10px 30px rgba(0, 0, 0, 0.5));
16164
+ }
16165
+ /* 底盘:所有扇区之下的玻璃圆盘,扇区细缝与外缘透出它,统一成一颗整盘 */
16166
+ .wjr-base {
16167
+ fill: rgba(18, 13, 10, 0.8);
16168
+ stroke: rgba(245, 235, 225, 0.14);
16169
+ stroke-width: 1;
16170
+ }
16171
+ .wjr-svg text {
16172
+ text-anchor: middle;
16173
+ dominant-baseline: central;
16174
+ font-size: 10.5px;
16175
+ font-weight: 600;
16176
+ fill: #f6ede3;
16177
+ /* 描边垫底 → 标签在任意扇区色/穿透的终端字上都清晰 */
16178
+ paint-order: stroke;
16179
+ stroke: rgba(10, 7, 5, 0.55);
16180
+ stroke-width: 2.2px;
16181
+ stroke-linejoin: round;
16182
+ pointer-events: none;
16183
+ }
16184
+ .wjr-inner text { font-size: 16px; fill: #fff; }
16185
+ .wjr-svg .wjr-2line { font-size: 9.5px; }
16186
+ .wjr-sector path {
16187
+ fill: rgba(74, 61, 53, 0.9); /* 功能圈:暖玻璃面,明显高于底盘与终端背景 */
16188
+ stroke: none;
16189
+ transition: fill 0.12s ease;
16190
+ }
16191
+ .wjr-inner path { fill: rgba(56, 45, 39, 0.92); } /* 方向圈略深,与功能圈区分层次 */
16192
+ .wjr-sector.is-repeating path,
16193
+ .wjr-sector.is-hover path { fill: var(--accent); }
16194
+ .wjr-sector.is-repeating text,
16195
+ .wjr-sector.is-hover text { fill: #fff; stroke: rgba(120, 42, 18, 0.5); }
16196
+ .wjr-sector.is-repeating,
16197
+ .wjr-sector.is-hover { filter: drop-shadow(0 0 9px rgba(197, 101, 61, 0.6)); }
16198
+ .wjr-hub {
16199
+ fill: rgba(14, 10, 8, 0.96);
16200
+ stroke: rgba(245, 235, 225, 0.22);
16201
+ stroke-width: 1.5;
16202
+ }
16203
+ text.wjr-hub-label { font-size: 12px; font-weight: 700; fill: #f6ede3; stroke: none; }
16204
+ .wand-joystick-ball.is-ringing { opacity: 0; }
16205
+ /* 钉住面板 */
16206
+ .wand-joystick-panel {
16207
+ position: fixed;
16208
+ right: 18px;
16209
+ bottom: 160px;
16210
+ z-index: 44;
16211
+ display: flex;
16212
+ flex-direction: column;
16213
+ gap: 8px;
16214
+ padding: 12px;
16215
+ border-radius: 16px;
16216
+ background: rgba(28, 22, 18, 0.92);
16217
+ border: 1px solid rgba(245, 235, 225, 0.14);
16218
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
16219
+ backdrop-filter: blur(10px);
16220
+ -webkit-backdrop-filter: blur(10px);
16221
+ pointer-events: none;
16222
+ opacity: 0;
16223
+ transform: translateY(8px) scale(0.96);
16224
+ transform-origin: bottom right;
16225
+ transition: opacity 0.18s var(--ease-out-expo), transform 0.22s var(--ease-spring);
16226
+ max-width: calc(100vw - 36px);
16227
+ }
16228
+ .wand-joystick-panel.active {
16229
+ pointer-events: auto;
16230
+ opacity: 1;
16231
+ transform: translateY(0) scale(1);
16232
+ }
16233
+ .wjp-title {
16234
+ font-size: 0.66rem;
16235
+ letter-spacing: 0.08em;
16236
+ text-transform: uppercase;
16237
+ color: rgba(245, 235, 225, 0.5);
16238
+ text-align: center;
16239
+ }
16240
+ .wjp-dpad { display: flex; flex-direction: column; align-items: center; gap: 4px; }
16241
+ .wjp-dpad-row { display: flex; gap: 4px; }
16242
+ .wjp-grid { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
16243
+ .wjp-fnkeys { max-width: 200px; }
16244
+ .wjp-key {
16245
+ min-width: 44px;
16246
+ height: 40px;
16247
+ padding: 0 8px;
16248
+ border-radius: 10px;
16249
+ font-size: 0.78rem;
16250
+ font-weight: 600;
16251
+ color: rgba(245, 235, 225, 0.92);
16252
+ background: rgba(255, 255, 255, 0.06);
16253
+ border: 1px solid rgba(245, 235, 225, 0.14);
16254
+ cursor: pointer;
16255
+ touch-action: manipulation;
16256
+ -webkit-tap-highlight-color: transparent;
16257
+ user-select: none;
16258
+ transition: transform 0.1s ease, background 0.15s ease;
16259
+ }
16260
+ .wjp-key:active { background: var(--accent-soft, rgba(197, 101, 61, 0.2)); transform: scale(0.94); }
16261
+ .wjp-key.wjp-mod.active {
16262
+ background: var(--accent);
16263
+ color: #fff;
16264
+ border-color: var(--accent);
16265
+ }
16266
+
15691
16267
  /* 结束标记 */