fraim 2.0.159 → 2.0.161

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 (32) hide show
  1. package/README.md +1 -1
  2. package/dist/src/ai-hub/cert-store.js +70 -0
  3. package/dist/src/ai-hub/desktop-main.js +224 -50
  4. package/dist/src/ai-hub/manager-turns.js +38 -0
  5. package/dist/src/ai-hub/office-sideload.js +156 -0
  6. package/dist/src/ai-hub/openclaw-bridge.js +239 -0
  7. package/dist/src/ai-hub/server.js +362 -115
  8. package/dist/src/ai-hub/word-sideload.js +95 -0
  9. package/dist/src/cli/commands/add-ide.js +9 -0
  10. package/dist/src/cli/commands/login.js +1 -2
  11. package/dist/src/cli/commands/setup.js +0 -2
  12. package/dist/src/cli/commands/sync.js +19 -10
  13. package/dist/src/cli/doctor/checks/mcp-connectivity-checks.js +66 -2
  14. package/dist/src/cli/doctor/checks/workflow-checks.js +1 -65
  15. package/dist/src/cli/mcp/fraim-mcp-latest-launcher.js +136 -0
  16. package/dist/src/cli/mcp/mcp-server-registry.js +14 -10
  17. package/dist/src/cli/setup/auto-mcp-setup.js +1 -1
  18. package/dist/src/cli/utils/fraim-gitignore.js +11 -0
  19. package/dist/src/cli/utils/remote-sync.js +1 -1
  20. package/dist/src/core/config-loader.js +1 -2
  21. package/dist/src/core/fraim-config-schema.generated.js +0 -5
  22. package/dist/src/core/quality-evidence.js +4 -1
  23. package/dist/src/core/types.js +0 -1
  24. package/dist/src/first-run/session-service.js +3 -3
  25. package/dist/src/local-mcp-server/stdio-server.js +28 -9
  26. package/package.json +2 -1
  27. package/public/ai-hub/index.html +20 -2
  28. package/public/ai-hub/powerpoint-taskpane/icon-64.png +0 -0
  29. package/public/ai-hub/powerpoint-taskpane/index.html +236 -0
  30. package/public/ai-hub/powerpoint-taskpane/manifest.xml +30 -0
  31. package/public/ai-hub/script.js +337 -120
  32. package/public/ai-hub/styles.css +456 -135
