@co0ontty/wand 1.39.1 → 1.40.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.
@@ -547,8 +547,8 @@
547
547
  }
548
548
  .sidebar.pinned.collapsed .sidebar-header-main,
549
549
  .sidebar.pinned.collapsed .sidebar-header-more,
550
- .sidebar.pinned.collapsed .sidebar-footer,
551
- .sidebar.pinned.collapsed .sidebar-history-region {
550
+ .sidebar.pinned.collapsed .sidebar-pin-toggle,
551
+ .sidebar.pinned.collapsed .sidebar-footer {
552
552
  display: none;
553
553
  }
554
554
  .sidebar.pinned.collapsed .sidebar-header-actions {
@@ -695,6 +695,17 @@
695
695
  .sidebar-collapse-toggle.collapsed {
696
696
  color: var(--primary);
697
697
  }
698
+ /* 常驻(图钉)开关:默认描边态;常驻时图钉「按下」,用 accent 高亮 + 45° 旋转。 */
699
+ .sidebar-pin-toggle {
700
+ flex-shrink: 0;
701
+ transition: background 0.16s ease, color var(--transition-fast),
702
+ transform 0.3s var(--ease-out-expo);
703
+ }
704
+ .sidebar-pin-toggle.pinned {
705
+ background: rgba(197, 101, 61, 0.12);
706
+ color: var(--accent);
707
+ transform: rotate(45deg);
708
+ }
698
709
 
699
710
  /* ===== 侧边栏头部 ===== */
700
711
  .sidebar-header {
@@ -724,11 +735,9 @@
724
735
  flex-shrink: 0;
725
736
  }
726
737
 
727
- /* On desktop pinned mode the close (X) button is redundant the hamburger
728
- toggle in the topbar already opens/closes the sidebar. Hide it to declutter. */
729
- .sidebar.pinned .sidebar-header-actions .sidebar-close {
730
- display: none;
731
- }
738
+ /* The close (X) is the deliberate "hide the sidebar" control on desktop —
739
+ the pin only toggles 常驻 lock and never hides. Keep X visible while docked
740
+ (it's still hidden in the narrow/collapsed strip via the rule above). */
732
741
 
733
742
  .sidebar-header-more {
734
743
  position: relative;
@@ -825,6 +834,8 @@
825
834
  font-weight: 600;
826
835
  color: var(--text-primary);
827
836
  letter-spacing: -0.01em;
837
+ white-space: nowrap;
838
+ flex-shrink: 0;
828
839
  }
829
840
 
830
841
  .session-count {
@@ -1034,6 +1045,8 @@
1034
1045
  opacity: 1;
1035
1046
  pointer-events: auto;
1036
1047
  }
1048
+ /* 常驻(图钉)只在桌面有意义——手机端隐藏这个按钮,避免死按钮。 */
1049
+ .sidebar-pin-toggle { display: none; }
1037
1050
  }
1038
1051
 
1039
1052
  .file-side-panel-header {
@@ -1276,6 +1289,7 @@
1276
1289
  flex: 1;
1277
1290
  min-height: 0;
1278
1291
  overflow-y: auto;
1292
+ -webkit-overflow-scrolling: touch;
1279
1293
  position: relative;
1280
1294
  }
1281
1295
 
@@ -1287,12 +1301,26 @@
1287
1301
 
1288
1302
  /* ===== 会话列表 ===== */
1289
1303
  .sessions-list {
1290
- flex: 1;
1304
+ /* Flex column that fills the scroll body so the 历史会话 group can pin to
1305
+ the very bottom (margin-top:auto) when the list is short, yet flow
1306
+ naturally and scroll when it's long. #sessions-panel is display:contents
1307
+ so this is effectively a direct child of the scrolling .sidebar-body. */
1308
+ flex: 1 0 auto;
1291
1309
  min-height: 0;
1292
- overflow-y: auto;
1310
+ display: flex;
1311
+ flex-direction: column;
1312
+ /* No own scroll: .sidebar-body is the scroll container. overflow:visible
1313
+ lets the manage bar's position:sticky bind to .sidebar-body. */
1314
+ overflow: visible;
1293
1315
  padding: 10px 10px 12px;
1294
1316
  }
1295
1317
 
1318
+ /* Unwrap the panel so .sessions-list is a direct flex child of the
1319
+ scrolling .sidebar-body (enables fill + bottom-pin). */
1320
+ #sessions-panel {
1321
+ display: contents;
1322
+ }
1323
+
1296
1324
  .sessions-list:empty::before {
1297
1325
  content: '暂无会话';
1298
1326
  display: flex;
@@ -1304,7 +1332,7 @@
1304
1332
  }
1305
1333
 
1306
1334
  /* ===== 会话分组 ===== */
1307
- .session-group { margin-bottom: 20px; }
1335
+ .session-group { margin-bottom: 14px; }
1308
1336
  .session-group:last-child { margin-bottom: 0; }
1309
1337
 
1310
1338
  /* Legacy .session-manage-bar / .session-manage-toggle / .session-manage-btn
@@ -1382,10 +1410,17 @@
1382
1410
  }
1383
1411
  .claude-history-directory-title {
1384
1412
  font-size: 0.6875rem;
1385
- padding: 6px 8px;
1413
+ padding: 6px 8px 6px 12px;
1386
1414
  opacity: 0.8;
1387
1415
  justify-content: space-between;
1388
1416
  }
1417
+ /* No accent bar on nested directory rows — the 3px bar stays on top-level
1418
+ groups (历史会话 / 已归档) only, so the hierarchy reads as group → folder
1419
+ → items instead of a column of identical orange ticks. The chevron +
1420
+ slight indent already signal the sub-level. */
1421
+ .claude-history-directory-header .claude-history-directory-title::before {
1422
+ display: none;
1423
+ }
1389
1424
  .claude-history-directory-label {
1390
1425
  min-width: 0;
1391
1426
  overflow: hidden;
@@ -1557,8 +1592,8 @@
1557
1592
  min-width: 0;
1558
1593
  display: flex;
1559
1594
  flex-direction: column;
1560
- gap: 4px;
1561
- padding-right: 64px;
1595
+ gap: 3px;
1596
+ padding-right: 60px;
1562
1597
  }
