@plmbr/notebook-intelligence 5.0.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.
Files changed (137) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +412 -0
  3. package/lib/api.d.ts +288 -0
  4. package/lib/api.js +927 -0
  5. package/lib/cell-output-bundle.d.ts +25 -0
  6. package/lib/cell-output-bundle.js +129 -0
  7. package/lib/cell-output-toolbar.d.ts +26 -0
  8. package/lib/cell-output-toolbar.js +188 -0
  9. package/lib/chat-progress-feedback.d.ts +3 -0
  10. package/lib/chat-progress-feedback.js +27 -0
  11. package/lib/chat-sidebar.d.ts +92 -0
  12. package/lib/chat-sidebar.js +3452 -0
  13. package/lib/command-ids.d.ts +39 -0
  14. package/lib/command-ids.js +44 -0
  15. package/lib/components/ask-user-question.d.ts +2 -0
  16. package/lib/components/ask-user-question.js +85 -0
  17. package/lib/components/checkbox.d.ts +2 -0
  18. package/lib/components/checkbox.js +30 -0
  19. package/lib/components/claude-mcp-panel.d.ts +2 -0
  20. package/lib/components/claude-mcp-panel.js +275 -0
  21. package/lib/components/claude-mcp-paste.d.ts +7 -0
  22. package/lib/components/claude-mcp-paste.js +104 -0
  23. package/lib/components/claude-session-picker.d.ts +8 -0
  24. package/lib/components/claude-session-picker.js +127 -0
  25. package/lib/components/form-dialog.d.ts +25 -0
  26. package/lib/components/form-dialog.js +35 -0
  27. package/lib/components/launcher-picker.d.ts +6 -0
  28. package/lib/components/launcher-picker.js +135 -0
  29. package/lib/components/mcp-util.d.ts +2 -0
  30. package/lib/components/mcp-util.js +37 -0
  31. package/lib/components/notebook-generation-popover.d.ts +7 -0
  32. package/lib/components/notebook-generation-popover.js +60 -0
  33. package/lib/components/pill.d.ts +2 -0
  34. package/lib/components/pill.js +5 -0
  35. package/lib/components/plugins-panel.d.ts +3 -0
  36. package/lib/components/plugins-panel.js +466 -0
  37. package/lib/components/settings-panel.d.ts +11 -0
  38. package/lib/components/settings-panel.js +742 -0
  39. package/lib/components/skills-panel.d.ts +2 -0
  40. package/lib/components/skills-panel.js +1264 -0
  41. package/lib/handler.d.ts +8 -0
  42. package/lib/handler.js +36 -0
  43. package/lib/icons.d.ts +45 -0
  44. package/lib/icons.js +54 -0
  45. package/lib/index.d.ts +8 -0
  46. package/lib/index.js +2079 -0
  47. package/lib/markdown-renderer.d.ts +10 -0
  48. package/lib/markdown-renderer.js +64 -0
  49. package/lib/notebook-generation-toolbar.d.ts +16 -0
  50. package/lib/notebook-generation-toolbar.js +197 -0
  51. package/lib/notebook-generation.d.ts +8 -0
  52. package/lib/notebook-generation.js +12 -0
  53. package/lib/open-file-refresh-watcher-env.d.ts +4 -0
  54. package/lib/open-file-refresh-watcher-env.js +33 -0
  55. package/lib/open-file-refresh-watcher.d.ts +97 -0
  56. package/lib/open-file-refresh-watcher.js +190 -0
  57. package/lib/shell-utils.d.ts +6 -0
  58. package/lib/shell-utils.js +9 -0
  59. package/lib/task-target-notebook.d.ts +2 -0
  60. package/lib/task-target-notebook.js +28 -0
  61. package/lib/terminal-drag-format.d.ts +9 -0
  62. package/lib/terminal-drag-format.js +23 -0
  63. package/lib/terminal-drag.d.ts +12 -0
  64. package/lib/terminal-drag.js +268 -0
  65. package/lib/tokens.d.ts +149 -0
  66. package/lib/tokens.js +88 -0
  67. package/lib/tour/tour-anchors.d.ts +18 -0
  68. package/lib/tour/tour-anchors.js +18 -0
  69. package/lib/tour/tour-config.d.ts +66 -0
  70. package/lib/tour/tour-config.js +99 -0
  71. package/lib/tour/tour-defaults.json +58 -0
  72. package/lib/tour/tour-events.d.ts +19 -0
  73. package/lib/tour/tour-events.js +30 -0
  74. package/lib/tour/tour-overlay.d.ts +6 -0
  75. package/lib/tour/tour-overlay.js +350 -0
  76. package/lib/tour/tour-state.d.ts +20 -0
  77. package/lib/tour/tour-state.js +81 -0
  78. package/lib/tour/tour-steps.d.ts +33 -0
  79. package/lib/tour/tour-steps.js +216 -0
  80. package/lib/utils.d.ts +53 -0
  81. package/lib/utils.js +385 -0
  82. package/package.json +258 -0
  83. package/schema/plugin.json +42 -0
  84. package/src/api.ts +1424 -0
  85. package/src/cell-output-bundle.ts +176 -0
  86. package/src/cell-output-toolbar.ts +232 -0
  87. package/src/chat-progress-feedback.ts +35 -0
  88. package/src/chat-sidebar.tsx +5147 -0
  89. package/src/command-ids.ts +67 -0
  90. package/src/components/ask-user-question.tsx +151 -0
  91. package/src/components/checkbox.tsx +62 -0
  92. package/src/components/claude-mcp-panel.tsx +543 -0
  93. package/src/components/claude-mcp-paste.ts +132 -0
  94. package/src/components/claude-session-picker.tsx +214 -0
  95. package/src/components/form-dialog.tsx +75 -0
  96. package/src/components/launcher-picker.tsx +237 -0
  97. package/src/components/mcp-util.ts +53 -0
  98. package/src/components/notebook-generation-popover.tsx +127 -0
  99. package/src/components/pill.tsx +15 -0
  100. package/src/components/plugins-panel.tsx +774 -0
  101. package/src/components/settings-panel.tsx +1631 -0
  102. package/src/components/skills-panel.tsx +2084 -0
  103. package/src/handler.ts +51 -0
  104. package/src/icons.ts +71 -0
  105. package/src/index.ts +2583 -0
  106. package/src/markdown-renderer.tsx +153 -0
  107. package/src/notebook-generation-toolbar.tsx +281 -0
  108. package/src/notebook-generation.ts +23 -0
  109. package/src/open-file-refresh-watcher-env.ts +52 -0
  110. package/src/open-file-refresh-watcher.ts +260 -0
  111. package/src/shell-utils.ts +10 -0
  112. package/src/svg.d.ts +4 -0
  113. package/src/task-target-notebook.ts +37 -0
  114. package/src/terminal-drag-format.ts +29 -0
  115. package/src/terminal-drag.ts +382 -0
  116. package/src/tokens.ts +171 -0
  117. package/src/tour/tour-anchors.ts +21 -0
  118. package/src/tour/tour-config.ts +160 -0
  119. package/src/tour/tour-events.ts +34 -0
  120. package/src/tour/tour-overlay.tsx +474 -0
  121. package/src/tour/tour-state.ts +87 -0
  122. package/src/tour/tour-steps.ts +281 -0
  123. package/src/utils.ts +455 -0
  124. package/style/base.css +3238 -0
  125. package/style/icons/cell-toolbar-bug.svg +5 -0
  126. package/style/icons/cell-toolbar-chat.svg +5 -0
  127. package/style/icons/cell-toolbar-sparkle.svg +5 -0
  128. package/style/icons/claude.svg +1 -0
  129. package/style/icons/copilot-warning.svg +1 -0
  130. package/style/icons/copilot.svg +1 -0
  131. package/style/icons/copy.svg +1 -0
  132. package/style/icons/openai.svg +1 -0
  133. package/style/icons/opencode.svg +1 -0
  134. package/style/icons/sparkles-warning.svg +5 -0
  135. package/style/icons/sparkles.svg +1 -0
  136. package/style/index.css +1 -0
  137. package/style/index.js +1 -0