@@ -1,25 +1,107 @@
1
1
  :root {
2
- color-scheme: light;
3
- --bg: #ebe4d7;
4
- --surface: #f8f4eb;
5
- --soft: #f1ebde;
6
- --line: #d7cdbf;
7
- --text: #231e17;
8
- --muted: #7c6f61;
2
+ color-scheme: light dark;
3
+ /* Light theme — system-neutral grays */
4
+ --bg: #ECECEC;
5
+ --surface: #F7F7F7;
6
+ --soft: #E8E8E8;
7
+ --line: rgba(0, 0, 0, 0.10);
8
+ --text: #1A1A1A;
9
+ --muted: #6B6B6B;
9
10
  --accent: #1f437d;
10
11
  --accent-strong: #16345f;
11
12
  --accent-soft: #dfe7f5;
12
13
  --warn: #b08442;
13
- --warn-soft: #fffaf0;
14
+ --warn-soft: #fdf6e8;
14
15
  --done: #2e7d32;
15
16
  --danger: #a24747;
16
- --shadow: 0 1px 2px rgba(35, 30, 23, 0.05);
17
- --shadow-lg: 0 18px 48px rgba(35, 30, 23, 0.16);
18
- /* Issue #347 — picker group dots. Decorative only; the picker uses
19
- these to scan groups by color without adding semantic weight. Kept
20
- as variables so future themes flow through here. */
17
+ --shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
18
+ --shadow-lg: 0 0 0 1px rgba(0, 0, 0, 0.10), 0 4px 16px rgba(0, 0, 0, 0.08);
21
19
  --picker-delegation: #5b7eb0;
22
20
  --picker-learning: #8b5fbf;
21
+ /* Safe zone for macOS hiddenInset traffic lights (~28px) and
22
+ Windows titleBarOverlay height (36px). Falls back to 0 in a browser tab. */
23
+ --titlebar-inset: env(titlebar-area-height, 0px);
24
+ }
25
+
26
+ @media (prefers-color-scheme: dark) {
27
+ :root {
28
+ --bg: #1E1E1E;
29
+ --surface: #2A2A2A;
30
+ --soft: #323232;
31
+ --line: rgba(255, 255, 255, 0.10);
32
+ --text: #E8E8E8;
33
+ --muted: #999999;
34
+ --accent: #5b8de8;
35
+ --accent-strong: #82aaee;
36
+ --accent-soft: rgba(91, 141, 232, 0.15);
37
+ --warn: #d4a04e;
38
+ --warn-soft: rgba(212, 160, 78, 0.12);
39
+ --done: #5cb85c;
40
+ --danger: #e07070;
41
+ --shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
42
+ --shadow-lg: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 4px 16px rgba(0, 0, 0, 0.40);
43
+ }
44
+ }
45
+
46
+ /* Electron shell: html.electron is set synchronously before CSS paints so there
47
+ is no flash. Mica (Win11) / vibrancy (macOS) paint the window-level background;
48
+ body + .page must be transparent to let that material show through. Content
49
+ surfaces use frosted-glass layering so they read against the OS material. */
50
+ html.electron body,
51
+ html.electron .page {
52
+ background: transparent;
53
+ }
54
+ /* Header floats directly on Mica — no card. Native Win11 pattern. */
55
+ html.electron .header {
56
+ background: transparent;
57
+ border: none;
58
+ }
59
+ /* Rail: frosted sidebar — clearly distinct from Mica, clearly distinct from
60
+ the conversation. A solid-ish left edge gives it visual grounding. */
61
+ html.electron .rail {
62
+ background: rgba(255, 255, 255, 0.76);
63
+ backdrop-filter: blur(20px);
64
+ -webkit-backdrop-filter: blur(20px);
65
+ border: none;
66
+ border-right: 1px solid rgba(0, 0, 0, 0.08);
67
+ border-radius: 10px;
68
+ box-shadow: none;
69
+ }
70
+ /* Conversation: the primary work surface — crisp white card on the Mica */
71
+ html.electron .conversation {
72
+ background: rgba(255, 255, 255, 0.88);
73
+ backdrop-filter: blur(24px);
74
+ -webkit-backdrop-filter: blur(24px);
75
+ border: 1px solid rgba(255, 255, 255, 0.60);
76
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
77
+ }
78
+ html.electron .modal {
79
+ background: rgba(253, 253, 253, 0.94);
80
+ backdrop-filter: blur(32px);
81
+ -webkit-backdrop-filter: blur(32px);
82
+ border: 1px solid rgba(255, 255, 255, 0.50);
83
+ box-shadow: 0 4px 32px rgba(0, 0, 0, 0.14);
84
+ }
85
+ html.electron .modal-backdrop {
86
+ background: rgba(0, 0, 0, 0.22);
87
+ backdrop-filter: blur(4px);
88
+ -webkit-backdrop-filter: blur(4px);
89
+ }
90
+ @media (prefers-color-scheme: dark) {
91
+ html.electron .rail {
92
+ background: rgba(42, 42, 42, 0.78);
93
+ border-right-color: rgba(255, 255, 255, 0.06);
94
+ }
95
+ html.electron .conversation {
96
+ background: rgba(36, 36, 36, 0.88);
97
+ border-color: rgba(255, 255, 255, 0.08);
98
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.20);
99
+ }
100
+ html.electron .modal {
101
+ background: rgba(30, 30, 30, 0.94);
102
+ border-color: rgba(255, 255, 255, 0.10);
103
+ box-shadow: 0 4px 32px rgba(0, 0, 0, 0.40);
104
+ }
23
105
  }
24
106
 
25
107
  * { box-sizing: border-box; }
@@ -28,16 +110,28 @@ html, body { margin: 0; padding: 0; }
28
110
 
29
111
  html, body { height: 100%; }
30
112
  body {
31
- font-family: "Avenir Next", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
113
+ /* System-native font stack: San Francisco on Mac, Segoe UI Variable on Windows */
114
+ font-family: system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI", sans-serif;
32
115
  color: var(--text);
33
- background:
34
- radial-gradient(circle at top left, rgba(255, 255, 255, 0.45), transparent 28%),
35
- linear-gradient(180deg, #efe8dc 0%, var(--bg) 100%);
116
+ background: var(--bg);
36
117
  line-height: 1.5;
37
118
  font-size: 15px;
38
- /* Issue #339 fix: bound the page to the viewport. The conversation
39
- pane scrolls internally instead of growing the entire page. */
40
119
  overflow: hidden;
120
+ /* Thin native-style scrollbars */
121
+ scrollbar-width: thin;
122
+ scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
123
+ }
124
+
125
+ @media (prefers-color-scheme: dark) {
126
+ body { scrollbar-color: rgba(255, 255, 255, 0.2) transparent; }
127
+ }
128
+
129
+ /* Respect reduced-motion preference */
130
+ @media (prefers-reduced-motion: reduce) {
131
+ *, *::before, *::after {
132
+ animation-duration: 0.01ms !important;
133
+ transition-duration: 0.01ms !important;
134
+ }
41
135
  }
42
136
 
43
137
  button { font: inherit; cursor: pointer; }
@@ -46,7 +140,8 @@ button { font: inherit; cursor: pointer; }
46
140
  max-width: none;
47
141
  width: 100%;
48
142
  margin: 0;
49
- padding: 20px 24px 16px;
143
+ /* Push content below traffic lights on macOS hiddenInset titlebar */
144
+ padding: calc(20px + var(--titlebar-inset)) 24px 16px;
50
145
  display: flex;
51
146
  flex-direction: column;
52
147
  gap: 14px;
@@ -54,11 +149,17 @@ button { font: inherit; cursor: pointer; }
54
149
  min-height: 0;
55
150
  }