1563
1598
 
1564
1599
  .session-title-row {
@@ -2249,11 +2284,18 @@
2249
2284
  .session-status.stopped .session-status-dot { background: var(--warning); }
2250
2285
 
2251
2286
  .session-status.running { background: var(--success-muted); color: var(--success); }
2252
- .session-status.exited { background: rgba(150, 118, 85, 0.1); color: var(--text-tertiary); }
2253
2287
  .session-status.failed { background: var(--danger-muted); color: var(--danger); }
2254
2288
  .session-status.stopped { background: var(--warning-muted); color: var(--warning); }
2255
2289
  .session-status.permission-blocked { background: rgba(240, 165, 0, 0.14); color: #d18b00; }
2256
- .session-status.archived { background: rgba(95, 74, 57, 0.08); color: var(--text-tertiary); }
2290
+ /* Quiet "done" states no filled pill, just a dot + muted text, so a long
2291
+ list of finished sessions doesn't read as a stack of grey boxes. */
2292
+ .session-status.exited,
2293
+ .session-status.archived {
2294
+ background: transparent;
2295
+ color: var(--text-muted);
2296
+ padding-left: 0;
2297
+ padding-right: 0;
2298
+ }
2257
2299
 
2258
2300
  @keyframes status-pulse {
2259
2301
  0%, 100% { opacity: 1; }
@@ -2270,126 +2312,36 @@
2270
2312
  font-weight: 500;
2271
2313
  }
2272
2314
 
2273
- /* ===== Sidebar: docked Claude history region =====
2274
- Lives between .sidebar-body and .sidebar-footer. Collapsed by default
2275
- only a slim header row ("历史消息" + 数字气泡) is visible, so the main
2276
- scrolling area focuses on recent / archived sessions. Expanding it
2277
- grows the region with a 40% max-height cap so it can never eat the
2278
- sessions list above. */
2279
- .sidebar-history-region {
2280
- flex-shrink: 0;
2281
- display: flex;
2282
- flex-direction: column;
2283
- min-height: 0;
2284
- max-height: 40%;
2285
- border-top: 1px solid var(--border-subtle);
2286
- background: rgba(255, 251, 245, 0.66);
2287
- transition: max-height 0.28s var(--ease-out-expo);
2288
- }
2289
-
2290
- .sidebar-history-header {
2291
- display: flex;
2292
- align-items: center;
2293
- justify-content: space-between;
2294
- width: 100%;
2295
- padding: 9px 14px;
2296
- min-height: 38px;
2297
- flex-shrink: 0;
2298
- background: transparent;
2299
- border: none;
2300
- border-radius: 0;
2301
- cursor: pointer;
2302
- text-align: left;
2303
- font-family: var(--font-sans);
2304
- font-size: 0.75rem;
2305
- font-weight: 600;
2306
- letter-spacing: 0.005em;
2307
- color: var(--text-secondary);
2308
- transition: background var(--transition-fast), color var(--transition-fast);
2309
- -webkit-tap-highlight-color: transparent;
2310
- }
2311
-
2312
- .sidebar-history-header:hover {
2313
- background: rgba(150, 118, 85, 0.06);
2314
- color: var(--text-primary);
2315
- }
2316
-
2317
- .sidebar-history-header:active {
2318
- background: rgba(150, 118, 85, 0.1);
2319
- }
2320
-
2321
- .sidebar-history-header.expanded {
2322
- background: rgba(255, 251, 245, 0.85);
2323
- color: var(--text-primary);
2324
- border-bottom: 1px solid var(--border-subtle);
2325
- }
2326
-
2327
- .sidebar-history-label {
2328
- display: inline-flex;
2329
- align-items: center;
2330
- gap: 6px;
2331
- }
2332
-
2333
- .sidebar-history-right {
2334
- display: inline-flex;
2335
- align-items: center;
2336
- gap: 8px;
2337
- flex-shrink: 0;
2338
- }
2339
-
2340
- /* Count bubble — pill shape, tabular numerals, accent-tinted when there
2341
- are items, muted when empty/loading. */
2342
- .history-bubble {
2343
- display: inline-flex;
2344
- align-items: center;
2345
- justify-content: center;
2346
- min-width: 22px;
2347
- height: 18px;
2348
- padding: 0 7px;
2349
- border-radius: 999px;
2350
- background: var(--accent-muted);
2351
- color: var(--accent);
2352
- font-size: 0.6875rem;
2353
- font-weight: 700;
2354
- font-variant-numeric: tabular-nums;
2355
- line-height: 1;
2356
- letter-spacing: 0;
2315
+ /* ===== Sidebar: inline 历史会话 group =====
2316
+ History (older Claude + Codex CLI sessions) is the final collapsible
2317
+ group of #sessions-list same scroll, same idiom as 已归档. No docked
2318
+ region, no 40% cap, no stranded bar above the footer: when the list is
2319
+ short the empty space simply falls below the content, as a list should. */
2320
+ /* Pin the history group to the very bottom of the sidebar (just above the
2321
+ footer). margin-top:auto eats the free space when the list is short;
2322
+ when the list overflows there is no free space, so history simply
2323
+ follows the content and scrolls. Collapsed + minimized by default. */
2324
+ .session-group--history {
2325
+ margin-top: auto;
2326
+ padding-top: 6px;
2357
2327
  }
2358
2328
 
2359
- .history-bubble.empty {
2360
- background: var(--bg-tertiary);
2329
+ /* Toggle header reuses .session-group-title + .claude-history-toggle.
2330
+ The count chip turns into a quiet ellipsis while history is still
2331
+ scanning, then settles to the real number. */
2332
+ .session-history-toggle .history-count.loading {
2333
+ letter-spacing: 0.12em;
2361
2334
  color: var(--text-muted);
2362
- opacity: 0.65;
2363
- }
2364
-
2365
- .history-bubble.loading {
2366
2335
  background: transparent;
2367
- color: var(--text-muted);
2368
- letter-spacing: 0.1em;
2369
- padding: 0 4px;
2370
- font-weight: 600;
2371
- }
2372
-
2373
- .sidebar-history-chevron {
2374
- flex-shrink: 0;
2375
- color: var(--text-muted);
2376
- transition: transform 0.22s var(--ease-out-expo), color var(--transition-fast);
2377
- }
2378
-
2379
- .sidebar-history-header.expanded .sidebar-history-chevron {
2380
- transform: rotate(180deg);
2381
- color: var(--text-secondary);
2336
+ padding-left: 2px;
2337
+ padding-right: 2px;
2382
2338
  }
2383
2339
 
2384
- /* Expanded body — scrollable, capped via parent max-height. */
2385
- .sidebar-history-body {
2386
- flex: 1;
2387
- min-height: 0;
2388
- overflow-y: auto;
2389
- padding: 6px 8px 10px;
2340
+ .session-history-body {
2390
2341
  display: flex;
2391
2342
  flex-direction: column;
2392
2343
  gap: 4px;
2344
+ padding: 2px 0 4px;
2393
2345
  animation: historyBodyFadeIn 0.22s var(--ease-out-expo);
2394
2346
  }
2395
2347
 
@@ -9467,11 +9419,16 @@
9467
9419
  transform: scale(0.98);
9468
9420
  }
9469
9421
 
9470
- /* ── Manage bar — Linear-style toolbar ── */
9422
+ /* ── Manage bar ──
9423
+ Normal: a quiet sub-header ("最近的会话记录" + 管理 toggle).
9424
+ Active: the SAME row morphs IN PLACE to a flat selection toolbar —
9425
+ no card, no shadow, no layout jump — and sticks to the top of the
9426
+ scroll so the count + 删除 stay reachable while selecting rows below. */
9471
9427
  .session-manage-bar {
9472
9428
  display: flex;
9473
9429
  align-items: center;
9474
9430
  justify-content: space-between;
9431
+ gap: 8px;
9475
9432
  padding: 4px 4px 4px 10px;
9476
9433
  border-radius: 10px;
9477
9434
  margin-bottom: 10px;
@@ -9487,22 +9444,53 @@
9487
9444
  letter-spacing: 0.005em;
9488
9445
  }
9489
9446
 
9490
- /* Active toolbar — iOS toolbar look: card with hairline + summary + actions */
9491
9447
  .session-manage-bar.active {
9492
- flex-direction: column;
9493
- align-items: stretch;
9494
- gap: 10px;
9495
- padding: 10px 12px;
9496
- background: rgba(255, 255, 255, 0.6);
9497
- border: 1px solid rgba(125, 91, 57, 0.1);
9498
- border-radius: 14px;
9499
- box-shadow: 0 1px 2px rgba(125, 91, 57, 0.03);
9448
+ position: sticky;
9449
+ top: 0;
9450
+ z-index: 6;
9451
+ /* bleed to the list edges and cancel the #sessions-list top padding so
9452
+ the bar sits flush at the scroll top — a flat header, not a card. */
9453
+ margin: -10px -10px 8px;
9454
+ padding: 9px 10px 9px 6px;
9455
+ border-radius: 0;
9456
+ background: rgba(255, 251, 245, 0.94);
9457
+ -webkit-backdrop-filter: saturate(1.2) blur(8px);
9458
+ backdrop-filter: saturate(1.2) blur(8px);
9459
+ border-bottom: 1px solid var(--border-subtle);
9460
+ box-shadow: none;
9461
+ }
9462
+ .session-manage-bar.active:hover {
9463
+ background: rgba(255, 251, 245, 0.94);
9464
+ }
9465
+
9466
+ /* Exit (✕) — the in-place "leave manage mode" affordance on the left. */
9467
+ .session-manage-exit {
9468
+ flex-shrink: 0;
9469
+ display: inline-flex;
9470
+ align-items: center;
9471
+ justify-content: center;
9472
+ width: 26px;
9473
+ height: 26px;
9474
+ padding: 0;
9475
+ border: none;
9476
+ border-radius: 8px;
9477
+ background: transparent;
9478
+ color: var(--text-muted);
9479
+ cursor: pointer;
9480
+ transition: background 0.14s ease, color 0.14s ease;
9481
+ -webkit-tap-highlight-color: transparent;
9482
+ }
9483
+ .session-manage-exit:hover {
9484
+ background: rgba(125, 91, 57, 0.1);
9485
+ color: var(--text-primary);
9500
9486
  }
9501
9487
 
9502
9488
  .session-manage-summary {
9503
9489
  display: inline-flex;
9504
9490
  align-items: center;
9505
- gap: 8px;
9491
+ gap: 6px;
9492
+ min-width: 0;
9493
+ flex: 1;
9506
9494
  font-size: 0.75rem;
9507
9495
  color: var(--text-secondary);
9508
9496
  font-weight: 500;
@@ -9511,33 +9499,29 @@
9511
9499
  display: inline-flex;
9512
9500
  align-items: center;
9513
9501
  justify-content: center;
9514
- min-width: 22px;
9515
- height: 22px;
9516
- padding: 0 7px;
9502
+ min-width: 20px;
9503
+ height: 18px;
9504
+ padding: 0 6px;
9517
9505
  background: var(--accent);
9518
9506
  color: var(--text-inverse);
9519
9507
  font-size: 0.6875rem;
9520
9508
  font-weight: 700;
9521
9509
  border-radius: 999px;
9522
9510
  font-variant-numeric: tabular-nums;
9523
- box-shadow: 0 1px 2px rgba(197, 101, 61, 0.32);
9524
9511
  }
9525
9512
  .session-manage-summary-label {
9526
9513
  color: var(--text-secondary);
9527
9514
  font-weight: 600;
9528
9515
  }
9516
+ .session-manage-summary-label.muted {
9517
+ color: var(--text-muted);
9518
+ font-weight: 500;
9519
+ }
9529
9520
 
9530
9521
  .session-manage-actions {
9531
9522
  display: flex;
9532
9523
  align-items: center;
9533
- gap: 4px;
9534
- flex-wrap: wrap;
9535
- }
9536
- .session-manage-divider {
9537
- width: 1px;
9538
- height: 16px;
9539
- background: rgba(125, 91, 57, 0.16);
9540
- margin: 0 4px;
9524
+ gap: 6px;
9541
9525
  flex-shrink: 0;
9542
9526
  }
9543
9527
 
@@ -9568,73 +9552,53 @@
9568
9552
  opacity: 1;
9569
9553
  }
9570
9554
 
9571
- /* ── Session item — clean card on glass ──
9572
- 克制原则:基础态用 hairline 描边 + 极轻顶部高光让卡片「贴」在侧栏上,
9573
- 不给每张卡都加漂浮投影;hover/active 才升起一层柔和投影。避免多层
9574
- box-shadow 在半透明侧栏里互相叠加显脏。 */
9555
+ /* ── Session item — flat list row, not a floating card ──
9556
+ 克制原则:基础态完全透明,让侧栏读起来是「一列」而不是「一摞卡片」;
9557
+ hover / active 才用填充背景区分。去掉每行的边框/渐变/投影/抬升,
9558
+ 避免在半透明侧栏里多层叠加显脏、以及 hover 抬升导致邻项跳动。 */
9575
9559
  .session-item {
9576
- background: linear-gradient(180deg, rgba(255, 255, 255, 0.55) 0%, rgba(255, 252, 247, 0.38) 100%);
9577
- border: 1px solid rgba(125, 91, 57, 0.08);
9578
- border-radius: 13px;
9579
- padding: 11px 14px;
9580
- margin-bottom: 6px;
9581
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
9582
- transition:
9583
- background 0.2s ease,
9584
- border-color 0.2s ease,
9585
- box-shadow 0.22s ease,
9586
- transform 0.22s var(--ease-out-expo);
9560
+ background: transparent;
9561
+ border: 1px solid transparent;
9562
+ border-radius: 11px;
9563
+ padding: 9px 12px;
9564
+ margin-bottom: 2px;
9565
+ box-shadow: none;
9566
+ transition: background 0.16s ease, border-color 0.16s ease;
9587
9567
  }
9588
9568
  .session-item::before {
9589
9569
  left: 4px;
9590
- top: 10px;
9591
- bottom: 10px;
9570
+ top: 9px;
9571
+ bottom: 9px;
9592
9572
  width: 3px;
9593
9573
  border-radius: 2px;
9594
9574
  background: linear-gradient(180deg, var(--accent), rgba(197, 101, 61, 0.5));
9595
9575
  }
9596
9576
  .session-item:hover {
9597
- background: linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 253, 248, 0.62) 100%);
9598
- border-color: rgba(125, 91, 57, 0.14);
9599
- transform: translateY(-1px);
9600
- box-shadow: 0 4px 12px -4px rgba(125, 91, 57, 0.16);
9601
- }
9602
- .session-item:hover::before {
9603
- opacity: 0.5;
9604
- transform: scaleY(1);
9577
+ background: rgba(125, 91, 57, 0.06);
9578
+ border-color: transparent;
9605
9579
  }
9606
- /* Selected (active)accent ring 用边框表达,再叠一层柔和暖投影 + 顶高光。
9607
- 去掉原先的 6 层叠加(外环/光晕/底影/三向 inset),层数过多在玻璃上显脏。 */
9580
+ /* Left accent bar marks the *active* row only not hover to keep scanning calm. */
9581
+ .session-item:hover::before { opacity: 0; }
9608
9582
  .session-item.active {
9609
- background:
9610
- linear-gradient(180deg, rgba(255, 252, 247, 0.92) 0%, rgba(255, 244, 232, 0.78) 100%);
9611
- border: 1px solid rgba(197, 101, 61, 0.32);
9612
- transform: translateY(-1px);
9613
- backdrop-filter: blur(20px) saturate(180%);
9614
- -webkit-backdrop-filter: blur(20px) saturate(180%);
9615
- box-shadow:
9616
- 0 4px 14px -4px rgba(197, 101, 61, 0.24),
9617
- inset 0 1px 0 rgba(255, 255, 255, 0.7);
9583
+ background: linear-gradient(180deg, rgba(255, 252, 247, 0.92) 0%, rgba(255, 244, 232, 0.74) 100%);
9584
+ border-color: rgba(197, 101, 61, 0.28);
9585
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55);
9618
9586
  }
