create-walle 0.9.30 → 0.9.32

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 (112) hide show
  1. package/package.json +1 -1
  2. package/template/claude-task-manager/api-prompts.js +410 -5
  3. package/template/claude-task-manager/api-reviews.js +251 -3
  4. package/template/claude-task-manager/approval-agent.js +322 -24
  5. package/template/claude-task-manager/db.js +77 -13
  6. package/template/claude-task-manager/docs/codex-app-server-approvals.md +35 -1
  7. package/template/claude-task-manager/docs/postgres-concurrency-dgx-spark.html +407 -0
  8. package/template/claude-task-manager/docs/prompt-manager-redesign-proposal.html +667 -0
  9. package/template/claude-task-manager/docs/resume-ux-redesign.html +493 -0
  10. package/template/claude-task-manager/docs/review-redesign-proposal.html +892 -0
  11. package/template/claude-task-manager/docs/unified-auto-approver-proposal.html +520 -0
  12. package/template/claude-task-manager/git-utils.js +164 -26
  13. package/template/claude-task-manager/lib/agent-capabilities.js +26 -5
  14. package/template/claude-task-manager/lib/agent-cli-cache.js +1 -1
  15. package/template/claude-task-manager/lib/agent-presets.js +12 -0
  16. package/template/claude-task-manager/lib/agent-version-service.js +650 -0
  17. package/template/claude-task-manager/lib/approval-drift.js +57 -0
  18. package/template/claude-task-manager/lib/approval-hook.js +13 -0
  19. package/template/claude-task-manager/lib/auth-rules.js +6 -0
  20. package/template/claude-task-manager/lib/broadcast-payload-memo.js +109 -0
  21. package/template/claude-task-manager/lib/coding-agent-models.js +89 -8
  22. package/template/claude-task-manager/lib/db-owner-cooperative-scheduler.js +10 -1
  23. package/template/claude-task-manager/lib/document-review.js +75 -1
  24. package/template/claude-task-manager/lib/escalation-review.js +33 -3
  25. package/template/claude-task-manager/lib/headless-term-service.js +54 -9
  26. package/template/claude-task-manager/lib/mcp-risk.js +128 -0
  27. package/template/claude-task-manager/lib/microsoft-dev-tunnel-setup.js +51 -2
  28. package/template/claude-task-manager/lib/native-agent-model-args.js +149 -0
  29. package/template/claude-task-manager/lib/opencode-conversation-store.js +269 -0
  30. package/template/claude-task-manager/lib/permission-match.js +77 -5
  31. package/template/claude-task-manager/lib/read-pool-client.js +15 -6
  32. package/template/claude-task-manager/lib/restore-backoff.js +82 -0
  33. package/template/claude-task-manager/lib/runtime-registry.js +1 -0
  34. package/template/claude-task-manager/lib/scheduled-wake.js +42 -0
  35. package/template/claude-task-manager/lib/session-capture.js +33 -6
  36. package/template/claude-task-manager/lib/session-history.js +60 -3
  37. package/template/claude-task-manager/lib/session-jobs.js +19 -0
  38. package/template/claude-task-manager/lib/session-restore.js +5 -4
  39. package/template/claude-task-manager/lib/session-standup.js +2 -0
  40. package/template/claude-task-manager/lib/session-stream.js +9 -0
  41. package/template/claude-task-manager/lib/state-sync/cell-diff.js +31 -4
  42. package/template/claude-task-manager/lib/state-sync/restore-frame-hold.js +39 -0
  43. package/template/claude-task-manager/lib/tui-input-modes.js +40 -0
  44. package/template/claude-task-manager/lib/walle-ctm-history.js +103 -36
  45. package/template/claude-task-manager/lib/walle-session-model-catalog.js +7 -1
  46. package/template/claude-task-manager/lib/walle-token-chip.js +65 -0
  47. package/template/claude-task-manager/package.json +1 -1
  48. package/template/claude-task-manager/providers/claude-code.js +20 -1
  49. package/template/claude-task-manager/providers/codex-mcp-extract.js +33 -0
  50. package/template/claude-task-manager/providers/codex-mcp.js +23 -20
  51. package/template/claude-task-manager/providers/codex.js +65 -1
  52. package/template/claude-task-manager/public/css/prompts.css +345 -0
  53. package/template/claude-task-manager/public/css/reviews.css +248 -40
  54. package/template/claude-task-manager/public/css/walle-session.css +90 -26
  55. package/template/claude-task-manager/public/index.html +2031 -428
  56. package/template/claude-task-manager/public/js/document-review-links.js +255 -13
  57. package/template/claude-task-manager/public/js/file-context-menu.js +185 -0
  58. package/template/claude-task-manager/public/js/message-renderer.js +46 -1
  59. package/template/claude-task-manager/public/js/mobile-review-core.js +54 -0
  60. package/template/claude-task-manager/public/js/prompt-diff.js +55 -0
  61. package/template/claude-task-manager/public/js/prompt-editor-chrome.js +108 -0
  62. package/template/claude-task-manager/public/js/prompt-editor-modes.js +87 -0
  63. package/template/claude-task-manager/public/js/prompt-organize.js +179 -0
  64. package/template/claude-task-manager/public/js/prompt-reuse.js +77 -0
  65. package/template/claude-task-manager/public/js/prompts.js +683 -215
  66. package/template/claude-task-manager/public/js/resume-state.js +186 -0
  67. package/template/claude-task-manager/public/js/reviews.js +402 -121
  68. package/template/claude-task-manager/public/js/screenshot-router.js +91 -0
  69. package/template/claude-task-manager/public/js/session-search-utils.js +81 -0
  70. package/template/claude-task-manager/public/js/state-sync-client.js +134 -17
  71. package/template/claude-task-manager/public/js/stream-view.js +93 -20
  72. package/template/claude-task-manager/public/js/walle-session.js +183 -32
  73. package/template/claude-task-manager/public/js/walle.js +21 -9
  74. package/template/claude-task-manager/public/m/app.css +117 -0
  75. package/template/claude-task-manager/public/m/app.js +309 -3
  76. package/template/claude-task-manager/public/m/index.html +56 -1
  77. package/template/claude-task-manager/server.js +724 -305
  78. package/template/claude-task-manager/workers/db-owner-worker.js +8 -0
  79. package/template/claude-task-manager/workers/read-pool-worker.js +4 -0
  80. package/template/claude-task-manager/workers/state-detectors/claude-code.js +10 -1
  81. package/template/docs/proposals/2026-06-23-local-model-right-path.html +340 -0
  82. package/template/docs/proposals/2026-06-24-qlora-done-right.md +255 -0
  83. package/template/package.json +1 -1
  84. package/template/wall-e/api-walle.js +21 -3
  85. package/template/wall-e/bin/train-gemma-e4b-tooluse.js +27 -4
  86. package/template/wall-e/brain.js +50 -5
  87. package/template/wall-e/chat/force-compact.js +73 -0
  88. package/template/wall-e/chat.js +137 -9
  89. package/template/wall-e/coding/action-memory-policy.js +120 -1
  90. package/template/wall-e/coding/compaction-service.js +10 -3
  91. package/template/wall-e/coding/model-router.js +116 -0
  92. package/template/wall-e/coding-orchestrator.js +303 -11
  93. package/template/wall-e/coding-prompts.js +1 -1
  94. package/template/wall-e/docs/skill-self-heal-design.html +429 -0
  95. package/template/wall-e/llm/client.js +115 -6
  96. package/template/wall-e/llm/codex-cli.js +71 -23
  97. package/template/wall-e/llm/codex-cli.plugin.json +1 -0
  98. package/template/wall-e/llm/default-fallback.js +71 -11
  99. package/template/wall-e/llm/mlx-worker.js +0 -0
  100. package/template/wall-e/llm/mlx.js +46 -12
  101. package/template/wall-e/llm/provider-error.js +9 -3
  102. package/template/wall-e/llm/provider-health-state.js +561 -11
  103. package/template/wall-e/llm/registry.js +6 -0
  104. package/template/wall-e/llm/routing-policy.js +255 -25
  105. package/template/wall-e/llm/tool-call-validator.js +156 -0
  106. package/template/wall-e/skills/skill-dispatch-decision.js +82 -2
  107. package/template/wall-e/skills/skill-planner.js +72 -5
  108. package/template/wall-e/tools/command-registry.js +34 -0
  109. package/template/wall-e/training/gemma-e4b-qlora.js +197 -1
  110. package/template/wall-e/training/mlx_lora_launch.py +196 -0
  111. package/template/wall-e/training/training-coexistence.sh +87 -0
  112. package/template/wall-e/training/training-mem-guard.sh +76 -0