56
151
 
57
- /* Header — single-row strip: title | welcome text | project button */
152
+ /* Header — draggable titlebar strip on Electron (macOS hiddenInset).
153
+ Buttons inside must override with no-drag so they remain clickable. */
58
154
  .header {
59
155
  display: flex;
60
156
  align-items: center;
61
157
  gap: 16px;
158
+ /* left margin reserves space for macOS traffic lights (78px) */
159
+ padding-left: max(0px, env(titlebar-area-x, 0px));
160
+ }
161
+ .header button, .header a, .header select {
162
+ -webkit-app-region: no-drag;
62
163
  }
63
164
  .header-title {
64
165
  font-size: 20px;
@@ -73,10 +174,10 @@ button { font: inherit; cursor: pointer; }
73
174
  display: inline-flex;
74
175
  align-items: center;
75
176
  gap: 8px;
76
- background: rgba(255, 255, 255, 0.5);
177
+ background: var(--surface);
77
178
  border: 1px solid var(--line);
78
- border-radius: 14px;
79
- padding: 10px 16px;
179
+ border-radius: 8px;
180
+ padding: 8px 14px;
80
181
  color: var(--text);
81
182
  box-shadow: var(--shadow);
82
183
  max-width: 360px;
@@ -131,15 +232,12 @@ button { font: inherit; cursor: pointer; }
131
232
  top: calc(100% + 10px);
132
233
  left: 0;
133
234
  width: 320px;
134
- /* Hard cap + internal scroll so a verbose explanation never clips off
135
- the bottom of the viewport (was a real bug — popover content used to
136
- run past the bottom edge with no way to read it). */
137
235
  max-height: min(60vh, 480px);
138
236
  overflow-y: auto;
139
237
  background: var(--surface);
140
238
  border: 1px solid var(--line);
141
- border-radius: 12px;
142
- padding: 14px 16px;
239
+ border-radius: 8px;
240
+ padding: 12px 14px;
143
241
  box-shadow: var(--shadow-lg);
144
242
  z-index: 50;
145
243
  font-weight: 400;
@@ -204,8 +302,8 @@ button { font: inherit; cursor: pointer; }
204
302
  align-self: start;
205
303
  max-height: 100%;
206
304
  overflow-y: auto;
207
- border-radius: 28px;
208
- background: rgba(248, 244, 235, 0.84);
305
+ border-radius: 10px;
306
+ background: var(--surface);
209
307
  box-shadow: var(--shadow);
210
308
  }
211
309
  .new-conv {
@@ -213,8 +311,8 @@ button { font: inherit; cursor: pointer; }
213
311
  background: var(--accent);
214
312
  color: #fff;
215
313
  border: none;
216
- border-radius: 14px;
217
- padding: 13px 16px;
314
+ border-radius: 8px;
315
+ padding: 11px 16px;
218
316
  font-weight: 600;
219
317
  box-shadow: var(--shadow);
220
318
  }
@@ -248,22 +346,22 @@ button { font: inherit; cursor: pointer; }
248
346
  .conv-item {
249
347
  width: 100%;
250
348
  text-align: left;
251
- background: rgba(255, 255, 255, 0.44);
252
- border: 1px solid rgba(31, 67, 125, 0.08);
253
- border-radius: 22px;
254
- padding: 14px;
349
+ background: transparent;
350
+ border: 1px solid var(--line);
351
+ border-radius: 8px;
352
+ padding: 10px 12px;
255
353
  display: flex;
256
354
  align-items: flex-start;
257
355
  justify-content: space-between;
258
- gap: 12px;
356
+ gap: 10px;
259
357
  color: var(--text);
260
- box-shadow: 0 10px 24px rgba(35, 30, 23, 0.04);
358
+ box-shadow: none;
261
359
  }
262
360
  .conv-item:hover { background: var(--soft); }
263
361
  .conv-item.active {
264
- background: rgba(229, 236, 248, 0.92);
265
- border-color: rgba(31, 67, 125, 0.2);
266
- box-shadow: 0 14px 28px rgba(31, 67, 125, 0.12);
362
+ background: var(--accent-soft);
363
+ border-color: rgba(31, 67, 125, 0.25);
364
+ box-shadow: none;
267
365
  }
268
366
  /* Text column: stacks persona name label above job title */
269
367
  .conv-body {
@@ -293,14 +391,13 @@ button { font: inherit; cursor: pointer; }
293
391
  -webkit-line-clamp: 2;
294
392
  -webkit-box-orient: vertical;
295
393
  }