9619
- /* ::before 的左侧高亮条受父级 overflow:hidden 裁切,原来的 box-shadow 光晕
9620
- 根本显示不出来,移除以省一次绘制。 */
9621
9587
  .session-item.active::before {
9622
9588
  opacity: 1;
9623
9589
  transform: scaleY(1);
9624
9590
  }
9625
- /* Multi-select state — quieter glass tint, no accent halo */
9591
+ /* Multi-select state — quieter accent tint */
9626
9592
  .session-item.selected {
9627
- background:
9628
- linear-gradient(180deg, rgba(255, 250, 244, 0.85) 0%, rgba(255, 246, 236, 0.65) 100%);
9629
- border: 1px solid rgba(197, 101, 61, 0.2);
9630
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6);
9593
+ background: rgba(197, 101, 61, 0.09);
9594
+ border-color: rgba(197, 101, 61, 0.18);
9631
9595
  }
9632
9596
  .session-item.selected::before {
9633
9597
  opacity: 0.7;
9634
9598
  transform: scaleY(1);
9635
9599
  }
9636
9600
  .session-item:active {
9637
- transform: translateY(0) scale(0.99);
9601
+ transform: scale(0.992);
9638
9602
  transition-duration: 0.08s;
9639
9603
  }
9640
9604
 
