@bolloon/bolloon-agent 0.6.5 → 0.6.7

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.
Files changed (188) hide show
  1. package/dist/agents/chain/chain-settlement.js +0 -1
  2. package/dist/agents/chat-segmenter.js +4 -16
  3. package/dist/agents/contacts/human-directory.js +155 -0
  4. package/dist/agents/contacts/tools.js +79 -0
  5. package/dist/agents/experience-review.js +0 -3
  6. package/dist/agents/goal-flywheel/goal-change.js +3 -4
  7. package/dist/agents/goal-resume.js +0 -4
  8. package/dist/agents/ha-daemon.js +85 -0
  9. package/dist/agents/ha-supervisor.js +146 -0
  10. package/dist/agents/intent-classifier.js +1 -1
  11. package/dist/agents/iteration-budget.js +12 -0
  12. package/dist/agents/knowledge-organizer.js +0 -2
  13. package/dist/agents/lesson-to-skill.js +0 -1
  14. package/dist/agents/loop-review.js +2 -2
  15. package/dist/agents/memory-store.js +384 -0
  16. package/dist/agents/opportunity-match.js +15 -3
  17. package/dist/agents/opportunity-web-search.js +39 -0
  18. package/dist/agents/p2p-chat-tools.js +1 -2
  19. package/dist/agents/parse-tool-call.js +9 -22
  20. package/dist/agents/pi-harness.js +1 -2
  21. package/dist/agents/pi-sdk-session-manager.js +8 -0
  22. package/dist/agents/pi-sdk-tools.js +180 -5
  23. package/dist/agents/pi-sdk.js +210 -503
  24. package/dist/agents/process-runner.js +28 -9
  25. package/dist/agents/react-loop.js +9 -17
  26. package/dist/agents/runner-resolver.js +4 -3
  27. package/dist/agents/skill-loader.js +22 -15
  28. package/dist/agents/skills-manager.js +1 -25
  29. package/dist/agents/workflow-pivot-loop.js +152 -61
  30. package/dist/bootstrap/context-collector.js +67 -7
  31. package/dist/bootstrap/context-hierarchy.js +13 -1
  32. package/dist/bootstrap/persona-loader.js +26 -0
  33. package/dist/cli/ink-app.js +44 -17
  34. package/dist/cli/intent-command.js +22 -12
  35. package/dist/cli/loading-tui.js +8 -2
  36. package/dist/cli/log-gate.js +40 -8
  37. package/dist/cli/mention-data.js +1 -0
  38. package/dist/cli/reply-hygiene.js +22 -0
  39. package/dist/cli/trace-line.js +61 -2
  40. package/dist/electron-build/agents/agent-gateway.js.map +1 -1
  41. package/dist/electron-build/agents/chain/chain-indexer.js.map +1 -1
  42. package/dist/electron-build/agents/chain/chain-settlement.js +0 -1
  43. package/dist/electron-build/agents/chain/chain-settlement.js.map +1 -1
  44. package/dist/electron-build/agents/contacts/chain.js.map +1 -1
  45. package/dist/electron-build/agents/contacts/human-directory.js +204 -0
  46. package/dist/electron-build/agents/contacts/human-directory.js.map +1 -0
  47. package/dist/electron-build/agents/contacts/policy.js.map +1 -1
  48. package/dist/electron-build/agents/contacts/tools.js +112 -0
  49. package/dist/electron-build/agents/contacts/tools.js.map +1 -1
  50. package/dist/electron-build/agents/experience-review.js +0 -3
  51. package/dist/electron-build/agents/experience-review.js.map +1 -1
  52. package/dist/electron-build/agents/external-events.js.map +1 -1
  53. package/dist/electron-build/agents/goal-flywheel/goal-change.js +3 -4
  54. package/dist/electron-build/agents/goal-flywheel/goal-change.js.map +1 -1
  55. package/dist/electron-build/agents/goal-flywheel-wiring.js.map +1 -1
  56. package/dist/electron-build/agents/goal-resume.js +0 -4
  57. package/dist/electron-build/agents/goal-resume.js.map +1 -1
  58. package/dist/electron-build/agents/intent-classifier.js +1 -1
  59. package/dist/electron-build/agents/lesson-to-skill.js +0 -1
  60. package/dist/electron-build/agents/lesson-to-skill.js.map +1 -1
  61. package/dist/electron-build/agents/loop-review.js +2 -2
  62. package/dist/electron-build/agents/loop-review.js.map +1 -1
  63. package/dist/electron-build/agents/memory-recall.js.map +1 -1
  64. package/dist/electron-build/agents/memory-store.js +430 -0
  65. package/dist/electron-build/agents/memory-store.js.map +1 -0
  66. package/dist/electron-build/agents/parse-tool-call.js +9 -22
  67. package/dist/electron-build/agents/parse-tool-call.js.map +1 -1
  68. package/dist/electron-build/agents/pi-harness.js +1 -2
  69. package/dist/electron-build/agents/pi-harness.js.map +1 -1
  70. package/dist/electron-build/agents/pi-sdk-session-manager.js +8 -0
  71. package/dist/electron-build/agents/pi-sdk-session-manager.js.map +1 -1
  72. package/dist/electron-build/agents/pi-sdk-tools.js +180 -5
  73. package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
  74. package/dist/electron-build/agents/pi-sdk.js +208 -501
  75. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  76. package/dist/electron-build/agents/pre-tool-validator.js.map +1 -1
  77. package/dist/electron-build/agents/process-runner.js +28 -9
  78. package/dist/electron-build/agents/process-runner.js.map +1 -1
  79. package/dist/electron-build/agents/runner-resolver.js +4 -3
  80. package/dist/electron-build/agents/runner-resolver.js.map +1 -1
  81. package/dist/electron-build/agents/skill-loader.js +22 -16
  82. package/dist/electron-build/agents/skill-loader.js.map +1 -1
  83. package/dist/electron-build/agents/skill-supervisor-link.js.map +1 -1
  84. package/dist/electron-build/agents/skills-manager.js +0 -24
  85. package/dist/electron-build/agents/skills-manager.js.map +1 -1
  86. package/dist/electron-build/agents/task/task-runner.js.map +1 -1
  87. package/dist/electron-build/agents/workflow-engine.js.map +1 -1
  88. package/dist/electron-build/agents/workflow-pivot-loop.js +155 -62
  89. package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -1
  90. package/dist/electron-build/agents/x402/goal-run-bridge.js.map +1 -1
  91. package/dist/electron-build/bollharness-integration/gate-state-machine.js.map +1 -1
  92. package/dist/electron-build/bootstrap/context-collector.js +68 -7
  93. package/dist/electron-build/bootstrap/context-collector.js.map +1 -1
  94. package/dist/electron-build/bootstrap/context-hierarchy.js +13 -1
  95. package/dist/electron-build/bootstrap/context-hierarchy.js.map +1 -1
  96. package/dist/electron-build/bootstrap/persona-loader.js +27 -0
  97. package/dist/electron-build/bootstrap/persona-loader.js.map +1 -1
  98. package/dist/electron-build/electron-preload.js.map +1 -1
  99. package/dist/electron-build/external-engines/delegate.js.map +1 -1
  100. package/dist/electron-build/kernel/channel-actor.js +31 -2
  101. package/dist/electron-build/kernel/channel-actor.js.map +1 -1
  102. package/dist/electron-build/kernel/model-runtime.js +8 -1
  103. package/dist/electron-build/kernel/model-runtime.js.map +1 -1
  104. package/dist/electron-build/llm/config-store.js +20 -0
  105. package/dist/electron-build/llm/config-store.js.map +1 -1
  106. package/dist/electron-build/llm/embedding-adapter.js +75 -0
  107. package/dist/electron-build/llm/embedding-adapter.js.map +1 -0
  108. package/dist/electron-build/llm/pi-ai.js +112 -38
  109. package/dist/electron-build/llm/pi-ai.js.map +1 -1
  110. package/dist/electron-build/llm/system-prompt/registry.js +8 -6
  111. package/dist/electron-build/llm/system-prompt/registry.js.map +1 -1
  112. package/dist/electron-build/network/agent-network.js.map +1 -1
  113. package/dist/electron-build/orbitdb/memory-sync.js +76 -0
  114. package/dist/electron-build/orbitdb/memory-sync.js.map +1 -0
  115. package/dist/electron-build/pi-ecosystem-judgment/adaptive-scan.js.map +1 -1
  116. package/dist/electron-build/security/tool-gate.js +2 -0
  117. package/dist/electron-build/security/tool-gate.js.map +1 -1
  118. package/dist/electron-build/setup/setup-store.js +34 -6
  119. package/dist/electron-build/setup/setup-store.js.map +1 -1
  120. package/dist/electron-build/social/heartbeat.js +18 -5
  121. package/dist/electron-build/social/heartbeat.js.map +1 -1
  122. package/dist/electron-build/utils/update-manager.js.map +1 -1
  123. package/dist/index.js +250 -12
  124. package/dist/ios/bolloon-web.json +3 -3
  125. package/dist/ios/client.js +74 -35
  126. package/dist/ios/icons/icon-1400x1400.png +0 -0
  127. package/dist/ios/icons/icon-1400x1400.webp +0 -0
  128. package/dist/ios/index.html +122 -108
  129. package/dist/ios/mobile-agent.js +572 -45
  130. package/dist/ios/mobile-contacts.js +0 -4
  131. package/dist/ios/mobile-core.js +8079 -4590
  132. package/dist/ios/mobile-harness.js +1004 -0
  133. package/dist/ios/mobile-memory.js +317 -0
  134. package/dist/ios/mobile-orbitdb.js +194 -0
  135. package/dist/ios/mobile-persona.js +80 -0
  136. package/dist/ios/mobile-privacy.js +2 -3
  137. package/dist/ios/mobile.css +286 -21
  138. package/dist/ios/mobile.html +122 -108
  139. package/dist/ios/mobile.js +434 -152
  140. package/dist/ios/routes-contacts.js +94 -1
  141. package/dist/ios/routes-world.js +13 -2
  142. package/dist/ios/server.js +54 -41
  143. package/dist/ios/style.css +13 -5
  144. package/dist/ios/sw.js +1 -1
  145. package/dist/ios/ui/message-renderer.js +4 -18
  146. package/dist/ios/ui/step-timeline.js +14 -1
  147. package/dist/kernel/channel-actor.js +30 -2
  148. package/dist/kernel/gate-scan.js +2 -2
  149. package/dist/kernel/ha/ha-arbiter.js +177 -0
  150. package/dist/kernel/ha/ha-guard.js +151 -0
  151. package/dist/kernel/index.js +36 -0
  152. package/dist/kernel/model-runtime.js +8 -1
  153. package/dist/kernel/plan.js +5 -5
  154. package/dist/kernel/roster.js +3 -3
  155. package/dist/llm/config-store.js +20 -0
  156. package/dist/llm/embedding-adapter.js +69 -0
  157. package/dist/llm/pi-ai.js +110 -37
  158. package/dist/llm/system-prompt/registry.js +8 -6
  159. package/dist/orbitdb/memory-sync.js +70 -0
  160. package/dist/pi-ecosystem-judgment/adaptive-scan.js +1 -1
  161. package/dist/security/tool-gate.js +2 -0
  162. package/dist/setup/setup-store.js +34 -6
  163. package/dist/social/heartbeat.js +18 -5
  164. package/dist/web/bolloon-web.json +3 -3
  165. package/dist/web/client.js +74 -35
  166. package/dist/web/icons/icon-1400x1400.png +0 -0
  167. package/dist/web/icons/icon-1400x1400.webp +0 -0
  168. package/dist/web/index.html +37 -25
  169. package/dist/web/mobile-agent.js +572 -45
  170. package/dist/web/mobile-contacts.js +0 -4
  171. package/dist/web/mobile-core.js +8079 -4590
  172. package/dist/web/mobile-harness.js +1004 -0
  173. package/dist/web/mobile-memory.js +317 -0
  174. package/dist/web/mobile-orbitdb.js +194 -0
  175. package/dist/web/mobile-persona.js +80 -0
  176. package/dist/web/mobile-privacy.js +2 -3
  177. package/dist/web/mobile.css +286 -21
  178. package/dist/web/mobile.html +122 -108
  179. package/dist/web/mobile.js +434 -152
  180. package/dist/web/routes-contacts.js +94 -1
  181. package/dist/web/routes-world.js +13 -2
  182. package/dist/web/server.js +54 -41
  183. package/dist/web/style.css +13 -5
  184. package/dist/web/sw.js +1 -1
  185. package/dist/web/ui/message-renderer.js +4 -18
  186. package/dist/web/ui/step-timeline.js +14 -1
  187. package/package.json +3 -2
  188. package/scripts/build-web.ts +16 -1