296
- /* Persona avatar chip — enlarged to 34px to serve as a clear visual anchor */
297
394
  .conv-persona-chip {
298
395
  flex-shrink: 0;
299
- width: 48px;
300
- height: 48px;
301
- border-radius: 16px;
302
- background: #ffffff;
303
- border: 2px solid rgba(31, 67, 125, 0.14);
396
+ width: 36px;
397
+ height: 36px;
398
+ border-radius: 8px;
399
+ background: var(--surface);
400
+ border: 1px solid var(--line);
304
401
  display: flex;
305
402
  align-items: center;
306
403
  justify-content: center;
@@ -311,7 +408,7 @@ button { font: inherit; cursor: pointer; }
311
408
  line-height: 1;
312
409
  text-transform: uppercase;
313
410
  }
314
- .conv-persona-chip img { width: 100%; height: 100%; object-fit: cover; border-radius: 16px; }
411
+ .conv-persona-chip img { width: 100%; height: 100%; object-fit: cover; border-radius: 7px; }
315
412
  .conv-persona-chip--free { background: transparent; border-color: var(--line); color: var(--muted); }
316
413
  .conv-status {
317
414
  font-size: 11px;
@@ -325,14 +422,13 @@ button { font: inherit; cursor: pointer; }
325
422
  .conv-status.attention { color: var(--warn); }
326
423
  .conv-status.failed { color: var(--danger); }
327
424
 
328
- /* Conversation pane — fills the layout column vertically. Inner regions
329
- manage their own height; the .messages list is the only scrollable area. */
425
+ /* Conversation pane */
330
426
  .conversation {
331
- background: rgba(248, 244, 235, 0.94);
427
+ background: var(--surface);
332
428
  border: 1px solid var(--line);
333
- border-radius: 30px;
334
- box-shadow: var(--shadow-lg);
335
- padding: 24px 26px;
429
+ border-radius: 10px;
430
+ box-shadow: var(--shadow);
431
+ padding: 20px 22px;
336
432
  display: flex;
337
433
  flex-direction: column;
338
434
  gap: 14px;
@@ -351,16 +447,16 @@ button { font: inherit; cursor: pointer; }
351
447
  }
352
448
  .empty-state::before {
353
449
  content: "F";
354
- width: 56px;
355
- height: 56px;
356
- border-radius: 18px;
450
+ width: 52px;
451
+ height: 52px;
452
+ border-radius: 12px;
357
453
  display: inline-flex;
358
454
  align-items: center;
359
455
  justify-content: center;
360
456
  background: var(--accent-soft);
361
457
  color: var(--accent-strong);
362
458
  font-weight: 700;
363
- font-size: 24px;
459
+ font-size: 22px;
364
460
  }
365
461
  .empty-state h3 { margin: 0; color: var(--text); font-weight: 600; font-size: 17px; }
366
462
  .empty-state p { margin: 0; max-width: 320px; }
@@ -404,16 +500,16 @@ button { font: inherit; cursor: pointer; }
404
500
  min-width: 0;
405
501
  }
406
502
  .identity-avatar {
407
- width: 52px;
408
- height: 52px;
409
- border-radius: 18px;
410
- background: #ffffff;
411
- border: 1px solid rgba(31, 67, 125, 0.14);
503
+ width: 44px;
504
+ height: 44px;
505
+ border-radius: 10px;
506
+ background: var(--surface);
507
+ border: 1px solid var(--line);
412
508
  display: inline-flex;
413
509
  align-items: center;
414
510
  justify-content: center;
415
511
  overflow: hidden;
416
- font-size: 16px;
512
+ font-size: 15px;
417
513
  font-weight: 700;
418
514
  color: var(--accent-strong);
419
515
  flex-shrink: 0;
@@ -454,12 +550,12 @@ button { font: inherit; cursor: pointer; }
454
550
  background: rgba(31, 67, 125, 0.14);
455
551
  }
456
552
  .run-state-pill.failed {
457
- background: #fbebeb;
553
+ background: color-mix(in srgb, var(--danger) 12%, transparent);
458
554
  color: var(--danger);
459
555
  }
460
556
  .run-state-pill.completed {
461
- background: #e4f0ea;
462
- color: #2c6b4e;
557
+ background: color-mix(in srgb, var(--done) 14%, transparent);
558
+ color: var(--done);
463
559
  }
464
560
  .conv-header {
465
561
  display: flex;
@@ -502,9 +598,9 @@ button { font: inherit; cursor: pointer; }
502
598
  flex-shrink: 0;
503
599
  }
504
600
  .panel-details {
505
- background: rgba(255, 255, 255, 0.4);
506
- border: 1px solid rgba(31, 67, 125, 0.08);
507
- border-radius: 22px;
601
+ background: var(--soft);
602
+ border: 1px solid var(--line);
603
+ border-radius: 8px;
508
604
  overflow: hidden;
509
605
  }
510
606
  .panel-details > summary {
@@ -603,15 +699,11 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
603
699
  padding: 4px 10px;
604
700
  border-radius: 8px;
605
701
  }