@@ -572,6 +572,84 @@ html[data-theme="light"] #prompts-panel {
572
572
  padding: 2px 0;
573
573
  }
574
574
 
575
+ /* ============================================================
576
+ Editor chrome declutter: selection bubble + "…" overflow menu
577
+ + Details popover. Reuses .toolbar-btn and the send-dropdown
578
+ open/close skeleton.
579
+ ============================================================ */
580
+
581
+ /* Floating formatting bubble (shown on text selection in rich mode) */
582
+ .pe-bubble {
583
+ position: fixed;
584
+ z-index: 120;
585
+ display: flex;
586
+ align-items: center;
587
+ gap: 2px;
588
+ padding: 3px;
589
+ background: var(--bg-light);
590
+ border: 1px solid var(--border);
591
+ border-radius: 8px;
592
+ box-shadow: 0 8px 24px rgba(0,0,0,0.4);
593
+ }
594
+ .pe-bubble .toolbar-btn { padding: 4px 8px; font-size: 12px; }
595
+ .pe-bubble-sep {
596
+ width: 1px; align-self: stretch; margin: 2px 3px;
597
+ background: var(--border);
598
+ }
599
+
600
+ /* "…" overflow + Details popover share the dropdown skeleton */
601
+ .pe-overflow-wrap, .pe-details-wrap { position: relative; display: inline-flex; }
602
+ .pe-overflow-btn { font-size: 15px; letter-spacing: 1px; }
603
+ .pe-details-btn {
604
+ color: var(--fg-dim); border: 1px solid transparent; background: none;
605
+ font-weight: 600; white-space: nowrap;
606
+ }
607
+ .pe-details-btn:hover { color: var(--fg); background: var(--bg-lighter); }
608
+ .pe-overflow-menu, .pe-details-popover {
609
+ display: none;
610
+ position: absolute;
611
+ top: 100%;
612
+ margin-top: 4px;
613
+ background: var(--bg-light);
614
+ border: 1px solid var(--border);
615
+ border-radius: 8px;
616
+ box-shadow: 0 8px 24px rgba(0,0,0,0.4);
617
+ z-index: 100;
618
+ padding: 6px;
619
+ }
620
+ .pe-overflow-menu { left: 0; min-width: 220px; }
621
+ .pe-details-popover { right: 0; min-width: 260px; }
622
+ .pe-overflow-menu.open, .pe-details-popover.open { display: block; }
623
+ .pe-overflow-section { padding: 4px 2px; border-bottom: 1px solid var(--border); }
624
+ .pe-overflow-section:last-child { border-bottom: none; }
625
+ .pe-overflow-label, .pe-details-label {
626
+ font-size: 9.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
627
+ color: var(--fg-dim);
628
+ }
629
+ .pe-overflow-label { margin: 0 2px 4px; }
630
+ .pe-overflow-row { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; }
631
+ .pe-overflow-row select {
632
+ background: var(--bg); color: var(--fg); border: 1px solid var(--border);
633
+ border-radius: 4px; font-size: 11px; padding: 2px 4px; outline: none; cursor: pointer;
634
+ }
635
+ .pe-overflow-row #pe-font-select { min-width: 130px; }
636
+
637
+ /* Details popover layout */
638
+ .pe-details-row { display: flex; align-items: center; gap: 8px; padding: 5px 2px; }
639
+ .pe-details-row .pe-details-label { width: 64px; flex-shrink: 0; }
640
+ .pe-details-popover select {
641
+ flex: 1; background: var(--bg); color: var(--fg); border: 1px solid var(--border);
642
+ padding: 4px 8px; border-radius: 4px; font-size: 11px; outline: none;
643
+ }
644
+ .pe-details-popover .tags-input { flex: 1; }
645
+ .pe-details-actions { gap: 6px; flex-wrap: wrap; padding-top: 8px; border-top: 1px solid var(--border); }
646
+
647
+ /* Narrow widths: let the inline insert trio wrap/collapse gracefully */
648
+ @media (max-width: 680px) {
649
+ .pe-details-popover { min-width: 220px; }
650
+ .pe-overflow-menu { min-width: 200px; }
651
+ }
652
+
575
653
  /* Send dropdown */
576
654
  .send-dropdown-wrap {
577
655
  position: relative;
@@ -1067,3 +1145,270 @@ html[data-theme="light"] #prompts-panel {
1067
1145
  padding: 8px 10px;
1068
1146
  border-bottom: 1px solid var(--border);
1069
1147
  }