@@ -10333,13 +10297,15 @@
10333
10297
  }
10334
10298
 
10335
10299
  .sessions-list {
10336
- display: block;
10337
- flex: 1;
10300
+ /* Match desktop: flex column that fills the scroll body so 历史会话
10301
+ bottom-pins and the manage bar stays sticky. .sidebar-body owns the
10302
+ scroll (and momentum) on mobile, so this stays overflow:visible. */
10303
+ display: flex;
10304
+ flex-direction: column;
10305
+ flex: 1 0 auto;
10338
10306
  min-height: 0;
10339
- overflow-x: hidden;
10340
- overflow-y: auto;
10307
+ overflow: visible;
10341
10308
  padding: 4px;
10342
- -webkit-overflow-scrolling: touch;
10343
10309
  }
10344
10310
 
10345
10311
  /* 移动端会话项 - 紧凑 */
@@ -15339,7 +15305,7 @@
15339
15305
 
15340
15306
  /* ── 快捷提交模态框 ── */
15341
15307
  .quick-commit-modal {
15342
- max-width: 560px;
15308
+ max-width: 540px;
15343
15309
  }
15344
15310
  .quick-commit-modal .modal-body {
15345
15311
  display: flex;
@@ -15347,17 +15313,17 @@
15347
15313
  gap: 12px;
15348
15314
  }