package/style/base.css ADDED
@@ -0,0 +1,3238 @@
1
+ /*
2
+ Copyright (c) Mehmet Bektas <mbektasgh@outlook.com>
3
+
4
+ See the JupyterLab Developer Guide for useful CSS Patterns:
5
+ https://jupyterlab.readthedocs.io/en/stable/developer/css.html
6
+ */
7
+
8
+ .sidebar {
9
+ display: flex;
10
+ flex-direction: column;
11
+ height: 100%;
12
+ position: relative;
13
+ }
14
+
15
+ /* Visually-hidden text that stays in the accessibility tree. Used to add
16
+ screen-reader-only annotations next to links / buttons (e.g.
17
+ "(opens in new tab)") without changing the visual layout. */
18
+ .nbi-sr-only {
19
+ position: absolute;
20
+ width: 1px;
21
+ height: 1px;
22
+ padding: 0;
23
+ margin: -1px;
24
+ overflow: hidden;
25
+ clip: rect(0, 0, 0, 0);
26
+ white-space: nowrap;
27
+ border: 0;
28
+ }
29
+
30
+ .drop-zone-overlay {
31
+ position: absolute;
32
+ inset: 0;
33
+ background-color: color-mix(in srgb, var(--jp-brand-color1) 15%, transparent);
34
+ border: 2px dashed var(--jp-brand-color1);
35
+ border-radius: 4px;
36
+ display: flex;
37
+ align-items: center;
38
+ justify-content: center;
39
+ font-size: 14px;
40
+
41
+ /* The wrapper's color is only used by themes that don't reach the
42
+ inner <span> (e.g. if a future variant omits the chip). The chip
43
+ itself uses the theme's body text color so contrast against the
44
+ solid layer background is guaranteed regardless of how the brand
45
+ color is tuned. */
46
+ color: var(--jp-brand-color1);
47
+ z-index: 100;
48
+ pointer-events: none;
49
+ }
50
+
51
+ .drop-zone-overlay span {
52
+ /* WCAG 1.4.3: 4.5:1 against the layer1 background is the minimum the
53
+ theme commits to via --jp-ui-font-color0; use that for the chip
54
+ text and lock the chip background to a solid layer color so the
55
+ parent's 15%-brand wash never bleeds through and softens contrast.
56
+ The brand-color border keeps the visual identity of the drop
57
+ affordance without being load-bearing for legibility. */
58
+ background-color: var(--jp-layout-color1);
59
+ color: var(--jp-ui-font-color0);
60
+ padding: 8px 16px;
61
+ border-radius: 6px;
62
+ border: 1px solid var(--jp-brand-color1);
63
+ }
64
+
65
+ .user-input-context.uploaded-file {
66
+ border-style: dashed;
67
+ }
68
+
69
+ .user-input-context.image-file {
70
+ border-style: dashed;
71
+ }
72
+
73
+ .context-pill-thumbnail-wrap {
74
+ position: relative;
75
+ display: inline-block;
76
+ vertical-align: middle;
77
+ line-height: 0;
78
+ }
79
+
80
+ .context-pill-thumbnail {
81
+ max-height: 36px;
82
+ max-width: 54px;
83
+ object-fit: contain;
84
+ border-radius: 2px;
85
+ margin-right: 4px;
86
+ }
87
+
88
+ .context-pill-thumbnail-preview {
89
+ display: none;
90
+ position: absolute;
91
+ bottom: calc(100% + 6px);
92
+ left: 0;
93
+ max-width: 320px;
94
+ max-height: 320px;
95
+ object-fit: contain;
96
+ border-radius: 6px;
97
+ background: var(--jp-layout-color1);
98
+ padding: 4px;
99
+ box-shadow: 0 6px 20px rgb(0 0 0 / 25%);
100
+ z-index: 100;
101
+ pointer-events: none;
102
+ }
103
+
104
+ .context-pill-thumbnail-wrap:hover .context-pill-thumbnail-preview,
105
+ .context-pill-thumbnail-wrap:focus-within .context-pill-thumbnail-preview {
106
+ display: block;
107
+ }
108
+
109
+ .user-input-context.uploading-indicator {
110
+ border: none;
111
+ font-size: 11px;
112
+ color: var(--jp-ui-font-color2);
113
+ }
114
+
115
+ /* Animated trailing dots ("Uploading...") so the indicator visibly
116
+ moves while a request is in flight. ::after appends three dots and
117
+ steps through their reveal in 1.2 seconds. Honors prefers-reduced-
118
+ motion: vestibular-sensitive users see the literal three dots
119
+ without animation. */
120
+ .loading-ellipsis::after {
121
+ content: '\2026';
122
+ display: inline-block;
123
+ width: 1.5em;
124
+ text-align: left;
125
+ animation: nbi-loading-ellipsis-cycle 1.2s steps(4, end) infinite;
126
+ }
127
+
128
+ @keyframes nbi-loading-ellipsis-cycle {
129
+ 0% {
130
+ content: '';
131
+ }
132
+
133
+ 25% {
134
+ content: '.';
135
+ }
136
+
137
+ 50% {
138
+ content: '..';
139
+ }
140
+
141
+ 75% {
142
+ content: '...';
143
+ }
144
+
145
+ 100% {
146
+ content: '';
147
+ }
148
+ }
149
+
150
+ @media (prefers-reduced-motion: reduce) {
151
+ .loading-ellipsis::after {
152
+ animation: none;
153
+ content: '...';
154
+ }
155
+ }
156
+
157
+ /* Skip link at the top of the chat sidebar; hidden via .nbi-sr-only,
158
+ revealed only when focused so sighted users never see it and keyboard
159
+ users land on it as the very first Tab inside the sidebar. */
160
+ .nbi-skip-link {
161
+ z-index: 1000;
162
+ }
163
+
164
+ .nbi-skip-link:focus,
165
+ .nbi-skip-link:focus-visible {
166
+ left: 8px;
167
+
168
+ /* Below the 25px sidebar header so the focused chip doesn't overlap
169
+ the "Notebook Intelligence" title. */
170
+ top: 28px;
171
+ width: auto;
172
+ height: auto;
173
+ padding: 6px 10px;
174
+ margin: 0;
175
+ overflow: visible;
176
+ clip: auto;
177
+ background-color: var(--jp-layout-color1);
178
+ color: var(--jp-content-link-color);
179
+ border: 2px solid var(--jp-brand-color1);
180
+ border-radius: 3px;
181
+ text-decoration: underline;
182
+ }
183
+
184
+ .chat-message-notice {
185
+ background-color: transparent;
186
+ font-size: 12px;
187
+ color: var(--jp-ui-font-color2);
188
+ padding: 3px 5px;
189
+ }
190
+
191
+ .sidebar-header {
192
+ height: 25px;
193
+ padding: 5px 10px;
194
+ display: flex;
195
+ }
196
+
197
+ .sidebar-title {
198
+ font-size: 14px;
199
+ font-weight: bold;
200
+ flex-grow: 1;
201
+ }
202
+
203
+ .sidebar-messages {
204
+ flex-grow: 1;
205
+ overflow-y: auto;
206
+ padding: 5px;
207
+ }
208
+
209
+ #sidebar-user-input {
210
+ /* stylelint-disable */
211
+ anchor-name: --sidebaruserinput;
212
+ /* stylelint-enable */
213
+ }
214
+
215
+ .sidebar-user-input {
216
+ height: auto;
217
+ padding: 5px;
218
+ display: flex;
219
+ flex-direction: column;
220
+ background-color: var(--jp-cell-editor-background);
221
+ border: 2px solid var(--jp-border-color1);
222
+ margin: 4px;
223
+ border-radius: 3px;
224
+ }
225
+
226
+ /* stylelint-disable */
227
+ .sidebar-user-input.generating {
228
+ background:
229
+ linear-gradient(
230
+ var(--jp-cell-editor-active-background),
231
+ var(--jp-cell-editor-active-background)
232
+ )
233
+ padding-box,
234
+ linear-gradient(var(--angle), #f1259c, #687aff) border-box;
235
+ animation: 4s rotate-gen linear infinite;
236
+ border: 2px solid #0000 !important;
237
+ }
238
+ /* stylelint-enable */
239
+
240
+ .sidebar-user-input:focus-within {
241
+ border-radius: 2px;
242
+ border-color: var(--jp-brand-color1);
243
+ }
244
+
245
+ .sidebar-user-input textarea {
246
+ width: 100%;
247
+ font-family: var(--jp-ui-font-family);
248
+ color: var(--jp-ui-font-color1);
249
+ outline: none;
250
+ border: none;
251
+ resize: none;
252
+ background: none;
253
+ /* stylelint-disable */
254
+ field-sizing: content;
255
+ /* stylelint-enable */
256
+ min-height: 36px;
257
+ max-height: 200px;
258
+ }
259
+
260
+ .sidebar-user-input .user-input-context-row {
261
+ display: flex;
262
+ align-items: center;
263
+ flex-flow: row wrap;
264
+ gap: 4px;
265
+ margin-bottom: 4px;
266
+ }
267
+
268
+ .user-input-context {
269
+ display: flex;
270
+ align-items: center;
271
+ border: 1px solid var(--jp-border-color1);
272
+ border-radius: 4px;
273
+ padding: 2px;
274
+ gap: 5px;
275
+ font-size: 11px;
276
+ max-width: 100%;
277
+ }
278
+
279
+ .user-input-context > div:first-child {
280
+ overflow: hidden;
281
+ text-overflow: ellipsis;
282
+ white-space: nowrap;
283
+ }
284
+
285
+ /* Image pills need overflow: visible so the hover preview can escape
286
+ the truncation clip. Their visible content is the filename plus a
287
+ small thumbnail, so dropping the ellipsis here is fine. */
288
+ .user-input-context.image-file > div:first-child {
289
+ overflow: visible;
290
+ }
291
+
292
+ .user-input-context.off {
293
+ color: var(--jp-ui-font-color2);
294
+ font-style: italic;
295
+ }
296
+
297
+ .user-input-context-toggle {
298
+ cursor: pointer;
299
+ background: none;
300
+ border: none;
301
+ padding: 0;
302
+ color: inherit;
303
+ font: inherit;
304
+ display: inline-flex;
305
+ align-items: center;
306
+ }
307
+
308
+ .user-input-context-toggle:hover {
309
+ background-color: var(--jp-layout-color2);
310
+ }
311
+
312
+ .user-input-context-toggle:focus-visible {
313
+ outline: 2px solid var(--jp-brand-color1);
314
+ outline-offset: 1px;
315
+ }
316
+
317
+ .user-input-context svg {
318
+ width: 16px;
319
+ height: 16px;
320
+ margin: -4px 0;
321
+ }
322
+
323
+ .sidebar-user-input .user-input-footer {
324
+ display: flex;
325
+ flex-direction: row;
326
+ align-items: center;
327
+ gap: 4px;
328
+ }
329
+
330
+ .chat-mode-widgets-container {
331
+ display: flex;
332
+ flex-direction: row;
333
+ align-items: center;
334
+ gap: 5px;
335
+ margin-right: 5px;
336
+ }
337
+
338
+ .chat-mode-select {
339
+ height: 24px;
340
+ background-color: initial;
341
+ color: var(--jp-ui-font-color1);
342
+ padding: 0 5px;
343
+ border-color: var(--jp-border-color0);
344
+ outline: none;
345
+ }
346
+
347
+ .user-input-footer-button {
348
+ width: 24px;
349
+ height: 24px;
350
+ box-sizing: border-box;
351
+ padding: 2px;
352
+ cursor: pointer;
353
+ color: var(--jp-ui-font-color2);
354
+ transition: color var(--jp-transition-duration, 100ms) ease-in-out;
355
+ }
356
+
357
+ .user-input-footer-button:hover {
358
+ color: var(--jp-ui-font-color1);
359
+ }
360
+
361
+ /* Reset native chrome on the footer buttons that now render as <button>
362
+ so they line up visually with the older <div onClick> variants.
363
+ `line-height: 1` keeps the tools-button badge from drifting a pixel
364
+ relative to the icon when rendered inside a button vs a div. */
365
+ button.user-input-footer-button {
366
+ background: none;
367
+ border: none;
368
+ font: inherit;
369
+ line-height: 1;
370
+ display: inline-flex;
371
+ align-items: center;
372
+ justify-content: center;
373
+ }
374
+
375
+ /* Visible focus ring for keyboard users. :focus-visible keeps it from
376
+ firing on a plain click. Matches the brand-color focus indicator
377
+ the other NBI buttons use elsewhere in this stylesheet. */
378
+ .user-input-footer-button:focus-visible {
379
+ outline: 2px solid var(--jp-brand-color1);
380
+ outline-offset: 1px;
381
+ border-radius: 3px;
382
+ color: var(--jp-ui-font-color1);
383
+ }
384
+
385
+ /* The slash-button (mentions and commands) renders text rather than an
386
+ svg, so size and center the glyph instead of relying on the svg rule. */
387
+ .user-input-footer-slash-button {
388
+ font-weight: 600;
389
+ font-size: 16px;
390
+ line-height: 1;
391
+ }
392
+
393
+ .user-input-footer-button.tools-button {
394
+ width: auto;
395
+ border: 1px solid var(--jp-border-color0);
396
+ display: flex;
397
+ align-items: center;
398
+ gap: 2px;
399
+ padding-right: 3px;
400
+ }
401
+
402
+ .user-input-footer-button.tools-button-warning {
403
+ color: var(--jp-warn-color0);
404
+ border-color: var(--jp-warn-color0);
405
+ }
406
+
407
+ .user-input-footer-button.tools-button-active {
408
+ color: var(--jp-brand-color0);
409
+ border-color: var(--jp-brand-color0);
410
+ }
411
+
412
+ .user-input-footer-button svg {
413
+ width: 18px;
414
+ height: 18px;
415
+ }
416
+
417
+ .chat-message {
418
+ padding: 5px;
419
+ display: flex;
420
+ flex-direction: column;
421
+ }
422
+
423
+ .chat-message pre {
424
+ padding: 3px;
425
+ border-radius: 3px;
426
+ border: 1px solid var(--jp-border-color1);
427
+ }
428
+
429
+ pre:has(.code-block-header) {
430
+ padding: 2px;
431
+ background-color: var(--jp-layout-color2);
432
+ }
433
+
434
+ .chat-message-header {
435
+ display: flex;
436
+ }
437
+
438
+ .chat-message-from {
439
+ display: flex;
440
+ align-items: center;
441
+ flex-grow: 1;
442
+ }
443
+
444
+ .chat-message-from-icon {
445
+ margin-right: 6px;
446
+ }
447
+
448
+ .chat-message-from-icon img {
449
+ width: 18px;
450
+ height: 18px;
451
+ }
452
+
453
+ .chat-response-img img {
454
+ max-width: 100%;
455
+ }
456
+
457
+ .chat-message-from-icon-default.dark img {
458
+ filter: invert(100%);
459
+ }
460
+
461
+ .chat-message-from-title {
462
+ font-weight: bold;
463
+ }
464
+
465
+ .chat-message-notice .chat-message-from-title {
466
+ font-weight: normal;
467
+ font-style: italic;
468
+ }
469
+
470
+ .chat-message-from-progress {
471
+ padding-left: 10px;
472
+ flex-grow: 1;
473
+ font-size: 12px;
474
+ display: flex;
475
+ align-items: center;
476
+ gap: 6px;
477
+ }
478
+
479
+ /* The React `key` prop on this span is keyed to the heartbeat tick, so
480
+ each beat remounts the element and the animation runs from t=0. */
481
+ .generating-pulse {
482
+ display: inline-block;
483
+ width: 6px;
484
+ height: 6px;
485
+ border-radius: 50%;
486
+ background-color: var(--jp-brand-color1);
487
+ flex-shrink: 0;
488
+ opacity: 0.5;
489
+ animation: nbi-progress-pulse 1.2s ease-out;
490
+ }
491
+
492
+ .generating-pulse.is-stalled {
493
+ background-color: var(--jp-warn-color1);
494
+ }
495
+
496
+ .generating-label {
497
+ font-variant-numeric: tabular-nums;
498
+ }
499
+
500
+ @keyframes nbi-progress-pulse {
501
+ 0% {
502
+ opacity: 1;
503
+ transform: scale(1.4);
504
+ }
505
+
506
+ 100% {
507
+ opacity: 0.5;
508
+ transform: scale(1);
509
+ }
510
+ }
511
+
512
+ @media (prefers-reduced-motion: reduce) {
513
+ .generating-pulse {
514
+ animation: none;
515
+ }
516
+
517
+ /* The conic-gradient generating border on the chat input and inline-
518
+ completion editor rotates indefinitely while a response streams in.
519
+ Pause it for vestibular-sensitive users so the brand-tinted border
520
+ becomes a static indicator instead of a rotating one. */
521
+ .sidebar-user-input.generating,
522
+ .jp-InputArea-editor.generating {
523
+ animation: none;
524
+ }
525
+ }
526
+
527
+ .chat-message-timestamp {
528
+ padding-left: 10px;
529
+ font-size: 11px;
530
+ }
531
+
532
+ .chat-message-content p {
533
+ margin-block: 5px 5px;
534
+ line-height: 18px;
535
+ }
536
+
537
+ .chat-message-notice .chat-message-content p {
538
+ margin-block: 2px;
539
+ }
540
+
541
+ .chat-message-content a {
542
+ text-decoration: underline;
543
+ }
544
+
545
+ .chat-message-content table {
546
+ border-collapse: collapse;
547
+ margin: 8px 0;
548
+ font-size: 12px;
549
+ line-height: 1.4;
550
+ display: block;
551
+ overflow-x: auto;
552
+ max-width: 100%;
553
+ }
554
+
555
+ .chat-message-content th,
556
+ .chat-message-content td {
557
+ border: 1px solid var(--jp-border-color1);
558
+ padding: 4px 8px;
559
+ text-align: left;
560
+ vertical-align: top;
561
+ }
562
+
563
+ .chat-message-content thead th {
564
+ background-color: var(--jp-layout-color2);
565
+ font-weight: bold;
566
+ }
567
+
568
+ .chat-message-content tbody tr:nth-child(even) {
569
+ background-color: var(--jp-layout-color1);
570
+ }
571
+
572
+ .chat-message-content ul,
573
+ .chat-message-content ol {
574
+ margin-block: 5px;
575
+ padding-left: 24px;
576
+ }
577
+
578
+ .chat-message-content li {
579
+ margin-block: 2px;
580
+ line-height: 18px;
581
+ }
582
+
583
+ .chat-message-content blockquote {
584
+ margin: 8px 0;
585
+ padding: 2px 10px;
586
+ border-left: 3px solid var(--jp-border-color1);
587
+ color: var(--jp-ui-font-color2);
588
+ }
589
+
590
+ .chat-message-content hr {
591
+ border: none;
592
+ border-top: 1px solid var(--jp-border-color2);
593
+ margin: 10px 0;
594
+ }
595
+
596
+ .chat-message-content h1,
597
+ .chat-message-content h2,
598
+ .chat-message-content h3,
599
+ .chat-message-content h4,
600
+ .chat-message-content h5,
601
+ .chat-message-content h6 {
602
+ margin-block: 10px 5px;
603
+ line-height: 1.3;
604
+ }
605
+
606
+ .chat-message-content h1 {
607
+ font-size: 18px;
608
+ }
609
+
610
+ .chat-message-content h2 {
611
+ font-size: 16px;
612
+ }
613
+
614
+ .chat-message-content h3 {
615
+ font-size: 14px;
616
+ }
617
+
618
+ .chat-message-content h4,
619
+ .chat-message-content h5,
620
+ .chat-message-content h6 {
621
+ font-size: 13px;
622
+ }
623
+
624
+ .chat-message-content :not(pre) > code {
625
+ background-color: var(--jp-layout-color2);
626
+ padding: 1px 4px;
627
+ border-radius: 3px;
628
+ font-size: 0.9em;
629
+ }
630
+
631
+ .chat-message-copilot {
632
+ background-color: rgb(159 153 208 / 15%);
633
+ }
634
+
635
+ .chat-message-feedback {
636
+ display: flex;
637
+ align-items: center;
638
+ gap: 4px;
639
+ padding: 2px 0 4px;
640
+ opacity: 0;
641
+ transition: opacity 0.15s ease;
642
+ }
643
+
644
+ .chat-message-feedback:focus-within,
645
+ .chat-message-feedback:has(.selected),
646
+ .chat-message:hover .chat-message-feedback {
647
+ opacity: 1;
648
+ }
649
+
650
+ .chat-feedback-btn {
651
+ display: flex;
652
+ align-items: center;
653
+ justify-content: center;
654
+ background: none;
655
+ border: 1px solid transparent;
656
+ border-radius: 4px;
657
+ padding: 3px;
658
+ cursor: pointer;
659
+ color: var(--jp-ui-font-color2);
660
+ transition:
661
+ color 0.15s ease,
662
+ background-color 0.15s ease;
663
+ }
664
+
665
+ .chat-feedback-btn:hover {
666
+ color: var(--jp-ui-font-color0);
667
+ background-color: var(--jp-layout-color2);
668
+ }
669
+
670
+ .chat-feedback-btn.selected {
671
+ color: var(--jp-brand-color1);
672
+ background-color: var(--jp-layout-color2);
673
+ }
674
+
675
+ .chat-feedback-btn svg {
676
+ width: 14px;
677
+ height: 14px;
678
+ }
679
+
680
+ /* Rendered as a real <button> so it picks up Tab order, Enter/Space
681
+ activation, and "button" role announcement. The visual presentation
682
+ stays anchor-like: underline + link color so users still recognise it
683
+ as a clickable "open notebook" affordance. */
684
+ .copilot-generated-notebook-link {
685
+ background: none;
686
+ border: none;
687
+ padding: 0;
688
+ font: inherit;
689
+ color: var(--jp-content-link-color);
690
+ text-decoration: underline;
691
+ text-underline-offset: 2px;
692
+ cursor: pointer;
693
+ }
694
+
695
+ .copilot-generated-notebook-link:hover {
696
+ filter: brightness(1.15);
697
+ }
698
+
699
+ .copilot-generated-notebook-link:focus-visible {
700
+ outline: 2px solid var(--jp-brand-color1);
701
+ outline-offset: 1px;
702
+ border-radius: 2px;
703
+ }
704
+
705
+ .sidebar-login-info {
706
+ padding: 5px;
707
+ display: flex;
708
+ flex-direction: column;
709
+ align-items: center;
710
+ gap: 10px;
711
+ line-height: 20px;
712
+ }
713
+
714
+ .sidebar-login-info a {
715
+ text-decoration: underline;
716
+ }
717
+
718
+ .sidebar-login-buttons {
719
+ display: flex;
720
+ flex-direction: column;
721
+ align-items: center;
722
+ gap: 10px;
723
+ }
724
+
725
+ .sidebar-login-buttons .jp-Dialog-button.jp-mod-styled {
726
+ margin-right: 0;
727
+ }
728
+
729
+ .sidebar-greeting {
730
+ padding: 5px;
731
+ font-size: 14px;
732
+ line-height: 20px;
733
+ }
734
+
735
+ .user-code-span {
736
+ cursor: pointer;
737
+ color: var(--jp-content-link-color);
738
+ }
739
+
740
+ .user-code-span:hover {
741
+ text-shadow: 1px 1px var(--jp-border-color1);
742
+ }
743
+
744
+ .user-code-span:active {
745
+ color: var(--jp-ui-font-color2);
746
+ }
747
+
748
+ .chat-response-html-frame {
749
+ margin: 5px 0;
750
+ }
751
+
752
+ .chat-response-html-frame-iframe {
753
+ width: 100%;
754
+ border: none;
755
+ }
756
+
757
+ .chat-response-anchor {
758
+ margin: 5px 0;
759
+ }
760
+
761
+ .chat-response-button {
762
+ margin: 5px 0;
763
+ }
764
+
765
+ .chat-response-progress {
766
+ margin: 5px 0;
767
+ }
768
+
769
+ .chat-confirmation-form {
770
+ border: 1px solid var(--jp-border-color1);
771
+ padding: 5px;
772
+ line-height: 20px;
773
+ }
774
+
775
+ .chat-confirmation-form button {
776
+ height: 24px;
777
+ line-height: 24px;
778
+ padding: 0 6px;
779
+ margin-top: 2px;
780
+ }
781
+
782
+ .user-input-autocomplete,
783
+ .mode-tools-popover,
784
+ .workspace-file-popover {
785
+ display: flex;
786
+ background-color: var(--jp-layout-color2);
787
+ border: 1px solid var(--jp-border-color1);
788
+ flex-direction: column;
789
+ position: absolute;
790
+ /* stylelint-disable */
791
+ position-anchor: --sidebaruserinput;
792
+ position-area: top;
793
+ /* stylelint-enable */
794
+ width: calc(100% - 16px);
795
+ gap: 2px;
796
+ /* stylelint-disable */
797
+ max-height: min(calc(100% - 120px), 400px);
798
+ /* stylelint-enable */
799
+ overflow-y: auto;
800
+ user-select: none;
801
+ }
802
+
803
+ .mode-tools-popover {
804
+ width: calc(100% - 10px);
805
+ /* stylelint-disable */
806
+ max-height: min(calc(100% - 200px), 400px);
807
+ /* stylelint-enable */
808
+ box-shadow: var(--jp-brand-color0) 0 0 1px 1px;
809
+ display: flex;
810
+ flex-direction: column;
811
+ }
812
+
813
+ .workspace-file-popover {
814
+ width: calc(100% - 10px);
815
+ /* stylelint-disable */
816
+ max-height: min(calc(100% - 220px), 420px);
817
+ /* stylelint-enable */
818
+ box-shadow: var(--jp-brand-color0) 0 0 1px 1px;
819
+ }
820
+
821
+ .mode-tools-popover-title {
822
+ font-weight: bold;
823
+ }
824
+
825
+ .mode-tools-popover-header {
826
+ display: flex;
827
+ align-items: center;
828
+ gap: 5px;
829
+ height: 24px;
830
+ background-color: var(--jp-layout-color1);
831
+ padding: 2px;
832
+ }
833
+
834
+ .mode-tools-popover-header-icon svg {
835
+ width: 18px;
836
+ height: 18px;
837
+ }
838
+
839
+ .mode-tools-popover-clear-tools-button {
840
+ flex-grow: 1;
841
+ color: var(--jp-ui-font-color2);
842
+ display: flex;
843
+ padding-top: 3px;
844
+ }
845
+
846
+ .mode-tools-popover-clear-tools-button svg {
847
+ width: 16px;
848
+ height: 16px;
849
+ }
850
+
851
+ /* Anchor-styled button used in place of the old <a href="javascript:void(0)">
852
+ pattern. Keeps the visual affordance (link color + underline) while
853
+ participating in the document's natural tab order. The color matches
854
+ JupyterLab's anchor token so the affordance reads as a link, not as
855
+ plain underlined body text. */
856
+ .link-button {
857
+ background: none;
858
+ border: none;
859
+ padding: 0;
860
+ font: inherit;
861
+ color: var(--jp-content-link-color);
862
+ text-decoration: underline;
863
+ text-underline-offset: 2px;
864
+ cursor: pointer;
865
+ }
866
+
867
+ .link-button:hover {
868
+ filter: brightness(1.15);
869
+ }
870
+
871
+ .link-button:focus-visible {
872
+ outline: 2px solid var(--jp-brand-color1);
873
+ outline-offset: 1px;
874
+ border-radius: 2px;
875
+ }
876
+
877
+ /* tabIndex=-1 wrappers receive programmatic focus on open; the popover
878
+ already carries a brand-color box-shadow as its visual affordance, so
879
+ the wrapper's default browser focus ring would only stack a second
880
+ indicator on top. */
881
+ .workspace-file-popover:focus,
882
+ .mode-tools-popover:focus {
883
+ outline: none;
884
+ }
885
+
886
+ /* Reset the UA <button> chrome (border, padding, font) on the icon-
887
+ buttons so the conversion from <div onClick> doesn't shift the 24px
888
+ header height or push the icons off-center. padding-right keeps the
889
+ pre-conversion gap from the icon to the next sibling. */
890
+ .mode-tools-popover-button {
891
+ display: flex;
892
+ align-items: center;
893
+ justify-content: center;
894
+ cursor: pointer;
895
+ width: auto;
896
+ height: 24px;
897
+ color: white;
898
+ background-color: var(--jp-brand-color0);
899
+ padding: 0 6px 0 0;
900
+ border: none;
901
+ font: inherit;
902
+ line-height: 1;
903
+ border-radius: 2px;
904
+ }
905
+
906
+ .mode-tools-popover-button svg {
907
+ width: 16px;
908
+ height: 16px;
909
+ padding: 4px;
910
+ margin-top: 2px;
911
+ }
912
+
913
+ .mode-tools-popover-button:focus-visible {
914
+ outline: 2px solid var(--jp-brand-color1);
915
+ outline-offset: 1px;
916
+ }
917
+
918
+ .mode-tools-popover-close-button {
919
+ width: 24px;
920
+ padding: 0;
921
+ }
922
+
923
+ .mode-tools-popover-close-button svg {
924
+ padding: 0;
925
+ margin: 0;
926
+ }
927
+
928
+ .mode-tools-popover-refresh-button {
929
+ width: 24px;
930
+ padding: 0;
931
+ margin-right: 4px;
932
+ }
933
+
934
+ .mode-tools-popover-refresh-button.is-loading {
935
+ cursor: progress;
936
+ opacity: 0.6;
937
+ }
938
+
939
+ .mode-tools-popover-tool-list {
940
+ flex-grow: 1;
941
+ overflow-y: auto;
942
+ }
943
+
944
+ .workspace-file-popover-body {
945
+ display: flex;
946
+ flex-direction: column;
947
+ gap: 6px;
948
+ padding: 6px;
949
+ overflow: hidden;
950
+ }
951
+
952
+ .workspace-file-search-input {
953
+ width: 100%;
954
+ box-sizing: border-box;
955
+ background-color: var(--jp-layout-color1);
956
+ color: var(--jp-ui-font-color1);
957
+ border: 1px solid var(--jp-border-color1);
958
+ padding: 6px 8px;
959
+ outline: none;
960
+ }
961
+
962
+ .workspace-file-search-input:focus {
963
+ border-color: var(--jp-brand-color1);
964
+ }
965
+
966
+ .workspace-file-popover-status {
967
+ font-size: 12px;
968
+ line-height: 16px;
969
+ color: var(--jp-ui-font-color2);
970
+ }
971
+
972
+ .workspace-file-popover-status.error {
973
+ color: var(--jp-error-color1);
974
+ }
975
+
976
+ /* Pin the Coding Agent section to the top of the launcher.
977
+ JupyterLab hardcodes Notebook/Console/Other as the first categories,
978
+ so we use flex order to visually promote our section above them. */
979
+ .jp-Launcher-content {
980
+ display: flex !important;
981
+ flex-direction: column;
982
+ }
983
+
984
+ .jp-Launcher-cwd {
985
+ order: -2;
986
+ }
987
+
988
+ .jp-Launcher-section:has(.jp-LauncherCard[data-category='Coding Agent']) {
989
+ order: -1;
990
+ }
991
+
992
+ /* Claude Code session picker (used inside Dialog from launcher tile) */
993
+ .nbi-claude-code-picker {
994
+ min-width: 480px;
995
+ height: 400px;
996
+ }
997
+
998
+ .nbi-claude-code-picker-body {
999
+ display: flex;
1000
+ flex-direction: column;
1001
+ gap: 0;
1002
+ width: 500px;
1003
+ height: 100%;
1004
+ }
1005
+
1006
+ .nbi-claude-code-picker-search {
1007
+ width: 100%;
1008
+ box-sizing: border-box;
1009
+ padding: 7px 10px;
1010
+ margin-bottom: 10px;
1011
+ border: 1px solid var(--jp-border-color1);
1012
+ border-radius: 4px;
1013
+ background: var(--jp-layout-color1);
1014
+ color: var(--jp-ui-font-color1);
1015
+ font-size: var(--jp-ui-font-size1);
1016
+ outline: none;
1017
+ }
1018
+
1019
+ .nbi-claude-code-picker-list {
1020
+ max-height: 380px;
1021
+ overflow-y: auto;
1022
+ }
1023
+
1024
+ .nbi-claude-code-picker-status {
1025
+ display: flex;
1026
+ align-items: center;
1027
+ justify-content: center;
1028
+ min-height: 80px;
1029
+ color: var(--jp-ui-font-color2);
1030
+ }
1031
+
1032
+ .nbi-claude-code-picker-error {
1033
+ color: var(--jp-error-color1);
1034
+ }
1035
+
1036
+ .nbi-claude-code-picker-empty {
1037
+ padding: 16px 0;
1038
+ color: var(--jp-ui-font-color2);
1039
+ text-align: center;
1040
+ font-size: var(--jp-ui-font-size1);
1041
+ }
1042
+
1043
+ .nbi-claude-code-picker-project {
1044
+ margin-bottom: 8px;
1045
+ }
1046
+
1047
+ .nbi-claude-code-picker-project-label {
1048
+ display: flex;
1049
+ align-items: center;
1050
+ gap: 6px;
1051
+ font-size: 11px;
1052
+ text-transform: uppercase;
1053
+ letter-spacing: 0.08em;
1054
+ color: var(--jp-ui-font-color2);
1055
+ margin-bottom: 4px;
1056
+ padding: 0 2px;
1057
+ }
1058
+
1059
+ .nbi-claude-code-picker-session {
1060
+ display: flex;
1061
+ flex-direction: column;
1062
+ gap: 3px;
1063
+ padding: 8px 10px;
1064
+ margin-bottom: 4px;
1065
+ border: 1px solid var(--jp-border-color2);
1066
+ border-radius: 4px;
1067
+ cursor: pointer;
1068
+ background: var(--jp-layout-color1);
1069
+ transition: border-color 0.1s;
1070
+ }
1071
+
1072
+ .nbi-claude-code-picker-session:hover,
1073
+ .nbi-claude-code-picker-session:focus,
1074
+ .nbi-claude-code-picker-session.highlighted {
1075
+ border-color: var(--jp-brand-color1);
1076
+ outline: none;
1077
+ }
1078
+
1079
+ .nbi-claude-code-picker-session-top {
1080
+ display: flex;
1081
+ align-items: center;
1082
+ gap: 6px;
1083
+ }
1084
+
1085
+ .nbi-claude-code-picker-session-id {
1086
+ font-family: var(--jp-code-font-family);
1087
+ font-size: 12px;
1088
+ color: var(--jp-ui-font-color1);
1089
+ font-weight: 600;
1090
+ }
1091
+
1092
+ .nbi-claude-code-picker-time {
1093
+ margin-left: auto;
1094
+ font-size: 11px;
1095
+ color: var(--jp-ui-font-color3);
1096
+ }
1097
+
1098
+ /* The session row's project basename rides at the right edge,
1099
+ mirroring the old `time` slot. Keeps long paths from blowing out the
1100
+ row while leaving the full cwd available on hover via the title attr.
1101
+ (Named `-session-project` not `-project` to avoid colliding with the
1102
+ project-grouping header class higher up in this stylesheet.) */
1103
+ .nbi-claude-code-picker-session-project {
1104
+ margin-left: auto;
1105
+ font-size: 11px;
1106
+ color: var(--jp-ui-font-color3);
1107
+ max-width: 50%;
1108
+ overflow: hidden;
1109
+ text-overflow: ellipsis;
1110
+ white-space: nowrap;
1111
+ }
1112
+
1113
+ .nbi-claude-code-picker-msg {
1114
+ font-size: var(--jp-ui-font-size1);
1115
+ color: var(--jp-ui-font-color2);
1116
+ white-space: nowrap;
1117
+ overflow: hidden;
1118
+ text-overflow: ellipsis;
1119
+ }
1120
+
1121
+ .mode-tools-group {
1122
+ display: flex;
1123
+ flex-direction: column;
1124
+ padding-left: 5px;
1125
+ margin-bottom: 5px;
1126
+ }
1127
+
1128
+ .mode-tools-group-header {
1129
+ padding: 5px 0;
1130
+ border-bottom: 1px solid var(--jp-border-color1);
1131
+ margin: 0 5px;
1132
+ font-weight: bold;
1133
+ }
1134
+
1135
+ .user-input-autocomplete-item {
1136
+ cursor: pointer;
1137
+ padding: 4px;
1138
+ }
1139
+
1140
+ .user-input-autocomplete-item.selected {
1141
+ background-color: var(--jp-layout-color1);
1142
+ }
1143
+
1144
+ .code-block-header {
1145
+ display: flex;
1146
+ align-items: flex-end;
1147
+ gap: 5px;
1148
+ padding: 3px;
1149
+ padding-bottom: 0;
1150
+ }
1151
+
1152
+ .code-block-header-language {
1153
+ flex-grow: 1;
1154
+ }
1155
+
1156
+ .code-block-header-button {
1157
+ display: flex;
1158
+ align-items: center;
1159
+ gap: 4px;
1160
+ cursor: pointer;
1161
+ padding: 2px;
1162
+ background: none;
1163
+ border: none;
1164
+ color: inherit;
1165
+ font: inherit;
1166
+ }
1167
+
1168
+ .code-block-header-button:hover {
1169
+ background-color: var(--jp-layout-color1);
1170
+ }
1171
+
1172
+ .code-block-header-button:active {
1173
+ background-color: var(--jp-layout-color3);
1174
+ }
1175
+
1176
+ .code-block-header-button:focus-visible {
1177
+ outline: 2px solid var(--jp-brand-color1);
1178
+ outline-offset: 1px;
1179
+ }
1180
+
1181
+ .copy-icon svg {
1182
+ width: 12px;
1183
+ height: 12px;
1184
+ }
1185
+
1186
+ .claude-icon svg {
1187
+ width: 16px;
1188
+ height: 16px;
1189
+ color: #d97757;
1190
+ }
1191
+
1192
+ .send-button {
1193
+ display: flex;
1194
+ align-items: center;
1195
+ cursor: pointer;
1196
+ gap: 5px;
1197
+ border: 1px solid var(--jp-border-color1);
1198
+ }
1199
+
1200
+ button.send-button {
1201
+ padding: 4px;
1202
+ width: 24px;
1203
+ height: 24px;
1204
+ }
1205
+
1206
+ button.send-button:disabled:not(.send-button-stop),
1207
+ button.send-button:disabled:hover:not(.send-button-stop),
1208
+ button.send-button:disabled:active:not(.send-button-stop) {
1209
+ cursor: default;
1210
+ background-color: var(--jp-accept-color-normal);
1211
+ }
1212
+
1213
+ .send-button:hover:enabled {
1214
+ background-color: var(--jp-layout-color1);
1215
+ }
1216
+
1217
+ .send-button svg {
1218
+ width: 18px;
1219
+ height: 18px;
1220
+ }
1221
+
1222
+ /* During generation the send action turns into a stop action. The
1223
+ icon switch alone would fail WCAG 3.3.4 (icon shape is a single
1224
+ non-redundant signal); pair it with a warn-tinted background and a
1225
+ border that picks up the warn color so the state is visible to
1226
+ color-blind users too. The accessible name on the <button> swaps to
1227
+ "Stop generating" in lockstep.
1228
+ We do NOT reuse JupyterLab's own jp-mod-warn rule because that token
1229
+ resolves to --jp-warn-color-normal (red) which reads as "error". We
1230
+ want "caution" (amber) via --jp-warn-color1, so the custom rule
1231
+ stays intentionally separate. */
1232
+ .send-button.send-button-stop {
1233
+ background-color: var(--jp-warn-color1, #ff9800);
1234
+ border-color: var(--jp-warn-color1, #ff9800);
1235
+ color: white;
1236
+ }
1237
+
1238
+ .send-button.send-button-stop:hover:enabled {
1239
+ background-color: var(--jp-warn-color0, #f57c00);
1240
+ }
1241
+
1242
+ .inline-popover {
1243
+ width: calc(100% - 6px);
1244
+ height: calc(100% - 6px);
1245
+ display: flex;
1246
+ flex-direction: column;
1247
+ position: absolute;
1248
+
1249
+ /* Use the JupyterLab layer token so the inline prompt picks up the
1250
+ ambient theme (light, dark, high-contrast, solarized, etc.). The
1251
+ previous fixed #f2f3ff / #14162b values bypassed the theme and
1252
+ could yield insufficient text contrast under custom themes.
1253
+ --jp-layout-color2 matches the elevation pattern used by the
1254
+ sibling popovers (mode-tools-popover, workspace-file-popover) so
1255
+ the popover surface sits above the inner footer (color1) rather
1256
+ than reading as recessed. */
1257
+ background-color: var(--jp-layout-color2);
1258
+ color: var(--jp-content-font-color1);
1259
+ }
1260
+
1261
+ .inline-prompt-container {
1262
+ width: 100%;
1263
+ height: 100%;
1264
+ padding: 2px;
1265
+ }
1266
+
1267
+ .monaco-editor-container {
1268
+ width: 100%;
1269
+ flex-grow: 1;
1270
+ border: 1px solid var(--jp-border-color2);
1271
+ border-left: none;
1272
+ border-right: none;
1273
+ }
1274
+
1275
+ .inline-popover-footer {
1276
+ height: 32px;
1277
+ width: calc(100% - 6px);
1278
+ display: flex;
1279
+ flex-direction: row;
1280
+ gap: 5px;
1281
+ align-items: center;
1282
+ padding-left: 5px;
1283
+ background-color: var(--jp-layout-color2);
1284
+ }
1285
+
1286
+ .inline-prompt-container textarea {
1287
+ width: calc(100% - 2px);
1288
+ height: calc(100% - 2px);
1289
+ font-family: var(--jp-ui-font-family);
1290
+ color: var(--jp-ui-font-color1);
1291
+ resize: none;
1292
+ background: none;
1293
+ outline: none;
1294
+ border: none;
1295
+ }
1296
+
1297
+ .inline-popover-footer .jp-Button {
1298
+ height: 24px;
1299
+ padding: 4px;
1300
+ }
1301
+
1302
+ .github-copilot-status-bar {
1303
+ color: var(--jp-inverse-layout-color2);
1304
+ }
1305
+
1306
+ .github-copilot-status-bar svg {
1307
+ margin-top: 4px;
1308
+ }
1309
+
1310
+ .github-copilot-login-dialog {
1311
+ display: flex;
1312
+ flex-direction: column;
1313
+ gap: 10px;
1314
+ padding: 10px;
1315
+ width: 500px;
1316
+ line-height: 20px;
1317
+ }
1318
+
1319
+ .github-copilot-login-status-text.logged-in {
1320
+ color: var(--jp-brand-color1);
1321
+ }
1322
+
1323
+ .config-dialog {
1324
+ display: flex;
1325
+ flex-direction: column;
1326
+ }
1327
+
1328
+ .config-dialog-container .jp-Dialog-content {
1329
+ max-height: 600px;
1330
+ }
1331
+
1332
+ .config-dialog-container .jp-Dialog-footer {
1333
+ display: none;
1334
+ }
1335
+
1336
+ .config-dialog-body {
1337
+ display: flex;
1338
+ flex-direction: column;
1339
+ overflow-y: auto;
1340
+ gap: 15px;
1341
+ }
1342
+
1343
+ .model-config-section-row {
1344
+ display: flex;
1345
+ flex-direction: row;
1346
+ gap: 10px;
1347
+ }
1348
+
1349
+ .model-config-section-column {
1350
+ display: flex;
1351
+ flex-direction: column;
1352
+ gap: 10px;
1353
+ flex: 1 1 0px;
1354
+ }
1355
+
1356
+ .config-dialog-footer {
1357
+ height: 32px;
1358
+ display: flex;
1359
+ margin-top: 10px;
1360
+ }
1361
+
1362
+ .config-dialog-body select.jp-mod-styled {
1363
+ appearance: auto;
1364
+ }
1365
+
1366
+ .config-dialog-body input.jp-mod-styled {
1367
+ width: 100%;
1368
+ }
1369
+
1370
+ .model-config-section {
1371
+ display: flex;
1372
+ flex-direction: column;
1373
+ gap: 10px;
1374
+ }
1375
+
1376
+ .form-field-row {
1377
+ padding-left: 15px;
1378
+ }
1379
+
1380
+ .form-field-description {
1381
+ color: var(--jp-ui-font-color2);
1382
+ margin-bottom: 5px;
1383
+ }
1384
+
1385
+ .model-config-section-header {
1386
+ font-weight: bold;
1387
+ font-size: 15px;
1388
+ }
1389
+
1390
+ .model-config-section-body {
1391
+ padding-left: 10px;
1392
+ display: flex;
1393
+ flex-direction: column;
1394
+ gap: 10px;
1395
+ }
1396
+
1397
+ .inline-prompt-widget {
1398
+ border-radius: 4px;
1399
+ padding: 3px;
1400
+ }
1401
+
1402
+ .inline-prompt-widget-floating {
1403
+ z-index: 1000;
1404
+ box-shadow: rgba(90 76 191 / 30%) 0 0 10px 10px;
1405
+ }
1406
+
1407
+ .inline-prompt-widget-inline {
1408
+ position: relative;
1409
+ width: 100%;
1410
+ box-sizing: border-box;
1411
+ margin: 4px 0;
1412
+ box-shadow: rgba(90 76 191 / 25%) 0 0 4px 1px;
1413
+ }
1414
+
1415
+ /* Undo .cm-content { caret-color: transparent } from CM6's drawSelection,
1416
+ which inherits into our textarea when the popover renders as a block
1417
+ widget inside the editor. */
1418
+ .inline-prompt-widget-inline textarea {
1419
+ caret-color: auto;
1420
+ }
1421
+
1422
+ .nbi-inline-prompt-block {
1423
+ box-sizing: border-box;
1424
+ display: block;
1425
+ width: 100%;
1426
+ padding: 2px 0;
1427
+ }
1428
+
1429
+ .inline-prompt-widget::before {
1430
+ border-radius: 4px;
1431
+ content: '';
1432
+ background-image: conic-gradient(
1433
+ from 270deg at 50% 50%,
1434
+ #3b37ff 0deg,
1435
+ #096bde 160deg,
1436
+ #f1259c 175deg,
1437
+ #7c3ffe 200deg,
1438
+ #7c3ffe 350deg,
1439
+ #3b37ff 360deg
1440
+ );
1441
+ /* stylelint-disable */
1442
+ left: -1px;
1443
+ right: -1px;
1444
+ top: -1px;
1445
+ bottom: -1px;
1446
+ /* stylelint-enable */
1447
+ position: absolute;
1448
+ z-index: -1;
1449
+ }
1450
+
1451
+ /* stylelint-disable */
1452
+ .jp-InputArea-editor.generating {
1453
+ background:
1454
+ linear-gradient(
1455
+ var(--jp-cell-editor-active-background),
1456
+ var(--jp-cell-editor-active-background)
1457
+ )
1458
+ padding-box,
1459
+ linear-gradient(var(--angle), #f1259c, #687aff) border-box;
1460
+ animation: 4s rotate-gen linear infinite;
1461
+ border: 2px solid #0000 !important;
1462
+ }
1463
+
1464
+ @keyframes rotate-gen {
1465
+ to {
1466
+ --angle: 360deg;
1467
+ }
1468
+ }
1469
+
1470
+ @property --angle {
1471
+ syntax: '<angle>';
1472
+ initial-value: 0deg;
1473
+ inherits: false;
1474
+ }
1475
+ /* stylelint-enable */
1476
+
1477
+ .ollama-warning-message {
1478
+ color: var(--jp-warn-color0);
1479
+ line-height: 20px;
1480
+ }
1481
+
1482
+ .expandable-content-title {
1483
+ margin-top: 5px;
1484
+ margin-bottom: 5px;
1485
+ display: flex;
1486
+ align-items: center;
1487
+ gap: 5px;
1488
+ cursor: pointer;
1489
+ color: var(--jp-ui-font-color2);
1490
+ background: none;
1491
+ border: none;
1492
+ padding: 0;
1493
+ font: inherit;
1494
+ text-align: left;
1495
+ width: 100%;
1496
+ }
1497
+
1498
+ .expandable-content-title:focus-visible {
1499
+ outline: 2px solid var(--jp-brand-color1);
1500
+ outline-offset: 1px;
1501
+ }
1502
+
1503
+ .expandable-content-text {
1504
+ display: none;
1505
+ margin: 5px;
1506
+ padding: 0 5px;
1507
+ border: 1px solid var(--jp-border-color2);
1508
+ border-radius: 5px;
1509
+ max-height: 200px;
1510
+ overflow-y: auto;
1511
+ box-shadow: inset 0 0 15px 15px rgb(23 23 23 / 50%);
1512
+ }
1513
+
1514
+ .expandable-content .collapsed-icon {
1515
+ display: inline;
1516
+ }
1517
+
1518
+ .expandable-content .expanded-icon {
1519
+ display: none;
1520
+ }
1521
+
1522
+ .expandable-content.expanded .expanded-icon {
1523
+ display: inline;
1524
+ }
1525
+
1526
+ .expandable-content.expanded .expandable-content-text {
1527
+ display: block;
1528
+ }
1529
+
1530
+ .expandable-content.expanded .collapsed-icon {
1531
+ display: none;
1532
+ }
1533
+
1534
+ .access-token-config-header {
1535
+ display: flex;
1536
+ align-items: center;
1537
+ gap: 10px;
1538
+ }
1539
+
1540
+ svg.access-token-warning {
1541
+ color: var(--jp-warn-color0);
1542
+ width: 18px;
1543
+ height: 18px;
1544
+ }
1545
+
1546
+ .checkbox-item {
1547
+ display: flex;
1548
+ flex-direction: column;
1549
+ cursor: pointer;
1550
+ }
1551
+
1552
+ .checkbox-item:hover {
1553
+ background-color: var(--jp-layout-color1);
1554
+ }
1555
+
1556
+ .checkbox-item:focus-visible {
1557
+ outline: 2px solid var(--jp-brand-color1);
1558
+ outline-offset: 1px;
1559
+ border-radius: 2px;
1560
+ }
1561
+
1562
+ .checkbox-item-indent-0 {
1563
+ padding-left: 0;
1564
+ }
1565
+
1566
+ .checkbox-item-indent-1 {
1567
+ padding-left: 12px;
1568
+ }
1569
+
1570
+ .checkbox-item-indent-2 {
1571
+ padding-left: 24px;
1572
+ }
1573
+
1574
+ .checkbox-item-indent-3 {
1575
+ padding-left: 36px;
1576
+ }
1577
+
1578
+ .checkbox-icon {
1579
+ flex: 0 0 16px;
1580
+ width: 16px;
1581
+ height: 16px;
1582
+ color: var(--jp-brand-color1);
1583
+ padding-top: 1px;
1584
+ }
1585
+
1586
+ .checkbox-item-toggle {
1587
+ display: flex;
1588
+ align-items: center;
1589
+ gap: 5px;
1590
+ margin: 0 2px;
1591
+ padding: 3px 2px;
1592
+ color: var(--jp-ui-font-color1);
1593
+ }
1594
+
1595
+ .checkbox-item-toggle span {
1596
+ min-width: 0;
1597
+ overflow: hidden;
1598
+ text-overflow: ellipsis;
1599
+ white-space: nowrap;
1600
+ }
1601
+
1602
+ .checkbox-item-header .checkbox-item-toggle {
1603
+ color: var(--jp-ui-font-color0);
1604
+ font-weight: bold;
1605
+ }
1606
+
1607
+ .mode-tools-group-built-in {
1608
+ flex-flow: row wrap;
1609
+ }
1610
+
1611
+ .mode-tools-group-built-in .checkbox-item {
1612
+ width: 50%;
1613
+ }
1614
+
1615
+ .mode-tools-group-built-in .checkbox-item-toggle {
1616
+ font-weight: normal;
1617
+ }
1618
+
1619
+ .checkbox-item-description {
1620
+ padding-left: 25px;
1621
+ color: var(--jp-ui-font-color2);
1622
+ padding-bottom: 4px;
1623
+ overflow: hidden;
1624
+ text-overflow: ellipsis;
1625
+ }
1626
+
1627
+ .nbi-settings-panel {
1628
+ display: flex;
1629
+ height: 100%;
1630
+ }
1631
+
1632
+ .nbi-settings-panel-tabs {
1633
+ display: flex;
1634
+ flex-direction: column;
1635
+ padding: 10px;
1636
+ width: 150px;
1637
+
1638
+ /* Hold the column width when a panel renders wide non-wrapping content
1639
+ (e.g. the Skills panel's project-skills filesystem path) — without
1640
+ this, flex-shrink lets the right pane squeeze the sidebar and labels
1641
+ like "Claude MCP" wrap mid-word. */
1642
+ flex-shrink: 0;
1643
+ background-color: var(--jp-layout-color2);
1644
+ }
1645
+
1646
+ .nbi-settings-panel-tab {
1647
+ display: flex;
1648
+ gap: 5px;
1649
+ cursor: pointer;
1650
+ padding: 10px;
1651
+ border-radius: 4px;
1652
+ background: none;
1653
+ border: none;
1654
+ color: inherit;
1655
+ font: inherit;
1656
+ text-align: left;
1657
+ width: 100%;
1658
+ }
1659
+
1660
+ .nbi-settings-panel-tab:hover {
1661
+ background-color: var(--jp-layout-color1);
1662
+ }
1663
+
1664
+ .nbi-settings-panel-tab.active {
1665
+ background-color: var(--jp-layout-color0);
1666
+ font-weight: bold;
1667
+ }
1668
+
1669
+ .nbi-settings-panel-tab:focus-visible {
1670
+ outline: 2px solid var(--jp-brand-color1);
1671
+ outline-offset: -2px;
1672
+ }
1673
+
1674
+ .nbi-settings-panel-tab-content {
1675
+ flex-grow: 1;
1676
+ padding: 20px;
1677
+ overflow-y: auto;
1678
+ }
1679
+
1680
+ .nbi-subtab-bar {
1681
+ display: flex;
1682
+ gap: 4px;
1683
+ border-bottom: 1px solid var(--jp-border-color2);
1684
+ margin-bottom: 16px;
1685
+ }
1686
+
1687
+ .nbi-subtab {
1688
+ cursor: pointer;
1689
+ padding: 8px 16px;
1690
+ border-bottom: 2px solid transparent;
1691
+ border-top: none;
1692
+ border-left: none;
1693
+ border-right: none;
1694
+ color: var(--jp-ui-font-color2);
1695
+ margin-bottom: -1px;
1696
+ background: none;
1697
+ font: inherit;
1698
+ }
1699
+
1700
+ .nbi-subtab:hover {
1701
+ color: var(--jp-ui-font-color1);
1702
+ }
1703
+
1704
+ .nbi-subtab:focus-visible {
1705
+ outline: 2px solid var(--jp-brand-color1);
1706
+ outline-offset: -2px;
1707
+ }
1708
+
1709
+ .nbi-subtab.active {
1710
+ color: var(--jp-ui-font-color1);
1711
+ border-bottom-color: var(--jp-brand-color1);
1712
+ font-weight: bold;
1713
+ }
1714
+
1715
+ .pill-item {
1716
+ cursor: pointer;
1717
+ background-color: var(--jp-layout-color1);
1718
+ display: inline-block;
1719
+ padding: 2px 8px;
1720
+ margin: 2px 4px;
1721
+ border: 1px solid var(--jp-border-color2);
1722
+ border-radius: 10px;
1723
+ font-size: var(--jp-ui-font-size0);
1724
+ color: var(--jp-ui-font-color1);
1725
+ }
1726
+
1727
+ .pill-item:hover {
1728
+ cursor: pointer;
1729
+ background-color: var(--jp-layout-color2);
1730
+ }
1731
+
1732
+ .pill-item.checked {
1733
+ background-color: var(--jp-brand-color3, rgb(68 138 255 / 12%));
1734
+ border-color: var(--jp-brand-color1);
1735
+ color: var(--jp-brand-color0, var(--jp-ui-font-color1));
1736
+ }
1737
+
1738
+ .server-status-indicator {
1739
+ width: 10px;
1740
+ height: 10px;
1741
+ margin: 2px;
1742
+ border-radius: 50%;
1743
+ background-color: var(--jp-brand-color0);
1744
+ }
1745
+
1746
+ .server-status-indicator.connected,
1747
+ .server-status-indicator.updated-tool-list,
1748
+ .server-status-indicator.updated-prompt-list {
1749
+ background-color: var(--jp-success-color1);
1750
+ }
1751
+
1752
+ .server-status-indicator.connecting,
1753
+ .server-status-indicator.disconnecting,
1754
+ .server-status-indicator.updating-tool-list,
1755
+ .server-status-indicator.updating-prompt-list {
1756
+ background-color: var(--jp-warn-color1);
1757
+ }
1758
+
1759
+ .server-status-indicator.not-connected,
1760
+ .server-status-indicator.failed-to-connect {
1761
+ background-color: var(--jp-error-color1);
1762
+ }
1763
+
1764
+ .form-input-dialog-body {
1765
+ width: 500px;
1766
+ }
1767
+
1768
+ .form-input-dialog-body-content-fields {
1769
+ display: flex;
1770
+ flex-direction: column;
1771
+ gap: 10px;
1772
+ }
1773
+
1774
+ .form-input-dialog-body-content-field {
1775
+ display: flex;
1776
+ flex-direction: row;
1777
+ align-items: center;
1778
+ }
1779
+
1780
+ .form-input-dialog-body-content-field-label {
1781
+ width: 50%;
1782
+ }
1783
+
1784
+ .form-input-dialog-body-content-field-input {
1785
+ width: 50%;
1786
+ }
1787
+
1788
+ .mcp-server-prompts .pill-item {
1789
+ cursor: default;
1790
+ }
1791
+
1792
+ .nbi-status-banner {
1793
+ padding: 8px 12px;
1794
+ margin: 4px 8px;
1795
+ border-radius: 4px;
1796
+ background-color: var(--jp-layout-color2);
1797
+ border-left: 3px solid var(--jp-info-color1);
1798
+ color: var(--jp-ui-font-color1);
1799
+ font-size: var(--jp-ui-font-size0);
1800
+ }
1801
+
1802
+ .mcp-server-tools-header,
1803
+ .mcp-server-prompts-header {
1804
+ margin: 5px;
1805
+ font-style: italic;
1806
+ }
1807
+
1808
+ /* ============================================================
1809
+ * Claude Skills panel
1810
+ * ============================================================ */
1811
+
1812
+ .nbi-skills-panel {
1813
+ display: flex;
1814
+ flex-direction: column;
1815
+ gap: 12px;
1816
+ padding: 12px;
1817
+ flex: 1 1 auto;
1818
+ min-height: 0;
1819
+ overflow-y: auto;
1820
+ }
1821
+
1822
+ .nbi-skills-header {
1823
+ display: flex;
1824
+ align-items: center;
1825
+ justify-content: space-between;
1826
+ gap: 8px;
1827
+ }
1828
+
1829
+ .nbi-skills-header-actions {
1830
+ display: flex;
1831
+ gap: 8px;
1832
+ }
1833
+
1834
+ .nbi-skills-title {
1835
+ font-size: var(--jp-ui-font-size2);
1836
+ font-weight: 600;
1837
+ }
1838
+
1839
+ .nbi-skills-error {
1840
+ padding: 8px 12px;
1841
+ border-radius: 4px;
1842
+ background-color: var(--jp-layout-color2);
1843
+ color: var(--jp-ui-font-color1);
1844
+ border-left: 3px solid var(--jp-error-color1, #d32f2f);
1845
+ font-size: var(--jp-ui-font-size1);
1846
+ }
1847
+
1848
+ .nbi-skills-sync-message,
1849
+ .nbi-skills-info-banner,
1850
+ .nbi-info-banner {
1851
+ padding: 6px 12px;
1852
+ border-radius: 4px;
1853
+ background-color: var(--jp-layout-color2);
1854
+ color: var(--jp-ui-font-color1);
1855
+ font-size: var(--jp-ui-font-size1);
1856
+ }
1857
+
1858
+ .nbi-skills-managed-banner {
1859
+ padding: 8px 12px;
1860
+ margin-bottom: 8px;
1861
+ border-radius: 4px;
1862
+ background-color: var(--jp-layout-color2);
1863
+ color: var(--jp-ui-font-color1);
1864
+ border: 1px solid var(--jp-border-color2);
1865
+ font-size: var(--jp-ui-font-size1);
1866
+ }
1867
+
1868
+ .nbi-skills-tracking-row {
1869
+ display: flex;
1870
+ align-items: center;
1871
+ gap: 12px;
1872
+ flex-wrap: wrap;
1873
+ padding: 6px 12px;
1874
+ margin-bottom: 8px;
1875
+ border-radius: 4px;
1876
+ background-color: var(--jp-layout-color1);
1877
+ border: 1px solid var(--jp-border-color2);
1878
+ font-size: var(--jp-ui-font-size1);
1879
+ }
1880
+
1881
+ .nbi-skill-managed-badge,
1882
+ .nbi-skill-tracking-badge {
1883
+ display: inline-block;
1884
+ margin-left: 8px;
1885
+ padding: 1px 6px;
1886
+ border-radius: 10px;
1887
+ color: var(--jp-ui-font-color0);
1888
+ font-size: var(--jp-ui-font-size0);
1889
+ font-weight: 600;
1890
+ vertical-align: middle;
1891
+ text-transform: uppercase;
1892
+ letter-spacing: 0.04em;
1893
+ }
1894
+
1895
+ .nbi-skill-managed-badge {
1896
+ background-color: var(--jp-brand-color3, var(--jp-layout-color3));
1897
+ }
1898
+
1899
+ /* Distinct hue from Managed so the two states are visually obvious at a
1900
+ glance: managed = org-curated, tracking = user-opted-in.
1901
+ `--jp-info-color3` is the closest semantic match in the JupyterLab
1902
+ theme palette and resolves to a visible color in both light and dark
1903
+ themes. */
1904
+ .nbi-skill-tracking-badge {
1905
+ background-color: var(--jp-info-color3, var(--jp-layout-color3));
1906
+ }
1907
+
1908
+ .nbi-skills-section {
1909
+ display: flex;
1910
+ flex-direction: column;
1911
+ gap: 6px;
1912
+ }
1913
+
1914
+ .nbi-skills-section-caption {
1915
+ font-size: var(--jp-ui-font-size1);
1916
+ color: var(--jp-ui-font-color1);
1917
+ font-weight: 600;
1918
+ padding: 4px 0;
1919
+ border-bottom: 1px solid var(--jp-border-color2);
1920
+ }
1921
+
1922
+ .nbi-skills-empty {
1923
+ display: flex;
1924
+ flex-direction: column;
1925
+ align-items: center;
1926
+ gap: 10px;
1927
+ padding: 20px 12px;
1928
+ border: 1px dashed var(--jp-border-color2);
1929
+ border-radius: 4px;
1930
+ color: var(--jp-ui-font-color2);
1931
+ font-size: var(--jp-ui-font-size1);
1932
+ text-align: center;
1933
+ }
1934
+
1935
+ /* stylelint-disable-next-line no-descending-specificity */
1936
+ .nbi-skills-empty code {
1937
+ background-color: var(--jp-layout-color2);
1938
+ padding: 1px 4px;
1939
+ border-radius: 3px;
1940
+ font-size: 0.9em;
1941
+ }
1942
+
1943
+ .nbi-skill-row {
1944
+ display: flex;
1945
+ align-items: flex-start;
1946
+ justify-content: space-between;
1947
+ gap: 8px;
1948
+ padding: 8px 10px;
1949
+ border: 1px solid var(--jp-border-color2);
1950
+ border-radius: 4px;
1951
+ cursor: pointer;
1952
+ background-color: var(--jp-layout-color1);
1953
+ }
1954
+
1955
+ .nbi-skill-row:hover {
1956
+ background-color: var(--jp-layout-color2);
1957
+ }
1958
+
1959
+ /* Highlight the whole row whenever any of its action buttons receives
1960
+ keyboard focus, so a sighted keyboard user can tell which row they're
1961
+ acting on. The row itself isn't focusable any more (the explicit
1962
+ action buttons are); :focus-within bubbles the affordance up from
1963
+ them. */
1964
+ .nbi-skill-row:focus-within {
1965
+ outline: 2px solid var(--jp-brand-color1);
1966
+ outline-offset: -2px;
1967
+ }
1968
+
1969
+ .nbi-skill-row-main {
1970
+ flex: 1 1 auto;
1971
+ min-width: 0;
1972
+ }
1973
+
1974
+ .nbi-skill-row-name {
1975
+ display: flex;
1976
+ align-items: center;
1977
+ gap: 8px;
1978
+ font-weight: 600;
1979
+ font-size: var(--jp-ui-font-size1);
1980
+ }
1981
+
1982
+ .nbi-skill-row-description {
1983
+ margin-top: 2px;
1984
+ color: var(--jp-ui-font-color2);
1985
+ font-size: var(--jp-ui-font-size0);
1986
+ }
1987
+
1988
+ .nbi-skill-row-version {
1989
+ font-weight: 400;
1990
+ color: var(--jp-ui-font-color2);
1991
+ font-size: var(--jp-ui-font-size0);
1992
+ }
1993
+
1994
+ .nbi-skill-row-plugins {
1995
+ overflow: hidden;
1996
+ text-overflow: ellipsis;
1997
+ white-space: nowrap;
1998
+ }
1999
+
2000
+ .nbi-skill-row-disabled {
2001
+ border-style: dashed;
2002
+ }
2003
+
2004
+ .nbi-skill-row-disabled .nbi-skill-row-name {
2005
+ font-style: italic;
2006
+ }
2007
+
2008
+ .nbi-skill-row-badge {
2009
+ display: inline-block;
2010
+ padding: 1px 6px;
2011
+ border-radius: 8px;
2012
+ background-color: var(--jp-layout-color3);
2013
+ color: var(--jp-ui-font-color1);
2014
+ font-weight: 500;
2015
+ font-size: var(--jp-ui-font-size0);
2016
+ text-transform: none;
2017
+ }
2018
+
2019
+ /* Inline row actions (reveal on hover/focus-within) */
2020
+ .nbi-skill-row-actions {
2021
+ flex: 0 0 auto;
2022
+ display: flex;
2023
+ align-items: center;
2024
+ gap: 2px;
2025
+ opacity: 0;
2026
+ transition: opacity 0.1s ease-in-out;
2027
+ }
2028
+
2029
+ /* When a row is disabled-for-workspace, the user needs an immediate way to
2030
+ re-enable it. Override the hover-only reveal so the toggle button is
2031
+ always visible. */
2032
+ .nbi-skill-row-disabled .nbi-skill-row-actions {
2033
+ opacity: 1;
2034
+ }
2035
+
2036
+ .nbi-skill-row:hover .nbi-skill-row-actions,
2037
+ .nbi-skill-row:focus-within .nbi-skill-row-actions {
2038
+ opacity: 1;
2039
+ }
2040
+
2041
+ /* Modal dialog used for rename/duplicate */
2042
+ .nbi-modal-backdrop {
2043
+ position: fixed;
2044
+ inset: 0;
2045
+ background: rgb(0 0 0 / 35%);
2046
+ display: flex;
2047
+ align-items: center;
2048
+ justify-content: center;
2049
+ z-index: 1000;
2050
+ }
2051
+
2052
+ .nbi-modal-card {
2053
+ background-color: var(--jp-layout-color1);
2054
+ border: 1px solid var(--jp-border-color1);
2055
+ border-radius: 6px;
2056
+ box-shadow: 0 4px 16px rgb(0 0 0 / 25%);
2057
+ padding: 16px;
2058
+ min-width: 320px;
2059
+ max-width: 420px;
2060
+ display: flex;
2061
+ flex-direction: column;
2062
+ gap: 12px;
2063
+ }
2064
+
2065
+ .nbi-modal-title {
2066
+ font-size: var(--jp-ui-font-size2);
2067
+ font-weight: 600;
2068
+ }
2069
+
2070
+ .nbi-modal-body {
2071
+ display: flex;
2072
+ flex-direction: column;
2073
+ gap: 10px;
2074
+ }
2075
+
2076
+ .nbi-modal-actions {
2077
+ display: flex;
2078
+ justify-content: flex-end;
2079
+ gap: 8px;
2080
+ }
2081
+
2082
+ .nbi-import-preview {
2083
+ display: flex;
2084
+ flex-direction: column;
2085
+ gap: 6px;
2086
+ padding: 10px;
2087
+ background-color: var(--jp-layout-color2);
2088
+ border: 1px solid var(--jp-border-color2);
2089
+ border-radius: 4px;
2090
+ font-size: var(--jp-ui-font-size1);
2091
+ }
2092
+
2093
+ .nbi-import-preview-row {
2094
+ display: flex;
2095
+ gap: 8px;
2096
+ align-items: baseline;
2097
+ }
2098
+
2099
+ .nbi-import-preview-label {
2100
+ flex: 0 0 90px;
2101
+ color: var(--jp-ui-font-color2);
2102
+ font-size: var(--jp-ui-font-size0);
2103
+ text-transform: uppercase;
2104
+ letter-spacing: 0.04em;
2105
+ }
2106
+
2107
+ .nbi-import-preview-value {
2108
+ flex: 1 1 auto;
2109
+ color: var(--jp-ui-font-color1);
2110
+ word-break: break-word;
2111
+ }
2112
+
2113
+ .nbi-import-preview-source {
2114
+ font-family: var(--jp-code-font-family);
2115
+ font-size: var(--jp-ui-font-size0);
2116
+ color: var(--jp-ui-font-color2);
2117
+ }
2118
+
2119
+ .nbi-checkbox-label {
2120
+ display: flex;
2121
+ gap: 6px;
2122
+ align-items: center;
2123
+ color: var(--jp-ui-font-color1);
2124
+ font-size: var(--jp-ui-font-size1);
2125
+ }
2126
+
2127
+ /* Undo toast */
2128
+ .nbi-undo-toast {
2129
+ position: fixed;
2130
+ bottom: 16px;
2131
+ left: 50%;
2132
+ transform: translateX(-50%);
2133
+ z-index: 1001;
2134
+ display: flex;
2135
+ align-items: center;
2136
+ gap: 12px;
2137
+ padding: 8px 12px;
2138
+ background-color: var(--jp-layout-color2);
2139
+ color: var(--jp-ui-font-color1);
2140
+ border: 1px solid var(--jp-border-color1);
2141
+ border-radius: 4px;
2142
+ box-shadow: 0 2px 8px rgb(0 0 0 / 30%);
2143
+ font-size: var(--jp-ui-font-size1);
2144
+ }
2145
+
2146
+ .nbi-undo-toast-message {
2147
+ flex: 1 1 auto;
2148
+ }
2149
+
2150
+ .nbi-undo-toast-action {
2151
+ background: transparent;
2152
+ border: none;
2153
+ color: var(--jp-brand-color2, #82b1ff);
2154
+ cursor: pointer;
2155
+ font-weight: 600;
2156
+ text-transform: uppercase;
2157
+ padding: 4px 6px;
2158
+ }
2159
+
2160
+ .nbi-undo-toast-action:hover {
2161
+ text-decoration: underline;
2162
+ }
2163
+
2164
+ .nbi-undo-toast-close {
2165
+ background: transparent;
2166
+ border: none;
2167
+ color: inherit;
2168
+ cursor: pointer;
2169
+ font-size: 16px;
2170
+ line-height: 1;
2171
+ padding: 2px 6px;
2172
+ opacity: 0.7;
2173
+ }
2174
+
2175
+ .nbi-undo-toast-close:hover {
2176
+ opacity: 1;
2177
+ }
2178
+
2179
+ /* Editor */
2180
+ .nbi-skill-editor {
2181
+ display: flex;
2182
+ flex-direction: column;
2183
+ gap: 12px;
2184
+ padding: 12px;
2185
+ flex: 1 1 auto;
2186
+ min-height: 0;
2187
+ overflow-y: auto;
2188
+ }
2189
+
2190
+ .nbi-skill-editor-header {
2191
+ display: flex;
2192
+ align-items: center;
2193
+ justify-content: space-between;
2194
+ gap: 12px;
2195
+ }
2196
+
2197
+ .nbi-skill-editor-breadcrumb {
2198
+ display: flex;
2199
+ align-items: baseline;
2200
+ gap: 6px;
2201
+ min-width: 0;
2202
+ font-size: var(--jp-ui-font-size1);
2203
+ }
2204
+
2205
+ .nbi-breadcrumb-link {
2206
+ background: transparent;
2207
+ border: none;
2208
+ padding: 0;
2209
+ color: var(--jp-content-link-color, var(--jp-brand-color1));
2210
+ cursor: pointer;
2211
+ font: inherit;
2212
+ }
2213
+
2214
+ .nbi-breadcrumb-link:hover {
2215
+ text-decoration: underline;
2216
+ }
2217
+
2218
+ .nbi-breadcrumb-separator {
2219
+ color: var(--jp-ui-font-color2);
2220
+ }
2221
+
2222
+ .nbi-breadcrumb-current {
2223
+ font-weight: 600;
2224
+ color: var(--jp-ui-font-color1);
2225
+ overflow: hidden;
2226
+ text-overflow: ellipsis;
2227
+ white-space: nowrap;
2228
+ min-width: 0;
2229
+ }
2230
+
2231
+ .nbi-skill-editor-actions {
2232
+ display: flex;
2233
+ gap: 8px;
2234
+ flex-shrink: 0;
2235
+ }
2236
+
2237
+ .nbi-skill-editor-actions .jp-Dialog-button.jp-mod-accept:not(:disabled) {
2238
+ background-color: var(--jp-brand-color1);
2239
+ color: #fff;
2240
+ border-color: var(--jp-brand-color1);
2241
+ font-weight: 600;
2242
+ }
2243
+
2244
+ .nbi-skill-editor-actions .jp-Dialog-button:disabled,
2245
+ .nbi-skills-header .jp-Dialog-button:disabled {
2246
+ opacity: 0.45;
2247
+ cursor: not-allowed;
2248
+ }
2249
+
2250
+ .nbi-dirty-marker {
2251
+ display: inline-block;
2252
+ width: 6px;
2253
+ height: 6px;
2254
+ margin-left: 6px;
2255
+ border-radius: 50%;
2256
+ background-color: var(--jp-warn-color1, #f57c00);
2257
+ vertical-align: middle;
2258
+ font-size: 0;
2259
+ line-height: 0;
2260
+ }
2261
+
2262
+ .nbi-skill-editor-loading {
2263
+ padding: 20px;
2264
+ text-align: center;
2265
+ color: var(--jp-ui-font-color2);
2266
+ }
2267
+
2268
+ .nbi-skill-editor-meta {
2269
+ display: flex;
2270
+ flex-direction: column;
2271
+ gap: 16px;
2272
+ padding: 16px;
2273
+ background-color: var(--jp-layout-color1);
2274
+ border: 1px solid var(--jp-border-color2);
2275
+ border-radius: 6px;
2276
+ margin-bottom: 12px;
2277
+ }
2278
+
2279
+ .nbi-form-row {
2280
+ display: flex;
2281
+ flex-direction: column;
2282
+ gap: 4px;
2283
+ }
2284
+
2285
+ .nbi-form-row-inline {
2286
+ display: flex;
2287
+ gap: 12px;
2288
+ flex-wrap: wrap;
2289
+ }
2290
+
2291
+ .nbi-form-field {
2292
+ display: flex;
2293
+ flex-direction: column;
2294
+ gap: 6px;
2295
+ flex: 1 1 0;
2296
+ min-width: 140px;
2297
+ }
2298
+
2299
+ .nbi-form-field-wide {
2300
+ width: 100%;
2301
+ }
2302
+
2303
+ .nbi-form-field label {
2304
+ font-size: var(--jp-ui-font-size1);
2305
+ color: var(--jp-ui-font-color1);
2306
+ font-weight: 500;
2307
+ }
2308
+
2309
+ .nbi-form-field input,
2310
+ .nbi-form-field select,
2311
+ .nbi-form-field textarea {
2312
+ width: 100%;
2313
+ box-sizing: border-box;
2314
+ padding: 6px 8px;
2315
+ border: 1px solid var(--jp-border-color1);
2316
+ border-radius: 3px;
2317
+ background-color: var(--jp-input-background, var(--jp-layout-color1));
2318
+ color: var(--jp-ui-font-color1);
2319
+ font-size: var(--jp-ui-font-size1);
2320
+ font-family: inherit;
2321
+ }
2322
+
2323
+ .nbi-form-field textarea {
2324
+ resize: vertical;
2325
+ }
2326
+
2327
+ .nbi-form-field input[aria-invalid='true'] {
2328
+ border-color: var(--jp-error-color1, #d32f2f);
2329
+ }
2330
+
2331
+ .nbi-form-field input:disabled,
2332
+ .nbi-form-field select:disabled {
2333
+ background-color: var(--jp-layout-color2);
2334
+ color: var(--jp-ui-font-color2);
2335
+ border-color: var(--jp-border-color2);
2336
+ cursor: not-allowed;
2337
+ }
2338
+
2339
+ .nbi-form-field input:focus,
2340
+ .nbi-form-field select:focus,
2341
+ .nbi-form-field textarea:focus {
2342
+ outline: none;
2343
+ border-color: var(--jp-brand-color1);
2344
+ box-shadow: 0 0 0 1px var(--jp-brand-color1);
2345
+ }
2346
+
2347
+ .nbi-segmented-control {
2348
+ display: inline-flex;
2349
+ border: 1px solid var(--jp-border-color1);
2350
+ border-radius: 3px;
2351
+ overflow: hidden;
2352
+ align-self: flex-start;
2353
+ }
2354
+
2355
+ .nbi-segmented-control-option {
2356
+ background: var(--jp-layout-color1);
2357
+ color: var(--jp-ui-font-color1);
2358
+ border: none;
2359
+ padding: 6px 14px;
2360
+ font-size: var(--jp-ui-font-size1);
2361
+ font-family: inherit;
2362
+ cursor: pointer;
2363
+ }
2364
+
2365
+ .nbi-segmented-control-option + .nbi-segmented-control-option {
2366
+ border-left: 1px solid var(--jp-border-color1);
2367
+ }
2368
+
2369
+ .nbi-segmented-control-option:hover {
2370
+ background: var(--jp-layout-color2);
2371
+ }
2372
+
2373
+ .nbi-segmented-control-option.is-active {
2374
+ background: var(--jp-brand-color1);
2375
+ color: var(--jp-ui-inverse-font-color1, #fff);
2376
+ }
2377
+
2378
+ .nbi-segmented-control-option:focus-visible {
2379
+ outline: 2px solid var(--jp-brand-color1);
2380
+ outline-offset: -2px;
2381
+ }
2382
+
2383
+ .nbi-form-field-error {
2384
+ font-size: var(--jp-ui-font-size0);
2385
+ color: var(--jp-error-color1, #d32f2f);
2386
+ }
2387
+
2388
+ .nbi-form-hint {
2389
+ font-size: var(--jp-ui-font-size0);
2390
+ color: var(--jp-ui-font-color2);
2391
+ }
2392
+
2393
+ /* stylelint-disable-next-line no-descending-specificity */
2394
+ .nbi-form-hint code {
2395
+ background-color: var(--jp-layout-color2);
2396
+ padding: 1px 4px;
2397
+ border-radius: 3px;
2398
+ font-size: 0.9em;
2399
+ }
2400
+
2401
+ /* Tools picker */
2402
+ .nbi-tools-picker-input {
2403
+ display: flex;
2404
+ flex-wrap: wrap;
2405
+ gap: 4px;
2406
+ padding: 4px 6px;
2407
+ border: 1px solid var(--jp-border-color1);
2408
+ border-radius: 3px;
2409
+ background-color: var(--jp-input-background, var(--jp-layout-color1));
2410
+ min-height: 30px;
2411
+ align-items: center;
2412
+ }
2413
+
2414
+ .nbi-tools-picker-input:focus-within {
2415
+ outline: none;
2416
+ border-color: var(--jp-brand-color1);
2417
+ box-shadow: 0 0 0 1px var(--jp-brand-color1);
2418
+ }
2419
+
2420
+ /* stylelint-disable-next-line no-descending-specificity */
2421
+ .nbi-tools-picker-input input {
2422
+ flex: 1 1 100px;
2423
+ min-width: 100px;
2424
+ border: none;
2425
+ outline: none;
2426
+ background: transparent;
2427
+ color: var(--jp-ui-font-color1);
2428
+ font-size: var(--jp-ui-font-size1);
2429
+ padding: 2px 4px;
2430
+ }
2431
+
2432
+ .nbi-pill-remove {
2433
+ background: transparent;
2434
+ border: none;
2435
+ cursor: pointer;
2436
+ margin-left: 4px;
2437
+ padding: 0 2px;
2438
+ color: inherit;
2439
+ font-size: 1em;
2440
+ line-height: 1;
2441
+ }
2442
+
2443
+ .nbi-pill-remove:hover {
2444
+ color: var(--jp-error-color1, #d32f2f);
2445
+ }
2446
+
2447
+ .nbi-tools-picker-suggestions {
2448
+ display: flex;
2449
+ flex-wrap: wrap;
2450
+ gap: 4px;
2451
+ margin-top: 6px;
2452
+ }
2453
+
2454
+ .nbi-tools-picker-suggestions .pill-item {
2455
+ cursor: pointer;
2456
+ }
2457
+
2458
+ /* Editor body */
2459
+ .nbi-skill-editor-body {
2460
+ display: flex;
2461
+ flex-direction: column;
2462
+ gap: 8px;
2463
+ }
2464
+
2465
+ .nbi-skill-editor-pane {
2466
+ flex: 1 1 auto;
2467
+ min-width: 0;
2468
+ display: flex;
2469
+ flex-direction: column;
2470
+ }
2471
+
2472
+ /* File tab strip */
2473
+ .nbi-skill-editor-tabs {
2474
+ display: flex;
2475
+ flex-wrap: wrap;
2476
+ align-items: center;
2477
+ gap: 4px;
2478
+ padding: 4px 0;
2479
+ margin-bottom: 8px;
2480
+ }
2481
+
2482
+ .nbi-skill-editor-tab {
2483
+ display: flex;
2484
+ align-items: center;
2485
+ gap: 4px;
2486
+ padding: 4px 10px;
2487
+ border: 1px solid var(--jp-border-color2);
2488
+ border-radius: 4px;
2489
+ background-color: var(--jp-layout-color1);
2490
+ color: var(--jp-ui-font-color2);
2491
+ font-family: var(--jp-code-font-family, monospace);
2492
+ font-size: var(--jp-ui-font-size0);
2493
+ cursor: pointer;
2494
+ white-space: nowrap;
2495
+ flex-shrink: 0;
2496
+ }
2497
+
2498
+ .nbi-skill-editor-tab:hover {
2499
+ background-color: var(--jp-layout-color2);
2500
+ color: var(--jp-ui-font-color1);
2501
+ }
2502
+
2503
+ .nbi-skill-editor-tab.active {
2504
+ background-color: var(--jp-brand-color3, rgb(68 138 255 / 12%));
2505
+ border-color: var(--jp-brand-color1);
2506
+ color: var(--jp-brand-color0, var(--jp-ui-font-color1));
2507
+ font-weight: 600;
2508
+ }
2509
+
2510
+ .nbi-skill-editor-tab-label {
2511
+ overflow: hidden;
2512
+ text-overflow: ellipsis;
2513
+ max-width: 200px;
2514
+ }
2515
+
2516
+ .nbi-skill-editor-tab-kebab-wrap {
2517
+ position: relative;
2518
+ display: flex;
2519
+ }
2520
+
2521
+ .nbi-skill-editor-tab-menu {
2522
+ position: absolute;
2523
+ top: 100%;
2524
+ right: 0;
2525
+ z-index: 10;
2526
+ display: flex;
2527
+ flex-direction: column;
2528
+ min-width: 120px;
2529
+ background-color: var(--jp-layout-color1);
2530
+ border: 1px solid var(--jp-border-color1);
2531
+ border-radius: 3px;
2532
+ box-shadow: 0 2px 6px rgb(0 0 0 / 15%);
2533
+ padding: 4px 0;
2534
+ }
2535
+
2536
+ .nbi-skill-editor-tab-menu button {
2537
+ background: transparent;
2538
+ border: none;
2539
+ padding: 6px 12px;
2540
+ text-align: left;
2541
+ cursor: pointer;
2542
+ color: var(--jp-ui-font-color1);
2543
+ font-size: var(--jp-ui-font-size1);
2544
+ font-family: inherit;
2545
+ }
2546
+
2547
+ .nbi-skill-editor-tab-menu button:hover {
2548
+ background-color: var(--jp-layout-color2);
2549
+ }
2550
+
2551
+ .nbi-skill-editor-tab-menu button.danger:hover {
2552
+ background-color: var(--jp-error-color3, rgb(230 100 100 / 20%));
2553
+ color: var(--jp-error-color1, #d32f2f);
2554
+ }
2555
+
2556
+ .nbi-skill-editor-tab-rename-input {
2557
+ padding: 2px 6px;
2558
+ border: 1px solid var(--jp-brand-color1);
2559
+ border-radius: 3px;
2560
+ background-color: var(--jp-input-background, var(--jp-layout-color1));
2561
+ color: var(--jp-ui-font-color1);
2562
+ font-family: var(--jp-code-font-family, monospace);
2563
+ font-size: var(--jp-ui-font-size0);
2564
+ min-width: 120px;
2565
+ }
2566
+
2567
+ .nbi-skill-editor-tab-add {
2568
+ background: transparent;
2569
+ border: 1px solid var(--jp-border-color2);
2570
+ border-radius: 4px;
2571
+ color: var(--jp-ui-font-color2);
2572
+ cursor: pointer;
2573
+ padding: 4px 10px;
2574
+ font-size: var(--jp-ui-font-size1);
2575
+ line-height: 1;
2576
+ flex-shrink: 0;
2577
+ }
2578
+
2579
+ .nbi-skill-editor-tab-add:hover {
2580
+ background-color: var(--jp-layout-color2);
2581
+ color: var(--jp-ui-font-color1);
2582
+ }
2583
+
2584
+ .nbi-skill-editor-textarea {
2585
+ width: 100%;
2586
+ box-sizing: border-box;
2587
+ padding: 8px;
2588
+ border: 1px solid var(--jp-border-color1);
2589
+ border-radius: 3px;
2590
+ background-color: var(--jp-input-background, var(--jp-layout-color1));
2591
+ color: var(--jp-ui-font-color1);
2592
+ font-family: var(--jp-code-font-family, monospace);
2593
+ font-size: var(--jp-code-font-size, var(--jp-ui-font-size1));
2594
+ line-height: 1.5;
2595
+ resize: none;
2596
+ overflow: hidden;
2597
+ min-height: 200px;
2598
+ }
2599
+
2600
+ .nbi-icon-button {
2601
+ background: transparent;
2602
+ border: none;
2603
+ cursor: pointer;
2604
+ padding: 2px 6px;
2605
+ border-radius: 3px;
2606
+ color: var(--jp-ui-font-color1);
2607
+ font-size: var(--jp-ui-font-size1);
2608
+ line-height: 1;
2609
+ display: inline-flex;
2610
+ align-items: center;
2611
+ justify-content: center;
2612
+ }
2613
+
2614
+ .nbi-icon-button:hover {
2615
+ background-color: var(--jp-layout-color3);
2616
+ }
2617
+
2618
+ /* The rename action has no obvious icon, so it falls back to a short
2619
+ text glyph ("Aa") rendered with the same vertical metrics as the SVG
2620
+ icons so the row stays visually balanced. */
2621
+ .nbi-icon-button-text {
2622
+ font-weight: 600;
2623
+ font-size: 12px;
2624
+ line-height: 1;
2625
+ }
2626
+
2627
+ /* Destructive action: the icon-only delete button signals risk through
2628
+ color + a hover border. Color alone is a WCAG 1.4.1 issue (color is
2629
+ not the only signal); the rest border + focus ring together give a
2630
+ non-color affordance. */
2631
+ .nbi-icon-button.danger {
2632
+ color: var(--jp-error-color1, #d32f2f);
2633
+ }
2634
+
2635
+ .nbi-icon-button.danger:hover {
2636
+ background-color: var(--jp-error-color3, rgb(230 100 100 / 20%));
2637
+ color: var(--jp-error-color1, #d32f2f);
2638
+ outline: 1px solid var(--jp-error-color1, #d32f2f);
2639
+ }
2640
+
2641
+ .nbi-icon-button:disabled {
2642
+ opacity: 0.4;
2643
+ cursor: not-allowed;
2644
+ }
2645
+
2646
+ .nbi-breadcrumb-link:focus-visible,
2647
+ .nbi-skill-editor-tab:focus-visible,
2648
+ .nbi-skill-editor-tab-add:focus-visible,
2649
+ .nbi-pill-remove:focus-visible,
2650
+ .pill-item:focus-visible,
2651
+ .nbi-icon-button:focus-visible {
2652
+ outline: 2px solid var(--jp-brand-color1);
2653
+ outline-offset: 1px;
2654
+ }
2655
+
2656
+ .nbi-icon-button:disabled:hover {
2657
+ background-color: transparent;
2658
+ }
2659
+
2660
+ .config-dialog-body a {
2661
+ color: var(--jp-content-link-color);
2662
+ }
2663
+
2664
+ .chat-mode-widgets-container .claude-icon svg {
2665
+ margin-top: 4px;
2666
+ width: 18px;
2667
+ height: 18px;
2668
+ }
2669
+
2670
+ .chat-confirmation-form.ask-user-question {
2671
+ display: flex;
2672
+ flex-direction: column;
2673
+ }
2674
+
2675
+ .ask-user-question-container {
2676
+ padding: 10px;
2677
+ display: flex;
2678
+ flex-direction: column;
2679
+ gap: 10px;
2680
+ border-bottom: 1px solid var(--jp-border-color1);
2681
+ }
2682
+
2683
+ .ask-user-question .ask-user-question-container:nth-last-child(-n + 2) {
2684
+ border-bottom: none;
2685
+ }
2686
+
2687
+ .ask-user-question-form {
2688
+ display: flex;
2689
+ flex-direction: column;
2690
+ gap: 5px;
2691
+ }
2692
+
2693
+ .ask-user-question-question {
2694
+ font-weight: bold;
2695
+ }
2696
+
2697
+ .ask-user-question-header {
2698
+ font-style: italic;
2699
+ }
2700
+
2701
+ .ask-user-question-options {
2702
+ display: flex;
2703
+ flex-direction: column;
2704
+ }
2705
+
2706
+ .ask-user-question-option {
2707
+ display: flex;
2708
+ flex-direction: column;
2709
+ }
2710
+
2711
+ .ask-user-question-option-input-container {
2712
+ display: flex;
2713
+ flex-direction: row;
2714
+ align-items: center;
2715
+ gap: 5px;
2716
+ }
2717
+
2718
+ /* stylelint-disable-next-line no-descending-specificity */
2719
+ .ask-user-question-option-input-container input {
2720
+ transform: scale(1.25);
2721
+ }
2722
+
2723
+ .ask-user-question-option-label-container {
2724
+ width: calc(100% - 15px);
2725
+ margin-left: 2px;
2726
+ display: flex;
2727
+ flex-direction: column;
2728
+ }
2729
+
2730
+ .ask-user-question-option-label {
2731
+ font-weight: bold;
2732
+ }
2733
+
2734
+ .ask-user-question-option-description {
2735
+ color: var(--jp-ui-font-color2);
2736
+ padding-bottom: 4px;
2737
+ overflow: hidden;
2738
+ text-overflow: ellipsis;
2739
+ white-space: nowrap;
2740
+ }
2741
+
2742
+ .ask-user-question-footer {
2743
+ padding: 0 0 5px 10px;
2744
+ }
2745
+
2746
+ .claude-mode-config-dialog .form-field-description {
2747
+ color: var(--jp-ui-font-color1);
2748
+ }
2749
+
2750
+ .claude-session-picker-list {
2751
+ list-style: none;
2752
+ margin: 0;
2753
+ padding: 0;
2754
+ overflow-y: auto;
2755
+ }
2756
+
2757
+ .claude-session-picker-item {
2758
+ padding: 6px 8px;
2759
+ border-bottom: 1px solid var(--jp-border-color2);
2760
+ cursor: pointer;
2761
+ }
2762
+
2763
+ .claude-session-picker-item:hover {
2764
+ background-color: var(--jp-layout-color1);
2765
+ }
2766
+
2767
+ .claude-session-picker-item.busy {
2768
+ opacity: 0.6;
2769
+ pointer-events: none;
2770
+ }
2771
+
2772
+ .claude-session-picker-item-preview {
2773
+ color: var(--jp-ui-font-color1);
2774
+ font-size: var(--jp-ui-font-size1);
2775
+ margin-bottom: 4px;
2776
+ overflow: hidden;
2777
+ text-overflow: ellipsis;
2778
+ display: -webkit-box;
2779
+ -webkit-line-clamp: 2;
2780
+ -webkit-box-orient: vertical;
2781
+ }
2782
+
2783
+ .claude-session-picker-item-meta {
2784
+ color: var(--jp-ui-font-color2);
2785
+ font-size: var(--jp-ui-font-size0);
2786
+ display: flex;
2787
+ align-items: center;
2788
+ gap: 6px;
2789
+ flex-wrap: wrap;
2790
+ }
2791
+
2792
+ .claude-session-picker-item-id {
2793
+ flex-grow: 1;
2794
+ text-align: right;
2795
+ font-family: var(--jp-code-font-family);
2796
+ }
2797
+
2798
+ .claude-session-picker-item-copy {
2799
+ display: inline-flex;
2800
+ align-items: center;
2801
+ justify-content: center;
2802
+ background: transparent;
2803
+ border: 1px solid transparent;
2804
+ border-radius: 3px;
2805
+ color: var(--jp-ui-font-color2);
2806
+ cursor: pointer;
2807
+ padding: 2px 4px;
2808
+ margin-left: 2px;
2809
+ line-height: 1;
2810
+ }
2811
+
2812
+ .claude-session-picker-item-copy:hover,
2813
+ .claude-session-picker-item-copy:focus-visible {
2814
+ background-color: var(--jp-layout-color2);
2815
+ color: var(--jp-ui-font-color1);
2816
+ border-color: var(--jp-border-color2);
2817
+ outline: none;
2818
+ }
2819
+
2820
+ .claude-session-picker-item-copy.copied {
2821
+ color: var(--jp-success-color1, var(--jp-ui-font-color1));
2822
+ }
2823
+
2824
+ .claude-session-picker-item-copy.failed {
2825
+ color: var(--jp-error-color1, var(--jp-ui-font-color1));
2826
+ }
2827
+
2828
+ /* Hover toolbar over notebook cell outputs (Explain / Ask / Troubleshoot). */
2829
+ .jp-Cell-outputArea {
2830
+ position: relative;
2831
+ }
2832
+
2833
+ .nbi-cell-output-toolbar {
2834
+ position: absolute;
2835
+ top: 0;
2836
+ right: 8px;
2837
+ display: flex;
2838
+ gap: 2px;
2839
+ background-color: var(--jp-layout-color1);
2840
+ border: 1px solid var(--jp-border-color2);
2841
+ border-radius: 4px;
2842
+ box-shadow: 0 1px 2px rgb(0 0 0 / 8%);
2843
+ z-index: 10;
2844
+ }
2845
+
2846
+ .nbi-cell-output-toolbar-button {
2847
+ display: inline-flex;
2848
+ align-items: center;
2849
+ gap: 4px;
2850
+ padding: 2px 6px;
2851
+ background: transparent;
2852
+ border: none;
2853
+ border-radius: 3px;
2854
+ color: var(--jp-ui-font-color1);
2855
+ font-size: var(--jp-ui-font-size0);
2856
+ font-family: var(--jp-ui-font-family);
2857
+ cursor: pointer;
2858
+ }
2859
+
2860
+ .nbi-cell-output-toolbar-button:hover {
2861
+ background-color: var(--jp-layout-color2);
2862
+ }
2863
+
2864
+ .nbi-cell-output-toolbar-button:focus-visible {
2865
+ outline: 1px solid var(--jp-brand-color1);
2866
+ outline-offset: 1px;
2867
+ }
2868
+
2869
+ .nbi-cell-output-toolbar .nbi-cell-output-toolbar-button svg {
2870
+ width: 14px;
2871
+ height: 14px;
2872
+ flex-shrink: 0;
2873
+ }
2874
+
2875
+ .nbi-cell-output-toolbar-button-label {
2876
+ white-space: nowrap;
2877
+ }
2878
+
2879
+ /* Notebook generation toolbar button + popover */
2880
+ .nbi-notebook-generation-toolbar-button .jp-ToolbarButtonComponent {
2881
+ background-color: transparent;
2882
+ }
2883
+
2884
+ .nbi-notebook-generation-toolbar-button .jp-icon3[fill] {
2885
+ fill: var(--jp-brand-color1);
2886
+ }
2887
+
2888
+ .nbi-notebook-generation-popover-host {
2889
+ display: block;
2890
+ pointer-events: auto;
2891
+ }
2892
+
2893
+ .notebook-generation-popover {
2894
+ display: flex;
2895
+ flex-direction: column;
2896
+ background-color: var(--jp-layout-color1);
2897
+ border: 1px solid var(--jp-border-color1);
2898
+ box-shadow: 0 4px 12px rgb(0 0 0 / 18%);
2899
+ border-radius: 4px;
2900
+ overflow: hidden;
2901
+ }
2902
+
2903
+ .notebook-generation-popover-header {
2904
+ display: flex;
2905
+ align-items: center;
2906
+ gap: 6px;
2907
+ height: 28px;
2908
+ padding: 2px 6px;
2909
+ background-color: var(--jp-layout-color2);
2910
+ border-bottom: 1px solid var(--jp-border-color2);
2911
+ }
2912
+
2913
+ .notebook-generation-popover-header-icon {
2914
+ display: flex;
2915
+ align-items: center;
2916
+ color: var(--jp-brand-color1);
2917
+ }
2918
+
2919
+ .notebook-generation-popover .notebook-generation-popover-header-icon svg {
2920
+ width: 16px;
2921
+ height: 16px;
2922
+ }
2923
+
2924
+ .notebook-generation-popover-title {
2925
+ font-weight: bold;
2926
+ color: var(--jp-ui-font-color1);
2927
+ }
2928
+
2929
+ .notebook-generation-popover-close-button {
2930
+ display: flex;
2931
+ align-items: center;
2932
+ justify-content: center;
2933
+ width: 22px;
2934
+ height: 22px;
2935
+ cursor: pointer;
2936
+ color: var(--jp-ui-font-color2);
2937
+ background: none;
2938
+ border: none;
2939
+ padding: 0;
2940
+ font: inherit;
2941
+ }
2942
+
2943
+ .notebook-generation-popover-close-button:hover {
2944
+ color: var(--jp-ui-font-color0);
2945
+ background-color: var(--jp-layout-color3);
2946
+ border-radius: 2px;
2947
+ }
2948
+
2949
+ .notebook-generation-popover-close-button:focus-visible {
2950
+ outline: 2px solid var(--jp-brand-color1);
2951
+ outline-offset: 1px;
2952
+ }
2953
+
2954
+ .notebook-generation-popover-body {
2955
+ display: flex;
2956
+ flex-direction: column;
2957
+ gap: 8px;
2958
+ padding: 10px;
2959
+ }
2960
+
2961
+ .notebook-generation-popover-input {
2962
+ width: 100%;
2963
+ box-sizing: border-box;
2964
+ background-color: var(--jp-layout-color0);
2965
+ color: var(--jp-ui-font-color1);
2966
+ border: 1px solid var(--jp-border-color1);
2967
+ font-family: var(--jp-ui-font-family);
2968
+ font-size: var(--jp-ui-font-size1);
2969
+ padding: 6px 8px;
2970
+ outline: none;
2971
+ resize: vertical;
2972
+ min-height: 64px;
2973
+ }
2974
+
2975
+ .notebook-generation-popover-input:focus {
2976
+ border-color: var(--jp-brand-color1);
2977
+ }
2978
+
2979
+ .notebook-generation-popover-actions {
2980
+ display: flex;
2981
+ justify-content: flex-end;
2982
+ }
2983
+
2984
+ .notebook-generation-popover-submit {
2985
+ display: inline-flex;
2986
+ align-items: center;
2987
+ gap: 4px;
2988
+ background-color: var(--jp-brand-color1);
2989
+ color: white;
2990
+ border: none;
2991
+ border-radius: 2px;
2992
+ padding: 5px 10px;
2993
+ cursor: pointer;
2994
+ font-family: var(--jp-ui-font-family);
2995
+ font-size: var(--jp-ui-font-size1);
2996
+ }
2997
+
2998
+ .notebook-generation-popover-submit:disabled {
2999
+ opacity: 0.5;
3000
+ cursor: not-allowed;
3001
+ }
3002
+
3003
+ .notebook-generation-popover .notebook-generation-popover-submit svg {
3004
+ width: 14px;
3005
+ height: 14px;
3006
+ }
3007
+
3008
+ .nbi-notebook-generation-status {
3009
+ display: inline-flex;
3010
+ align-items: center;
3011
+ margin-left: 8px;
3012
+ padding: 2px 8px;
3013
+ border-radius: 10px;
3014
+ background-color: var(--jp-brand-color3);
3015
+ color: var(--jp-brand-color0);
3016
+ font-size: var(--jp-ui-font-size0);
3017
+ white-space: nowrap;
3018
+ }
3019
+
3020
+ .nbi-terminal-drag-mode-button {
3021
+ display: inline-flex;
3022
+ align-items: center;
3023
+ }
3024
+
3025
+ .nbi-terminal-drag-mode-button-toggle {
3026
+ min-width: 24px;
3027
+ height: 24px;
3028
+ padding: 0 6px;
3029
+ border: 1px solid transparent;
3030
+ border-radius: 2px;
3031
+ background: transparent;
3032
+ color: var(--jp-ui-font-color1);
3033
+ font-family: var(--jp-ui-font-family);
3034
+ font-size: var(--jp-ui-font-size1);
3035
+ cursor: pointer;
3036
+ }
3037
+
3038
+ .nbi-terminal-drag-mode-button-toggle:hover {
3039
+ background-color: var(--jp-layout-color2);
3040
+ }
3041
+
3042
+ .nbi-terminal-drag-mode-button-toggle:focus-visible {
3043
+ outline: 2px solid var(--jp-brand-color1);
3044
+ outline-offset: 1px;
3045
+ }
3046
+
3047
+ .nbi-terminal-drag-mode-button-toggle[aria-pressed='true'] {
3048
+ border-color: var(--jp-brand-color1);
3049
+ color: var(--jp-brand-color1);
3050
+ }
3051
+
3052
+ .nbi-terminal-drag-over {
3053
+ position: relative;
3054
+ }
3055
+
3056
+ .nbi-terminal-drag-over::after {
3057
+ content: '';
3058
+ position: absolute;
3059
+ inset: 0;
3060
+ pointer-events: none;
3061
+ border: 2px dashed var(--jp-brand-color1);
3062
+ border-radius: 4px;
3063
+ background-color: color-mix(in srgb, var(--jp-brand-color1) 12%, transparent);
3064
+ z-index: 100;
3065
+ }
3066
+
3067
+ /* Set Claude Code launcher title color to Anthropic orange */
3068
+ .jp-LauncherCard-icon svg[data-icon='notebook-intelligence:claude-icon'] {
3069
+ color: #d97757;
3070
+ }
3071
+
3072
+ /* Set Codex launcher icon color to OpenAI blue */
3073
+ .jp-LauncherCard-icon svg[data-icon='notebook-intelligence:openai-icon'] {
3074
+ color: #0a84ff;
3075
+ }
3076
+
3077
+ /* Set Claude Code launcher category icon to sparkles.svg */
3078
+ .jp-Launcher-sectionHeader svg[data-icon='notebook-intelligence:claude-icon'] {
3079
+ /* Use sparkles.svg from the project assets via a mask + background-image trick */
3080
+ mask: url('../style/icons/sparkles.svg') no-repeat center / contain;
3081
+ -webkit-mask: url('../style/icons/sparkles.svg') no-repeat center / contain;
3082
+ background-color: currentcolor;
3083
+
3084
+ /* Hide the default SVG fill to show only the masked shape */
3085
+ fill: transparent;
3086
+ color: var(--jp-brand-color1);
3087
+ }
3088
+
3089
+ /* First-run tour overlay. Rendered into document.body via portal so
3090
+ it floats above the entire JupyterLab UI, not just the sidebar.
3091
+ JupyterLab uses z-index 10000 for dialogs / command palette /
3092
+ menus and 10001 for the completer and active menubar item; sit one
3093
+ above so the tour reliably covers any concurrent JupyterLab UI
3094
+ layer the user might pop while the tour is visible. */
3095
+ .nbi-tour-root {
3096
+ position: fixed;
3097
+ inset: 0;
3098
+ z-index: 10002;
3099
+ pointer-events: none;
3100
+ }
3101
+
3102
+ .nbi-tour-scrim {
3103
+ position: absolute;
3104
+ inset: 0;
3105
+ background: rgb(0 0 0 / 45%);
3106
+ pointer-events: auto;
3107
+ }
3108
+
3109
+ .nbi-tour-spotlight {
3110
+ position: absolute;
3111
+ border-radius: 6px;
3112
+
3113
+ /* Theme-aware ring via the JupyterLab brand color. A solid scrim
3114
+ "wall" (outer box-shadow) cuts the dimming hole around the
3115
+ anchor, then the inner ring draws the brand accent so the
3116
+ spotlight reads on both light and dark themes. */
3117
+ box-shadow:
3118
+ 0 0 0 3px var(--jp-brand-color1, rgb(33 150 243 / 80%)),
3119
+ 0 0 0 9999px rgb(0 0 0 / 45%);
3120
+ pointer-events: none;
3121
+ }
3122
+
3123
+ .nbi-tour-tooltip {
3124
+ position: absolute;
3125
+ pointer-events: auto;
3126
+ background: var(--jp-layout-color1);
3127
+ color: var(--jp-content-font-color1);
3128
+ border: 1px solid var(--jp-border-color2);
3129
+ border-radius: 8px;
3130
+ padding: 16px;
3131
+ box-shadow: 0 8px 24px rgb(0 0 0 / 25%);
3132
+ font-size: var(--jp-ui-font-size1);
3133
+ }
3134
+
3135
+ /* CSS-triangle arrow pointing from the tooltip toward the anchor. The
3136
+ direction class encodes "tooltip is on the SIDE of the anchor", so
3137
+ .nbi-tour-arrow-top (tooltip above anchor) puts the arrow at the
3138
+ bottom edge pointing down. */
3139
+ .nbi-tour-arrow {
3140
+ position: absolute;
3141
+ width: 0;
3142
+ height: 0;
3143
+ border-style: solid;
3144
+ }
3145
+
3146
+ .nbi-tour-arrow-top {
3147
+ bottom: -8px;
3148
+ left: 50%;
3149
+ transform: translateX(-50%);
3150
+ border-width: 8px 8px 0;
3151
+ border-color: var(--jp-layout-color1) transparent transparent transparent;
3152
+ filter: drop-shadow(0 1px 0 var(--jp-border-color2));
3153
+ }
3154
+
3155
+ .nbi-tour-arrow-bottom {
3156
+ top: -8px;
3157
+ left: 50%;
3158
+ transform: translateX(-50%);
3159
+ border-width: 0 8px 8px;
3160
+ border-color: transparent transparent var(--jp-layout-color1) transparent;
3161
+ filter: drop-shadow(0 -1px 0 var(--jp-border-color2));
3162
+ }
3163
+
3164
+ .nbi-tour-arrow-left {
3165
+ right: -8px;
3166
+ top: 50%;
3167
+ transform: translateY(-50%);
3168
+ border-width: 8px 0 8px 8px;
3169
+ border-color: transparent transparent transparent var(--jp-layout-color1);
3170
+ filter: drop-shadow(1px 0 0 var(--jp-border-color2));
3171
+ }
3172
+
3173
+ .nbi-tour-arrow-right {
3174
+ left: -8px;
3175
+ top: 50%;
3176
+ transform: translateY(-50%);
3177
+ border-width: 8px 8px 8px 0;
3178
+ border-color: transparent var(--jp-layout-color1) transparent transparent;
3179
+ filter: drop-shadow(-1px 0 0 var(--jp-border-color2));
3180
+ }
3181
+
3182
+ .nbi-tour-progress {
3183
+ position: relative;
3184
+ height: 4px;
3185
+ background: var(--jp-layout-color2);
3186
+ border-radius: 2px;
3187
+ margin-bottom: 12px;
3188
+ overflow: hidden;
3189
+ }
3190
+
3191
+ .nbi-tour-progress-bar {
3192
+ position: absolute;
3193
+ inset: 0 auto 0 0;
3194
+ background: var(--jp-brand-color1, #2196f3);
3195
+ border-radius: 2px;
3196
+ transition: width 200ms ease-out;
3197
+ }
3198
+
3199
+ .nbi-tour-body {
3200
+ /* aria-live region; no presentational change needed here, but the
3201
+ class is a stable hook for future polish (illustrations, etc). */
3202
+ }
3203
+
3204
+ .nbi-tour-title {
3205
+ font-weight: 600;
3206
+ margin-bottom: 8px;
3207
+ }
3208
+
3209
+ .nbi-tour-description {
3210
+ margin-bottom: 14px;
3211
+ line-height: 1.45;
3212
+ }
3213
+
3214
+ .nbi-tour-actions {
3215
+ display: flex;
3216
+ align-items: center;
3217
+ gap: 8px;
3218
+ }
3219
+
3220
+ /* Skip is the *passive* exit (Esc / Done / Next are the active paths),
3221
+ so style it as a muted text link rather than a full button. This
3222
+ keeps the visual hierarchy at one primary action per step. */
3223
+ .nbi-tour-skip-link {
3224
+ background: none;
3225
+ border: none;
3226
+ padding: 4px 6px;
3227
+ font: inherit;
3228
+ color: var(--jp-ui-font-color2);
3229
+ cursor: pointer;
3230
+ text-decoration: underline;
3231
+ text-underline-offset: 2px;
3232
+ }
3233
+
3234
+ .nbi-tour-skip-link:hover,
3235
+ .nbi-tour-skip-link:focus-visible {
3236
+ color: var(--jp-ui-font-color1);
3237
+ outline: none;
3238
+ }