1148
+
1149
+ /* ============================================================
1150
+ Phase 1 — Findability: consolidated sidebar (Views + Tags)
1151
+ One organization model: search + Favorites/Recent/All + tags.
1152
+ ============================================================ */
1153
+ .pe-views { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin-top: 8px; }
1154
+ .pe-view {
1155
+ display: flex; align-items: center; justify-content: center; gap: 5px;
1156
+ background: var(--bg); color: var(--fg-muted); border: 1px solid var(--border);
1157
+ border-radius: 7px; padding: 5px 6px; font-size: 11px; cursor: pointer; min-width: 0;
1158
+ }
1159
+ .pe-view:hover { border-color: var(--accent); color: var(--fg); }
1160
+ .pe-view.active { background: var(--accent-soft, rgba(122,162,247,0.13)); border-color: var(--accent); color: var(--accent); font-weight: 600; }
1161
+ .pe-view .pe-view-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1162
+ .pe-view .pe-view-ct { font-size: 10px; opacity: 0.8; font-family: 'SF Mono', Menlo, monospace; }
1163
+ .pe-view .pe-view-ic { font-size: 11px; line-height: 1; }
1164
+
1165
+ .pe-tag-facets { margin-top: 10px; }
1166
+ .pe-facet-title {
1167
+ font-size: 9.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
1168
+ color: var(--fg-dim); margin: 0 2px 6px;
1169
+ }
1170
+ .pe-tag-wrap { display: flex; flex-wrap: wrap; gap: 5px; max-height: 116px; overflow-y: auto; }
1171
+ .pe-tag-chip {
1172
+ display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px;
1173
+ padding: 2px 8px; border-radius: 20px; background: var(--bg-lighter);
1174
+ color: var(--fg-muted); border: 1px solid var(--border); cursor: pointer; user-select: none;
1175
+ }
1176
+ .pe-tag-chip:hover { border-color: var(--accent); color: var(--fg); }
1177
+ .pe-tag-chip.on { background: var(--accent); color: var(--accent-fg, #0d1117); border-color: var(--accent); font-weight: 600; }
1178
+ .pe-tag-chip .pe-tag-ct { font-size: 9px; opacity: 0.7; font-family: 'SF Mono', Menlo, monospace; }
1179
+ .pe-tag-chip.on .pe-tag-ct { opacity: 0.85; }
1180
+
1181
+ .pe-sidebar-actions { display: flex; align-items: center; gap: 4px; margin-top: 10px; }
1182
+
1183
+ .pe-list-head {
1184
+ display: flex; align-items: center; justify-content: space-between;
1185
+ padding: 8px 10px 5px; gap: 8px;
1186
+ }
1187
+ .pe-list-head .pe-list-scope {
1188
+ font-size: 10px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--fg-muted);
1189
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1190
+ }
1191
+ .pe-list-head .pe-list-count {
1192
+ font-size: 10px; color: var(--fg-dim); background: var(--bg-lighter);
1193
+ border-radius: 20px; padding: 1px 8px; font-weight: 600; flex-shrink: 0;
1194
+ }
1195
+
1196
+ .pe-folders-group { margin: 2px 0 4px; border-bottom: 1px solid var(--border); }
1197
+ .pe-folders-group > summary {
1198
+ list-style: none; cursor: pointer; padding: 6px 10px; font-size: 10px; font-weight: 700;
1199
+ letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-dim); user-select: none;
1200
+ }
1201
+ .pe-folders-group > summary::-webkit-details-marker { display: none; }
1202
+ .pe-folders-group > summary::before { content: '▸ '; color: var(--fg-dim); }
1203
+ .pe-folders-group[open] > summary::before { content: '▾ '; }
1204
+ .pe-folders-group > summary:hover { color: var(--fg); }
1205
+
1206
+ /* Per-row favorite toggle (replaces the old star + pin duo with one axis) */
1207
+ .prompt-item .pe-fav-btn {
1208
+ background: none; border: 0; cursor: pointer; padding: 0; margin-top: 1px;
1209
+ color: var(--fg-dim); font-size: 13px; line-height: 1; flex-shrink: 0; opacity: 0.55;
1210
+ }
1211
+ .prompt-item:hover .pe-fav-btn { opacity: 0.9; }
1212
+ .prompt-item .pe-fav-btn.on { color: var(--yellow); opacity: 1; }
1213
+ .prompt-item .pe-fav-btn:hover { color: var(--yellow); opacity: 1; }
1214
+ /* The dedicated button replaces the old ::before star marker */
1215
+ .prompt-item.starred .prompt-title::before { content: none; }
1216
+ .prompt-item.starred { border-left-color: var(--yellow); }
1217
+
1218
+ /* Row meta badges */
1219
+ .prompt-item .prompt-meta .pe-varbadge {
1220
+ font-family: 'SF Mono', Menlo, monospace; font-size: 9px; color: var(--purple);
1221
+ background: color-mix(in srgb, var(--purple) 14%, transparent); border-radius: 4px; padding: 0 4px;
1222
+ }
1223
+ .prompt-item .prompt-meta .pe-vbadge {
1224
+ font-family: 'SF Mono', Menlo, monospace; font-size: 9px; color: var(--green);
1225
+ background: var(--success-soft, rgba(158,206,106,0.14)); border-radius: 4px; padding: 0 4px;
1226
+ }
1227
+ .prompt-item .prompt-meta .pe-uses { font-size: 9.5px; color: var(--fg-dim); }
1228
+ .prompt-item .prompt-meta .when { margin-left: auto; font-size: 9.5px; color: var(--fg-dim); }
1229
+ .prompt-item .prompt-meta mark { background: var(--warning-soft, rgba(224,175,104,0.22)); color: inherit; border-radius: 2px; padding: 0 1px; }
1230
+ .prompt-item .prompt-title mark { background: var(--warning-soft, rgba(224,175,104,0.22)); color: inherit; border-radius: 2px; padding: 0 1px; }
1231
+
1232
+ /* Body-match snippet under the title (search results, #10) */
1233
+ .prompt-item .prompt-snippet {
1234
+ font-size: 10px; color: var(--fg-dim); line-height: 1.4; margin: 2px 0 1px;
1235
+ overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
1236
+ }
1237
+ .prompt-item .prompt-snippet mark {
1238
+ background: var(--warning-soft, rgba(224,175,104,0.22)); color: inherit; border-radius: 2px; padding: 0 1px;
1239
+ }
1240
+
1241
+ .pe-empty {
1242
+ padding: 16px 12px; font-size: 12px; color: var(--fg-dim); text-align: center; line-height: 1.5;
1243
+ }
1244
+ .pe-empty b { color: var(--fg-muted); }
1245
+
1246
+ /* ============================================================
1247
+ Phase 2 — Dual-mode editor (Rich WYSIWYG default + Markdown)
1248
+ ============================================================ */
1249
+ .pe-mode-switch, .pe-submode-switch {
1250
+ display: inline-flex; background: var(--bg); border: 1px solid var(--border);
1251
+ border-radius: 7px; padding: 2px; gap: 2px;
1252
+ }
1253
+ .pe-submode-switch { margin-left: 6px; }
1254
+ .pe-mode-btn, .pe-submode-btn {
1255
+ font: inherit; font-size: 11px; color: var(--fg-muted); background: none; border: 0;
1256
+ padding: 3px 9px; border-radius: 5px; cursor: pointer; white-space: nowrap;
1257
+ }
1258
+ .pe-mode-btn:hover, .pe-submode-btn:hover { color: var(--fg); }
1259
+ .pe-mode-btn.active, .pe-submode-btn.active { background: var(--accent); color: var(--accent-fg, #0d1117); font-weight: 600; }
1260
+
1261
+ .pe-token-meter {
1262
+ font-family: 'SF Mono', Menlo, monospace; font-size: 11px; color: var(--fg-dim);
1263
+ white-space: nowrap; padding: 2px 4px;
1264
+ }
1265
+
1266
+ .pe-var-bar {
1267
+ display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
1268
+ padding: 6px 12px; margin: 0 8px 4px; background: var(--bg-light, #24283b);
1269
+ border: 1px solid var(--border); border-radius: 6px;
1270
+ }
1271
+ .pe-var-bar-label {
1272
+ font-size: 9.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-dim);
1273
+ }
1274
+ .pe-var-chip {
1275
+ font-family: 'SF Mono', Menlo, monospace; font-size: 11px; color: var(--purple);
1276
+ background: color-mix(in srgb, var(--purple) 15%, transparent); border-radius: 5px; padding: 1px 7px;
1277
+ }
1278
+ /* Inline {{variable}} chips rendered inside the rich editor (#19) */
1279
+ .pe-var-inline {
1280
+ font-family: 'SF Mono', Menlo, monospace; font-size: 0.92em; color: var(--purple);
1281
+ background: color-mix(in srgb, var(--purple) 14%, transparent);
1282
+ border: 1px solid color-mix(in srgb, var(--purple) 30%, transparent);
1283
+ border-radius: 5px; padding: 0 4px; white-space: nowrap;
1284
+ }
1285
+
1286
+ /* Markdown panes */
1287
+ .pe-md { display: flex; gap: 0; min-height: 320px; align-items: stretch; }
1288
+ .pe-md-edit { flex: 1; min-width: 0; position: relative; display: flex; }
1289
+ .pe-md-preview {
1290
+ flex: 1; min-width: 0; overflow: auto; padding: 4px 18px; border-left: 1px solid var(--border);
1291
+ font-size: 14px; line-height: 1.6; color: var(--fg);
1292
+ }
1293
+ /* When only one pane is shown it takes the full width (no divider) */
1294
+ .pe-md-edit:only-child, .pe-md-preview:only-child { border-left: 0; }
1295
+
1296
+ /* Highlight overlay: transparent textarea on top of a highlighted <pre>,
1297
+ sharing identical box metrics so the caret aligns with the text. */
1298
+ .pe-md-pre, .pe-md-input {
1299
+ margin: 0; padding: 8px 12px; border: 0;
1300
+ font-family: 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
1301
+ font-size: 13px; line-height: 1.6; tab-size: 2;
1302
+ white-space: pre-wrap; word-break: break-word; overflow-wrap: break-word;
1303
+ }
1304
+ .pe-md-pre {
1305
+ position: absolute; inset: 0; overflow: auto; pointer-events: none;
1306
+ color: var(--fg); background: transparent; z-index: 0;
1307
+ }
1308
+ .pe-md-input {
1309
+ position: relative; flex: 1; width: 100%; resize: none; outline: none;
1310
+ background: transparent; color: transparent; caret-color: var(--accent);
1311
+ z-index: 1; overflow: auto;
1312
+ }
1313
+ .pe-md-input::placeholder { color: var(--fg-dim); }
1314
+
1315
+ /* Markdown source token colors (escape-safe spans from highlightMarkdownSource) */
1316
+ .pe-md-pre .md-h { color: var(--syn-fn, var(--accent)); font-weight: 700; }
1317
+ .pe-md-pre .md-var { color: var(--purple); background: color-mix(in srgb, var(--purple) 16%, transparent); border-radius: 3px; }
1318
+ .pe-md-pre .md-code { color: var(--syn-str, var(--green)); }
1319
+ .pe-md-pre .md-ctx { color: var(--syn-num, #ff9e64); background: color-mix(in srgb, var(--syn-num, #ff9e64) 14%, transparent); border-radius: 3px; }
1320
+ .pe-md-pre .md-bold { color: var(--fg); font-weight: 700; }
1321
+
1322
+ .pe-md-preview h1, .pe-md-preview h2, .pe-md-preview h3 { margin: 0.6em 0 0.3em; line-height: 1.25; }
1323
+ .pe-md-preview p { margin: 0 0 0.7em; }
1324
+ .pe-md-preview ul, .pe-md-preview ol { margin: 0 0 0.7em 1.3em; }
1325
+ .pe-md-preview code { font-family: 'SF Mono', Menlo, monospace; font-size: 0.88em; background: var(--code-bg, rgba(122,162,247,0.12)); border-radius: 4px; padding: 1px 5px; }
1326
+ .pe-md-preview pre { background: var(--bg-lighter); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; overflow: auto; }
1327
+ .pe-md-preview pre code { background: none; padding: 0; }
1328
+ .pe-md-preview blockquote { border-left: 3px solid var(--border); margin: 0 0 0.7em; padding-left: 12px; color: var(--fg-muted); }
1329
+
1330
+ /* ============================================================
1331
+ Phase 3 — Variable fill-in form (Reuse)
1332
+ ============================================================ */
1333
+ .pe-fill-overlay {
1334
+ position: fixed; inset: 0; z-index: 10000; display: flex; align-items: flex-start;
1335
+ justify-content: center; padding-top: 14vh; background: rgba(0,0,0,0.5); backdrop-filter: blur(4px);
1336
+ }
1337
+ .pe-fill-modal {
1338
+ width: 460px; max-width: 92vw; max-height: 74vh; overflow: auto;
1339
+ background: var(--bg-elevated, #2b3045); border: 1px solid var(--border); border-radius: 13px;
1340
+ box-shadow: 0 24px 60px rgba(0,0,0,0.45); padding: 18px 20px;
1341
+ }
1342
+ .pe-ff-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 16px; }
1343
+ .pe-ff-title { font-size: 14px; font-weight: 650; color: var(--fg); }
1344
+ .pe-ff-sub { font-size: 11px; color: var(--fg-dim); margin-left: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 55%; }
1345
+ .pe-ff-field { margin-bottom: 13px; }
1346
+ .pe-ff-field label {
1347
+ display: block; font-size: 10.5px; color: var(--fg-dim); margin-bottom: 5px;
1348
+ text-transform: uppercase; letter-spacing: 0.05em;
1349
+ }
1350
+ .pe-ff-input {
1351
+ width: 100%; background: var(--bg-input, var(--bg)); border: 1px solid var(--border);
1352
+ border-radius: 8px; padding: 8px 12px; font-size: 13px; color: var(--fg);
1353
+ font-family: 'SF Mono', Menlo, monospace; outline: none;
1354
+ }
1355
+ .pe-ff-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus-ring, rgba(122,162,247,0.32)); }
1356
+ .pe-ff-nofields { font-size: 12.5px; color: var(--fg-muted); margin-bottom: 10px; }
1357
+ .pe-ff-dyn {
1358
+ margin-top: 6px; padding: 9px 11px; background: var(--bg-light, #24283b); border: 1px solid var(--border);
1359
+ border-radius: 8px; font-size: 11.5px; color: var(--fg-muted); line-height: 1.6;
1360
+ }
1361
+ .pe-ff-dyn code {
1362
+ font-family: 'SF Mono', Menlo, monospace; font-size: 10.5px; color: var(--syn-num, #ff9e64);
1363
+ background: color-mix(in srgb, var(--syn-num, #ff9e64) 14%, transparent); border-radius: 4px; padding: 1px 5px;
1364
+ }
1365
+ .pe-ff-dyn-hint { display: block; margin-top: 4px; color: var(--fg-dim); font-size: 10.5px; }
1366
+ .pe-ff-actions { display: flex; gap: 9px; margin-top: 18px; }
1367
+ .pe-ff-btn { flex: 1; text-align: center; font: inherit; font-size: 12.5px; font-weight: 600; padding: 9px; border-radius: 8px; cursor: pointer; border: 1px solid var(--border); }
1368
+ .pe-ff-btn.primary { background: var(--accent); color: var(--accent-fg, #0d1117); border-color: var(--accent); }
1369
+ .pe-ff-btn.ghost { background: var(--bg-light, #24283b); color: var(--fg-muted); }
1370
+ .pe-ff-btn .pe-ff-kbd { font-family: 'SF Mono', Menlo, monospace; font-size: 10px; opacity: 0.7; margin-left: 4px; }
1371
+
1372
+ /* ============================================================
1373
+ Phase 4 — Version diff (side-by-side)
1374
+ ============================================================ */
1375
+ .pe-diff-modal {
1376
+ width: 860px; max-width: 94vw; max-height: 80vh; display: flex; flex-direction: column;
1377
+ background: var(--bg-elevated, #2b3045); border: 1px solid var(--border); border-radius: 13px;
1378
+ box-shadow: 0 24px 60px rgba(0,0,0,0.45); overflow: hidden;
1379
+ }
1380
+ .pe-diff-head { display: flex; align-items: center; gap: 12px; padding: 13px 16px; border-bottom: 1px solid var(--border); }
1381
+ .pe-diff-title { font-size: 14px; font-weight: 650; color: var(--fg); }
1382
+ .pe-diff-stat { font-family: 'SF Mono', Menlo, monospace; font-size: 12px; }
1383
+ .pe-diff-stat .add { color: var(--green); } .pe-diff-stat .del { color: var(--red); }
1384
+ .pe-diff-head .pe-ff-btn { margin-left: auto; }
1385
+ .pe-diff-cols { display: flex; padding: 6px 16px; background: var(--bg-panel, var(--bg-light)); border-bottom: 1px solid var(--border); font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-dim); }
1386
+ .pe-diff-cols span { flex: 1; }
1387
+ .pe-diff-body { overflow: auto; }
1388
+ .pe-diff-table { width: 100%; border-collapse: collapse; font-family: 'SF Mono', 'JetBrains Mono', Menlo, monospace; font-size: 12px; line-height: 1.55; }
1389
+ .pe-diff-gutter { width: 38px; text-align: right; padding: 0 8px; color: var(--fg-dim); opacity: 0.6; user-select: none; vertical-align: top; }
1390
+ .pe-diff-side { width: 50%; padding: 0 10px 0 4px; white-space: pre-wrap; word-break: break-word; vertical-align: top; color: var(--fg); }
1391
+ .pe-diff-side.left { border-right: 1px solid var(--border); }
1392
+ .pe-diff-sign { display: inline-block; width: 1ch; margin-right: 6px; opacity: 0.6; }
1393
+ .pe-diff-del .left { background: var(--diff-del-bg, rgba(247,118,142,0.16)); }
1394
+ .pe-diff-add .right { background: var(--diff-add-bg, rgba(158,206,106,0.16)); }
1395
+ .pe-diff-del .left .pe-diff-sign { color: var(--red); }
1396
+ .pe-diff-add .right .pe-diff-sign { color: var(--green); }
1397
+
1398
+ /* ============================================================
1399
+ Gap-close: toolbar insert chips, palette footer, token over-limit
1400
+ ============================================================ */
1401
+ .pe-insert-btn {
1402
+ font-family: 'SF Mono', Menlo, monospace !important; font-size: 10.5px !important;
1403
+ padding: 2px 7px !important; white-space: nowrap;
1404
+ }
1405
+ .pe-token-meter.over { color: var(--red); font-weight: 600; }
1406
+
1407
+ .pe-palette-foot {
1408
+ display: flex; gap: 16px; padding: 9px 16px; border-top: 1px solid var(--border);
1409
+ background: var(--bg-panel, var(--bg-light)); font-size: 11px; color: var(--fg-dim);
1410
+ }
1411
+ .pe-palette-foot .kbd {
1412
+ font-family: 'SF Mono', Menlo, monospace; font-size: 10px; color: var(--fg-dim);
1413
+ border: 1px solid var(--border); border-radius: 4px; padding: 0 5px; margin-right: 3px; background: var(--bg);
1414
+ }
@@ -94,6 +94,17 @@
94
94
  .ctm-doc-review-link:hover {
95
95
  color: var(--fg, #c0caf5);
96
96
  }
97
+ .ctm-commit-link {
98
+ color: var(--accent, #7aa2f7);
99
+ font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
100
+ text-decoration: underline;
101
+ text-decoration-style: dotted;
102
+ text-underline-offset: 2px;
103
+ cursor: pointer;
104
+ }
105
+ .ctm-commit-link:hover {
106
+ color: var(--fg, #c0caf5);
107
+ }
97
108
 
98
109
  /* Commit summary card (shown at top of diff area when a commit is selected) */
99
110
  .cr-file-item.summary {
@@ -633,7 +644,11 @@
633
644
  }
634
645
 
635
646
  /* Side-by-side (split) diff layout */
636
- .cr-diff-table.split { table-layout: fixed; }
647
+ .cr-diff-table.split { table-layout: fixed; width: 100%; }
648
+ /* Column widths come from the colgroup (see _renderFileDiffSplit): narrow gutters,
649
+ two equal code columns. Without this the colspan=4 hunk header would force four
650
+ equal 25% columns and leave a dead channel between the panes. */
651
+ .cr-diff-table.split col.cr-col-num { width: 46px; }
637
652
  .cr-diff-table.split .cr-line-num { width: 46px; min-width: 46px; }
638
653
  .cr-diff-table.split .cr-line-content {
639
654
  white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere; padding: 0 10px;
@@ -971,45 +986,6 @@
971
986
  .cr-project-action-hint {
972
987
  color: var(--fg-dim); font-size: 11px;
973
988
  }
974
- /* Session list inside project card */
975
- .cr-project-session-count {
976
- font-size: 10px; color: var(--fg-dim);
977
- }
978
- .cr-project-session-section {
979
- margin: 9px 0 4px; padding-top: 8px; border-top: 1px solid rgba(255,255,255,0.06);
980
- }
981
- .cr-session-section-label {
982
- margin-bottom: 4px; color: var(--fg-dim); font-size: 10px; font-weight: 800;
983
- text-transform: uppercase; letter-spacing: 0;
984
- }
985
- .cr-project-session-list {
986
- display: flex; flex-direction: column; gap: 2px;
987
- }
988
- .cr-project-session-item {
989
- display: flex; align-items: center; gap: 6px; padding: 4px 8px;
990
- border-radius: 4px; font-size: 11px; cursor: pointer;
991
- transition: background 0.1s;
992
- }
993
- .cr-project-session-item:hover { background: rgba(122,162,247,0.1); }
994
- .cr-project-session-item.hidden { display: none; }
995
- .cr-session-active {
996
- font-size: 9px; font-weight: 600; color: var(--green, #9ece6a);
997
- background: rgba(158,206,106,0.12); padding: 1px 5px; border-radius: 8px;
998
- flex-shrink: 0;
999
- }
1000
- .cr-session-label {
1001
- flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
1002
- white-space: nowrap; color: var(--fg);
1003
- }
1004
- .cr-session-time {
1005
- font-size: 10px; color: var(--fg-dim); flex-shrink: 0; white-space: nowrap;
1006
- }
1007
- .cr-session-toggle {
1008
- font-size: 10px; color: var(--accent); background: none; border: none;
1009
- cursor: pointer; padding: 2px 8px; text-align: left;
1010
- }
1011
- .cr-session-toggle:hover { text-decoration: underline; }
1012
-
1013
989
  .cr-project-files {
1014
990
  display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px;
1015
991
  }
@@ -1253,3 +1229,235 @@
1253
1229
  }
1254
1230
  .cr-chat-toggle:hover { background: var(--bg-lighter); color: var(--fg); }
1255
1231
  .cr-chat-toggle.active { color: var(--accent); border-color: var(--accent); }
1232
+
1233
+ /* ===== Phase A: shared shell — nav history + breadcrumb ===== */
1234
+ .cr-navcluster {
1235
+ display: flex; align-items: center; gap: 10px; min-width: 0; flex-shrink: 1;
1236
+ }
1237
+ .cr-nav-history { display: inline-flex; gap: 2px; flex-shrink: 0; }
1238
+ .cr-nav-btn {
1239
+ width: 26px; height: 26px; display: inline-grid; place-items: center;
1240
+ font-size: 14px; line-height: 1; cursor: pointer; color: var(--fg-dim);
1241
+ background: var(--bg-light); border: 1px solid var(--border); border-radius: 7px;
1242
+ transition: color .12s, border-color .12s, background .12s;
1243
+ }
1244
+ .cr-nav-btn:hover:not(:disabled) { color: var(--fg); border-color: var(--accent); }
1245
+ .cr-nav-btn:disabled { opacity: 0.34; cursor: default; }
1246
+ .cr-breadcrumb {
1247
+ display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 13px; flex-wrap: nowrap; overflow: hidden;
1248
+ }
1249
+ .cr-crumb {
1250
+ color: var(--fg-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 22ch;
1251
+ border-radius: 5px; padding: 2px 4px;
1252
+ }
1253
+ .cr-crumb[role="link"] { cursor: pointer; }
1254
+ .cr-crumb[role="link"]:hover { color: var(--fg); background: var(--bg-hover); }
1255
+ .cr-crumb.active { color: var(--fg); font-weight: 600; }
1256
+ .cr-crumb-sep { color: var(--fg-dim); flex-shrink: 0; }
1257
+ .cr-hub-tagline { font-size: 12px; color: var(--fg-dim); margin-left: 4px; }
1258
+
1259
+ /* ===== Phase A: project groups (worktrees nested under their repo) ===== */
1260
+ .cr-project-groups { display: flex; flex-direction: column; gap: 16px; }
1261
+ .cr-project-group {
1262
+ border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: var(--bg-panel, var(--bg-light));
1263
+ }
1264
+ .cr-project-group.solo { border: 0; border-radius: 0; background: none; overflow: visible; }
1265
+ .cr-project-group-header {
1266
+ display: flex; align-items: center; gap: 10px; padding: 10px 14px;
1267
+ background: var(--bg-lighter); border-bottom: 1px solid var(--border);
1268
+ }
1269
+ .cr-project-group-icon { font-size: 14px; opacity: 0.85; }
1270
+ .cr-project-group-name { font-size: 14px; font-weight: 700; color: var(--fg); }
1271
+ .cr-project-group-meta { font-size: 11.5px; color: var(--fg-dim); }
1272
+ .cr-project-group-changes {
1273
+ margin-left: auto; font-size: 11px; font-weight: 600; color: var(--accent);
1274
+ background: var(--accent-soft); border-radius: 20px; padding: 2px 10px;
1275
+ }
1276
+ .cr-project-group-members { display: flex; flex-direction: column; gap: 1px; padding: 8px; }
1277
+ .cr-project-group-members .cr-project-card {
1278
+ border-radius: 9px;
1279
+ }
1280
+ .cr-project-group-members .cr-project-card.is-worktree {
1281
+ margin-left: 14px; border-left: 2px solid var(--border);
1282
+ }
1283
+ .cr-project-group-members .cr-project-card.is-worktree.has-changes { border-left-color: var(--accent); }
1284
+ .cr-worktree-name {
1285
+ font-size: 11px; color: var(--purple); font-family: var(--font-mono, 'SF Mono', Menlo, monospace);
1286
+ background: color-mix(in srgb, var(--purple) 12%, transparent); border-radius: 6px; padding: 1px 7px;
1287
+ }
1288
+
1289
+ /* ===== Phase B: viewer quality — highlight.js + stronger diff/inline-code ===== */
1290
+ #codereview-panel { --cr-teal: #2ac3de; }
1291
+ html[data-theme="light"] #codereview-panel { --cr-teal: #0e7490; }
1292
+
1293
+ /* Inline code: accent text + hairline border = unmistakably "code" */
1294
+ .cr-doc-markdown code {
1295
+ color: var(--accent); font-size: 0.88em;
1296
+ border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent); border-radius: 5px;
1297
+ }
1298
+ .cr-doc-markdown pre code { color: var(--fg); border: 0; }
1299
+
1300
+ /* Diff lines: stronger fill + a left accent bar so add/del read at a glance */
1301
+ .cr-diff-line.add { background: var(--success-soft, rgba(158,206,106,0.14)); }
1302
+ .cr-diff-line.del { background: var(--danger-soft, rgba(247,118,142,0.14)); }
1303
+ .cr-diff-line.add:hover { background: rgba(158,206,106,0.22); }
1304
+ .cr-diff-line.del:hover { background: rgba(247,118,142,0.22); }
1305
+ .cr-diff-line.add .cr-line-content { box-shadow: inset 2px 0 0 var(--green, #9ece6a); }
1306
+ .cr-diff-line.del .cr-line-content { box-shadow: inset 2px 0 0 var(--red, #f7768e); }
1307
+ .cr-diff-line-split .cr-line-content.add { background: var(--success-soft, rgba(158,206,106,0.14)); box-shadow: inset 2px 0 0 var(--green, #9ece6a); }
1308
+ .cr-diff-line-split .cr-line-content.del { background: var(--danger-soft, rgba(247,118,142,0.14)); box-shadow: inset 2px 0 0 var(--red, #f7768e); }
1309
+
1310
+ /* highlight.js token theme — semantic CTM vars, flips with the app theme,
1311
+ scoped to the review panel so it never leaks into other code surfaces. */
1312
+ #codereview-panel .hljs { color: var(--fg); background: transparent; }
1313
+ #codereview-panel .hljs-comment, #codereview-panel .hljs-quote { color: var(--fg-dim); font-style: italic; }
1314
+ #codereview-panel .hljs-keyword, #codereview-panel .hljs-selector-tag, #codereview-panel .hljs-literal, #codereview-panel .hljs-meta-keyword { color: var(--purple); }
1315
+ #codereview-panel .hljs-string, #codereview-panel .hljs-regexp, #codereview-panel .hljs-char.escape_, #codereview-panel .hljs-symbol { color: var(--green); }
1316
+ #codereview-panel .hljs-number { color: var(--yellow); }
1317
+ #codereview-panel .hljs-title, #codereview-panel .hljs-title.function_, #codereview-panel .hljs-section { color: var(--accent); }
1318
+ #codereview-panel .hljs-attr, #codereview-panel .hljs-attribute, #codereview-panel .hljs-property, #codereview-panel .hljs-variable, #codereview-panel .hljs-template-variable, #codereview-panel .hljs-built_in, #codereview-panel .hljs-type, #codereview-panel .hljs-title.class_ { color: var(--cr-teal); }
1319
+ #codereview-panel .hljs-tag, #codereview-panel .hljs-name, #codereview-panel .hljs-selector-id, #codereview-panel .hljs-selector-class { color: var(--red); }
1320
+ #codereview-panel .hljs-meta { color: var(--fg-dim); }
1321
+ #codereview-panel .hljs-emphasis { font-style: italic; }
1322
+ #codereview-panel .hljs-strong { font-weight: 700; }
1323
+ #codereview-panel .hljs-deletion { color: var(--red); }
1324
+ #codereview-panel .hljs-addition { color: var(--green); }
1325
+
1326
+ /* ===== Phase C: file-router context menu + typed file links ===== */
1327
+ .ctm-file-menu {
1328
+ position: fixed; z-index: 100050; min-width: 210px; padding: 6px;
1329
+ background: var(--bg-elevated, var(--bg-light)); border: 1px solid var(--border);
1330
+ border-radius: 11px; box-shadow: 0 18px 46px rgba(0,0,0,0.42), 0 0 0 1px rgba(255,255,255,0.03) inset;
1331
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
1332
+ }
1333
+ html[data-theme="light"] .ctm-file-menu { box-shadow: 0 24px 60px rgba(15,23,42,0.18), 0 8px 20px rgba(15,23,42,0.08); }
1334
+ .ctm-file-menu-head {
1335
+ font-size: 10.5px; color: var(--fg-dim); font-family: var(--mono, 'SF Mono', Menlo, monospace);
1336
+ padding: 7px 10px 8px; border-bottom: 1px solid var(--border); margin-bottom: 5px;
1337
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 320px;
1338
+ direction: rtl; text-align: left;
1339
+ }
1340
+ .ctm-file-menu-item {
1341
+ display: block; width: 100%; text-align: left; font: inherit; font-size: 13px;
1342
+ color: var(--fg); background: none; border: 0; padding: 8px 10px; border-radius: 7px; cursor: pointer;
1343
+ }
1344
+ .ctm-file-menu-item:hover { background: var(--accent); color: var(--accent-fg); }
1345
+ .ctm-file-menu-item.primary { color: var(--accent); font-weight: 600; }
1346
+ .ctm-file-menu-item.primary:hover { color: var(--accent-fg); }
1347
+ .ctm-file-menu-sep { height: 1px; background: var(--border); margin: 5px 6px; }
1348
+
1349
+ /* Typed file links in session output / summaries — a subtle per-type tint */
1350
+ .ctm-file-link { cursor: pointer; text-underline-offset: 2px; }
1351
+ .ctm-file-link.type-source { text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent); }
1352
+ .ctm-file-link.type-html { text-decoration-color: color-mix(in srgb, var(--purple) 50%, transparent); }
1353
+ .ctm-file-link.type-html { color: var(--purple); }
1354
+ .ctm-file-link.type-source { color: var(--accent); }
1355
+
1356
+ /* ===== Hub two-pane layout: Changed Code | Documents ===== */
1357
+ .cr-hub-cols { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 22px; align-items: start; }
1358
+ .cr-hub-col-head { display: flex; align-items: center; gap: 10px; margin-bottom: 13px; }
1359
+ .cr-hub-col-head h4 {
1360
+ font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--fg-muted); margin: 0;
1361
+ }
1362
+ .cr-hub-col-count { font-size: 11px; color: var(--fg-dim); background: var(--bg-lighter); border-radius: 20px; padding: 2px 9px; font-weight: 600; }
1363
+ .cr-hub-docs { position: sticky; top: 8px; }
1364
+ .cr-hub-docs-list { display: flex; flex-direction: column; gap: 6px; max-height: 70vh; overflow-y: auto; }
1365
+ .cr-hub-doc-row {
1366
+ display: flex; align-items: center; gap: 10px; padding: 9px 12px; cursor: pointer;
1367
+ background: var(--bg-card); border: 1px solid var(--border); border-radius: 10px;
1368
+ }
1369
+ .cr-hub-doc-row:hover { border-color: var(--accent); }
1370
+ .cr-hub-doc-row:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 1px; }
1371
+ .cr-hub-doc-icon { color: var(--accent); flex-shrink: 0; }
1372
+ .cr-hub-doc-name { font-size: 13px; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
1373
+ .cr-hub-doc-dir {
1374
+ margin-left: auto; font-size: 11px; color: var(--fg-dim); flex-shrink: 0;
1375
+ font-family: var(--mono, 'SF Mono', Menlo, monospace); max-width: 45%;
1376
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; text-align: right;
1377
+ }
1378
+ .cr-hub-docs-empty { font-size: 12.5px; color: var(--fg-dim); padding: 16px 12px; text-align: center; }
1379
+ @media (max-width: 920px) { .cr-hub-cols { grid-template-columns: 1fr; } .cr-hub-docs { position: static; } }
1380
+
1381
+ /* ===== Redesign fixes: compact cards · collapsible groups · docs · empty-state ===== */
1382
+
1383
+ /* Compact project card — a single clickable row (matches the design proposal) */
1384
+ .cr-project-card.compact {
1385
+ display: flex; align-items: center; gap: 12px; padding: 9px 12px; margin: 0;
1386
+ border-radius: 9px; cursor: pointer; position: relative;
1387
+ }
1388
+ .cr-project-card.compact:hover { border-color: var(--accent); background: var(--bg-hover); }
1389
+ .cr-pc-icon {
1390
+ width: 30px; height: 30px; flex-shrink: 0; display: grid; place-items: center;
1391
+ border-radius: 8px; background: var(--bg-lighter); font-size: 14px;
1392
+ }
1393
+ .cr-pc-icon.worktree { color: var(--purple); }
1394
+ .cr-pc-icon.folder { color: var(--accent); }
1395
+ .cr-pc-body { flex: 1; min-width: 0; }
1396
+ .cr-pc-name { display: flex; align-items: center; gap: 8px; min-width: 0; }
1397
+ .cr-pc-star { color: var(--yellow); flex-shrink: 0; font-size: 11px; }
1398
+ .cr-pc-title { font-size: 13.5px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex-shrink: 1; min-width: 40px; }
1399
+ .cr-pc-branch {
1400
+ font-family: var(--mono, 'SF Mono', Menlo, monospace); font-size: 10.5px; color: var(--purple);
1401
+ background: color-mix(in srgb, var(--purple) 12%, transparent); border-radius: 6px; padding: 1px 7px;
1402
+ flex-shrink: 0; max-width: 46%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
1403
+ }
1404
+ .cr-pc-branch.main { color: var(--fg-dim); background: var(--bg-lighter); }
1405
+ .cr-pc-type { font-size: 10px; color: var(--fg-dim); flex-shrink: 0; white-space: nowrap; }
1406
+ .cr-pc-sub {
1407
+ font-size: 11px; color: var(--fg-dim); font-family: var(--mono, 'SF Mono', Menlo, monospace);
1408
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px;
1409
+ }
1410
+ .cr-pc-stat { flex-shrink: 0; font-family: var(--mono, 'SF Mono', Menlo, monospace); font-size: 12px; }
1411
+ .cr-pc-files { color: var(--accent); font-weight: 600; }
1412
+ .cr-pc-clean { color: var(--fg-dim); font-size: 11px; }
1413
+ .cr-pc-pin {
1414
+ flex-shrink: 0; background: none; border: 0; cursor: pointer; font-size: 12px; padding: 4px;
1415
+ opacity: 0; transition: opacity .12s; line-height: 1;
1416
+ }
1417
+ .cr-project-card.compact:hover .cr-pc-pin { opacity: 0.55; }
1418
+ .cr-pc-pin.pinned { opacity: 0.85; }
1419
+ .cr-pc-pin:hover { opacity: 1 !important; }
1420
+
1421
+ /* Collapsible groups — default collapsed; chevron rotates when open */
1422
+ .cr-project-group-header {
1423
+ display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
1424
+ background: var(--bg-lighter); border: 0; cursor: pointer; font: inherit; padding: 11px 14px;
1425
+ }
1426
+ .cr-project-group.expanded .cr-project-group-header { border-bottom: 1px solid var(--border); }
1427
+ .cr-project-group:not(.expanded) .cr-project-group-members { display: none; }
1428
+ .cr-group-chevron { color: var(--fg-dim); font-size: 11px; transition: transform .15s; flex-shrink: 0; }
1429
+ .cr-project-group.expanded .cr-group-chevron { transform: rotate(90deg); }
1430
+ .cr-project-group-header:hover { background: var(--bg-elevated, var(--bg-lighter)); }
1431
+ .cr-project-group-header:hover .cr-project-group-name { color: var(--accent); }
1432
+ .cr-project-group-clean { margin-left: auto; font-size: 11px; color: var(--fg-dim); }
1433
+ .cr-project-group-members { padding: 6px; gap: 2px; }
1434
+ .cr-project-group-members .cr-project-card.is-worktree { margin-left: 18px; }
1435
+
1436
+ /* Documents column — two-line rows, full title, no truncation hack, no right clipping */
1437
+ .cr-hub-docs-list { padding-right: 4px; }
1438
+ .cr-hub-doc-row { align-items: center; gap: 10px; padding: 8px 11px; }
1439
+ .cr-hub-doc-text { display: flex; flex-direction: column; min-width: 0; flex: 1; gap: 1px; }
1440
+ .cr-hub-doc-name {
1441
+ font-size: 13px; color: var(--fg); display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
1442
+ max-width: none; margin-left: 0;
1443
+ }
1444
+ .cr-hub-doc-dir {
1445
+ font-size: 10.5px; color: var(--fg-dim); font-family: var(--mono, 'SF Mono', Menlo, monospace);
1446
+ white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
1447
+ direction: ltr; text-align: left; margin-left: 0; max-width: none;
1448
+ }
1449
+
1450
+ /* Empty-review state — actionable, suggests a base that has changes */
1451
+ .cr-no-changes {
1452
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
1453
+ gap: 9px; padding: 56px 20px; text-align: center;
1454
+ }
1455
+ .cr-no-changes-icon { font-size: 30px; color: var(--green); opacity: 0.55; }
1456
+ .cr-no-changes-text { font-size: 15px; font-weight: 600; color: var(--fg); }
1457
+ .cr-no-changes-sub { font-size: 12px; color: var(--fg-dim); }
1458
+ .cr-no-changes-suggest { margin-top: 10px; }
1459
+ .cr-no-changes-suggest-label { font-size: 10.5px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 9px; }
1460
+ .cr-no-changes-suggest-row { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
1461
+ .cr-no-changes-base .cr-suggest-count { color: var(--accent); font-family: var(--mono, 'SF Mono', Menlo, monospace); margin-left: 5px; font-weight: 600; }
1462
+ .cr-no-changes-back { margin-top: 12px; background: none; border: 0; color: var(--accent); cursor: pointer; font-size: 12.5px; }
1463
+ .cr-no-changes-back:hover { text-decoration: underline; }