606
- /* Thread panel fills the available space between tracker and coach.
607
- The panel itself is the scroll container — the summary stays sticky at the
608
- top so it's always visible, and tracker + coach below are never obscured. */
702
+ /* Thread panel */
609
703
  .panel-details--thread {
610
- border-radius: 28px;
611
- border: 1px solid rgba(31, 67, 125, 0.1);
612
- background:
613
- linear-gradient(180deg, rgba(255, 255, 255, 0.74), rgba(255, 255, 255, 0.5)),
614
- radial-gradient(circle at top left, rgba(31, 67, 125, 0.06), transparent 34%);
704
+ border-radius: 8px;
705
+ border: 1px solid var(--line);
706
+ background: var(--bg);
615
707
  overflow-y: auto;
616
708
  overflow-x: hidden;
617
709
  flex: 1;
@@ -681,9 +773,9 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
681
773
  flex: 1 1 auto;
682
774
  }
683
775
  .tracker-inline {
684
- background: rgba(255, 255, 255, 0.42);
685
- border: 1px solid rgba(31, 67, 125, 0.08);
686
- border-radius: 18px;
776
+ background: var(--soft);
777
+ border: 1px solid var(--line);
778
+ border-radius: 8px;
687
779
  padding: 8px 12px;
688
780
  }
689
781
 
@@ -693,12 +785,10 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
693
785
  gap: 14px;
694
786
  min-height: 0;
695
787
  flex: 1;
696
- padding: 22px 22px 18px;
697
- border-radius: 28px;
698
- border: 1px solid rgba(31, 67, 125, 0.1);
699
- background:
700
- linear-gradient(180deg, rgba(255, 255, 255, 0.74), rgba(255, 255, 255, 0.5)),
701
- radial-gradient(circle at top left, rgba(31, 67, 125, 0.06), transparent 34%);
788
+ padding: 16px 18px 14px;
789
+ border-radius: 8px;
790
+ border: 1px solid var(--line);
791
+ background: var(--bg);
702
792
  }
703
793
 
704
794
  .thread-surface-label {
@@ -798,11 +888,11 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
798
888
  display: none;
799
889
  }
800
890
  .bubble {
801
- border-radius: 18px;
802
- padding: 9px 14px;
891
+ border-radius: 10px;
892
+ padding: 8px 13px;
803
893
  font-size: 14px;
804
894
  line-height: 1.5;
805
- box-shadow: 0 4px 12px rgba(35, 30, 23, 0.04);
895
+ box-shadow: none;
806
896
  max-width: min(720px, 100%);
807
897
  }
808
898
  .message.manager .bubble {
@@ -810,13 +900,13 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
810
900
  color: #fff;
811
901
  }
812
902
  .message.employee .bubble {
813
- background: rgba(255, 255, 255, 0.86);
814
- border: 1px solid rgba(31, 67, 125, 0.1);
903
+ background: var(--surface);
904
+ border: 1px solid var(--line);
815
905
  color: var(--text);
816
906
  }
817
907
  .message.system .bubble {
818
- background: rgba(255, 255, 255, 0.6);
819
- border: 1px solid rgba(35, 30, 23, 0.08);
908
+ background: var(--soft);
909
+ border: 1px solid var(--line);
820
910
  color: var(--text);
821
911
  }
822
912
 
@@ -828,7 +918,7 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
828
918
  align-items: center;
829
919
  gap: 6px;
830
920
  background: var(--warn-soft);
831
- border: 1px solid #ecd9b0;
921
+ border: 1px solid color-mix(in srgb, var(--warn) 35%, transparent);
832
922
  border-radius: 999px;
833
923
  padding: 4px 10px;
834
924
  font-size: 12px;
@@ -876,8 +966,8 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
876
966
  max-height: 22vh;
877
967
  resize: vertical;
878
968
  border: 1px solid var(--line);
879
- border-radius: 18px;
880
- padding: 13px 52px 13px 15px;
969
+ border-radius: 8px;
970
+ padding: 12px 52px 12px 14px;
881
971
  font: inherit;
882
972
  color: var(--text);
883
973
  background: var(--surface);
@@ -887,13 +977,13 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
887
977
  .coach-input #send,
888
978
  .coach-input #ab-direct-send {
889
979
  position: absolute;
890
- bottom: 8px;
891
- right: 8px;
892
- width: 34px;
893
- height: 34px;
980
+ bottom: 7px;
981
+ right: 7px;
982
+ width: 32px;
983
+ height: 32px;
894
984
  padding: 0;
895
- border-radius: 10px;
896
- font-size: 18px;
985
+ border-radius: 6px;
986
+ font-size: 16px;
897
987
  line-height: 1;
898
988
  display: flex;
899
989
  align-items: center;
@@ -910,13 +1000,13 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
910
1000
  background: var(--accent);
911
1001
  color: #fff;
912
1002
  border: none;
913
- border-radius: 10px;
914
- padding: 10px 18px;
1003
+ border-radius: 6px;
1004
+ padding: 8px 16px;
915
1005
  font-weight: 600;
916
1006
  }
917
1007
  .send-button:hover { background: var(--accent-strong); }
918
1008
  .send-button:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