@@ -361,12 +361,13 @@ body {
361
361
 
362
362
  /* ============ 世界机会流 (2026-10-05, leo Intent Network) ============ */
363
363
  /* 主动流入: 打开首页即拉, 持续刷新; 不是按钮式被动响应 */
364
+ /* 首页世界机会流 (2026-10-07: 双栏卡片, 对应桌面世界模式) */
364
365
  .world-feed {
365
366
  padding: 10px 14px 4px;
366
- border-bottom: 1px solid var(--border);
367
367
  background: var(--bg);
368
368
  overflow-y: auto;
369
- max-height: 42vh;
369
+ flex: 1;
370
+ min-height: 0;
370
371
  }
371
372
  .world-feed-header {
372
373
  display: flex;
@@ -382,20 +383,27 @@ body {
382
383
  color: var(--text-muted);
383
384
  font-weight: 400;
384
385
  }
385
- .world-feed-cards { display: flex; flex-direction: column; gap: 8px; }
386
- .world-feed-loading { font-size: 12px; color: var(--text-muted); padding: 8px 0; }
386
+ /* 双栏网格 (2026-10-07: 首页双栏卡片) */
387
+ .world-feed-cards {
388
+ display: grid;
389
+ grid-template-columns: repeat(2, 1fr);
390
+ gap: 10px;
391
+ padding-bottom: 12px;
392
+ }
393
+ .world-feed-loading { font-size: 12px; color: var(--text-muted); padding: 8px 0; grid-column: 1 / -1; }
387
394
  .world-feed-card {
388
395
  background: var(--bg-card);
389
396
  border: 1px solid var(--border);
390
397
  border-left: 3px solid transparent;
391
- border-radius: 10px;
392
- padding: 10px 12px;
398
+ border-radius: 12px;
399
+ padding: 10px 10px;
400
+ min-width: 0;
393
401
  }
394
402
  .world-feed-card-top {
395
403
  display: flex;
396
404
  justify-content: space-between;
397
405
  align-items: center;
398
- gap: 8px;
406
+ gap: 6px;
399
407
  }
400
408
  .world-feed-title {
401
409
  font-size: 13px;
@@ -404,6 +412,8 @@ body {
404
412
  overflow: hidden;
405
413
  text-overflow: ellipsis;
406
414
  white-space: nowrap;
415
+ flex: 1;
416
+ min-width: 0;
407
417
  }
408
418
  .world-feed-pct {
409
419
  color: var(--accent);
@@ -416,11 +426,15 @@ body {
416
426
  font-size: 12px;
417
427
  color: var(--text-secondary);
418
428
  margin-top: 4px;
419
- line-height: 1.5;
429
+ line-height: 1.4;
430
+ display: -webkit-box;
431
+ -webkit-line-clamp: 3;
432
+ -webkit-box-orient: vertical;
433
+ overflow: hidden;
420
434
  }
421
435
  .world-feed-actions {
422
436
  display: flex;
423
- gap: 8px;
437
+ gap: 6px;
424
438
  margin-top: 8px;
425
439
  }
426
440
  .world-feed-btn {
@@ -439,6 +453,258 @@ body {
439
453
  border-color: var(--border);
440
454
  }
441
455
 
456
+ /* 首页底部输入框 (2026-10-07: 对应桌面世界模式输入框, Bolloon 风格) */
457
+ .world-input-bar {
458
+ display: flex;
459
+ gap: 8px;
460
+ align-items: center;
461
+ padding: 10px 14px;
462
+ border-top: 1px solid var(--border);
463
+ background: var(--bg-sidebar, #222220);
464
+ flex-shrink: 0;
465
+ }
466
+ .world-input-bar input {
467
+ flex: 1;
468
+ min-width: 0;
469
+ padding: 10px 12px;
470
+ border-radius: 10px;
471
+ border: 1px solid var(--border);
472
+ background: var(--bg-card, #222220);
473
+ color: var(--text);
474
+ font-size: 14px;
475
+ outline: none;
476
+ }
477
+ .world-input-bar input:focus {
478
+ border-color: var(--accent);
479
+ }
480
+ .world-input-send {
481
+ padding: 10px 16px;
482
+ border: 1px solid var(--accent);
483
+ background: var(--accent);
484
+ color: #1a1a18;
485
+ border-radius: 10px;
486
+ font-size: 13px;
487
+ font-weight: 600;
488
+ flex-shrink: 0;
489
+ }
490
+
491
+ /* ============ 好友 tab: 通讯录风格 (2026-10-07, 微信式) ============ */
492
+ .contacts-wrap {
493
+ position: relative;
494
+ }
495
+ .contacts-group-head {
496
+ padding: 6px 14px;
497
+ font-size: 12px;
498
+ font-weight: 600;
499
+ color: var(--text-muted);
500
+ background: var(--bg-hover, #222220);
501
+ }
502
+ .contact-row {
503
+ padding: 10px 14px;
504
+ border-bottom: 1px solid var(--border);
505
+ }
506
+ .contact-avatar {
507
+ background: var(--accent);
508
+ color: #1a1a18;
509
+ font-weight: 700;
510
+ }
511
+ .contact-sub {
512
+ font-size: 11px;
513
+ color: var(--text-muted);
514
+ margin-top: 2px;
515
+ }
516
+ .contacts-index {
517
+ position: fixed;
518
+ right: 2px;
519
+ top: 50%;
520
+ transform: translateY(-50%);
521
+ display: flex;
522
+ flex-direction: column;
523
+ align-items: center;
524
+ z-index: 50;
525
+ font-size: 10px;
526
+ color: var(--text-secondary);
527
+ user-select: none;
528
+ background: rgba(0,0,0,0.25);
529
+ border-radius: 8px;
530
+ padding: 2px 3px;
531
+ }
532
+ .contacts-index-letter {
533
+ padding: 1px 2px;
534
+ cursor: pointer;
535
+ line-height: 1.3;
536
+ }
537
+ .contacts-index-letter:hover { color: var(--accent); }
538
+
539
+ /* ============ 任务 tab: 公告板双栏瀑布流 (2026-10-07, 发现页风格) ============ */
540
+ .board-grid {
541
+ display: grid;
542
+ grid-template-columns: repeat(2, 1fr);
543
+ gap: 10px;
544
+ padding: 10px 14px;
545
+ }
546
+ .board-card {
547
+ background: var(--bg-card);
548
+ border: 1px solid var(--border);
549
+ border-radius: 12px;
550
+ padding: 10px;
551
+ min-width: 0;
552
+ display: flex;
553
+ flex-direction: column;
554
+ gap: 6px;
555
+ }
556
+ .board-card-cap {
557
+ font-size: 13px;
558
+ font-weight: 600;
559
+ color: var(--text);
560
+ line-height: 1.4;
561
+ display: -webkit-box;
562
+ -webkit-line-clamp: 2;
563
+ -webkit-box-orient: vertical;
564
+ overflow: hidden;
565
+ }
566
+ .board-card-status {
567
+ font-size: 10px;
568
+ padding: 2px 6px;
569
+ border-radius: 4px;
570
+ background: var(--bg-hover, #222220);
571
+ color: var(--accent);
572
+ align-self: flex-start;
573
+ }
574
+ .board-card-sub {
575
+ font-size: 11px;
576
+ color: var(--text-muted);
577
+ }
578
+ .board-card-btn {
579
+ margin-top: auto;
580
+ padding: 6px 0;
581
+ border: 1px solid var(--accent);
582
+ background: var(--accent);
583
+ color: #1a1a18;
584
+ border-radius: 8px;
585
+ font-size: 12px;
586
+ font-weight: 600;
587
+ }
588
+
589
+ /* ============ 任务 tab: 对话框模式 (2026-10-07) ============ */
590
+ .task-chat-page {
591
+ display: flex;
592
+ flex-direction: column;
593
+ min-height: 0;
594
+ }
595
+ .task-dash {
596
+ display: flex;
597
+ gap: 8px;
598
+ padding: 8px 14px;
599
+ border-bottom: 1px solid var(--border);
600
+ flex-shrink: 0;
601
+ }
602
+ .task-dash-btn {
603
+ flex: 1;
604
+ display: flex;
605
+ flex-direction: column;
606
+ align-items: center;
607
+ gap: 2px;
608
+ padding: 6px 0;
609
+ background: var(--bg-card, #222220);
610
+ border: 1px solid var(--border);
611
+ border-radius: 10px;
612
+ color: var(--text-secondary);
613
+ font-size: 11px;
614
+ }
615
+ .task-dash-ico { font-size: 16px; }
616
+ .task-chat {
617
+ flex: 1;
618
+ min-height: 0;
619
+ overflow-y: auto;
620
+ padding: 12px 14px;
621
+ display: flex;
622
+ flex-direction: column;
623
+ gap: 8px;
624
+ }
625
+ .task-chat-empty {
626
+ color: var(--text-muted);
627
+ font-size: 13px;
628
+ text-align: center;
629
+ padding: 40px 20px;
630
+ line-height: 1.6;
631
+ }
632
+ .task-msg {
633
+ max-width: 88%;
634
+ padding: 10px 12px;
635
+ border-radius: 12px;
636
+ font-size: 14px;
637
+ line-height: 1.5;
638
+ white-space: pre-wrap;
639
+ word-break: break-word;
640
+ }
641
+ .task-msg-user {
642
+ align-self: flex-end;
643
+ background: var(--accent);
644
+ color: #1a1a18;
645
+ border-bottom-right-radius: 4px;
646
+ }
647
+ .task-msg-ai {
648
+ align-self: flex-start;
649
+ background: var(--bg-card, #222220);
650
+ border: 1px solid var(--border);
651
+ color: var(--text);
652
+ border-bottom-left-radius: 4px;
653
+ }
654
+ .task-input-bar {
655
+ display: flex;
656
+ gap: 8px;
657
+ align-items: center;
658
+ padding: 10px 14px;
659
+ border-top: 1px solid var(--border);
660
+ background: var(--bg-sidebar, #222220);
661
+ flex-shrink: 0;
662
+ }
663
+ .task-input-bar input {
664
+ flex: 1;
665
+ min-width: 0;
666
+ padding: 10px 12px;
667
+ border-radius: 10px;
668
+ border: 1px solid var(--border);
669
+ background: var(--bg-card, #222220);
670
+ color: var(--text);
671
+ font-size: 14px;
672
+ outline: none;
673
+ }
674
+ .task-input-bar input:focus { border-color: var(--accent); }
675
+ .task-input-bar button {
676
+ padding: 10px 16px;
677
+ border: 1px solid var(--accent);
678
+ background: var(--accent);
679
+ color: #1a1a18;
680
+ border-radius: 10px;
681
+ font-size: 13px;
682
+ font-weight: 600;
683
+ flex-shrink: 0;
684
+ }
685
+ /* 网络工具覆盖层 */
686
+ .task-network-panel {
687
+ position: fixed;
688
+ inset: 0;
689
+ z-index: 80;
690
+ background: var(--bg);
691
+ display: flex;
692
+ flex-direction: column;
693
+ }
694
+ .task-network-head {
695
+ display: flex;
696
+ align-items: center;
697
+ gap: 8px;
698
+ padding: 10px 14px;
699
+ border-bottom: 1px solid var(--border);
700
+ flex-shrink: 0;
701
+ }
702
+ .task-network-body {
703
+ flex: 1;
704
+ min-height: 0;
705
+ overflow-y: auto;
706
+ }
707
+
442
708
  /* ============ 双频滑动卡片 (主页面) ============ */
443
709
 
444
710
  .card-carousel {
@@ -450,29 +716,28 @@ body {
450
716
  }
451
717
 
452
718
  .card-track {
453
- display: flex;
454
- flex-direction: column; /* 上下翻卡 */
455
- gap: 16px;
456
- padding: 16px;
719
+ /* 2026-10-06 (用户: 首页卡片变双栏): 从单卡纵向翻页改为两列网格, 一屏看更多智能体 */
720
+ display: grid;
721
+ grid-template-columns: repeat(2, 1fr);
722
+ gap: 12px;
723
+ padding: 12px;
457
724
  overflow-y: auto;
458
725
  overflow-x: hidden;
459
- scroll-snap-type: y mandatory;
460
726
  -webkit-overflow-scrolling: touch;
461
727
  scroll-behavior: smooth;
462
728
  height: 100%;
463
- align-items: stretch;
464
- touch-action: pan-y; /* 垂直交给原生滚动翻卡, 水平交给 JS 做删除 reveal */
729
+ align-content: start;
730
+ touch-action: pan-y; /* 垂直交给原生滚动, 水平交给 JS 做删除 reveal */
465
731
  }
466
732
 
467
733
  .card-track::-webkit-scrollbar { display: none; }
468
734
 
469
- /* 每张卡片外层: 纵向单元 + 删除位 */
735
+ /* 每张卡片外层: 网格单元 + 删除位 (双栏下固定比例, 不满屏) */
470
736
  .card-wrap {
471
- flex: 0 0 auto;
472
- height: 80%; /* 不满屏: 露出下一张卡片的位置 */
473
- scroll-snap-align: start;
737
+ height: auto;
738
+ aspect-ratio: 3 / 4;
474
739
  position: relative;
475
- border-radius: 16px;
740
+ border-radius: 14px;
476
741
  overflow: hidden;
477
742
  min-height: 0;
478
743
  }