15349
15315
  .qc-files-wrap {
15350
- max-height: 200px;
15316
+ max-height: 190px;
15351
15317
  overflow-y: auto;
15352
- padding: 8px 10px;
15353
- border: 1px solid var(--border-color, rgba(0, 0, 0, 0.08));
15354
- border-radius: 6px;
15355
- background: rgba(255, 255, 255, 0.45);
15318
+ padding: 6px 8px;
15319
+ border: 1px solid rgba(125, 91, 57, 0.10);
15320
+ border-radius: 10px;
15321
+ background: rgba(255, 255, 255, 0.4);
15356
15322
  font-family: var(--font-mono, monospace);
15357
15323
  font-size: 0.78rem;
15358
15324
  display: flex;
15359
15325
  flex-direction: column;
15360
- gap: 2px;
15326
+ gap: 1px;
15361
15327
  }
15362
15328
  .qc-empty {
15363
15329
  color: var(--text-muted);
@@ -15368,30 +15334,45 @@
15368
15334
  .qc-file-row {
15369
15335
  display: flex;
15370
15336
  align-items: center;
15371
- gap: 8px;
15372
- line-height: 1.5;
15337
+ gap: 9px;
15338
+ line-height: 1.6;
15339
+ padding: 1px 2px;
15340
+ border-radius: 5px;
15341
+ }
15342
+ .qc-file-row:hover {
15343
+ background: rgba(125, 91, 57, 0.06);
15373
15344
  }
15374
- .qc-flag {
15345
+ /* Single-letter status badge, VS Code style */
15346
+ .qc-file-badge {
15375
15347
  flex-shrink: 0;
15376
- width: 24px;
15377
- text-align: center;
15378
- font-weight: 700;
15379
- color: var(--text-muted);
15348
+ width: 17px;
15349
+ height: 17px;
15350
+ display: inline-flex;
15351
+ align-items: center;
15352
+ justify-content: center;
15353
+ border-radius: 4px;
15354
+ font-size: 0.66rem;
15355
+ font-weight: 800;
15380
15356
  letter-spacing: 0;
15357
+ line-height: 1;
15358
+ font-family: var(--font-sans);
15381
15359
  }
15382
- .qc-flag-add { color: rgba(60, 160, 90, 0.95); }
15383
- .qc-flag-mod { color: rgba(220, 150, 30, 0.95); }
15384
- .qc-flag-del { color: rgba(200, 70, 70, 0.95); }
15385
- .qc-flag-ren { color: rgba(110, 130, 200, 0.95); }
15386
- .qc-flag-untracked { color: rgba(140, 140, 140, 0.95); }
15360
+ .qc-badge-add { color: rgba(34, 128, 66, 0.98); background: rgba(60, 160, 90, 0.16); }
15361
+ .qc-badge-mod { color: rgba(170, 110, 14, 0.98); background: rgba(220, 150, 30, 0.16); }
15362
+ .qc-badge-del { color: rgba(190, 56, 56, 0.98); background: rgba(200, 70, 70, 0.15); }
15363
+ .qc-badge-ren { color: rgba(78, 100, 188, 0.98); background: rgba(110, 130, 200, 0.16); }
15364
+ .qc-badge-untracked { color: rgba(34, 128, 66, 0.95); background: rgba(60, 160, 90, 0.12); }
15365
+ .qc-badge-ignored,
15366
+ .qc-badge-other { color: var(--text-muted); background: rgba(120, 120, 120, 0.12); }
15387
15367
  .qc-file-path {
15388
- color: var(--text-secondary);
15389
15368
  overflow: hidden;
15390
15369
  text-overflow: ellipsis;
15391
15370
  white-space: nowrap;
15392
15371
  flex: 1 1 auto;
15393
15372
  min-width: 0;
15394
15373
  }
15374
+ .qc-file-dir { color: var(--text-muted); }
15375
+ .qc-file-name { color: var(--text-primary); font-weight: 500; }
15395
15376
  .qc-submodule-badge {
15396
15377
  flex-shrink: 0;
15397
15378
  padding: 1px 6px;
@@ -15403,20 +15384,12 @@
15403
15384
  letter-spacing: 0.02em;
15404
15385
  white-space: nowrap;
15405
15386
  }
15406
- .qc-switch {
15407
- flex-shrink: 0;
15408
- display: inline-flex;
15409
- align-items: center;
15410
- cursor: pointer;
15411
- }
15412
- .qc-message-row,
15413
- .qc-tag-row {
15387
+ .qc-message-row {
15414
15388
  display: flex;
15415
15389
  flex-direction: column;
15416
- gap: 4px;
15390
+ gap: 6px;
15417
15391
  }
15418
- .qc-message-row.hidden,
15419
- .qc-tag-row.hidden {
15392
+ .qc-message-row.hidden {
15420
15393
  display: none;
15421
15394
  }
15422
15395
  .qc-message-header {
@@ -15424,68 +15397,75 @@
15424
15397
  align-items: center;
15425
15398
  justify-content: space-between;
15426
15399
  gap: 8px;
15427
- flex-wrap: wrap;
15428
15400
  }
15429
- .qc-ai-controls {
15430
- display: inline-flex;
15431
- align-items: center;
15432
- justify-content: flex-end;
15433
- gap: 7px;
15434
- margin-left: auto;
15435
- flex: 0 0 auto;
15401
+ .qc-message-label {
15402
+ margin-bottom: 0;
15436
15403
  }
15437
- .qc-ai-tag-toggle {
15404
+ /* AI generate button: icon + text */
15405
+ .qc-ai-btn {
15438
15406
  display: inline-flex;
15439
15407
  align-items: center;
15440
- gap: 6px;
15441
- min-height: 30px;
15442
- padding: 3px 7px 3px 9px;
15443
- border: 1px solid rgba(125, 91, 57, 0.12);
15444
- border-radius: 999px;
15445
- background: rgba(255, 255, 255, 0.58);
15446
- color: var(--text-muted);
15447
- font-size: 0.74rem;
15448
- font-weight: 700;
15449
- line-height: 1;
15450
- user-select: none;
15451
- cursor: pointer;
15452
- transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease, box-shadow 0.16s ease;
15453
- }
15454
- .qc-ai-tag-toggle:hover {
15455
- background: rgba(255, 255, 255, 0.82);
15456
- border-color: rgba(125, 91, 57, 0.20);
15408
+ gap: 5px;
15409
+ color: var(--accent);
15457
15410
  }
15458
- .qc-ai-tag-toggle:has(.switch-toggle:checked) {
15459
- color: rgba(170, 79, 42, 0.98);
15460
- background: linear-gradient(180deg, #fff8f1 0%, #fff1e3 100%);
15461
- border-color: rgba(197, 101, 61, 0.32);
15462
- box-shadow: 0 1px 4px rgba(197, 101, 61, 0.10);
15411
+ .qc-ai-btn svg {
15412
+ color: var(--accent);
15413
+ flex-shrink: 0;
15463
15414
  }
15464
- .qc-ai-tag-toggle:has(.switch-toggle:disabled) {
15465
- cursor: default;
15466
- opacity: 0.68;
15415
+ .qc-ai-btn:disabled {
15416
+ opacity: 0.5;
15417
+ cursor: not-allowed;
15418
+ color: var(--text-muted);
15467
15419
  }
15468
- .qc-ai-tag-label {
15469
- white-space: nowrap;
15420
+ .qc-ai-btn:disabled svg { color: var(--text-muted); }
15421
+ .qc-message-input {
15422
+ resize: vertical;
15423
+ min-height: 68px;
15424
+ font-family: var(--font-mono, monospace);
15425
+ font-size: 0.84rem;
15426
+ line-height: 1.55;
15470
15427
  }
15471
- .qc-switch--compact .switch-slider {
15472
- width: 34px;
15473
- min-width: 34px;
15474
- height: 20px;
15475
- border-radius: 999px;
15428
+
15429
+ /* Tag field — single line: [Tag] [version input] */
15430
+ .qc-tag-field {
15431
+ display: flex;
15432
+ align-items: center;
15433
+ gap: 10px;
15476
15434
  }
15477
- .qc-switch--compact .switch-slider::after {
15478
- width: 16px;
15479
- height: 16px;
15435
+ .qc-tag-field-label {
15436
+ flex-shrink: 0;
15437
+ width: 2.4em;
15438
+ font-size: 0.7rem;
15439
+ font-weight: 700;
15440
+ letter-spacing: 0.06em;
15441
+ text-transform: uppercase;
15442
+ color: var(--accent);
15480
15443
  }
15481
- .qc-switch--compact .switch-toggle:checked + .switch-slider::after {
15482
- transform: translateX(14px);
15444
+ .qc-tag-field.is-off .qc-tag-field-label {
15445
+ color: var(--text-muted);
15483
15446
  }
15484
- .qc-message-row textarea {
15485
- resize: vertical;
15486
- min-height: 56px;
15447
+ .qc-tag-field-input {
15448
+ flex: 1 1 auto;
15449
+ min-width: 0;
15487
15450
  font-family: var(--font-mono, monospace);
15488
- font-size: 0.85rem;
15451
+ font-size: 0.82rem;
15452
+ }
15453
+ /* "Commit only" state: show the suggested tag greyed, as a non-editable preview. */
15454
+ .qc-tag-field-input:disabled {
15455
+ color: var(--text-muted);
15456
+ background: rgba(125, 91, 57, 0.04);
15457
+ border-color: rgba(125, 91, 57, 0.08);
15458
+ cursor: default;
15459
+ box-shadow: none;
15460
+ }
15461
+ .qc-tag-field-note {
15462
+ flex-shrink: 0;
15463
+ font-size: 0.7rem;
15464
+ font-weight: 600;
15465
+ color: var(--text-muted);
15466
+ padding: 2px 8px;
15467
+ border-radius: 999px;
15468
+ background: rgba(125, 91, 57, 0.08);
15489
15469
  }
15490
15470
  .quick-commit-modal .worktree-merge-actions {
15491
15471
  display: flex;
@@ -15500,21 +15480,17 @@
15500
15480
  flex-direction: column;
15501
15481
  gap: 14px;
15502
15482
  }
15483
+ /* Flat sections — no nested cards. Sections are just grouped rows,
15484
+ separated by a hairline divider rather than boxed in their own card. */
15503
15485
  .qc-section {
15504
15486
  display: flex;
15505
15487
  flex-direction: column;
15506
- gap: 10px;
15507
- padding: 12px 14px;
15508
- background: rgba(255, 255, 255, 0.6);
15509
- border: 1px solid rgba(125, 91, 57, 0.10);
15510
- border-radius: 14px;
15511
- box-shadow: 0 1px 2px rgba(125, 91, 57, 0.04);
15488
+ gap: 12px;
15512
15489
  }
15490
+ /* The repo/sync block sits below a divider instead of inside its own card. */
15513
15491
  .qc-section--repo {
15514
- background: linear-gradient(180deg, rgba(255, 250, 244, 0.7) 0%, rgba(255, 247, 238, 0.7) 100%);
15515
- }
15516
- .qc-section--empty {
15517
- background: rgba(245, 245, 245, 0.5);
15492
+ padding-top: 16px;
15493
+ border-top: 1px solid rgba(125, 91, 57, 0.12);
15518
15494
  }
15519
15495
  .qc-section-head {
15520
15496
  display: flex;
@@ -15523,14 +15499,14 @@
15523
15499
  gap: 8px;
15524
15500
  }
15525
15501
  .qc-section-title {
15526
- font-size: 0.78rem;
15502
+ font-size: 0.72rem;
15527
15503
  font-weight: 700;
15528
15504
  text-transform: uppercase;
15529
- letter-spacing: 0.06em;
15530
- color: var(--text-muted);
15505
+ letter-spacing: 0.07em;
15506
+ color: var(--text-secondary);
15531
15507
  }
15532
15508
  .qc-section-meta {
15533
- font-size: 0.75rem;
15509
+ font-size: 0.74rem;
15534
15510
  color: var(--text-muted);
15535
15511
  font-family: var(--font-mono, monospace);
15536
15512
  overflow: hidden;
@@ -15549,55 +15525,46 @@
15549
15525
  .qc-section-actions--secondary {
15550
15526
  justify-content: space-between;
15551
15527
  }
15552
-
15553
- /* Empty state */
15554
- .qc-empty-state {
15555
- display: flex;
15556
- align-items: center;
15557
- gap: 12px;
15558
- padding: 6px 4px;
15528
+ /* Groups the Commit split-button + standalone Push button in the footer. */
15529
+ .qc-action-group {
15530
+ display: inline-flex;
15531
+ align-items: stretch;
15532
+ gap: 8px;
15559
15533
  }
15560
- .qc-empty-icon {
15561
- flex-shrink: 0;
15562
- width: 32px;
15563
- height: 32px;
15564
- border-radius: 50%;
15565
- background: rgba(60, 160, 90, 0.14);
15566
- color: rgba(40, 130, 70, 0.95);
15567
- display: flex;
15534
+
15535
+ /* Small "工作区干净" badge shown inline in the modal subtitle. */
15536
+ .qc-clean-badge {
15537
+ display: inline-flex;
15568
15538
  align-items: center;
15569
- justify-content: center;
15570
- font-weight: 700;
15571
- font-size: 1rem;
15572
- }
15573
- .qc-empty-title {
15574
- font-size: 0.9rem;
15539
+ gap: 3px;
15540
+ margin-left: 8px;
15541
+ padding: 1px 8px;
15542
+ border-radius: 999px;
15543
+ font-size: 0.7rem;
15575
15544
  font-weight: 600;
15576
- color: var(--text-primary);
15577
- }
15578
- .qc-empty-sub {
15579
- font-size: 0.78rem;
15580
- color: var(--text-muted);
15545
+ color: rgba(40, 130, 70, 0.95);
15546
+ background: rgba(60, 160, 90, 0.12);
15547
+ border: 1px solid rgba(60, 160, 90, 0.22);
15548
+ vertical-align: 1px;
15581
15549
  }
15550
+ .qc-clean-badge svg { flex-shrink: 0; }
15582
15551
 
15583
- /* HEAD card (last commit info) */
15552
+ /* HEAD a plain inline line (no nested box). */
15584
15553
  .qc-head-card {
15585
15554
  display: flex;
15586
15555
  align-items: center;
15587
- gap: 10px;
15588
- padding: 8px 12px;
15589
- background: rgba(255, 255, 255, 0.7);
15590
- border: 1px solid rgba(125, 91, 57, 0.08);
15591
- border-radius: 10px;
15592
- min-height: 36px;
15556
+ gap: 8px;
15593
15557
  }
15594
15558
  .qc-head-label {
15595
15559
  flex-shrink: 0;
15596
- font-size: 0.7rem;
15560
+ font-size: 0.66rem;
15597
15561
  font-weight: 700;
15598
- letter-spacing: 0.05em;
15562
+ letter-spacing: 0.06em;
15599
15563
  color: var(--text-muted);
15600
15564
  text-transform: uppercase;
15565
+ padding: 1px 6px;
15566
+ border-radius: 5px;
15567
+ background: rgba(125, 91, 57, 0.08);
15601
15568
  }
15602
15569
  .qc-head-text {
15603
15570
  flex: 1 1 auto;
@@ -15642,11 +15609,6 @@
15642
15609
  color: rgba(160, 90, 50, 0.95);
15643
15610
  border-color: rgba(180, 100, 60, 0.28);
15644
15611
  }
15645
- .qc-chip--tag {
15646
- background: rgba(140, 100, 200, 0.14);
15647
- color: rgba(110, 70, 180, 0.95);
15648
- border-color: rgba(140, 100, 200, 0.28);
15649
- }
15650
15612
  .qc-chip--warn {
15651
15613
  background: rgba(220, 150, 30, 0.14);
15652
15614
  color: rgba(180, 110, 20, 0.95);
@@ -15658,16 +15620,34 @@
15658
15620
  border-color: rgba(60, 160, 90, 0.24);
15659
15621
  }
15660
15622
 
15623
+ /* "为当前提交打 Tag" button (icon + text, balances the push button) */
15624
+ .qc-tag-head-btn {
15625
+ display: inline-flex;
15626
+ align-items: center;
15627
+ gap: 5px;
15628
+ }
15629
+ .qc-tag-head-btn svg { flex-shrink: 0; opacity: 0.8; }
15630
+ .qc-tag-head-btn.is-open {
15631
+ background: rgba(140, 100, 200, 0.12);
15632
+ border-color: rgba(140, 100, 200, 0.28);
15633
+ color: rgba(96, 60, 160, 0.98);
15634
+ }
15635
+
15661
15636
  /* Tag HEAD inline drawer */
15662
15637
  .qc-tag-head-panel {
15663
15638
  display: flex;
15664
15639
  flex-direction: column;
15665
15640
  gap: 8px;
15666
- padding: 10px 12px;
15641
+ padding: 11px 12px;
15667
15642
  background: rgba(255, 255, 255, 0.85);
15668
15643
  border: 1px solid rgba(140, 100, 200, 0.18);
15669
15644
  border-radius: 10px;
15670
15645
  }
15646
+ .qc-tag-head-hint {
15647
+ font-size: 0.74rem;
15648
+ color: var(--text-muted);
15649
+ line-height: 1.4;
15650
+ }
15671
15651
  .qc-tag-head-row {
15672
15652
  display: flex;
15673
15653
  gap: 6px;
@@ -15750,7 +15730,7 @@
15750
15730
  all: unset;
15751
15731
  display: flex;
15752
15732
  flex-direction: column;
15753
- gap: 1px;
15733
+ gap: 2px;
15754
15734
  padding: 8px 10px;
15755
15735
  border-radius: 8px;
15756
15736
  cursor: pointer;
@@ -15760,12 +15740,26 @@
15760
15740
  background: rgba(197, 101, 61, 0.08);
15761
15741
  }
15762
15742
  .qc-dropdown-item.is-selected {
15763
- background: rgba(197, 101, 61, 0.12);
15743
+ background: rgba(197, 101, 61, 0.10);
15764
15744
  }
15765
15745
  .qc-dropdown-item.is-disabled {
15766
15746
  opacity: 0.5;
15767
15747
  cursor: not-allowed;
15768
15748
  }
15749
+ .qc-dropdown-item-main {
15750
+ display: flex;
15751
+ align-items: center;
15752
+ gap: 6px;
15753
+ }
15754
+ .qc-dropdown-check {
15755
+ flex-shrink: 0;
15756
+ width: 13px;
15757
+ height: 13px;
15758
+ display: inline-flex;
15759
+ align-items: center;
15760
+ justify-content: center;
15761
+ color: var(--accent);
15762
+ }
15769
15763
  .qc-dropdown-item-title {
15770
15764
  font-size: 0.84rem;
15771
15765
  font-weight: 600;
@@ -15775,6 +15769,7 @@
15775
15769
  font-size: 0.72rem;
15776
15770
  color: var(--text-muted);
15777
15771
  line-height: 1.4;
15772
+ padding-left: 19px;
15778
15773
  }
15779
15774
 
15780
15775
  @media (max-width: 720px) {
@@ -15782,12 +15777,11 @@
15782
15777
  .topbar-git-badge { padding: 0 8px; font-size: 0.7rem; }
15783
15778
  .quick-commit-modal { max-width: 95vw; }
15784
15779
  .qc-files-wrap { max-height: 160px; }
15785
- .qc-section { padding: 10px 12px; }
15786
15780
  .qc-dropdown-menu { min-width: 180px; }
15787
- .qc-ai-controls {
15788
- width: 100%;
15789
- justify-content: flex-end;
15790
- }
15781
+ .qc-section-actions--secondary { flex-wrap: wrap; gap: 8px; }
15782
+ .qc-section-actions--secondary .qc-tag-head-btn { flex: 1 1 auto; justify-content: center; }
15783
+ /* Keep the commit footer one row, but let the two button groups share width. */
15784
+ .qc-action-group { flex: 1 1 auto; justify-content: flex-end; }
15791
15785
  }
15792
15786
 
15793
15787
  /* ============================================================ */