919
- .send-button:disabled { background: #c5d2cb; cursor: not-allowed; }
1009
+ .send-button:disabled { background: color-mix(in srgb, var(--accent) 35%, var(--bg) 65%); cursor: not-allowed; }
920
1010
 
921
1011
  .micro {
922
1012
  margin-top: 0;
@@ -942,8 +1032,8 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
942
1032
  .micro[open] summary::before { transform: rotate(90deg); }
943
1033
  .micro-log {
944
1034
  margin: 0 16px 16px;
945
- background: #1f2a24;
946
- color: #c5d2cb;
1035
+ background: color-mix(in srgb, var(--text) 12%, transparent);
1036
+ color: var(--muted);
947
1037
  border-radius: 8px;
948
1038
  padding: 12px 14px;
949
1039
  font-family: Consolas, Menlo, monospace;
@@ -980,7 +1070,7 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
980
1070
 
981
1071
  .modal {
982
1072
  background: var(--surface);
983
- border-radius: 16px;
1073
+ border-radius: 10px;
984
1074
  box-shadow: var(--shadow-lg);
985
1075
  width: 100%;
986
1076
  max-width: 540px;
@@ -1023,8 +1113,8 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
1023
1113
  .ghost {
1024
1114
  background: transparent;
1025
1115
  border: 1px solid var(--line);
1026
- border-radius: 10px;
1027
- padding: 9px 14px;
1116
+ border-radius: 6px;
1117
+ padding: 7px 13px;
1028
1118
  color: var(--text);
1029
1119
  font-weight: 500;
1030
1120
  }
@@ -1034,9 +1124,11 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
1034
1124
  .search {
1035
1125
  width: 100%;
1036
1126
  border: 1px solid var(--line);
1037
- border-radius: 10px;
1038
- padding: 10px 14px;
1127
+ border-radius: 6px;
1128
+ padding: 8px 12px;
1039
1129
  font: inherit;
1130
+ background: var(--bg);
1131
+ color: var(--text);
1040
1132
  margin-bottom: 14px;
1041
1133
  }
1042
1134
  .search:focus { outline: none; border-color: var(--accent); }
@@ -1055,9 +1147,9 @@ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
1055
1147
  text-align: left;
1056
1148
  background: transparent;
1057
1149
  border: 1px solid var(--line);
1058
- border-radius: 10px;
1059
- padding: 10px 14px;
1060
- margin-bottom: 6px;
1150
+ border-radius: 6px;
1151
+ padding: 9px 12px;
1152
+ margin-bottom: 5px;
1061
1153
  display: grid;
1062
1154
  gap: 2px;
1063
1155
  color: var(--text);
@@ -1298,9 +1390,9 @@ button.small { padding: 4px 10px; font-size: 12px; }
1298
1390
  overflow-y: auto;
1299
1391
  background: var(--surface);
1300
1392
  border: 1px solid var(--line);
1301
- border-radius: 12px;
1393
+ border-radius: 8px;
1302
1394
  box-shadow: var(--shadow-lg);
1303
- padding: 12px;
1395
+ padding: 10px;
1304
1396
  z-index: 200;
1305
1397
  }
1306
1398
  .template-popover .group {
@@ -1373,39 +1465,39 @@ button.small { padding: 4px 10px; font-size: 12px; }
1373
1465
  }
1374
1466
  .roster-chip {
1375
1467
  display: grid;
1376
- grid-template-columns: 48px minmax(0, 1fr);
1468
+ grid-template-columns: 40px minmax(0, 1fr);
1377
1469
  align-items: center;
1378
- gap: 12px;
1470
+ gap: 10px;
1379
1471
  width: 100%;
1380
- min-height: 74px;
1381
- border-radius: 22px;
1382
- background: rgba(255, 255, 255, 0.5);
1383
- border: 1px solid rgba(31, 67, 125, 0.1);
1472
+ min-height: 58px;
1473
+ border-radius: 8px;
1474
+ background: var(--soft);
1475
+ border: 1px solid var(--line);
1384
1476
  font-size: 12px;
1385
1477
  color: var(--text);
1386
1478
  cursor: pointer;
1387
1479
  overflow: hidden;
1388
- padding: 12px 14px;
1480
+ padding: 10px 12px;
1389
1481
  text-align: left;
1390
- box-shadow: 0 10px 24px rgba(35, 30, 23, 0.04);
1482
+ box-shadow: none;
1391
1483
  }
1392
1484
  .roster-chip.active {
1393
- border-color: rgba(31, 67, 125, 0.22);
1394
- background: rgba(223, 231, 245, 0.92);
1395
- box-shadow: 0 14px 28px rgba(31, 67, 125, 0.1);
1485
+ border-color: rgba(31, 67, 125, 0.25);
1486
+ background: var(--accent-soft);
1487
+ box-shadow: none;
1396
1488
  }
1397
1489
  .roster-avatar {
1398
- width: 48px;
1399
- height: 48px;
1400
- border-radius: 16px;
1490
+ width: 40px;
1491
+ height: 40px;
1492
+ border-radius: 8px;
1401
1493
  display: inline-flex;
1402
1494
  align-items: center;
1403
1495
  justify-content: center;
1404
- background: #ffffff;
1496
+ background: var(--surface);
1405
1497
  color: var(--accent-strong);
1406
1498
  font-size: 12px;
1407
1499
  font-weight: 700;
1408
- border: 1px solid rgba(31, 67, 125, 0.1);
1500
+ border: 1px solid var(--line);
1409
1501
  overflow: hidden;
1410
1502
  }
1411
1503
  .roster-avatar img { width: 100%; height: 100%; object-fit: cover; }
@@ -1665,3 +1757,232 @@ button.small { padding: 4px 10px; font-size: 12px; }
1665
1757
  @media (max-width: 900px) {
1666
1758
  #conversation.ab-mode { flex-direction: column; }
1667
1759
  }
1760
+
1761
+ /* ── Task-pane surface (embedded in Office sidebar at ~375px) ────────────────
1762
+ Applied when the Hub is loaded with ?surface=task-pane. The JS sets
1763
+ body:is([data-surface="task-pane"],[data-surface="extension"]). No media queries — this is a surface
1764
+ flag, not a viewport breakpoint. */
1765
+
1766
+ body:is([data-surface="task-pane"],[data-surface="extension"]) {
1767
+ font-size: 13px;
1768
+ overflow: auto;
1769
+ }
1770
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .page {
1771
+ padding: 10px 12px 8px;
1772
+ gap: 10px;
1773
+ height: auto;
1774
+ min-height: 100vh;
1775
+ }
1776
+ /* Hide the full-width welcome header — task pane has no room for it */
1777
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .header { display: none; }
1778
+ /* Collapse rail + conversation into a single column */
1779
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .layout {
1780
+ grid-template-columns: 1fr;
1781
+ gap: 0;
1782
+ }
1783
+ /* Rail: strip to just the "+ New job" button so the user can always start a
1784
+ new job even after a conversation is active. All other rail children stay
1785
+ hidden — task pane shows one job at a time with no history sidebar. */
1786
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .rail {
1787
+ display: flex;
1788
+ align-items: center;
1789
+ justify-content: space-between;
1790
+ background: none;
1791
+ box-shadow: none;
1792
+ border-radius: 0;
1793
+ overflow: visible;
1794
+ padding: 0 0 8px;
1795
+ gap: 0;
1796
+ grid-row: 1;
1797
+ }
1798
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .rail > :not(#new-conv-btn):not(.tp-project-label) { display: none; }
1799
+ /* Hidden by default — only shown inside the task-pane surface rail */
1800
+ .tp-project-label { display: none; }
1801
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-project-label {
1802
+ display: block;
1803
+ font-size: 11px;
1804
+ color: var(--muted);
1805
+ overflow: hidden;
1806
+ text-overflow: ellipsis;
1807
+ white-space: nowrap;
1808
+ flex: 1;
1809
+ min-width: 0;
1810
+ margin-right: 8px;
1811
+ }
1812
+ body:is([data-surface="task-pane"],[data-surface="extension"]) #new-conv-btn {
1813
+ font-size: 12px;
1814
+ padding: 6px 14px;
1815
+ border-radius: 8px;
1816
+ width: auto;
1817
+ }
1818
+ /* Hide the "+ New job" strip when the modal is open — redundant while modal
1819
+ is in view, and it avoids the button floating above the backdrop overlay. */
1820
+ body:is([data-surface="task-pane"],[data-surface="extension"]):has(.modal-backdrop.open) .rail { display: none; }
1821
+ /* Tighter conversation card */
1822
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .conversation {
1823
+ border-radius: 16px;
1824
+ padding: 12px 14px;
1825
+ height: auto;
1826
+ overflow: visible;
1827
+ }
1828
+ body:is([data-surface="task-pane"],[data-surface="extension"]) #active-conv {
1829
+ overflow: visible;
1830
+ flex: initial;
1831
+ }
1832
+ /* Shrink identity avatar to fit narrower column */
1833
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .identity-avatar {
1834
+ width: 36px; height: 36px;
1835
+ border-radius: 12px;
1836
+ font-size: 13px;
1837
+ }
1838
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .identity-copy strong { font-size: 13px; }
1839
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .identity-copy small { font-size: 10px; }
1840
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .conv-header h2 { font-size: 15px; }
1841
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .conv-job-title { font-size: 12px; }
1842
+ /* Compact message bubbles */
1843
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .bubble {
1844
+ font-size: 12px;
1845
+ padding: 7px 11px;
1846
+ border-radius: 13px;
1847
+ }
1848
+ /* Compact coach input */
1849
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .coach-input textarea {
1850
+ font-size: 12px;
1851
+ min-height: 44px;
1852
+ padding: 10px 44px 10px 12px;
1853
+ }
1854
+ /* Compact micro-manage log */
1855
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .micro-log { font-size: 11px; }
1856
+ /* Thread panel: normal block flow, page scrolls naturally */
1857
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .panel-details--thread {
1858
+ flex: initial;
1859
+ min-height: auto;
1860
+ display: block;
1861
+ max-height: 40vh;
1862
+ }
1863
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .panel-details--thread .messages {
1864
+ flex: initial;
1865
+ max-height: calc(40vh - 44px);
1866
+ overflow-y: auto;
1867
+ }
1868
+ /* Modal bottom-sheet instead of center-screen */
1869
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-backdrop {
1870
+ align-items: flex-end;
1871
+ padding: 0;
1872
+ }
1873
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal {
1874
+ border-radius: 18px 18px 0 0;
1875
+ max-width: 100%;
1876
+ max-height: 88vh;
1877
+ }
1878
+ /* Tighter modal chrome at task-pane widths */
1879
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-header { padding: 16px 16px 10px; }
1880
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-body { padding: 12px 16px; }
1881
+ /* Stack footer: label on top (single line, ellipsis) then buttons in a row.
1882
+ Prevents "Just describe what you need" + long job names from bloating height. */
1883
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-footer {
1884
+ padding: 10px 12px 14px;
1885
+ flex-direction: column;
1886
+ align-items: stretch;
1887
+ gap: 8px;
1888
+ }
1889
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-footer .left {
1890
+ font-size: 12px;
1891
+ white-space: nowrap;
1892
+ overflow: hidden;
1893
+ text-overflow: ellipsis;
1894
+ }
1895
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-footer .right {
1896
+ display: flex;
1897
+ gap: 6px;
1898
+ }
1899
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-footer .right button {
1900
+ flex: 1;
1901
+ font-size: 11px;
1902
+ padding: 7px 6px;
1903
+ text-align: center;
1904
+ }
1905
+
1906
+ /* ── Word context bar (between rail and conversation in task-pane) ─────────── */
1907
+ .word-context-bar { display: none; }
1908
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .word-context-bar {
1909
+ display: flex;
1910
+ align-items: center;
1911
+ gap: 6px;
1912
+ padding: 6px 14px 4px;
1913
+ font-size: 11px;
1914
+ color: var(--muted);
1915
+ border-bottom: 1px solid var(--border, rgba(0,0,0,0.07));
1916
+ min-height: 28px;
1917
+ overflow: hidden;
1918
+ }
1919
+ .word-ctx-text {
1920
+ flex: 1;
1921
+ overflow: hidden;
1922
+ text-overflow: ellipsis;
1923
+ white-space: nowrap;
1924
+ min-width: 0;
1925
+ }
1926
+ .word-ctx-refresh {
1927
+ background: none;
1928
+ border: none;
1929
+ color: var(--muted);
1930
+ font-size: 13px;
1931
+ cursor: pointer;
1932
+ padding: 0 2px;
1933
+ line-height: 1;
1934
+ flex-shrink: 0;
1935
+ }
1936
+ .word-ctx-refresh:hover { color: var(--accent); }
1937
+
1938
+ /* ── Word context card in step 2 modal ────────────────────────────────────── */
1939
+ .word-context-card {
1940
+ border: 1px solid var(--border, rgba(0,0,0,0.10));
1941
+ border-radius: 8px;
1942
+ margin-top: 8px;
1943
+ font-size: 12px;
1944
+ overflow: hidden;
1945
+ }
1946
+ .word-ctx-card-header {
1947
+ display: flex;
1948
+ align-items: center;
1949
+ gap: 6px;
1950
+ padding: 7px 10px;
1951
+ background: var(--surface, rgba(0,0,0,0.03));
1952
+ cursor: default;
1953
+ }
1954
+ .word-ctx-card-label {
1955
+ flex: 1;
1956
+ font-weight: 600;
1957
+ font-size: 11px;
1958
+ color: var(--muted);
1959
+ overflow: hidden;
1960
+ text-overflow: ellipsis;
1961
+ white-space: nowrap;
1962
+ }
1963
+ .word-ctx-card-toggle {
1964
+ background: none;
1965
+ border: none;
1966
+ color: var(--muted);
1967
+ cursor: pointer;
1968
+ font-size: 11px;
1969
+ padding: 0 2px;
1970
+ flex-shrink: 0;
1971
+ }
1972
+ .word-ctx-card-toggle:hover { color: var(--accent); }
1973
+ .word-ctx-card-body {
1974
+ padding: 8px 10px;
1975
+ color: var(--fg, #231e17);
1976
+ font-size: 11px;
1977
+ line-height: 1.5;
1978
+ white-space: pre-wrap;
1979
+ word-break: break-word;
1980
+ max-height: 120px;
1981
+ overflow-y: auto;
1982
+ border-top: 1px solid var(--border, rgba(0,0,0,0.07));
1983
+ }
1984
+
1985
+ /* ── Extension surface overrides (Chrome/browser extensions) ─────────────────
1986
+ Inherits all task-pane layout rules (via :is() above) but hides the
1987
+ project label since extensions work on web pages, not local project paths. */
1988
+ body[data-surface="extension"] .tp-project-label { display: none; }