mbeditor 0.13.1 → 0.14.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +91 -0
- data/app/assets/javascripts/mbeditor/application.js +3 -0
- data/app/assets/javascripts/mbeditor/audit_log.js +165 -0
- data/app/assets/javascripts/mbeditor/collaboration_service.js +248 -26
- data/app/assets/javascripts/mbeditor/components/ChangelogView.js +89 -94
- data/app/assets/javascripts/mbeditor/components/CodeReviewPanel.js +6 -9
- data/app/assets/javascripts/mbeditor/components/CollapsibleSection.js +12 -7
- data/app/assets/javascripts/mbeditor/components/CombinedDiffViewer.js +20 -0
- data/app/assets/javascripts/mbeditor/components/DiffViewer.js +1 -1
- data/app/assets/javascripts/mbeditor/components/EditorPanel.js +429 -247
- data/app/assets/javascripts/mbeditor/components/FileHistoryPanel.js +6 -9
- data/app/assets/javascripts/mbeditor/components/FileTree.js +26 -12
- data/app/assets/javascripts/mbeditor/components/GitPanel.js +3 -0
- data/app/assets/javascripts/mbeditor/components/Gutter.js +51 -0
- data/app/assets/javascripts/mbeditor/components/LogPanel.js +3 -44
- data/app/assets/javascripts/mbeditor/components/MbeditorApp.js +1168 -1243
- data/app/assets/javascripts/mbeditor/components/ModelGraph.js +94 -37
- data/app/assets/javascripts/mbeditor/components/ProblemsPanel.js +47 -65
- data/app/assets/javascripts/mbeditor/components/QuickOpenDialog.js +26 -8
- data/app/assets/javascripts/mbeditor/components/SettingsModal.js +342 -0
- data/app/assets/javascripts/mbeditor/components/ShortcutHelp.js +2 -1
- data/app/assets/javascripts/mbeditor/components/TabBar.js +67 -98
- data/app/assets/javascripts/mbeditor/editor_plugins.js +687 -305
- data/app/assets/javascripts/mbeditor/file_import.js +13 -15
- data/app/assets/javascripts/mbeditor/file_service.js +38 -39
- data/app/assets/javascripts/mbeditor/git_service.js +15 -1
- data/app/assets/javascripts/mbeditor/history_service.js +5 -13
- data/app/assets/javascripts/mbeditor/search_service.js +9 -0
- data/app/assets/javascripts/mbeditor/tab_manager.js +127 -49
- data/app/assets/javascripts/mbeditor/websocket_service.js +13 -5
- data/app/assets/stylesheets/mbeditor/application.css +6 -1
- data/app/assets/stylesheets/mbeditor/editor.css +642 -248
- data/app/assets/stylesheets/mbeditor/glass.css +163 -0
- data/app/assets/stylesheets/mbeditor/themes.css +90 -30
- data/app/channels/mbeditor/collaboration_channel.rb +17 -4
- data/app/controllers/mbeditor/application_controller.rb +26 -3
- data/app/controllers/mbeditor/editors_controller.rb +117 -439
- data/app/services/mbeditor/archive_service.rb +137 -0
- data/app/services/mbeditor/collaboration_doc_store.rb +143 -14
- data/app/services/mbeditor/editor_state_service.rb +14 -51
- data/app/services/mbeditor/file_history_service.rb +222 -0
- data/app/services/mbeditor/git_info_service.rb +6 -0
- data/app/services/mbeditor/js_syntax_check_service.rb +42 -16
- data/app/services/mbeditor/lint_service.rb +137 -0
- data/app/services/mbeditor/locked_json_file.rb +67 -0
- data/app/services/mbeditor/process_runner.rb +32 -0
- data/app/services/mbeditor/ruby_lsp_result_translator.rb +226 -0
- data/app/services/mbeditor/search_replace_service.rb +8 -0
- data/app/views/layouts/mbeditor/application.html.erb +1 -1
- data/lib/mbeditor/audit_log.rb +203 -0
- data/lib/mbeditor/configuration.rb +6 -1
- data/lib/mbeditor/rack/pending_migration_bypass.rb +15 -9
- data/lib/mbeditor/route_map.rb +4 -0
- data/lib/mbeditor/ruby_lsp_client.rb +82 -14
- data/lib/mbeditor/version.rb +1 -1
- data/lib/mbeditor.rb +1 -0
- metadata +12 -2
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
/* ── Mini Browser Editor Global Styles ──────────────────── */
|
|
2
2
|
*, *::before, *::after { box-sizing: border-box; }
|
|
3
3
|
|
|
4
|
-
/* Suppress all focus outlines / coloured glows inside the IDE shell
|
|
4
|
+
/* Suppress all focus outlines / coloured glows inside the IDE shell, except
|
|
5
|
+
a keyboard-only ring on interactive elements (not Monaco's own DOM, which
|
|
6
|
+
draws its own focus treatment). */
|
|
5
7
|
#mbeditor-root *:focus,
|
|
6
8
|
#mbeditor-root *:focus-visible {
|
|
7
9
|
outline: none !important;
|
|
8
10
|
box-shadow: none !important;
|
|
9
11
|
}
|
|
10
12
|
|
|
13
|
+
#mbeditor-root :is(button, [role="button"], [tabindex], input, select, textarea, a, .tab-item, .ide-activity-btn, .tree-item):focus-visible {
|
|
14
|
+
outline: 1px solid var(--ide-accent-fg) !important;
|
|
15
|
+
outline-offset: -1px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#mbeditor-root .monaco-editor *:focus-visible {
|
|
19
|
+
outline: none !important;
|
|
20
|
+
}
|
|
21
|
+
|
|
11
22
|
/* ── Pico containment ──────────────────────────────────────────────────────
|
|
12
23
|
*
|
|
13
24
|
* The host app's stylesheet loads alongside this one, and when it is Pico (the
|
|
@@ -121,23 +132,23 @@ html, body, #mbeditor-root {
|
|
|
121
132
|
align-items: center;
|
|
122
133
|
background: var(--ide-panel-bg);
|
|
123
134
|
border-bottom: 1px solid var(--ide-border);
|
|
124
|
-
height:
|
|
125
|
-
padding: 0
|
|
135
|
+
height: 35px;
|
|
136
|
+
padding: 0 8px;
|
|
126
137
|
flex-shrink: 0;
|
|
127
138
|
user-select: none;
|
|
128
139
|
}
|
|
129
140
|
|
|
130
141
|
.ide-titlebar-icon {
|
|
131
|
-
color: var(--ide-
|
|
142
|
+
color: var(--ide-text-muted);
|
|
132
143
|
margin-right: 8px;
|
|
133
|
-
font-size:
|
|
144
|
+
font-size: 13px;
|
|
134
145
|
}
|
|
135
146
|
|
|
136
147
|
.ide-titlebar-title {
|
|
137
|
-
font-size:
|
|
138
|
-
color: var(--ide-text);
|
|
139
|
-
font-weight:
|
|
140
|
-
/* Never wrap: the titlebar is a fixed
|
|
148
|
+
font-size: 12px;
|
|
149
|
+
color: var(--ide-text-muted);
|
|
150
|
+
font-weight: 400;
|
|
151
|
+
/* Never wrap: the titlebar is a fixed 35px row, so a second line pushed the
|
|
141
152
|
toolbar buttons out of it. */
|
|
142
153
|
white-space: nowrap;
|
|
143
154
|
}
|
|
@@ -157,30 +168,30 @@ html, body, #mbeditor-root {
|
|
|
157
168
|
flex: 1 1 auto;
|
|
158
169
|
justify-content: center;
|
|
159
170
|
min-width: 0;
|
|
160
|
-
margin: 0
|
|
171
|
+
margin: 0 24px;
|
|
161
172
|
}
|
|
162
173
|
|
|
163
174
|
.ide-titlebar-search {
|
|
164
175
|
display: flex;
|
|
165
176
|
align-items: center;
|
|
166
177
|
justify-content: center;
|
|
167
|
-
/*
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
width:
|
|
172
|
-
|
|
173
|
-
padding:
|
|
174
|
-
background:
|
|
175
|
-
border: 1px solid
|
|
176
|
-
border-radius:
|
|
177
|
-
color:
|
|
178
|
+
/* The command centre. Capped so it stays a centred pill rather than a
|
|
179
|
+
stretched field, floored so the placeholder survives a narrow window. */
|
|
180
|
+
width: 100%;
|
|
181
|
+
max-width: 720px;
|
|
182
|
+
min-width: min(180px, 100%);
|
|
183
|
+
height: 24px;
|
|
184
|
+
padding: 0 10px;
|
|
185
|
+
background: color-mix(in srgb, var(--ide-text) 6%, transparent);
|
|
186
|
+
border: 1px solid var(--ide-border);
|
|
187
|
+
border-radius: 6px;
|
|
188
|
+
color: var(--ide-text-muted);
|
|
178
189
|
font-size: 12px;
|
|
179
190
|
cursor: pointer;
|
|
180
191
|
}
|
|
181
|
-
.ide-titlebar-search:hover { background:
|
|
192
|
+
.ide-titlebar-search:hover { background: color-mix(in srgb, var(--ide-text) 11%, transparent); }
|
|
182
193
|
.ide-titlebar-search-text {
|
|
183
|
-
opacity:
|
|
194
|
+
opacity: 1;
|
|
184
195
|
overflow: hidden;
|
|
185
196
|
text-overflow: ellipsis;
|
|
186
197
|
white-space: nowrap;
|
|
@@ -205,8 +216,8 @@ html, body, #mbeditor-root {
|
|
|
205
216
|
|
|
206
217
|
/* ── Activity Bar (VSCode-style, always visible) ───────── */
|
|
207
218
|
.ide-activity-bar {
|
|
208
|
-
width:
|
|
209
|
-
min-width:
|
|
219
|
+
width: 48px;
|
|
220
|
+
min-width: 48px;
|
|
210
221
|
flex-shrink: 0;
|
|
211
222
|
background: var(--ide-panel-bg);
|
|
212
223
|
border-right: 1px solid var(--ide-border);
|
|
@@ -240,69 +251,105 @@ html, body, #mbeditor-root {
|
|
|
240
251
|
than a bare class and was silently winning. */
|
|
241
252
|
.ide-activity-bar .ide-activity-btn {
|
|
242
253
|
width: 100%;
|
|
243
|
-
height:
|
|
254
|
+
height: 48px;
|
|
244
255
|
background: transparent;
|
|
245
256
|
border: none;
|
|
246
257
|
/* Always reserve the indicator's width so the glyph does not shift sideways
|
|
247
258
|
by a pixel the moment a panel is opened. */
|
|
248
259
|
border-left: 2px solid transparent;
|
|
249
260
|
border-radius: 0;
|
|
250
|
-
|
|
261
|
+
/* One glyph colour throughout; opacity carries the state, which is what
|
|
262
|
+
stops the icons reading as three different palettes at once. */
|
|
263
|
+
color: var(--ide-text);
|
|
264
|
+
opacity: 0.6;
|
|
251
265
|
display: flex;
|
|
252
266
|
align-items: center;
|
|
253
267
|
justify-content: center;
|
|
254
268
|
cursor: pointer;
|
|
255
|
-
font-size:
|
|
256
|
-
transition: color 0.
|
|
269
|
+
font-size: 16px;
|
|
270
|
+
transition: opacity 0.1s ease, border-color 0.1s ease;
|
|
257
271
|
}
|
|
258
272
|
|
|
259
273
|
/* The glyph carries the state, not a filled box behind it. */
|
|
260
274
|
.ide-activity-bar .ide-activity-btn:hover {
|
|
261
275
|
background: transparent;
|
|
262
|
-
|
|
276
|
+
opacity: 1;
|
|
263
277
|
}
|
|
264
278
|
|
|
265
279
|
.ide-activity-bar .ide-activity-btn.active {
|
|
280
|
+
opacity: 1;
|
|
281
|
+
background: transparent;
|
|
266
282
|
color: var(--ide-accent-fg);
|
|
267
|
-
border-left-color: var(--ide-accent
|
|
283
|
+
border-left-color: var(--ide-accent);
|
|
268
284
|
}
|
|
269
285
|
|
|
270
286
|
.sidebar-panel-title {
|
|
271
287
|
font-size: 11px;
|
|
272
288
|
font-weight: 700;
|
|
273
289
|
text-transform: uppercase;
|
|
274
|
-
letter-spacing: 0.
|
|
275
|
-
color: var(--ide-
|
|
276
|
-
padding:
|
|
290
|
+
letter-spacing: 0.06em;
|
|
291
|
+
color: var(--ide-text);
|
|
292
|
+
padding: 9px 20px 7px;
|
|
277
293
|
flex-shrink: 0;
|
|
278
|
-
border-bottom: 1px solid var(--ide-border);
|
|
279
294
|
}
|
|
280
295
|
|
|
281
296
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
297
|
+
/* ── The gutter ──────────────────────────────────────────────
|
|
298
|
+
One draggable strip, always in the gap between two cards, never inside
|
|
299
|
+
either of them. 6px in its thin dimension and transparent: wider reads as a
|
|
300
|
+
gap in the layout rather than a handle.
|
|
301
|
+
|
|
302
|
+
The three dots are a ::before on the gutter itself. A flat strip gives no
|
|
303
|
+
sign it can be dragged, and the cursor only says so once you are already on
|
|
304
|
+
it. One tiled radial gradient rather than three elements: the gutter has no
|
|
305
|
+
children and adding some would put a hit-testable node inside the drag
|
|
306
|
+
target. */
|
|
307
|
+
.ide-gutter {
|
|
308
|
+
flex: 0 0 auto;
|
|
309
|
+
position: relative;
|
|
310
|
+
background: transparent;
|
|
285
311
|
transition: background 0.12s ease;
|
|
286
312
|
}
|
|
287
313
|
|
|
288
|
-
.
|
|
289
|
-
|
|
290
|
-
background: var(--ide-panel-bg-alt);
|
|
291
|
-
border-right: 1px solid var(--ide-border);
|
|
292
|
-
}
|
|
314
|
+
.ide-gutter-v { width: 6px; cursor: col-resize; align-self: stretch; }
|
|
315
|
+
.ide-gutter-h { height: 6px; cursor: row-resize; align-self: stretch; width: 100%; }
|
|
293
316
|
|
|
317
|
+
.ide-gutter::before {
|
|
318
|
+
content: '';
|
|
319
|
+
position: absolute;
|
|
320
|
+
left: 50%;
|
|
321
|
+
top: 50%;
|
|
322
|
+
transform: translate(-50%, -50%);
|
|
323
|
+
opacity: 0.55;
|
|
324
|
+
transition: opacity 0.12s ease;
|
|
325
|
+
pointer-events: none;
|
|
326
|
+
}
|
|
294
327
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
328
|
+
/* Dots run top-to-bottom on a vertical gutter, left-to-right on a horizontal
|
|
329
|
+
one — the same tile, rotated. */
|
|
330
|
+
.ide-gutter-v::before {
|
|
331
|
+
width: 3px;
|
|
332
|
+
height: 15px;
|
|
333
|
+
background: radial-gradient(circle 1.5px at 1.5px 1.5px, var(--ide-text-muted) 99%, transparent) 0 0 / 3px 6px repeat-y;
|
|
299
334
|
}
|
|
300
335
|
|
|
301
|
-
.
|
|
302
|
-
|
|
303
|
-
|
|
336
|
+
.ide-gutter-h::before {
|
|
337
|
+
width: 15px;
|
|
338
|
+
height: 3px;
|
|
339
|
+
background: radial-gradient(circle 1.5px at 1.5px 1.5px, var(--ide-text-muted) 99%, transparent) 0 0 / 6px 3px repeat-x;
|
|
304
340
|
}
|
|
305
341
|
|
|
342
|
+
.ide-gutter:hover { background: var(--ide-hover-bg); }
|
|
343
|
+
.ide-gutter:hover::before,
|
|
344
|
+
.ide-gutter.active::before { opacity: 1; }
|
|
345
|
+
|
|
346
|
+
/* The split-pane gutter sits over the pane drop overlays. */
|
|
347
|
+
.ide-gutter-pane { z-index: 10; }
|
|
348
|
+
|
|
349
|
+
/* Modern: the seam beside the git panel card is drawn on the gutter, so the
|
|
350
|
+
panel itself carries no left border and there is only ever one line. */
|
|
351
|
+
.ide-gutter-gitpanel { border-left: 1px solid var(--ide-border); }
|
|
352
|
+
|
|
306
353
|
.ide-sidebar-header {
|
|
307
354
|
padding: 6px 12px;
|
|
308
355
|
font-size: 11px;
|
|
@@ -359,8 +406,8 @@ html, body, #mbeditor-root {
|
|
|
359
406
|
|
|
360
407
|
.tree-item:hover { background: var(--ide-hover-bg); }
|
|
361
408
|
.tree-item.active { background: var(--ide-active-bg); }
|
|
362
|
-
.tree-item.selected { box-shadow: inset 0 0 0 1px
|
|
363
|
-
.tree-item.active.selected { box-shadow: inset 0 0 0 1px
|
|
409
|
+
.tree-item.selected { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ide-accent) 35%, transparent); background: color-mix(in srgb, var(--ide-accent) 8%, transparent); }
|
|
410
|
+
.tree-item.active.selected { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ide-accent) 55%, transparent); }
|
|
364
411
|
.tree-item.drag-over { background: rgba(100, 160, 220, 0.25); box-shadow: inset 0 0 0 1px rgba(100, 160, 220, 0.7); }
|
|
365
412
|
/* External file drop (import) — green, to read as "add" rather than "move" */
|
|
366
413
|
.tree-item.drag-over-external { background: rgba(120, 200, 140, 0.22); box-shadow: inset 0 0 0 1px rgba(120, 200, 140, 0.75); }
|
|
@@ -463,6 +510,7 @@ html, body, #mbeditor-root {
|
|
|
463
510
|
.tab-bar {
|
|
464
511
|
display: flex;
|
|
465
512
|
align-items: center;
|
|
513
|
+
padding-left: 4px;
|
|
466
514
|
background: var(--ide-panel-bg);
|
|
467
515
|
border-bottom: 1px solid var(--ide-border);
|
|
468
516
|
height: 35px;
|
|
@@ -504,15 +552,15 @@ html, body, #mbeditor-root {
|
|
|
504
552
|
.tab-item {
|
|
505
553
|
display: flex;
|
|
506
554
|
align-items: center;
|
|
507
|
-
padding: 0
|
|
508
|
-
height:
|
|
509
|
-
|
|
510
|
-
max-width:
|
|
555
|
+
padding: 0 8px 0 10px;
|
|
556
|
+
height: 27px;
|
|
557
|
+
margin: 4px 0 4px 4px;
|
|
558
|
+
max-width: 220px;
|
|
511
559
|
cursor: pointer;
|
|
512
|
-
border-
|
|
513
|
-
background:
|
|
560
|
+
border-radius: 6px;
|
|
561
|
+
background: transparent;
|
|
514
562
|
color: var(--ide-text-muted);
|
|
515
|
-
font-size:
|
|
563
|
+
font-size: 13px;
|
|
516
564
|
transition: background 0.1s, color 0.1s;
|
|
517
565
|
white-space: nowrap;
|
|
518
566
|
overflow: hidden;
|
|
@@ -528,30 +576,22 @@ html, body, #mbeditor-root {
|
|
|
528
576
|
opacity: 0.55;
|
|
529
577
|
}
|
|
530
578
|
|
|
531
|
-
.tab-item:hover { background: var(--ide-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
}
|
|
538
|
-
.tab-item.active.tab-has-error {
|
|
539
|
-
border-top: 2px solid var(--ide-danger) !important;
|
|
540
|
-
border-bottom: none !important;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
.tab-has-warning {
|
|
544
|
-
border-bottom: 2px solid var(--ide-warning) !important;
|
|
579
|
+
.tab-item:hover { background: var(--ide-hover-bg); color: var(--ide-text); }
|
|
580
|
+
/* The active tab is a lifted rounded chip on the tab strip, not a seamless
|
|
581
|
+
join with the editor: the strip keeps its own bottom border. */
|
|
582
|
+
.tab-item.active {
|
|
583
|
+
background: var(--ide-hover-bg);
|
|
584
|
+
color: var(--ide-text);
|
|
545
585
|
}
|
|
586
|
+
.tab-item.tab-soft .tab-item-name { font-style: italic; }
|
|
546
587
|
|
|
547
|
-
.
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
588
|
+
/* Diagnostics colour the label, as VS Code does; a border would break the chip. */
|
|
589
|
+
.tab-has-error .tab-item-name { color: var(--ide-danger); }
|
|
590
|
+
.tab-has-warning .tab-item-name { color: var(--ide-warning); }
|
|
551
591
|
|
|
552
592
|
.tab-item-icon {
|
|
553
593
|
width: 14px;
|
|
554
|
-
margin-right:
|
|
594
|
+
margin-right: 6px;
|
|
555
595
|
font-size: 12px;
|
|
556
596
|
text-align: center;
|
|
557
597
|
flex-shrink: 0;
|
|
@@ -572,8 +612,8 @@ html, body, #mbeditor-root {
|
|
|
572
612
|
|
|
573
613
|
.tab-close {
|
|
574
614
|
margin-left: 6px;
|
|
575
|
-
width:
|
|
576
|
-
height:
|
|
615
|
+
width: 20px;
|
|
616
|
+
height: 20px;
|
|
577
617
|
display: flex;
|
|
578
618
|
align-items: center;
|
|
579
619
|
justify-content: center;
|
|
@@ -582,8 +622,14 @@ html, body, #mbeditor-root {
|
|
|
582
622
|
color: var(--ide-text-muted);
|
|
583
623
|
flex-shrink: 0;
|
|
584
624
|
transition: background 0.1s, color 0.1s;
|
|
625
|
+
background: transparent;
|
|
626
|
+
border: none;
|
|
627
|
+
padding: 0;
|
|
628
|
+
cursor: pointer;
|
|
629
|
+
opacity: 0.6;
|
|
585
630
|
}
|
|
586
631
|
|
|
632
|
+
.tab-item:hover .tab-close { opacity: 1; }
|
|
587
633
|
.tab-close:hover { background: var(--ide-hover-bg); color: var(--ide-text); }
|
|
588
634
|
|
|
589
635
|
.tab-welcome {
|
|
@@ -884,20 +930,21 @@ html, body, #mbeditor-root {
|
|
|
884
930
|
.ide-statusbar {
|
|
885
931
|
display: flex;
|
|
886
932
|
align-items: center;
|
|
887
|
-
background: var(--ide-
|
|
933
|
+
background: var(--ide-statusbar-bg);
|
|
934
|
+
border-top: 1px solid var(--ide-border);
|
|
888
935
|
height: 22px;
|
|
889
936
|
padding: 0;
|
|
890
937
|
gap: 0;
|
|
891
938
|
flex-shrink: 0;
|
|
892
|
-
font-size:
|
|
893
|
-
line-height: 1
|
|
939
|
+
font-size: 12px;
|
|
940
|
+
line-height: 20px; /* glyphs centre in the row; line-height 1 sat them high */
|
|
894
941
|
color: var(--ide-accent-text);
|
|
895
942
|
}
|
|
896
943
|
|
|
897
944
|
/* One cell rhythm for every item, button or not. The branch, the message and
|
|
898
945
|
* the chips each carried their own padding on top of the bar's, so the gaps
|
|
899
946
|
* between them were all different widths. */
|
|
900
|
-
.ide-statusbar > * { padding: 0
|
|
947
|
+
.ide-statusbar > * { padding: 0 6px; }
|
|
901
948
|
|
|
902
949
|
.statusbar-branch {
|
|
903
950
|
display: flex;
|
|
@@ -929,6 +976,29 @@ html, body, #mbeditor-root {
|
|
|
929
976
|
cursor: default;
|
|
930
977
|
}
|
|
931
978
|
|
|
979
|
+
/* Pending migrations: the whole status bar turns amber, rather than a banner
|
|
980
|
+
* that sat above everything and shoved the editor down the page every time it
|
|
981
|
+
* appeared.
|
|
982
|
+
*
|
|
983
|
+
* The bar's own variables are redefined rather than background and color,
|
|
984
|
+
* because the bar and every child — buttons, separators, the hover mix — are
|
|
985
|
+
* already painted from them. Setting the background alone left unreadable
|
|
986
|
+
* text on amber. */
|
|
987
|
+
body.mbeditor-migration-pending .ide-statusbar {
|
|
988
|
+
--ide-statusbar-bg: var(--ide-statusbar-warn-bg);
|
|
989
|
+
--ide-accent-text: var(--ide-statusbar-warn-text);
|
|
990
|
+
--ide-text-muted: var(--ide-statusbar-warn-text);
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
.statusbar-migration {
|
|
994
|
+
display: flex;
|
|
995
|
+
align-items: center;
|
|
996
|
+
gap: 6px;
|
|
997
|
+
font-weight: 600;
|
|
998
|
+
white-space: nowrap;
|
|
999
|
+
flex-shrink: 0;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
932
1002
|
.statusbar-offline {
|
|
933
1003
|
display: flex;
|
|
934
1004
|
align-items: center;
|
|
@@ -948,19 +1018,32 @@ html, body, #mbeditor-root {
|
|
|
948
1018
|
display: flex;
|
|
949
1019
|
align-items: center;
|
|
950
1020
|
gap: 4px;
|
|
951
|
-
padding: 0
|
|
952
|
-
height:
|
|
1021
|
+
padding: 0 6px;
|
|
1022
|
+
height: 20px;
|
|
1023
|
+
margin: 0 1px;
|
|
953
1024
|
flex-shrink: 0;
|
|
954
1025
|
background: transparent;
|
|
955
1026
|
border: none;
|
|
956
1027
|
color: var(--ide-accent-text);
|
|
957
1028
|
cursor: pointer;
|
|
958
|
-
font-size:
|
|
959
|
-
border-radius:
|
|
1029
|
+
font-size: 12px;
|
|
1030
|
+
border-radius: 5px;
|
|
960
1031
|
transition: background 0.1s;
|
|
961
1032
|
white-space: nowrap;
|
|
962
1033
|
}
|
|
963
1034
|
|
|
1035
|
+
/* Cursor position readout. Matches the buttons' metrics so the bar keeps one
|
|
1036
|
+
rhythm, but it is a span with no hover: nothing happens when you click it. */
|
|
1037
|
+
.statusbar-cursor {
|
|
1038
|
+
display: flex;
|
|
1039
|
+
align-items: center;
|
|
1040
|
+
padding: 0 6px;
|
|
1041
|
+
height: 20px;
|
|
1042
|
+
flex-shrink: 0;
|
|
1043
|
+
color: var(--ide-accent-text);
|
|
1044
|
+
font-variant-numeric: tabular-nums;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
964
1047
|
.statusbar-btn:hover { background: color-mix(in srgb, var(--ide-accent-text) 15%, transparent); }
|
|
965
1048
|
.statusbar-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
966
1049
|
|
|
@@ -1018,6 +1101,77 @@ html, body, #mbeditor-root {
|
|
|
1018
1101
|
.collab-hovercard-row { color: var(--ide-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
1019
1102
|
.collab-hovercard-hint { margin-top: 5px; padding-top: 5px; border-top: 1px solid var(--ide-border); color: var(--ide-text-muted); }
|
|
1020
1103
|
|
|
1104
|
+
/* Overlapping avatar stack: fixed width regardless of headcount, which is the
|
|
1105
|
+
point — a chip per peer is what broke past ~4 people. The ring is a
|
|
1106
|
+
box-shadow, not a border, so it doesn't perturb the circle's own layout
|
|
1107
|
+
before the negative margin overlaps it; it paints over the sibling behind it
|
|
1108
|
+
because later avatars are later in DOM order, no z-index needed. Its colour
|
|
1109
|
+
comes from --ide-panel-bg rather than an opaque literal, since glass chrome
|
|
1110
|
+
tints that same token instead of replacing it. */
|
|
1111
|
+
.collab-avatar-stack { display: flex; align-items: center; }
|
|
1112
|
+
.collab-avatar {
|
|
1113
|
+
width: 9px;
|
|
1114
|
+
height: 9px;
|
|
1115
|
+
flex-shrink: 0;
|
|
1116
|
+
border: none;
|
|
1117
|
+
border-radius: 50%;
|
|
1118
|
+
padding: 0;
|
|
1119
|
+
cursor: pointer;
|
|
1120
|
+
box-shadow: 0 0 0 1.5px var(--ide-panel-bg);
|
|
1121
|
+
}
|
|
1122
|
+
.collab-avatar:not(:first-child) { margin-left: -4.5px; }
|
|
1123
|
+
/* Dimmed rather than re-shaped: a peer in another file still reads as "here"
|
|
1124
|
+
at a glance, just fainter, instead of needing a second glyph on a 9px dot. */
|
|
1125
|
+
.collab-avatar-elsewhere { opacity: 0.55; }
|
|
1126
|
+
.collab-avatar-following { outline: 1.5px solid var(--ide-accent-fg); outline-offset: 1px; }
|
|
1127
|
+
.collab-avatar-more {
|
|
1128
|
+
width: auto;
|
|
1129
|
+
height: auto;
|
|
1130
|
+
margin-left: 6px;
|
|
1131
|
+
padding: 0;
|
|
1132
|
+
font-size: 10px;
|
|
1133
|
+
color: var(--ide-text-muted);
|
|
1134
|
+
background: none;
|
|
1135
|
+
border-radius: 0;
|
|
1136
|
+
box-shadow: none;
|
|
1137
|
+
}
|
|
1138
|
+
.collab-avatar-overflow { position: relative; }
|
|
1139
|
+
/* Fixed and anchored from the button's rect, like .collab-hovercard: inside the
|
|
1140
|
+
title bar it was painted under the editor whatever its z-index. */
|
|
1141
|
+
.collab-overflow-popover {
|
|
1142
|
+
position: fixed;
|
|
1143
|
+
z-index: 4000;
|
|
1144
|
+
min-width: 180px;
|
|
1145
|
+
max-width: 260px;
|
|
1146
|
+
max-height: 240px;
|
|
1147
|
+
overflow-y: auto;
|
|
1148
|
+
padding: 4px;
|
|
1149
|
+
background: var(--ide-panel-bg);
|
|
1150
|
+
border: 1px solid var(--ide-border);
|
|
1151
|
+
border-radius: 6px;
|
|
1152
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
|
|
1153
|
+
}
|
|
1154
|
+
.collab-overflow-row {
|
|
1155
|
+
display: flex;
|
|
1156
|
+
align-items: center;
|
|
1157
|
+
gap: 6px;
|
|
1158
|
+
width: 100%;
|
|
1159
|
+
padding: 4px 6px;
|
|
1160
|
+
background: transparent;
|
|
1161
|
+
border: none;
|
|
1162
|
+
border-radius: 4px;
|
|
1163
|
+
cursor: pointer;
|
|
1164
|
+
color: var(--ide-text);
|
|
1165
|
+
font-size: 11px;
|
|
1166
|
+
text-align: left;
|
|
1167
|
+
}
|
|
1168
|
+
.collab-overflow-row:hover { background: var(--ide-hover-bg); }
|
|
1169
|
+
.collab-overflow-row.is-following { background: color-mix(in srgb, var(--ide-accent) 15%, transparent); }
|
|
1170
|
+
.collab-overflow-swatch { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
|
|
1171
|
+
.collab-overflow-name { flex-shrink: 0; }
|
|
1172
|
+
.collab-overflow-file { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ide-text-muted); }
|
|
1173
|
+
.collab-overflow-eye { margin-left: auto; color: var(--ide-accent-fg); font-size: 10px; }
|
|
1174
|
+
|
|
1021
1175
|
.statusbar-msg {
|
|
1022
1176
|
margin-left: auto;
|
|
1023
1177
|
color: var(--ide-accent-text);
|
|
@@ -1032,7 +1186,7 @@ html, body, #mbeditor-root {
|
|
|
1032
1186
|
.statusbar-msg.success { color: var(--ide-success); }
|
|
1033
1187
|
|
|
1034
1188
|
.statusbar-version {
|
|
1035
|
-
color: color-mix(in srgb, var(--ide-accent-text)
|
|
1189
|
+
color: color-mix(in srgb, var(--ide-accent-text) 80%, transparent);
|
|
1036
1190
|
font-size: 10px;
|
|
1037
1191
|
white-space: nowrap;
|
|
1038
1192
|
cursor: pointer;
|
|
@@ -1180,13 +1334,20 @@ html, body, #mbeditor-root {
|
|
|
1180
1334
|
background: var(--ide-input-bg);
|
|
1181
1335
|
color: var(--ide-text);
|
|
1182
1336
|
border: 1px solid var(--ide-border-input);
|
|
1183
|
-
border-radius:
|
|
1337
|
+
border-radius: 8px;
|
|
1184
1338
|
font-size: 12px;
|
|
1185
1339
|
outline: none;
|
|
1186
1340
|
box-sizing: border-box;
|
|
1187
1341
|
}
|
|
1188
1342
|
.search-input::placeholder { color: var(--ide-text-muted); }
|
|
1189
|
-
.search-input:focus { border-color: var(--ide-
|
|
1343
|
+
.search-input:focus { border-color: var(--ide-accent); }
|
|
1344
|
+
|
|
1345
|
+
/* 8px on every text field, so the search box, the rename box and the import
|
|
1346
|
+
destination box are one shape rather than three. Pico's own 0.25rem applies
|
|
1347
|
+
to bare elements, hence the element selectors rather than a class list. */
|
|
1348
|
+
#mbeditor-root :is(input[type="text"], input[type="search"], input[type="number"], textarea, select) {
|
|
1349
|
+
border-radius: 8px;
|
|
1350
|
+
}
|
|
1190
1351
|
|
|
1191
1352
|
/* ── Results area wrapper (positions the loading overlay) ── */
|
|
1192
1353
|
.search-results-area {
|
|
@@ -1891,8 +2052,9 @@ html, body, #mbeditor-root {
|
|
|
1891
2052
|
|
|
1892
2053
|
/* ── Right-side Git Panel ───────────────────────────────── */
|
|
1893
2054
|
.ide-git-right-panel {
|
|
1894
|
-
|
|
1895
|
-
|
|
2055
|
+
/* A card like the sidebar: the seam on its left is drawn by the gutter, not
|
|
2056
|
+
by a border here, so the two never double up. */
|
|
2057
|
+
background: var(--ide-panel-bg);
|
|
1896
2058
|
display: flex;
|
|
1897
2059
|
flex-direction: column;
|
|
1898
2060
|
overflow: hidden;
|
|
@@ -1901,16 +2063,10 @@ html, body, #mbeditor-root {
|
|
|
1901
2063
|
max-width: 600px;
|
|
1902
2064
|
}
|
|
1903
2065
|
|
|
1904
|
-
.gitpanel-divider {
|
|
1905
|
-
width: 5px;
|
|
1906
|
-
background: var(--ide-panel-bg-alt);
|
|
1907
|
-
border-left: 1px solid var(--ide-border);
|
|
1908
|
-
}
|
|
1909
|
-
|
|
1910
2066
|
.ide-git-panel {
|
|
1911
2067
|
width: 100%;
|
|
1912
2068
|
height: 100%;
|
|
1913
|
-
background: var(--ide-panel-bg
|
|
2069
|
+
background: var(--ide-panel-bg);
|
|
1914
2070
|
display: flex;
|
|
1915
2071
|
flex-direction: column;
|
|
1916
2072
|
overflow: hidden;
|
|
@@ -2204,6 +2360,10 @@ html, body, #mbeditor-root {
|
|
|
2204
2360
|
background: var(--ide-hover-bg);
|
|
2205
2361
|
}
|
|
2206
2362
|
|
|
2363
|
+
/* Nothing to click, so nothing that looks clickable. */
|
|
2364
|
+
.collapsible-header-static { cursor: default; }
|
|
2365
|
+
.collapsible-header-static:hover { background: none; }
|
|
2366
|
+
|
|
2207
2367
|
|
|
2208
2368
|
.collapsible-toggle {
|
|
2209
2369
|
font-size: 8px;
|
|
@@ -2292,7 +2452,7 @@ html, body, #mbeditor-root {
|
|
|
2292
2452
|
|
|
2293
2453
|
/* Open-editors panel: height is controlled by the --open-editors-height CSS variable
|
|
2294
2454
|
set inline from React state (default 140px ≈ 5-6 items), drag-resizable via the
|
|
2295
|
-
|
|
2455
|
+
gutter below it. */
|
|
2296
2456
|
.ide-sidebar-fixed .collapsible-content {
|
|
2297
2457
|
max-height: var(--open-editors-height, 140px);
|
|
2298
2458
|
overflow-y: auto;
|
|
@@ -2302,17 +2462,6 @@ html, body, #mbeditor-root {
|
|
|
2302
2462
|
.ide-sidebar-fixed .collapsible-content::-webkit-scrollbar-track { background: transparent; }
|
|
2303
2463
|
.ide-sidebar-fixed .collapsible-content::-webkit-scrollbar-thumb { background: var(--ide-scrollbar); border-radius: 3px; }
|
|
2304
2464
|
|
|
2305
|
-
.open-editors-resize-handle {
|
|
2306
|
-
height: 4px;
|
|
2307
|
-
flex-shrink: 0;
|
|
2308
|
-
cursor: row-resize;
|
|
2309
|
-
background: transparent;
|
|
2310
|
-
transition: background 0.15s;
|
|
2311
|
-
}
|
|
2312
|
-
.open-editors-resize-handle:hover {
|
|
2313
|
-
background: var(--ide-border);
|
|
2314
|
-
}
|
|
2315
|
-
|
|
2316
2465
|
.open-editors-group-header {
|
|
2317
2466
|
font-size: 10px;
|
|
2318
2467
|
padding-left: 8px;
|
|
@@ -2329,12 +2478,45 @@ html, body, #mbeditor-root {
|
|
|
2329
2478
|
transition: opacity 0.12s ease;
|
|
2330
2479
|
}
|
|
2331
2480
|
|
|
2481
|
+
/* VS Code-style Open Editors row: 22px, filename dims when the tab isn't the
|
|
2482
|
+
active one, the directory trails it in muted small text, and the
|
|
2483
|
+
move-to-group / close controls stay invisible until the row is hovered. */
|
|
2484
|
+
.open-editors-item { height: 22px; padding: 0 8px; }
|
|
2485
|
+
.open-editors-name { color: var(--ide-text-muted); }
|
|
2486
|
+
.open-editors-item.active .open-editors-name { color: var(--ide-text); }
|
|
2487
|
+
.open-editors-dir {
|
|
2488
|
+
margin-left: 6px;
|
|
2489
|
+
color: var(--ide-text-muted);
|
|
2490
|
+
font-size: 12px;
|
|
2491
|
+
overflow: hidden;
|
|
2492
|
+
text-overflow: ellipsis;
|
|
2493
|
+
white-space: nowrap;
|
|
2494
|
+
min-width: 0;
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
.open-editors-item .tab-split { opacity: 0; }
|
|
2498
|
+
.open-editors-item:hover .tab-split { opacity: 0.6; }
|
|
2499
|
+
|
|
2500
|
+
/* Dot and close button share one cell: the dot shows at rest for a dirty
|
|
2501
|
+
tab, the close button takes over on hover — same slot, same as VS Code's
|
|
2502
|
+
tab UI, so a hover never shifts the row's width. */
|
|
2503
|
+
.open-editors-close-slot {
|
|
2504
|
+
display: grid;
|
|
2505
|
+
width: 20px;
|
|
2506
|
+
height: 16px;
|
|
2507
|
+
}
|
|
2508
|
+
.open-editors-close-slot > * { grid-area: 1 / 1; place-self: center; }
|
|
2509
|
+
.open-editors-dirty-dot { font-size: 5px; color: #e3d286; opacity: 1; }
|
|
2510
|
+
.open-editors-item .tab-close { opacity: 0; }
|
|
2511
|
+
.open-editors-item:hover .open-editors-dirty-dot { opacity: 0; }
|
|
2512
|
+
.open-editors-item:hover .tab-close { opacity: 1; }
|
|
2513
|
+
|
|
2332
2514
|
.ide-icon-btn {
|
|
2333
2515
|
min-width: 24px;
|
|
2334
2516
|
height: 24px;
|
|
2335
2517
|
background: transparent;
|
|
2336
2518
|
border: none;
|
|
2337
|
-
border-radius:
|
|
2519
|
+
border-radius: 5px;
|
|
2338
2520
|
color: var(--ide-text-muted);
|
|
2339
2521
|
display: inline-flex;
|
|
2340
2522
|
align-items: center;
|
|
@@ -2358,8 +2540,10 @@ html, body, #mbeditor-root {
|
|
|
2358
2540
|
display: flex;
|
|
2359
2541
|
justify-content: flex-start;
|
|
2360
2542
|
align-items: center;
|
|
2361
|
-
padding:
|
|
2362
|
-
|
|
2543
|
+
padding: 0 12px;
|
|
2544
|
+
height: 22px;
|
|
2545
|
+
min-height: 22px;
|
|
2546
|
+
background: var(--ide-bg);
|
|
2363
2547
|
border-bottom: 1px solid var(--ide-border);
|
|
2364
2548
|
gap: 4px;
|
|
2365
2549
|
overflow: hidden;
|
|
@@ -2373,14 +2557,18 @@ html, body, #mbeditor-root {
|
|
|
2373
2557
|
white-space: nowrap;
|
|
2374
2558
|
text-overflow: ellipsis;
|
|
2375
2559
|
text-align: left;
|
|
2376
|
-
font-size:
|
|
2560
|
+
font-size: 13px;
|
|
2377
2561
|
color: var(--ide-text-muted);
|
|
2378
2562
|
padding: 0 4px;
|
|
2379
2563
|
cursor: default;
|
|
2380
2564
|
user-select: text;
|
|
2381
|
-
font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
|
|
2382
2565
|
}
|
|
2383
2566
|
|
|
2567
|
+
.ide-breadcrumb-dir { color: var(--ide-text-muted); }
|
|
2568
|
+
.ide-breadcrumb-file { color: var(--ide-text); }
|
|
2569
|
+
.ide-breadcrumb-file-icon { margin-right: 5px; font-size: 12px; }
|
|
2570
|
+
.ide-breadcrumb-sep { font-size: 9px; color: var(--ide-text-muted); margin: 0 4px; }
|
|
2571
|
+
|
|
2384
2572
|
.ide-editor-toolbar .ide-icon-btn {
|
|
2385
2573
|
flex-shrink: 1;
|
|
2386
2574
|
min-width: 24px;
|
|
@@ -2408,10 +2596,12 @@ html, body, #mbeditor-root {
|
|
|
2408
2596
|
}
|
|
2409
2597
|
|
|
2410
2598
|
.ide-methods-dropdown {
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2599
|
+
backdrop-filter: blur(20px) saturate(180%);
|
|
2600
|
+
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
2601
|
+
background: color-mix(in srgb, var(--ide-panel-bg) 78%, transparent);
|
|
2602
|
+
border: 1px solid color-mix(in srgb, var(--ide-text) 16%, transparent);
|
|
2603
|
+
border-radius: 8px;
|
|
2604
|
+
box-shadow: 0 8px 24px rgba(0,0,0,0.45);
|
|
2415
2605
|
min-width: 200px;
|
|
2416
2606
|
max-width: 340px;
|
|
2417
2607
|
max-height: 320px;
|
|
@@ -2440,13 +2630,8 @@ html, body, #mbeditor-root {
|
|
|
2440
2630
|
|
|
2441
2631
|
.ide-methods-dropdown-item:hover,
|
|
2442
2632
|
.ide-methods-dropdown-item:focus {
|
|
2443
|
-
background:
|
|
2444
|
-
color:
|
|
2445
|
-
}
|
|
2446
|
-
|
|
2447
|
-
.ide-methods-dropdown-item:focus {
|
|
2448
|
-
outline: 1px solid #75beff;
|
|
2449
|
-
outline-offset: -1px;
|
|
2633
|
+
background: var(--ide-active-bg);
|
|
2634
|
+
color: var(--ide-text);
|
|
2450
2635
|
}
|
|
2451
2636
|
|
|
2452
2637
|
.ide-methods-dropdown-line {
|
|
@@ -2507,6 +2692,12 @@ html, body, #mbeditor-root {
|
|
|
2507
2692
|
.monaco-editor .line-numbers.mbeditor-gitline-deleted.mbeditor-gitline-added,
|
|
2508
2693
|
.monaco-editor .line-numbers.mbeditor-gitline-deleted.mbeditor-gitline-modified { color: var(--ide-danger); }
|
|
2509
2694
|
|
|
2695
|
+
/* Monaco's own active-selection rule is `.monaco-editor .focused .selected-text`,
|
|
2696
|
+
which wants `focused` on a DESCENDANT. In this build the class lands on the
|
|
2697
|
+
`.monaco-editor` element itself, so that rule never matches and every selection
|
|
2698
|
+
paints with the dim inactive colour. Same theme variable, one less space. */
|
|
2699
|
+
.monaco-editor.focused .selected-text { background-color: var(--vscode-editor-selectionBackground); }
|
|
2700
|
+
|
|
2510
2701
|
.ide-methods-dropdown-message {
|
|
2511
2702
|
padding: 8px 12px;
|
|
2512
2703
|
color: #858585;
|
|
@@ -2595,6 +2786,26 @@ html, body, #mbeditor-root {
|
|
|
2595
2786
|
margin: 4px 0;
|
|
2596
2787
|
}
|
|
2597
2788
|
|
|
2789
|
+
.ide-tab-context-menu-item {
|
|
2790
|
+
padding: 6px 14px;
|
|
2791
|
+
cursor: pointer;
|
|
2792
|
+
color: #ccc;
|
|
2793
|
+
font-size: 12px;
|
|
2794
|
+
display: flex;
|
|
2795
|
+
align-items: center;
|
|
2796
|
+
gap: 8px;
|
|
2797
|
+
background: transparent;
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
.ide-tab-context-menu-item:hover {
|
|
2801
|
+
background: #094771;
|
|
2802
|
+
}
|
|
2803
|
+
|
|
2804
|
+
.ide-tab-context-menu-item i {
|
|
2805
|
+
width: 14px;
|
|
2806
|
+
text-align: center;
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2598
2809
|
.collapsible-content {
|
|
2599
2810
|
animation: collapsible-open 0.15s ease;
|
|
2600
2811
|
}
|
|
@@ -2610,42 +2821,59 @@ html, body, #mbeditor-root {
|
|
|
2610
2821
|
}
|
|
2611
2822
|
}
|
|
2612
2823
|
|
|
2613
|
-
/* ── Quick Open Dialog ───────────────────────────────────────
|
|
2824
|
+
/* ── Quick Open Dialog ───────────────────────────────────────
|
|
2825
|
+
VS Code's command palette: a 600px sheet anchored near the top of the
|
|
2826
|
+
window, not a centred modal. The rows are 22px and single-line — the path
|
|
2827
|
+
sits beside the name rather than under it, which is what lets a full
|
|
2828
|
+
viewport of results be scanned without scrolling. */
|
|
2614
2829
|
.quick-open-overlay {
|
|
2615
2830
|
position: fixed;
|
|
2616
2831
|
inset: 0;
|
|
2617
|
-
background: rgba(0,0,0,0.
|
|
2832
|
+
background: rgba(0,0,0,0.35);
|
|
2618
2833
|
display: flex;
|
|
2619
2834
|
align-items: flex-start;
|
|
2620
2835
|
justify-content: center;
|
|
2621
|
-
padding-top:
|
|
2836
|
+
padding-top: 6px;
|
|
2622
2837
|
z-index: 9999;
|
|
2623
2838
|
}
|
|
2624
2839
|
|
|
2840
|
+
/* Always a frosted panel — VS Code's Quick Open floats over the editor, not
|
|
2841
|
+
inside it, so it stays readable whether or not the glass theme is on. */
|
|
2625
2842
|
.quick-open-box {
|
|
2626
|
-
|
|
2627
|
-
|
|
2843
|
+
backdrop-filter: blur(20px) saturate(180%);
|
|
2844
|
+
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
2845
|
+
background: color-mix(in srgb, var(--ide-panel-bg) 78%, transparent);
|
|
2846
|
+
border: 1px solid color-mix(in srgb, var(--ide-text) 16%, transparent);
|
|
2628
2847
|
border-radius: 8px;
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
max-height: min(620px, 72vh);
|
|
2848
|
+
width: min(600px, 94vw);
|
|
2849
|
+
max-height: min(440px, 72vh);
|
|
2632
2850
|
display: flex;
|
|
2633
2851
|
flex-direction: column;
|
|
2634
|
-
box-shadow: 0
|
|
2852
|
+
box-shadow: 0 8px 24px rgba(0,0,0,0.45);
|
|
2635
2853
|
overflow: hidden;
|
|
2636
2854
|
}
|
|
2637
2855
|
|
|
2856
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
2857
|
+
.quick-open-box,
|
|
2858
|
+
.ide-methods-dropdown {
|
|
2859
|
+
backdrop-filter: none;
|
|
2860
|
+
-webkit-backdrop-filter: none;
|
|
2861
|
+
background: var(--ide-panel-bg);
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2638
2865
|
.quick-open-input-wrap {
|
|
2639
2866
|
position: relative;
|
|
2867
|
+
padding: 6px;
|
|
2868
|
+
flex-shrink: 0;
|
|
2640
2869
|
}
|
|
2641
2870
|
|
|
2642
2871
|
.quick-open-input {
|
|
2643
2872
|
background: transparent;
|
|
2644
2873
|
border: none;
|
|
2645
|
-
border-bottom: 1px solid var(--ide-border);
|
|
2646
2874
|
color: var(--ide-text);
|
|
2647
|
-
padding:
|
|
2648
|
-
font-size:
|
|
2875
|
+
padding: 4px 30px 4px 8px;
|
|
2876
|
+
font-size: 13px;
|
|
2649
2877
|
outline: none;
|
|
2650
2878
|
width: 100%;
|
|
2651
2879
|
box-sizing: border-box;
|
|
@@ -2654,13 +2882,13 @@ html, body, #mbeditor-root {
|
|
|
2654
2882
|
|
|
2655
2883
|
.quick-open-clear-btn {
|
|
2656
2884
|
position: absolute;
|
|
2657
|
-
right:
|
|
2885
|
+
right: 10px;
|
|
2658
2886
|
top: 50%;
|
|
2659
2887
|
transform: translateY(-50%);
|
|
2660
|
-
width:
|
|
2661
|
-
height:
|
|
2888
|
+
width: 22px;
|
|
2889
|
+
height: 22px;
|
|
2662
2890
|
border: none;
|
|
2663
|
-
border-radius:
|
|
2891
|
+
border-radius: 5px;
|
|
2664
2892
|
background: transparent;
|
|
2665
2893
|
color: var(--ide-text-muted);
|
|
2666
2894
|
cursor: pointer;
|
|
@@ -2671,53 +2899,64 @@ html, body, #mbeditor-root {
|
|
|
2671
2899
|
|
|
2672
2900
|
.quick-open-clear-btn:hover {
|
|
2673
2901
|
background: var(--ide-hover-bg);
|
|
2674
|
-
color: var(--ide-text
|
|
2902
|
+
color: var(--ide-text);
|
|
2675
2903
|
}
|
|
2676
2904
|
|
|
2677
2905
|
.quick-open-results {
|
|
2678
2906
|
overflow-y: auto;
|
|
2679
2907
|
flex: 1;
|
|
2908
|
+
padding-bottom: 4px;
|
|
2680
2909
|
}
|
|
2681
2910
|
|
|
2682
2911
|
.quick-open-result {
|
|
2683
|
-
padding:
|
|
2912
|
+
padding: 0 10px;
|
|
2913
|
+
height: 22px;
|
|
2684
2914
|
cursor: pointer;
|
|
2685
2915
|
display: flex;
|
|
2686
2916
|
align-items: center;
|
|
2687
|
-
gap:
|
|
2688
|
-
font-size:
|
|
2689
|
-
transition: background 0.1s;
|
|
2917
|
+
gap: 8px;
|
|
2918
|
+
font-size: 13px;
|
|
2690
2919
|
}
|
|
2691
2920
|
|
|
2692
2921
|
.quick-open-result-icon {
|
|
2693
2922
|
flex-shrink: 0;
|
|
2694
|
-
width:
|
|
2923
|
+
width: 16px;
|
|
2924
|
+
font-size: 12px;
|
|
2695
2925
|
text-align: center;
|
|
2696
2926
|
color: #78b4e0;
|
|
2697
2927
|
}
|
|
2698
2928
|
|
|
2929
|
+
/* Name and path on one line: the name at its natural width, the path taking
|
|
2930
|
+
the slack and ellipsing. Two stacked lines would double the row height. */
|
|
2699
2931
|
.quick-open-result-body {
|
|
2700
2932
|
min-width: 0;
|
|
2701
2933
|
flex: 1;
|
|
2934
|
+
display: flex;
|
|
2935
|
+
align-items: baseline;
|
|
2936
|
+
gap: 8px;
|
|
2937
|
+
overflow: hidden;
|
|
2702
2938
|
}
|
|
2703
2939
|
|
|
2704
|
-
.quick-open-result:hover
|
|
2705
|
-
.quick-open-result.selected { background: var(--ide-active-bg); }
|
|
2940
|
+
.quick-open-result:hover { background: var(--ide-hover-bg); }
|
|
2941
|
+
.quick-open-result.selected { background: var(--ide-active-bg); color: var(--ide-text); }
|
|
2706
2942
|
|
|
2707
|
-
.quick-open-result-name { color: var(--ide-text); }
|
|
2943
|
+
.quick-open-result-name { color: var(--ide-text); flex-shrink: 0; white-space: nowrap; }
|
|
2708
2944
|
.quick-open-result-path { color: var(--ide-text-muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
2709
2945
|
|
|
2710
2946
|
.quick-open-section { margin-bottom: 4px; }
|
|
2711
|
-
.quick-open-section-header { padding: 8px
|
|
2947
|
+
.quick-open-section-header { padding: 8px 10px 4px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ide-text); font-weight: 700; }
|
|
2948
|
+
.quick-open-section-header-muted { color: var(--ide-text-muted); font-weight: 600; letter-spacing: 0.08em; }
|
|
2949
|
+
|
|
2950
|
+
.quick-open-recent-label { font-size: 12px; color: var(--ide-text-muted); flex-shrink: 0; }
|
|
2712
2951
|
|
|
2713
2952
|
.quick-open-star-btn {
|
|
2714
2953
|
flex-shrink: 0;
|
|
2715
2954
|
background: none;
|
|
2716
2955
|
border: none;
|
|
2717
2956
|
cursor: pointer;
|
|
2718
|
-
padding:
|
|
2957
|
+
padding: 0 4px;
|
|
2719
2958
|
color: var(--ide-text-muted);
|
|
2720
|
-
font-size:
|
|
2959
|
+
font-size: 12px;
|
|
2721
2960
|
line-height: 1;
|
|
2722
2961
|
opacity: 0;
|
|
2723
2962
|
transition: opacity 0.1s, color 0.1s;
|
|
@@ -2828,48 +3067,177 @@ html, body, #mbeditor-root {
|
|
|
2828
3067
|
.ide-draft-restore-btn:hover { background: var(--ide-hover-bg); }
|
|
2829
3068
|
.ide-draft-restore-btn-primary {
|
|
2830
3069
|
background: var(--ide-accent);
|
|
2831
|
-
color: var(--ide-accent
|
|
3070
|
+
color: var(--ide-on-accent);
|
|
2832
3071
|
border-color: var(--ide-accent);
|
|
2833
3072
|
}
|
|
2834
3073
|
.ide-draft-restore-btn-primary:hover { opacity: 0.9; }
|
|
2835
3074
|
|
|
2836
3075
|
/* ── Settings panel ─────────────────────────────────────────── */
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
.ide-settings-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
/* Inputs in full-width rows stay narrow */
|
|
2850
|
-
.ide-settings-input { background: var(--ide-input-bg); color: var(--ide-text); border: 1px solid var(--ide-border-input); border-radius: 3px; padding: 4px 6px; font-size: 12px; width: 72px; box-sizing: border-box; }
|
|
2851
|
-
.ide-settings-input-wide { font-family: monospace; flex: 1; width: auto; }
|
|
2852
|
-
/* Selects in half-width rows use Pico styling (inherit theme vars); just cap size */
|
|
2853
|
-
.ide-settings-row-half select { width: 100%; }
|
|
2854
|
-
.ide-settings-checkbox { width: auto; cursor: pointer; flex-shrink: 0; }
|
|
2855
|
-
.ide-settings-reset-btn { margin-top: 4px; grid-column: 1/-1; background: var(--ide-panel-bg-alt); color: var(--ide-text-muted); border: 1px solid var(--ide-border-input); border-radius: 3px; padding: 5px 10px; font-size: 11px; cursor: pointer; align-self: flex-start; }
|
|
2856
|
-
.ide-settings-reset-btn:hover { background: var(--ide-border-input); color: var(--ide-text-dim); }
|
|
2857
|
-
.ide-settings-section-header { font-size: 10px; font-weight: 700; color: var(--ide-text-muted); text-transform: uppercase; letter-spacing: 1px; padding: 8px 0 3px; border-bottom: 1px solid var(--ide-border); margin-top: 6px; grid-column: 1/-1; }
|
|
2858
|
-
.ide-settings-section-header:first-child { margin-top: 0; }
|
|
2859
|
-
.ide-settings-row-link { grid-column: 1/-1; flex-direction: row; align-items: center; justify-content: space-between; }
|
|
2860
|
-
.ide-settings-config-link { background: none; border: none; color: var(--ide-accent-fg); font-size: 11px; cursor: pointer; padding: 0; display: flex; align-items: center; gap: 3px; text-decoration: underline; text-underline-offset: 2px; }
|
|
2861
|
-
.ide-settings-config-link:hover { color: var(--ide-accent); }
|
|
3076
|
+
/* ══ SETTINGS MODAL ═════════════════════════════════════════════════════════
|
|
3077
|
+
* VS Code-style: left nav of sections, scrolling right pane of rows.
|
|
3078
|
+
* ─────────────────────────────────────────────────────────────────────────── */
|
|
3079
|
+
.ide-settings-overlay {
|
|
3080
|
+
position: fixed;
|
|
3081
|
+
inset: 0;
|
|
3082
|
+
background: rgba(0,0,0,0.45);
|
|
3083
|
+
z-index: 9100;
|
|
3084
|
+
display: flex;
|
|
3085
|
+
align-items: center;
|
|
3086
|
+
justify-content: center;
|
|
3087
|
+
}
|
|
2862
3088
|
|
|
2863
|
-
/*
|
|
2864
|
-
.ide-settings-
|
|
3089
|
+
/* Frosted like Quick Open — it floats over the editor, not inside it. */
|
|
3090
|
+
.ide-settings-modal {
|
|
3091
|
+
backdrop-filter: blur(20px) saturate(180%);
|
|
3092
|
+
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
3093
|
+
background: color-mix(in srgb, var(--ide-panel-bg) 82%, transparent);
|
|
3094
|
+
border: 1px solid color-mix(in srgb, var(--ide-text) 16%, transparent);
|
|
3095
|
+
border-radius: 8px;
|
|
3096
|
+
width: min(900px, 90vw);
|
|
3097
|
+
height: min(640px, 85vh);
|
|
2865
3098
|
display: flex;
|
|
2866
3099
|
flex-direction: column;
|
|
2867
|
-
|
|
3100
|
+
box-shadow: 0 8px 32px rgba(0,0,0,0.5);
|
|
3101
|
+
overflow: hidden;
|
|
3102
|
+
color: var(--ide-text);
|
|
3103
|
+
}
|
|
3104
|
+
|
|
3105
|
+
@media (prefers-reduced-transparency: reduce) {
|
|
3106
|
+
.ide-settings-modal {
|
|
3107
|
+
backdrop-filter: none;
|
|
3108
|
+
-webkit-backdrop-filter: none;
|
|
3109
|
+
background: var(--ide-panel-bg);
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
|
|
3113
|
+
.ide-settings-modal-header {
|
|
3114
|
+
height: 44px;
|
|
3115
|
+
flex-shrink: 0;
|
|
3116
|
+
display: flex;
|
|
3117
|
+
align-items: center;
|
|
3118
|
+
gap: 12px;
|
|
3119
|
+
padding: 0 12px;
|
|
3120
|
+
border-bottom: 1px solid var(--ide-border);
|
|
3121
|
+
}
|
|
3122
|
+
.ide-settings-modal-title { font-size: 13px; font-weight: 600; color: var(--ide-text); flex-shrink: 0; }
|
|
3123
|
+
.ide-settings-search {
|
|
3124
|
+
flex: 1;
|
|
3125
|
+
min-width: 0;
|
|
3126
|
+
background: var(--ide-input-bg);
|
|
3127
|
+
color: var(--ide-text);
|
|
3128
|
+
border: 1px solid var(--ide-border-input);
|
|
3129
|
+
border-radius: 8px;
|
|
3130
|
+
padding: 5px 10px;
|
|
3131
|
+
font-size: 12px;
|
|
3132
|
+
margin-bottom: 0;
|
|
3133
|
+
}
|
|
3134
|
+
.ide-settings-search::placeholder { color: var(--ide-text-muted); }
|
|
3135
|
+
/* Scoped under the modal: a global `button:not(.pico-btn)` rule sets 12px
|
|
3136
|
+
and would otherwise shrink the glyph to a speck. */
|
|
3137
|
+
.ide-settings-modal .ide-settings-modal-close {
|
|
3138
|
+
width: 28px;
|
|
3139
|
+
height: 28px;
|
|
3140
|
+
display: inline-flex;
|
|
3141
|
+
align-items: center;
|
|
3142
|
+
justify-content: center;
|
|
3143
|
+
background: none;
|
|
3144
|
+
border: none;
|
|
3145
|
+
border-radius: 6px;
|
|
3146
|
+
color: var(--ide-text-muted);
|
|
3147
|
+
font-size: 16px;
|
|
3148
|
+
line-height: 1;
|
|
3149
|
+
cursor: pointer;
|
|
3150
|
+
padding: 0;
|
|
3151
|
+
margin-bottom: 0;
|
|
3152
|
+
}
|
|
3153
|
+
.ide-settings-modal .ide-settings-modal-close:hover { color: var(--ide-text); background: var(--ide-hover-bg); }
|
|
3154
|
+
|
|
3155
|
+
.ide-settings-modal-body { flex: 1; display: flex; min-height: 0; }
|
|
3156
|
+
|
|
3157
|
+
.ide-settings-nav {
|
|
3158
|
+
width: 180px;
|
|
3159
|
+
flex-shrink: 0;
|
|
3160
|
+
border-right: 1px solid var(--ide-border);
|
|
3161
|
+
padding: 10px 0;
|
|
2868
3162
|
overflow-y: auto;
|
|
2869
|
-
|
|
2870
|
-
|
|
3163
|
+
display: flex;
|
|
3164
|
+
flex-direction: column;
|
|
3165
|
+
justify-content: flex-start; /* a shared nav rule sets space-between */
|
|
2871
3166
|
}
|
|
3167
|
+
.ide-settings-nav-item {
|
|
3168
|
+
background: none;
|
|
3169
|
+
border: none;
|
|
3170
|
+
border-left: 2px solid transparent;
|
|
3171
|
+
color: var(--ide-text-muted);
|
|
3172
|
+
font-size: 11px;
|
|
3173
|
+
font-weight: 600;
|
|
3174
|
+
text-transform: uppercase;
|
|
3175
|
+
letter-spacing: 0.6px;
|
|
3176
|
+
text-align: left;
|
|
3177
|
+
padding: 6px 14px;
|
|
3178
|
+
cursor: pointer;
|
|
3179
|
+
margin-bottom: 0;
|
|
3180
|
+
width: 100%;
|
|
3181
|
+
}
|
|
3182
|
+
.ide-settings-nav-item:hover { color: var(--ide-text); }
|
|
3183
|
+
.ide-settings-nav-item.active { color: var(--ide-text); border-left-color: var(--ide-accent); }
|
|
2872
3184
|
|
|
3185
|
+
.ide-settings-body {
|
|
3186
|
+
flex: 1;
|
|
3187
|
+
min-width: 0;
|
|
3188
|
+
overflow-y: auto;
|
|
3189
|
+
padding: 12px 20px 20px;
|
|
3190
|
+
}
|
|
3191
|
+
.ide-settings-section { padding-top: 10px; }
|
|
3192
|
+
.ide-settings-section-header {
|
|
3193
|
+
font-size: 13px;
|
|
3194
|
+
font-weight: 600;
|
|
3195
|
+
color: var(--ide-text);
|
|
3196
|
+
margin: 0 0 10px;
|
|
3197
|
+
padding-bottom: 4px;
|
|
3198
|
+
border-bottom: 1px solid var(--ide-border);
|
|
3199
|
+
}
|
|
3200
|
+
|
|
3201
|
+
.ide-settings-row {
|
|
3202
|
+
display: flex;
|
|
3203
|
+
flex-direction: column;
|
|
3204
|
+
align-items: flex-start;
|
|
3205
|
+
gap: 3px;
|
|
3206
|
+
margin-bottom: 12px;
|
|
3207
|
+
}
|
|
3208
|
+
.ide-settings-row-check {
|
|
3209
|
+
display: grid;
|
|
3210
|
+
grid-template-columns: auto 1fr;
|
|
3211
|
+
column-gap: 8px;
|
|
3212
|
+
align-items: start;
|
|
3213
|
+
}
|
|
3214
|
+
.ide-settings-row-check .ide-settings-checkbox { grid-column: 1; grid-row: 1; margin: 2px 0 0; }
|
|
3215
|
+
.ide-settings-row-check .ide-settings-label { grid-column: 2; grid-row: 1; }
|
|
3216
|
+
.ide-settings-row-check .ide-settings-desc { grid-column: 2; grid-row: 2; }
|
|
3217
|
+
|
|
3218
|
+
.ide-settings-label { font-size: 13px; color: var(--ide-text); }
|
|
3219
|
+
.ide-settings-desc { font-size: 12px; color: var(--ide-text-muted); line-height: 1.4; }
|
|
3220
|
+
.ide-settings-input {
|
|
3221
|
+
background: var(--ide-input-bg);
|
|
3222
|
+
color: var(--ide-text);
|
|
3223
|
+
border: 1px solid var(--ide-border-input);
|
|
3224
|
+
border-radius: 4px;
|
|
3225
|
+
padding: 4px 6px;
|
|
3226
|
+
font-size: 12px;
|
|
3227
|
+
width: 260px;
|
|
3228
|
+
max-width: 100%;
|
|
3229
|
+
box-sizing: border-box;
|
|
3230
|
+
margin-top: 2px;
|
|
3231
|
+
}
|
|
3232
|
+
.ide-settings-input-number { width: 100px; }
|
|
3233
|
+
.ide-settings-input-wide { font-family: monospace; width: 100%; }
|
|
3234
|
+
.ide-settings-checkbox { width: auto; cursor: pointer; flex-shrink: 0; }
|
|
3235
|
+
|
|
3236
|
+
.ide-settings-config-link { background: none; border: none; color: var(--ide-accent-fg); font-size: 12px; cursor: pointer; padding: 0; display: flex; align-items: center; gap: 3px; text-decoration: underline; text-underline-offset: 2px; margin-bottom: 0; }
|
|
3237
|
+
.ide-settings-config-link:hover { color: var(--ide-accent); }
|
|
3238
|
+
.ide-settings-empty { font-size: 12px; color: var(--ide-text-muted); padding: 20px 0; }
|
|
3239
|
+
.ide-settings-reset-btn { margin-top: 16px; background: var(--ide-panel-bg-alt); color: var(--ide-text-muted); border: 1px solid var(--ide-border-input); border-radius: 4px; padding: 5px 10px; font-size: 12px; cursor: pointer; }
|
|
3240
|
+
.ide-settings-reset-btn:hover { background: var(--ide-border-input); color: var(--ide-text-dim); }
|
|
2873
3241
|
|
|
2874
3242
|
/* ══ PICO CSS COMPACT OVERRIDES ═════════════════════════════════════════════
|
|
2875
3243
|
* Pico's classless variant inflates native elements with generous padding.
|
|
@@ -2974,12 +3342,12 @@ textarea {
|
|
|
2974
3342
|
.ide-statusbar button,
|
|
2975
3343
|
.statusbar-btn {
|
|
2976
3344
|
--pico-form-element-spacing-vertical: 0;
|
|
2977
|
-
--pico-form-element-spacing-horizontal:
|
|
2978
|
-
height:
|
|
2979
|
-
padding: 0
|
|
2980
|
-
font-size:
|
|
3345
|
+
--pico-form-element-spacing-horizontal: 6px;
|
|
3346
|
+
height: 20px;
|
|
3347
|
+
padding: 0 6px;
|
|
3348
|
+
font-size: 12px;
|
|
2981
3349
|
line-height: 1;
|
|
2982
|
-
border-radius:
|
|
3350
|
+
border-radius: 5px;
|
|
2983
3351
|
border: none;
|
|
2984
3352
|
background: transparent;
|
|
2985
3353
|
color: var(--ide-accent-text);
|
|
@@ -3076,7 +3444,19 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3076
3444
|
border-radius: 0;
|
|
3077
3445
|
}
|
|
3078
3446
|
/* Re-apply border-radius for buttons that intentionally need it */
|
|
3079
|
-
.ide-shell .ide-titlebar-search { border-radius:
|
|
3447
|
+
.ide-shell .ide-titlebar-search { border-radius: 6px; }
|
|
3448
|
+
.ide-shell .collab-avatar {
|
|
3449
|
+
width: 9px;
|
|
3450
|
+
height: 9px;
|
|
3451
|
+
padding: 0;
|
|
3452
|
+
border-radius: 50%;
|
|
3453
|
+
}
|
|
3454
|
+
.ide-shell .collab-avatar-more {
|
|
3455
|
+
width: auto;
|
|
3456
|
+
height: auto;
|
|
3457
|
+
padding: 0;
|
|
3458
|
+
border-radius: 0;
|
|
3459
|
+
}
|
|
3080
3460
|
.ide-shell .project-action-btn,
|
|
3081
3461
|
.ide-shell .git-header-btn,
|
|
3082
3462
|
.ide-shell .git-section-action-btn,
|
|
@@ -3192,15 +3572,6 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3192
3572
|
background: var(--ide-panel-bg, #1e1e1e);
|
|
3193
3573
|
border-top: 1px solid var(--ide-border, #333);
|
|
3194
3574
|
}
|
|
3195
|
-
.ide-log-resize {
|
|
3196
|
-
flex: 0 0 auto;
|
|
3197
|
-
height: 6px;
|
|
3198
|
-
cursor: ns-resize;
|
|
3199
|
-
background: transparent;
|
|
3200
|
-
}
|
|
3201
|
-
.ide-log-resize:hover {
|
|
3202
|
-
background: var(--ide-accent, #569cd6);
|
|
3203
|
-
}
|
|
3204
3575
|
.ide-log-header {
|
|
3205
3576
|
display: flex;
|
|
3206
3577
|
align-items: center;
|
|
@@ -3268,25 +3639,35 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3268
3639
|
background: var(--ide-panel-bg, #1e1e1e);
|
|
3269
3640
|
border-top: 1px solid var(--ide-border, #333);
|
|
3270
3641
|
}
|
|
3271
|
-
.ide-problems-resize {
|
|
3272
|
-
flex: 0 0 auto;
|
|
3273
|
-
height: 6px;
|
|
3274
|
-
cursor: ns-resize;
|
|
3275
|
-
background: transparent;
|
|
3276
|
-
}
|
|
3277
|
-
.ide-problems-resize:hover { background: var(--ide-accent, #569cd6); }
|
|
3278
3642
|
.ide-problems-header {
|
|
3279
3643
|
display: flex;
|
|
3280
3644
|
align-items: center;
|
|
3281
3645
|
gap: 8px;
|
|
3282
|
-
|
|
3646
|
+
height: 35px;
|
|
3647
|
+
padding: 0 10px;
|
|
3283
3648
|
border-bottom: 1px solid var(--ide-border, #333);
|
|
3284
3649
|
font-size: 12px;
|
|
3285
|
-
color: var(--ide-
|
|
3650
|
+
color: var(--ide-text, #ccc);
|
|
3651
|
+
}
|
|
3652
|
+
.ide-problems-title {
|
|
3653
|
+
font-size: 11px;
|
|
3654
|
+
font-weight: 600;
|
|
3655
|
+
text-transform: uppercase;
|
|
3656
|
+
letter-spacing: 0.06em;
|
|
3657
|
+
}
|
|
3658
|
+
.ide-problems-total-pill {
|
|
3659
|
+
display: inline-flex;
|
|
3660
|
+
align-items: center;
|
|
3661
|
+
height: 18px;
|
|
3662
|
+
padding: 0 7px;
|
|
3663
|
+
border-radius: 999px;
|
|
3664
|
+
background: var(--ide-hover-bg, #2a2a2a);
|
|
3665
|
+
color: var(--ide-text, #ccc);
|
|
3666
|
+
font-size: 11px;
|
|
3667
|
+
font-variant-numeric: tabular-nums;
|
|
3286
3668
|
}
|
|
3287
|
-
.
|
|
3288
|
-
|
|
3289
|
-
follows keeps its own left margin off `auto` so the two sit together. */
|
|
3669
|
+
/* Severity toggles. Pushed to the right of the title/count; the text filter
|
|
3670
|
+
that follows keeps its own left margin off `auto` so the two sit together. */
|
|
3290
3671
|
.ide-problems-severity-filter {
|
|
3291
3672
|
margin-left: auto;
|
|
3292
3673
|
display: flex;
|
|
@@ -3297,50 +3678,42 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3297
3678
|
align-items: center;
|
|
3298
3679
|
gap: 4px;
|
|
3299
3680
|
background: transparent;
|
|
3300
|
-
border:
|
|
3681
|
+
border: none;
|
|
3301
3682
|
border-radius: 3px;
|
|
3302
3683
|
padding: 1px 6px;
|
|
3303
3684
|
font-size: 11px;
|
|
3304
3685
|
font-variant-numeric: tabular-nums;
|
|
3305
3686
|
cursor: pointer;
|
|
3306
|
-
/* Off is legible but clearly recessive — a disabled-looking chip reads as
|
|
3307
|
-
"broken" rather than "toggled off". */
|
|
3308
3687
|
color: var(--ide-text-muted, #858585);
|
|
3309
|
-
opacity: 0.55;
|
|
3310
|
-
}
|
|
3311
|
-
.ide-problems-sev-chip:hover { opacity: 0.85; }
|
|
3312
|
-
.ide-problems-sev-chip.is-on {
|
|
3313
|
-
opacity: 1;
|
|
3314
|
-
border-color: var(--ide-border, #333);
|
|
3315
|
-
background: var(--ide-input-bg, #2d2d2d);
|
|
3316
3688
|
}
|
|
3317
|
-
.ide-problems-sev-chip
|
|
3318
|
-
.ide-problems-sev-chip.is-on
|
|
3319
|
-
.ide-problems-sev-chip.is-on.ide-problems-sev-info { color: var(--ide-info, #3794ff); }
|
|
3689
|
+
.ide-problems-sev-chip:hover,
|
|
3690
|
+
.ide-problems-sev-chip.is-on { color: var(--ide-text, #ccc); }
|
|
3320
3691
|
|
|
3321
3692
|
.ide-problems-filter {
|
|
3322
3693
|
margin-left: 8px;
|
|
3323
3694
|
background: var(--ide-input-bg, #2d2d2d);
|
|
3324
|
-
color: var(--ide-
|
|
3325
|
-
border: 1px solid var(--ide-border, #333);
|
|
3326
|
-
border-radius:
|
|
3327
|
-
padding:
|
|
3695
|
+
color: var(--ide-text, #eee);
|
|
3696
|
+
border: 1px solid var(--ide-border-input, #333);
|
|
3697
|
+
border-radius: 4px;
|
|
3698
|
+
padding: 0 6px;
|
|
3699
|
+
height: 22px;
|
|
3328
3700
|
font-size: 12px;
|
|
3329
|
-
width:
|
|
3701
|
+
width: 140px;
|
|
3330
3702
|
}
|
|
3331
3703
|
.ide-problems-btn {
|
|
3332
3704
|
background: transparent;
|
|
3333
3705
|
border: none;
|
|
3334
|
-
color: var(--ide-
|
|
3706
|
+
color: var(--ide-text-muted, #ccc);
|
|
3335
3707
|
cursor: pointer;
|
|
3336
3708
|
padding: 2px 6px;
|
|
3337
3709
|
}
|
|
3338
|
-
.ide-problems-btn:hover { color: var(--ide-
|
|
3710
|
+
.ide-problems-btn:hover { color: var(--ide-text, #fff); }
|
|
3339
3711
|
.ide-problems-btn:disabled { opacity: 0.4; cursor: default; }
|
|
3340
|
-
.ide-problems-btn:disabled:hover { color: var(--ide-
|
|
3712
|
+
.ide-problems-btn:disabled:hover { color: var(--ide-text-muted, #ccc); }
|
|
3341
3713
|
.ide-problems-actions { display: flex; gap: 2px; }
|
|
3342
|
-
.ide-problems-actions .ide-
|
|
3343
|
-
.ide-problems-
|
|
3714
|
+
.ide-problems-actions .ide-icon-btn,
|
|
3715
|
+
.ide-problems-header > .ide-icon-btn { min-width: 22px; width: 22px; height: 22px; font-size: 13px; }
|
|
3716
|
+
.ide-problems-actions .ide-icon-btn:disabled { opacity: 0.4; cursor: default; pointer-events: none; }
|
|
3344
3717
|
.ide-problems-body { flex: 1; overflow: auto; padding: 4px 0; font-size: 12px; }
|
|
3345
3718
|
.ide-problems-empty {
|
|
3346
3719
|
padding: 10px 14px;
|
|
@@ -3351,9 +3724,18 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3351
3724
|
display: flex;
|
|
3352
3725
|
align-items: center;
|
|
3353
3726
|
gap: 6px;
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3727
|
+
height: 22px;
|
|
3728
|
+
padding: 0 12px;
|
|
3729
|
+
color: var(--ide-text, #ccc);
|
|
3730
|
+
}
|
|
3731
|
+
.ide-problems-file-name .fa-chevron-down {
|
|
3732
|
+
color: var(--ide-text-muted, #858585);
|
|
3733
|
+
font-size: 10px;
|
|
3734
|
+
width: 10px;
|
|
3735
|
+
}
|
|
3736
|
+
.ide-problems-file-name .ide-problems-dir {
|
|
3737
|
+
color: var(--ide-text-muted, #858585);
|
|
3738
|
+
font-size: 12px;
|
|
3357
3739
|
}
|
|
3358
3740
|
.ide-problems-file-count {
|
|
3359
3741
|
background: var(--ide-hover-bg, #2a2a2a);
|
|
@@ -3368,22 +3750,23 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3368
3750
|
align-items: baseline;
|
|
3369
3751
|
gap: 8px;
|
|
3370
3752
|
width: 100%;
|
|
3371
|
-
|
|
3753
|
+
height: 22px;
|
|
3754
|
+
padding: 0 12px 0 28px;
|
|
3372
3755
|
background: transparent;
|
|
3373
3756
|
border: none;
|
|
3374
|
-
color: var(--ide-
|
|
3757
|
+
color: var(--ide-text, #d4d4d4);
|
|
3375
3758
|
font-size: 12px;
|
|
3376
3759
|
font-family: inherit;
|
|
3377
3760
|
text-align: left;
|
|
3378
3761
|
cursor: pointer;
|
|
3379
3762
|
}
|
|
3380
|
-
.ide-problems-item:hover,
|
|
3381
|
-
.ide-problems-item:focus-visible { background: var(--ide-
|
|
3763
|
+
.ide-problems-item:hover { background: var(--ide-hover-bg, #2a2a2a); }
|
|
3764
|
+
.ide-problems-item:focus-visible { background: var(--ide-active-bg, #2a2a2a); }
|
|
3382
3765
|
.ide-problems-icon { flex-shrink: 0; }
|
|
3383
3766
|
.ide-problems-item-error .ide-problems-icon { color: var(--ide-danger); }
|
|
3384
3767
|
.ide-problems-item-warning .ide-problems-icon { color: var(--ide-warning); }
|
|
3385
3768
|
.ide-problems-item-info .ide-problems-icon { color: var(--ide-accent, #3794ff); }
|
|
3386
|
-
.ide-problems-msg { flex-
|
|
3769
|
+
.ide-problems-msg { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ide-text, #d4d4d4); }
|
|
3387
3770
|
/* The offending source line, dimmed so it reads as context rather than as part
|
|
3388
3771
|
of the message. It is the one part of the row allowed to shrink, so a long
|
|
3389
3772
|
line gives way to the message and location instead of pushing them out. */
|
|
@@ -3393,7 +3776,6 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3393
3776
|
text-overflow: ellipsis;
|
|
3394
3777
|
white-space: nowrap;
|
|
3395
3778
|
color: var(--ide-text-muted, #858585);
|
|
3396
|
-
opacity: 0.8;
|
|
3397
3779
|
font-family: var(--ide-mono, monospace);
|
|
3398
3780
|
font-size: 11px;
|
|
3399
3781
|
}
|
|
@@ -3422,12 +3804,24 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3422
3804
|
margin-left: auto;
|
|
3423
3805
|
color: var(--ide-text-muted, #858585);
|
|
3424
3806
|
font-size: 11px;
|
|
3807
|
+
font-variant-numeric: tabular-nums;
|
|
3425
3808
|
}
|
|
3426
3809
|
|
|
3427
3810
|
/* ── Model graph ──────────────────────────────────────────────────────────
|
|
3428
3811
|
An SVG ER diagram of the app's ActiveRecord models. The panel is narrow, so
|
|
3429
3812
|
the SVG scrolls in both directions rather than being scaled down to
|
|
3430
3813
|
illegibility. */
|
|
3814
|
+
/* The graph replaces the whole centre column when its view is open, so it
|
|
3815
|
+
takes the same box the panes and drawers would have. */
|
|
3816
|
+
.ide-model-graph-view {
|
|
3817
|
+
flex: 1;
|
|
3818
|
+
display: flex;
|
|
3819
|
+
flex-direction: column;
|
|
3820
|
+
min-width: 0;
|
|
3821
|
+
min-height: 0;
|
|
3822
|
+
overflow: hidden;
|
|
3823
|
+
}
|
|
3824
|
+
|
|
3431
3825
|
.ide-model-graph { display: flex; flex-direction: column; height: 100%; min-height: 0; position: relative; }
|
|
3432
3826
|
.ide-model-graph-empty {
|
|
3433
3827
|
padding: 16px;
|
|
@@ -3577,8 +3971,7 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3577
3971
|
The gap is the icon-to-its-own-number spacing; the warning icon opens the
|
|
3578
3972
|
second pair, so it gets the wider separator. */
|
|
3579
3973
|
.statusbar-problems { gap: 4px; }
|
|
3580
|
-
.statusbar-problems-
|
|
3581
|
-
.statusbar-problems-warning-icon { color: var(--ide-warning); margin-left: 8px; }
|
|
3974
|
+
.statusbar-problems-warning-icon { margin-left: 8px; }
|
|
3582
3975
|
.statusbar-problems-count { font-variant-numeric: tabular-nums; }
|
|
3583
3976
|
|
|
3584
3977
|
/* Search decorations off across engines — Chrome/Safari draw their own
|
|
@@ -3717,6 +4110,7 @@ input.ide-model-graph-search[type="search"] {
|
|
|
3717
4110
|
/* Pair-programming diagnostics. The chip only appears when a condition pairing
|
|
3718
4111
|
needs has actually failed — an empty room is silence, not a warning. */
|
|
3719
4112
|
.mbeditor-collab-trouble { color: var(--ide-warning, #cca700); }
|
|
4113
|
+
.mbeditor-conflict-chip { color: var(--ide-error, #f48771); }
|
|
3720
4114
|
.mbeditor-modal-backdrop {
|
|
3721
4115
|
position: fixed; inset: 0; z-index: 5000;
|
|
3722
4116
|
background: rgba(0, 0, 0, 0.45);
|