mbeditor 0.13.0 → 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 +157 -1
- data/app/assets/javascripts/mbeditor/application.js +3 -1
- data/app/assets/javascripts/mbeditor/audit_log.js +165 -0
- data/app/assets/javascripts/mbeditor/collaboration_service.js +264 -22
- 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 +440 -334
- 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/ImportDialog.js +9 -1
- data/app/assets/javascripts/mbeditor/components/LogPanel.js +3 -44
- data/app/assets/javascripts/mbeditor/components/MbeditorApp.js +1322 -1431
- data/app/assets/javascripts/mbeditor/components/ModelGraph.js +94 -37
- data/app/assets/javascripts/mbeditor/components/ProblemsPanel.js +82 -72
- data/app/assets/javascripts/mbeditor/components/QuickOpenDialog.js +121 -81
- 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 +694 -306
- data/app/assets/javascripts/mbeditor/file_import.js +13 -15
- data/app/assets/javascripts/mbeditor/file_service.js +46 -57
- 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 +29 -2
- data/app/assets/javascripts/mbeditor/tab_manager.js +135 -54
- 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 +762 -297
- 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 +25 -6
- data/app/controllers/mbeditor/application_controller.rb +26 -3
- data/app/controllers/mbeditor/editors_controller.rb +125 -465
- data/app/services/mbeditor/archive_service.rb +137 -0
- data/app/services/mbeditor/collaboration_doc_store.rb +180 -12
- data/app/services/mbeditor/duplicate_content_scanner.rb +105 -0
- 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_globals_service.rb +12 -1
- 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/rubocop_run_service.rb +17 -5
- data/app/services/mbeditor/ruby_lsp_result_translator.rb +226 -0
- data/app/services/mbeditor/schema_service.rb +8 -2
- data/app/services/mbeditor/search_replace_service.rb +19 -2
- data/app/services/mbeditor/test_runner_service.rb +3 -56
- data/app/views/layouts/mbeditor/application.html.erb +1 -1
- data/lib/mbeditor/audit_log.rb +203 -0
- data/lib/mbeditor/configuration.rb +6 -9
- data/lib/mbeditor/rack/pending_migration_bypass.rb +15 -9
- data/lib/mbeditor/route_map.rb +4 -1
- data/lib/mbeditor/ruby_lsp_client.rb +82 -14
- data/lib/mbeditor/version.rb +1 -1
- data/lib/mbeditor.rb +1 -0
- data/lib/tasks/mbeditor.rake +23 -0
- metadata +14 -3
- data/app/assets/javascripts/mbeditor/components/TestRunPanel.js +0 -312
|
@@ -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 {
|
|
@@ -876,23 +922,34 @@ html, body, #mbeditor-root {
|
|
|
876
922
|
}
|
|
877
923
|
|
|
878
924
|
/* ── Status Bar ──────────────────────────────────────────── */
|
|
925
|
+
/* line-height: 1 is what keeps an icon and the number beside it on the same
|
|
926
|
+
* centre line. Pico's inherited 1.5 gave every text span a 16.5px line box
|
|
927
|
+
* inside a 22px bar while the icons' box was 11px, so the two were centred on
|
|
928
|
+
* different half-leadings; with 1 both boxes are the font's own content box
|
|
929
|
+
* and flex centres them together. */
|
|
879
930
|
.ide-statusbar {
|
|
880
931
|
display: flex;
|
|
881
932
|
align-items: center;
|
|
882
|
-
background: var(--ide-
|
|
933
|
+
background: var(--ide-statusbar-bg);
|
|
934
|
+
border-top: 1px solid var(--ide-border);
|
|
883
935
|
height: 22px;
|
|
884
|
-
padding: 0
|
|
885
|
-
gap:
|
|
936
|
+
padding: 0;
|
|
937
|
+
gap: 0;
|
|
886
938
|
flex-shrink: 0;
|
|
887
|
-
font-size:
|
|
939
|
+
font-size: 12px;
|
|
940
|
+
line-height: 20px; /* glyphs centre in the row; line-height 1 sat them high */
|
|
888
941
|
color: var(--ide-accent-text);
|
|
889
942
|
}
|
|
890
943
|
|
|
944
|
+
/* One cell rhythm for every item, button or not. The branch, the message and
|
|
945
|
+
* the chips each carried their own padding on top of the bar's, so the gaps
|
|
946
|
+
* between them were all different widths. */
|
|
947
|
+
.ide-statusbar > * { padding: 0 6px; }
|
|
948
|
+
|
|
891
949
|
.statusbar-branch {
|
|
892
950
|
display: flex;
|
|
893
951
|
align-items: center;
|
|
894
|
-
gap:
|
|
895
|
-
font-size: 13px;
|
|
952
|
+
gap: 4px;
|
|
896
953
|
font-weight: 600;
|
|
897
954
|
color: var(--ide-accent-text);
|
|
898
955
|
}
|
|
@@ -919,6 +976,29 @@ html, body, #mbeditor-root {
|
|
|
919
976
|
cursor: default;
|
|
920
977
|
}
|
|
921
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
|
+
|
|
922
1002
|
.statusbar-offline {
|
|
923
1003
|
display: flex;
|
|
924
1004
|
align-items: center;
|
|
@@ -926,7 +1006,6 @@ html, body, #mbeditor-root {
|
|
|
926
1006
|
font-size: 12px;
|
|
927
1007
|
font-weight: 600;
|
|
928
1008
|
color: var(--ide-danger);
|
|
929
|
-
padding: 0 10px;
|
|
930
1009
|
animation: statusbar-pulse 2s ease-in-out infinite;
|
|
931
1010
|
}
|
|
932
1011
|
|
|
@@ -939,19 +1018,32 @@ html, body, #mbeditor-root {
|
|
|
939
1018
|
display: flex;
|
|
940
1019
|
align-items: center;
|
|
941
1020
|
gap: 4px;
|
|
942
|
-
padding: 0
|
|
943
|
-
height:
|
|
1021
|
+
padding: 0 6px;
|
|
1022
|
+
height: 20px;
|
|
1023
|
+
margin: 0 1px;
|
|
944
1024
|
flex-shrink: 0;
|
|
945
1025
|
background: transparent;
|
|
946
1026
|
border: none;
|
|
947
1027
|
color: var(--ide-accent-text);
|
|
948
1028
|
cursor: pointer;
|
|
949
|
-
font-size:
|
|
950
|
-
border-radius:
|
|
1029
|
+
font-size: 12px;
|
|
1030
|
+
border-radius: 5px;
|
|
951
1031
|
transition: background 0.1s;
|
|
952
1032
|
white-space: nowrap;
|
|
953
1033
|
}
|
|
954
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
|
+
|
|
955
1047
|
.statusbar-btn:hover { background: color-mix(in srgb, var(--ide-accent-text) 15%, transparent); }
|
|
956
1048
|
.statusbar-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
957
1049
|
|
|
@@ -1009,6 +1101,77 @@ html, body, #mbeditor-root {
|
|
|
1009
1101
|
.collab-hovercard-row { color: var(--ide-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
1010
1102
|
.collab-hovercard-hint { margin-top: 5px; padding-top: 5px; border-top: 1px solid var(--ide-border); color: var(--ide-text-muted); }
|
|
1011
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
|
+
|
|
1012
1175
|
.statusbar-msg {
|
|
1013
1176
|
margin-left: auto;
|
|
1014
1177
|
color: var(--ide-accent-text);
|
|
@@ -1023,10 +1186,9 @@ html, body, #mbeditor-root {
|
|
|
1023
1186
|
.statusbar-msg.success { color: var(--ide-success); }
|
|
1024
1187
|
|
|
1025
1188
|
.statusbar-version {
|
|
1026
|
-
color: color-mix(in srgb, var(--ide-accent-text)
|
|
1189
|
+
color: color-mix(in srgb, var(--ide-accent-text) 80%, transparent);
|
|
1027
1190
|
font-size: 10px;
|
|
1028
1191
|
white-space: nowrap;
|
|
1029
|
-
padding-left: 8px;
|
|
1030
1192
|
cursor: pointer;
|
|
1031
1193
|
}
|
|
1032
1194
|
.statusbar-version:hover {
|
|
@@ -1039,7 +1201,6 @@ html, body, #mbeditor-root {
|
|
|
1039
1201
|
font-weight: 600;
|
|
1040
1202
|
letter-spacing: 0.04em;
|
|
1041
1203
|
opacity: 0.85;
|
|
1042
|
-
padding: 0 6px;
|
|
1043
1204
|
}
|
|
1044
1205
|
|
|
1045
1206
|
.statusbar-zen-btn {
|
|
@@ -1173,13 +1334,20 @@ html, body, #mbeditor-root {
|
|
|
1173
1334
|
background: var(--ide-input-bg);
|
|
1174
1335
|
color: var(--ide-text);
|
|
1175
1336
|
border: 1px solid var(--ide-border-input);
|
|
1176
|
-
border-radius:
|
|
1337
|
+
border-radius: 8px;
|
|
1177
1338
|
font-size: 12px;
|
|
1178
1339
|
outline: none;
|
|
1179
1340
|
box-sizing: border-box;
|
|
1180
1341
|
}
|
|
1181
1342
|
.search-input::placeholder { color: var(--ide-text-muted); }
|
|
1182
|
-
.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
|
+
}
|
|
1183
1351
|
|
|
1184
1352
|
/* ── Results area wrapper (positions the loading overlay) ── */
|
|
1185
1353
|
.search-results-area {
|
|
@@ -1225,52 +1393,88 @@ html, body, #mbeditor-root {
|
|
|
1225
1393
|
to { transform: rotate(360deg); }
|
|
1226
1394
|
}
|
|
1227
1395
|
|
|
1396
|
+
/* Tree rows. Both kinds are pinned to the same 22px because MbeditorApp
|
|
1397
|
+
windows them by index * SEARCH_ROW_HEIGHT — change one and change both. */
|
|
1398
|
+
.search-result-file-row,
|
|
1228
1399
|
.search-result-item {
|
|
1229
|
-
height:
|
|
1230
|
-
padding: 4px 6px;
|
|
1400
|
+
height: 22px;
|
|
1231
1401
|
cursor: pointer;
|
|
1232
|
-
border-radius: 3px;
|
|
1233
1402
|
transition: background 0.1s;
|
|
1234
|
-
border-bottom: 1px solid var(--ide-input-bg);
|
|
1235
1403
|
display: flex;
|
|
1236
1404
|
align-items: center;
|
|
1237
|
-
gap:
|
|
1405
|
+
gap: 6px;
|
|
1238
1406
|
overflow: hidden;
|
|
1239
1407
|
box-sizing: border-box;
|
|
1240
1408
|
flex-shrink: 0;
|
|
1241
1409
|
}
|
|
1242
1410
|
|
|
1411
|
+
.search-result-file-row { padding: 0 6px; }
|
|
1412
|
+
/* Indented under its file header, the way the explorer nests children. */
|
|
1413
|
+
.search-result-item { padding: 0 6px 0 24px; }
|
|
1414
|
+
|
|
1415
|
+
.search-result-file-row:hover,
|
|
1243
1416
|
.search-result-item:hover { background: var(--ide-hover-bg); }
|
|
1244
1417
|
|
|
1418
|
+
.search-result-chevron {
|
|
1419
|
+
flex-shrink: 0;
|
|
1420
|
+
width: 12px;
|
|
1421
|
+
font-size: 12px;
|
|
1422
|
+
color: var(--ide-text-muted);
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1245
1425
|
.search-result-icon {
|
|
1246
1426
|
flex-shrink: 0;
|
|
1247
1427
|
width: 16px;
|
|
1248
|
-
margin-top: 2px;
|
|
1249
1428
|
text-align: center;
|
|
1250
1429
|
color: #78b4e0;
|
|
1251
1430
|
}
|
|
1252
1431
|
|
|
1253
|
-
.search-result-
|
|
1254
|
-
|
|
1255
|
-
|
|
1432
|
+
.search-result-file-name {
|
|
1433
|
+
font-size: 12px;
|
|
1434
|
+
color: var(--ide-text);
|
|
1435
|
+
white-space: nowrap;
|
|
1436
|
+
flex-shrink: 0;
|
|
1437
|
+
max-width: 60%;
|
|
1438
|
+
overflow: hidden;
|
|
1439
|
+
text-overflow: ellipsis;
|
|
1256
1440
|
}
|
|
1257
1441
|
|
|
1258
|
-
.search-result-file {
|
|
1259
|
-
font-size:
|
|
1260
|
-
color: var(--ide-
|
|
1261
|
-
font-weight: 500;
|
|
1442
|
+
.search-result-file-dir {
|
|
1443
|
+
font-size: 10px;
|
|
1444
|
+
color: var(--ide-text-muted);
|
|
1262
1445
|
white-space: nowrap;
|
|
1263
1446
|
overflow: hidden;
|
|
1264
1447
|
text-overflow: ellipsis;
|
|
1448
|
+
flex: 1;
|
|
1449
|
+
min-width: 0;
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
/* Match count, VS Code's little pill on the right of the file row. */
|
|
1453
|
+
.search-result-count {
|
|
1454
|
+
flex-shrink: 0;
|
|
1455
|
+
margin-left: auto;
|
|
1456
|
+
min-width: 16px;
|
|
1457
|
+
padding: 0 5px;
|
|
1458
|
+
border-radius: 9px;
|
|
1459
|
+
background: var(--ide-input-bg);
|
|
1460
|
+
color: var(--ide-text-muted);
|
|
1461
|
+
font-size: 10px;
|
|
1462
|
+
line-height: 15px;
|
|
1463
|
+
text-align: center;
|
|
1265
1464
|
}
|
|
1266
1465
|
|
|
1267
1466
|
.search-result-line-num {
|
|
1467
|
+
flex-shrink: 0;
|
|
1268
1468
|
font-size: 10px;
|
|
1269
1469
|
color: var(--ide-text-muted);
|
|
1270
|
-
|
|
1470
|
+
font-family: monospace;
|
|
1471
|
+
min-width: 28px;
|
|
1472
|
+
text-align: right;
|
|
1271
1473
|
}
|
|
1272
1474
|
|
|
1273
1475
|
.search-result-text {
|
|
1476
|
+
flex: 1;
|
|
1477
|
+
min-width: 0;
|
|
1274
1478
|
font-size: 11px;
|
|
1275
1479
|
color: var(--ide-text-muted);
|
|
1276
1480
|
font-family: monospace;
|
|
@@ -1279,6 +1483,47 @@ html, body, #mbeditor-root {
|
|
|
1279
1483
|
text-overflow: ellipsis;
|
|
1280
1484
|
}
|
|
1281
1485
|
|
|
1486
|
+
/* The match has to stay on screen at any panel width, so a hit line is three
|
|
1487
|
+
boxes rather than one ellipsised string. Shrink order is what does the work:
|
|
1488
|
+
the text BEFORE the match gives way first, then the text after it, and the
|
|
1489
|
+
match itself only as a last resort — so it can never be the part that scrolls
|
|
1490
|
+
out of view. `direction: rtl` is what moves the leading ellipsis to the start
|
|
1491
|
+
of .search-result-pre; searchMatchParts() prefixes a U+200E so an all-symbol
|
|
1492
|
+
segment can't be reordered by it. */
|
|
1493
|
+
.search-result-text-split {
|
|
1494
|
+
display: flex;
|
|
1495
|
+
align-items: center;
|
|
1496
|
+
text-overflow: clip;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
.search-result-pre,
|
|
1500
|
+
.search-result-post,
|
|
1501
|
+
.search-result-match {
|
|
1502
|
+
overflow: hidden;
|
|
1503
|
+
text-overflow: ellipsis;
|
|
1504
|
+
white-space: pre;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
.search-result-pre {
|
|
1508
|
+
flex: 0 100 auto;
|
|
1509
|
+
direction: rtl;
|
|
1510
|
+
text-align: left;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
.search-result-post { flex: 0 10 auto; }
|
|
1514
|
+
|
|
1515
|
+
/* Never shrinks: flex distributes overflow across every shrinkable box in
|
|
1516
|
+
proportion to its size, so even shrink:1 against a long tail cost the match a
|
|
1517
|
+
character or two of ellipsis. max-width is what still bounds a match wider
|
|
1518
|
+
than the panel — it clips instead of overflowing. */
|
|
1519
|
+
.search-result-match {
|
|
1520
|
+
flex: 0 0 auto;
|
|
1521
|
+
max-width: 100%;
|
|
1522
|
+
background: color-mix(in srgb, var(--ide-accent) 40%, transparent);
|
|
1523
|
+
color: var(--ide-text);
|
|
1524
|
+
border-radius: 2px;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1282
1527
|
.search-results-loading-more {
|
|
1283
1528
|
padding: 8px 10px;
|
|
1284
1529
|
font-size: 11px;
|
|
@@ -1807,8 +2052,9 @@ html, body, #mbeditor-root {
|
|
|
1807
2052
|
|
|
1808
2053
|
/* ── Right-side Git Panel ───────────────────────────────── */
|
|
1809
2054
|
.ide-git-right-panel {
|
|
1810
|
-
|
|
1811
|
-
|
|
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);
|
|
1812
2058
|
display: flex;
|
|
1813
2059
|
flex-direction: column;
|
|
1814
2060
|
overflow: hidden;
|
|
@@ -1817,16 +2063,10 @@ html, body, #mbeditor-root {
|
|
|
1817
2063
|
max-width: 600px;
|
|
1818
2064
|
}
|
|
1819
2065
|
|
|
1820
|
-
.gitpanel-divider {
|
|
1821
|
-
width: 5px;
|
|
1822
|
-
background: var(--ide-panel-bg-alt);
|
|
1823
|
-
border-left: 1px solid var(--ide-border);
|
|
1824
|
-
}
|
|
1825
|
-
|
|
1826
2066
|
.ide-git-panel {
|
|
1827
2067
|
width: 100%;
|
|
1828
2068
|
height: 100%;
|
|
1829
|
-
background: var(--ide-panel-bg
|
|
2069
|
+
background: var(--ide-panel-bg);
|
|
1830
2070
|
display: flex;
|
|
1831
2071
|
flex-direction: column;
|
|
1832
2072
|
overflow: hidden;
|
|
@@ -2120,6 +2360,10 @@ html, body, #mbeditor-root {
|
|
|
2120
2360
|
background: var(--ide-hover-bg);
|
|
2121
2361
|
}
|
|
2122
2362
|
|
|
2363
|
+
/* Nothing to click, so nothing that looks clickable. */
|
|
2364
|
+
.collapsible-header-static { cursor: default; }
|
|
2365
|
+
.collapsible-header-static:hover { background: none; }
|
|
2366
|
+
|
|
2123
2367
|
|
|
2124
2368
|
.collapsible-toggle {
|
|
2125
2369
|
font-size: 8px;
|
|
@@ -2208,7 +2452,7 @@ html, body, #mbeditor-root {
|
|
|
2208
2452
|
|
|
2209
2453
|
/* Open-editors panel: height is controlled by the --open-editors-height CSS variable
|
|
2210
2454
|
set inline from React state (default 140px ≈ 5-6 items), drag-resizable via the
|
|
2211
|
-
|
|
2455
|
+
gutter below it. */
|
|
2212
2456
|
.ide-sidebar-fixed .collapsible-content {
|
|
2213
2457
|
max-height: var(--open-editors-height, 140px);
|
|
2214
2458
|
overflow-y: auto;
|
|
@@ -2218,17 +2462,6 @@ html, body, #mbeditor-root {
|
|
|
2218
2462
|
.ide-sidebar-fixed .collapsible-content::-webkit-scrollbar-track { background: transparent; }
|
|
2219
2463
|
.ide-sidebar-fixed .collapsible-content::-webkit-scrollbar-thumb { background: var(--ide-scrollbar); border-radius: 3px; }
|
|
2220
2464
|
|
|
2221
|
-
.open-editors-resize-handle {
|
|
2222
|
-
height: 4px;
|
|
2223
|
-
flex-shrink: 0;
|
|
2224
|
-
cursor: row-resize;
|
|
2225
|
-
background: transparent;
|
|
2226
|
-
transition: background 0.15s;
|
|
2227
|
-
}
|
|
2228
|
-
.open-editors-resize-handle:hover {
|
|
2229
|
-
background: var(--ide-border);
|
|
2230
|
-
}
|
|
2231
|
-
|
|
2232
2465
|
.open-editors-group-header {
|
|
2233
2466
|
font-size: 10px;
|
|
2234
2467
|
padding-left: 8px;
|
|
@@ -2245,17 +2478,50 @@ html, body, #mbeditor-root {
|
|
|
2245
2478
|
transition: opacity 0.12s ease;
|
|
2246
2479
|
}
|
|
2247
2480
|
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
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;
|
|
2254
2489
|
color: var(--ide-text-muted);
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
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
|
+
|
|
2514
|
+
.ide-icon-btn {
|
|
2515
|
+
min-width: 24px;
|
|
2516
|
+
height: 24px;
|
|
2517
|
+
background: transparent;
|
|
2518
|
+
border: none;
|
|
2519
|
+
border-radius: 5px;
|
|
2520
|
+
color: var(--ide-text-muted);
|
|
2521
|
+
display: inline-flex;
|
|
2522
|
+
align-items: center;
|
|
2523
|
+
justify-content: center;
|
|
2524
|
+
cursor: pointer;
|
|
2259
2525
|
font-size: 13px;
|
|
2260
2526
|
transition: background 0.12s ease, color 0.12s ease;
|
|
2261
2527
|
flex-shrink: 0;
|
|
@@ -2274,8 +2540,10 @@ html, body, #mbeditor-root {
|
|
|
2274
2540
|
display: flex;
|
|
2275
2541
|
justify-content: flex-start;
|
|
2276
2542
|
align-items: center;
|
|
2277
|
-
padding:
|
|
2278
|
-
|
|
2543
|
+
padding: 0 12px;
|
|
2544
|
+
height: 22px;
|
|
2545
|
+
min-height: 22px;
|
|
2546
|
+
background: var(--ide-bg);
|
|
2279
2547
|
border-bottom: 1px solid var(--ide-border);
|
|
2280
2548
|
gap: 4px;
|
|
2281
2549
|
overflow: hidden;
|
|
@@ -2289,14 +2557,18 @@ html, body, #mbeditor-root {
|
|
|
2289
2557
|
white-space: nowrap;
|
|
2290
2558
|
text-overflow: ellipsis;
|
|
2291
2559
|
text-align: left;
|
|
2292
|
-
font-size:
|
|
2560
|
+
font-size: 13px;
|
|
2293
2561
|
color: var(--ide-text-muted);
|
|
2294
2562
|
padding: 0 4px;
|
|
2295
2563
|
cursor: default;
|
|
2296
2564
|
user-select: text;
|
|
2297
|
-
font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
|
|
2298
2565
|
}
|
|
2299
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
|
+
|
|
2300
2572
|
.ide-editor-toolbar .ide-icon-btn {
|
|
2301
2573
|
flex-shrink: 1;
|
|
2302
2574
|
min-width: 24px;
|
|
@@ -2324,10 +2596,12 @@ html, body, #mbeditor-root {
|
|
|
2324
2596
|
}
|
|
2325
2597
|
|
|
2326
2598
|
.ide-methods-dropdown {
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
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);
|
|
2331
2605
|
min-width: 200px;
|
|
2332
2606
|
max-width: 340px;
|
|
2333
2607
|
max-height: 320px;
|
|
@@ -2356,13 +2630,8 @@ html, body, #mbeditor-root {
|
|
|
2356
2630
|
|
|
2357
2631
|
.ide-methods-dropdown-item:hover,
|
|
2358
2632
|
.ide-methods-dropdown-item:focus {
|
|
2359
|
-
background:
|
|
2360
|
-
color:
|
|
2361
|
-
}
|
|
2362
|
-
|
|
2363
|
-
.ide-methods-dropdown-item:focus {
|
|
2364
|
-
outline: 1px solid #75beff;
|
|
2365
|
-
outline-offset: -1px;
|
|
2633
|
+
background: var(--ide-active-bg);
|
|
2634
|
+
color: var(--ide-text);
|
|
2366
2635
|
}
|
|
2367
2636
|
|
|
2368
2637
|
.ide-methods-dropdown-line {
|
|
@@ -2423,6 +2692,12 @@ html, body, #mbeditor-root {
|
|
|
2423
2692
|
.monaco-editor .line-numbers.mbeditor-gitline-deleted.mbeditor-gitline-added,
|
|
2424
2693
|
.monaco-editor .line-numbers.mbeditor-gitline-deleted.mbeditor-gitline-modified { color: var(--ide-danger); }
|
|
2425
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
|
+
|
|
2426
2701
|
.ide-methods-dropdown-message {
|
|
2427
2702
|
padding: 8px 12px;
|
|
2428
2703
|
color: #858585;
|
|
@@ -2511,6 +2786,26 @@ html, body, #mbeditor-root {
|
|
|
2511
2786
|
margin: 4px 0;
|
|
2512
2787
|
}
|
|
2513
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
|
+
|
|
2514
2809
|
.collapsible-content {
|
|
2515
2810
|
animation: collapsible-open 0.15s ease;
|
|
2516
2811
|
}
|
|
@@ -2526,41 +2821,59 @@ html, body, #mbeditor-root {
|
|
|
2526
2821
|
}
|
|
2527
2822
|
}
|
|
2528
2823
|
|
|
2529
|
-
/* ── 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. */
|
|
2530
2829
|
.quick-open-overlay {
|
|
2531
2830
|
position: fixed;
|
|
2532
2831
|
inset: 0;
|
|
2533
|
-
background: rgba(0,0,0,0.
|
|
2832
|
+
background: rgba(0,0,0,0.35);
|
|
2534
2833
|
display: flex;
|
|
2535
2834
|
align-items: flex-start;
|
|
2536
2835
|
justify-content: center;
|
|
2537
|
-
padding-top:
|
|
2836
|
+
padding-top: 6px;
|
|
2538
2837
|
z-index: 9999;
|
|
2539
2838
|
}
|
|
2540
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. */
|
|
2541
2842
|
.quick-open-box {
|
|
2542
|
-
|
|
2543
|
-
|
|
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);
|
|
2544
2847
|
border-radius: 8px;
|
|
2545
|
-
width:
|
|
2546
|
-
max-height:
|
|
2848
|
+
width: min(600px, 94vw);
|
|
2849
|
+
max-height: min(440px, 72vh);
|
|
2547
2850
|
display: flex;
|
|
2548
2851
|
flex-direction: column;
|
|
2549
|
-
box-shadow: 0
|
|
2852
|
+
box-shadow: 0 8px 24px rgba(0,0,0,0.45);
|
|
2550
2853
|
overflow: hidden;
|
|
2551
2854
|
}
|
|
2552
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
|
+
|
|
2553
2865
|
.quick-open-input-wrap {
|
|
2554
2866
|
position: relative;
|
|
2867
|
+
padding: 6px;
|
|
2868
|
+
flex-shrink: 0;
|
|
2555
2869
|
}
|
|
2556
2870
|
|
|
2557
2871
|
.quick-open-input {
|
|
2558
2872
|
background: transparent;
|
|
2559
2873
|
border: none;
|
|
2560
|
-
border-bottom: 1px solid var(--ide-border);
|
|
2561
2874
|
color: var(--ide-text);
|
|
2562
|
-
padding:
|
|
2563
|
-
font-size:
|
|
2875
|
+
padding: 4px 30px 4px 8px;
|
|
2876
|
+
font-size: 13px;
|
|
2564
2877
|
outline: none;
|
|
2565
2878
|
width: 100%;
|
|
2566
2879
|
box-sizing: border-box;
|
|
@@ -2569,13 +2882,13 @@ html, body, #mbeditor-root {
|
|
|
2569
2882
|
|
|
2570
2883
|
.quick-open-clear-btn {
|
|
2571
2884
|
position: absolute;
|
|
2572
|
-
right:
|
|
2885
|
+
right: 10px;
|
|
2573
2886
|
top: 50%;
|
|
2574
2887
|
transform: translateY(-50%);
|
|
2575
2888
|
width: 22px;
|
|
2576
2889
|
height: 22px;
|
|
2577
2890
|
border: none;
|
|
2578
|
-
border-radius:
|
|
2891
|
+
border-radius: 5px;
|
|
2579
2892
|
background: transparent;
|
|
2580
2893
|
color: var(--ide-text-muted);
|
|
2581
2894
|
cursor: pointer;
|
|
@@ -2586,51 +2899,62 @@ html, body, #mbeditor-root {
|
|
|
2586
2899
|
|
|
2587
2900
|
.quick-open-clear-btn:hover {
|
|
2588
2901
|
background: var(--ide-hover-bg);
|
|
2589
|
-
color: var(--ide-text
|
|
2902
|
+
color: var(--ide-text);
|
|
2590
2903
|
}
|
|
2591
2904
|
|
|
2592
2905
|
.quick-open-results {
|
|
2593
2906
|
overflow-y: auto;
|
|
2594
2907
|
flex: 1;
|
|
2908
|
+
padding-bottom: 4px;
|
|
2595
2909
|
}
|
|
2596
2910
|
|
|
2597
2911
|
.quick-open-result {
|
|
2598
|
-
padding:
|
|
2912
|
+
padding: 0 10px;
|
|
2913
|
+
height: 22px;
|
|
2599
2914
|
cursor: pointer;
|
|
2600
2915
|
display: flex;
|
|
2601
2916
|
align-items: center;
|
|
2602
2917
|
gap: 8px;
|
|
2603
|
-
font-size:
|
|
2604
|
-
transition: background 0.1s;
|
|
2918
|
+
font-size: 13px;
|
|
2605
2919
|
}
|
|
2606
2920
|
|
|
2607
2921
|
.quick-open-result-icon {
|
|
2608
2922
|
flex-shrink: 0;
|
|
2609
2923
|
width: 16px;
|
|
2924
|
+
font-size: 12px;
|
|
2610
2925
|
text-align: center;
|
|
2611
2926
|
color: #78b4e0;
|
|
2612
2927
|
}
|
|
2613
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. */
|
|
2614
2931
|
.quick-open-result-body {
|
|
2615
2932
|
min-width: 0;
|
|
2616
2933
|
flex: 1;
|
|
2934
|
+
display: flex;
|
|
2935
|
+
align-items: baseline;
|
|
2936
|
+
gap: 8px;
|
|
2937
|
+
overflow: hidden;
|
|
2617
2938
|
}
|
|
2618
2939
|
|
|
2619
|
-
.quick-open-result:hover
|
|
2620
|
-
.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); }
|
|
2621
2942
|
|
|
2622
|
-
.quick-open-result-name { color: var(--ide-text); }
|
|
2623
|
-
.quick-open-result-path { color: var(--ide-text-muted); font-size:
|
|
2943
|
+
.quick-open-result-name { color: var(--ide-text); flex-shrink: 0; white-space: nowrap; }
|
|
2944
|
+
.quick-open-result-path { color: var(--ide-text-muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
2624
2945
|
|
|
2625
2946
|
.quick-open-section { margin-bottom: 4px; }
|
|
2626
|
-
.quick-open-section-header { padding:
|
|
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; }
|
|
2627
2951
|
|
|
2628
2952
|
.quick-open-star-btn {
|
|
2629
2953
|
flex-shrink: 0;
|
|
2630
2954
|
background: none;
|
|
2631
2955
|
border: none;
|
|
2632
2956
|
cursor: pointer;
|
|
2633
|
-
padding:
|
|
2957
|
+
padding: 0 4px;
|
|
2634
2958
|
color: var(--ide-text-muted);
|
|
2635
2959
|
font-size: 12px;
|
|
2636
2960
|
line-height: 1;
|
|
@@ -2646,9 +2970,9 @@ html, body, #mbeditor-root {
|
|
|
2646
2970
|
.quick-open-result-dir .quick-open-result-name { color: #dcb67a; }
|
|
2647
2971
|
|
|
2648
2972
|
.quick-open-empty-hint {
|
|
2649
|
-
padding:
|
|
2973
|
+
padding: 24px 18px;
|
|
2650
2974
|
color: var(--ide-text-muted);
|
|
2651
|
-
font-size:
|
|
2975
|
+
font-size: 13px;
|
|
2652
2976
|
text-align: center;
|
|
2653
2977
|
line-height: 1.6;
|
|
2654
2978
|
}
|
|
@@ -2743,48 +3067,177 @@ html, body, #mbeditor-root {
|
|
|
2743
3067
|
.ide-draft-restore-btn:hover { background: var(--ide-hover-bg); }
|
|
2744
3068
|
.ide-draft-restore-btn-primary {
|
|
2745
3069
|
background: var(--ide-accent);
|
|
2746
|
-
color: var(--ide-accent
|
|
3070
|
+
color: var(--ide-on-accent);
|
|
2747
3071
|
border-color: var(--ide-accent);
|
|
2748
3072
|
}
|
|
2749
3073
|
.ide-draft-restore-btn-primary:hover { opacity: 0.9; }
|
|
2750
3074
|
|
|
2751
3075
|
/* ── Settings panel ─────────────────────────────────────────── */
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
.ide-settings-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
/* Inputs in full-width rows stay narrow */
|
|
2765
|
-
.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; }
|
|
2766
|
-
.ide-settings-input-wide { font-family: monospace; flex: 1; width: auto; }
|
|
2767
|
-
/* Selects in half-width rows use Pico styling (inherit theme vars); just cap size */
|
|
2768
|
-
.ide-settings-row-half select { width: 100%; }
|
|
2769
|
-
.ide-settings-checkbox { width: auto; cursor: pointer; flex-shrink: 0; }
|
|
2770
|
-
.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; }
|
|
2771
|
-
.ide-settings-reset-btn:hover { background: var(--ide-border-input); color: var(--ide-text-dim); }
|
|
2772
|
-
.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; }
|
|
2773
|
-
.ide-settings-section-header:first-child { margin-top: 0; }
|
|
2774
|
-
.ide-settings-row-link { grid-column: 1/-1; flex-direction: row; align-items: center; justify-content: space-between; }
|
|
2775
|
-
.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; }
|
|
2776
|
-
.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
|
+
}
|
|
2777
3088
|
|
|
2778
|
-
/*
|
|
2779
|
-
.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);
|
|
2780
3098
|
display: flex;
|
|
2781
3099
|
flex-direction: column;
|
|
2782
|
-
|
|
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;
|
|
3162
|
+
overflow-y: auto;
|
|
3163
|
+
display: flex;
|
|
3164
|
+
flex-direction: column;
|
|
3165
|
+
justify-content: flex-start; /* a shared nav rule sets space-between */
|
|
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); }
|
|
3184
|
+
|
|
3185
|
+
.ide-settings-body {
|
|
3186
|
+
flex: 1;
|
|
3187
|
+
min-width: 0;
|
|
2783
3188
|
overflow-y: auto;
|
|
2784
|
-
|
|
2785
|
-
|
|
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);
|
|
2786
3199
|
}
|
|
2787
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); }
|
|
2788
3241
|
|
|
2789
3242
|
/* ══ PICO CSS COMPACT OVERRIDES ═════════════════════════════════════════════
|
|
2790
3243
|
* Pico's classless variant inflates native elements with generous padding.
|
|
@@ -2881,15 +3334,20 @@ textarea {
|
|
|
2881
3334
|
margin-bottom: 0;
|
|
2882
3335
|
}
|
|
2883
3336
|
|
|
2884
|
-
/* Status bar buttons override (22px tall, full-bleed)
|
|
3337
|
+
/* Status bar buttons override (22px tall, full-bleed).
|
|
3338
|
+
* line-height must be set here too, not just on .ide-statusbar: Pico gives
|
|
3339
|
+
* <button> its own line-height, so it does not inherit the bar's, and the
|
|
3340
|
+
* count next to an icon ended up in a 16.5px line box beside the icon's 11px
|
|
3341
|
+
* one. */
|
|
2885
3342
|
.ide-statusbar button,
|
|
2886
3343
|
.statusbar-btn {
|
|
2887
3344
|
--pico-form-element-spacing-vertical: 0;
|
|
2888
|
-
--pico-form-element-spacing-horizontal:
|
|
2889
|
-
height:
|
|
2890
|
-
padding: 0
|
|
2891
|
-
font-size:
|
|
2892
|
-
|
|
3345
|
+
--pico-form-element-spacing-horizontal: 6px;
|
|
3346
|
+
height: 20px;
|
|
3347
|
+
padding: 0 6px;
|
|
3348
|
+
font-size: 12px;
|
|
3349
|
+
line-height: 1;
|
|
3350
|
+
border-radius: 5px;
|
|
2893
3351
|
border: none;
|
|
2894
3352
|
background: transparent;
|
|
2895
3353
|
color: var(--ide-accent-text);
|
|
@@ -2986,7 +3444,19 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
2986
3444
|
border-radius: 0;
|
|
2987
3445
|
}
|
|
2988
3446
|
/* Re-apply border-radius for buttons that intentionally need it */
|
|
2989
|
-
.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
|
+
}
|
|
2990
3460
|
.ide-shell .project-action-btn,
|
|
2991
3461
|
.ide-shell .git-header-btn,
|
|
2992
3462
|
.ide-shell .git-section-action-btn,
|
|
@@ -3102,15 +3572,6 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3102
3572
|
background: var(--ide-panel-bg, #1e1e1e);
|
|
3103
3573
|
border-top: 1px solid var(--ide-border, #333);
|
|
3104
3574
|
}
|
|
3105
|
-
.ide-log-resize {
|
|
3106
|
-
flex: 0 0 auto;
|
|
3107
|
-
height: 6px;
|
|
3108
|
-
cursor: ns-resize;
|
|
3109
|
-
background: transparent;
|
|
3110
|
-
}
|
|
3111
|
-
.ide-log-resize:hover {
|
|
3112
|
-
background: var(--ide-accent, #569cd6);
|
|
3113
|
-
}
|
|
3114
3575
|
.ide-log-header {
|
|
3115
3576
|
display: flex;
|
|
3116
3577
|
align-items: center;
|
|
@@ -3178,25 +3639,35 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3178
3639
|
background: var(--ide-panel-bg, #1e1e1e);
|
|
3179
3640
|
border-top: 1px solid var(--ide-border, #333);
|
|
3180
3641
|
}
|
|
3181
|
-
.ide-problems-resize {
|
|
3182
|
-
flex: 0 0 auto;
|
|
3183
|
-
height: 6px;
|
|
3184
|
-
cursor: ns-resize;
|
|
3185
|
-
background: transparent;
|
|
3186
|
-
}
|
|
3187
|
-
.ide-problems-resize:hover { background: var(--ide-accent, #569cd6); }
|
|
3188
3642
|
.ide-problems-header {
|
|
3189
3643
|
display: flex;
|
|
3190
3644
|
align-items: center;
|
|
3191
3645
|
gap: 8px;
|
|
3192
|
-
|
|
3646
|
+
height: 35px;
|
|
3647
|
+
padding: 0 10px;
|
|
3193
3648
|
border-bottom: 1px solid var(--ide-border, #333);
|
|
3194
3649
|
font-size: 12px;
|
|
3195
|
-
color: var(--ide-
|
|
3650
|
+
color: var(--ide-text, #ccc);
|
|
3196
3651
|
}
|
|
3197
|
-
.ide-problems-title {
|
|
3198
|
-
|
|
3199
|
-
|
|
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;
|
|
3668
|
+
}
|
|
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. */
|
|
3200
3671
|
.ide-problems-severity-filter {
|
|
3201
3672
|
margin-left: auto;
|
|
3202
3673
|
display: flex;
|
|
@@ -3207,63 +3678,42 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3207
3678
|
align-items: center;
|
|
3208
3679
|
gap: 4px;
|
|
3209
3680
|
background: transparent;
|
|
3210
|
-
border:
|
|
3681
|
+
border: none;
|
|
3211
3682
|
border-radius: 3px;
|
|
3212
3683
|
padding: 1px 6px;
|
|
3213
3684
|
font-size: 11px;
|
|
3214
3685
|
font-variant-numeric: tabular-nums;
|
|
3215
3686
|
cursor: pointer;
|
|
3216
|
-
/* Off is legible but clearly recessive — a disabled-looking chip reads as
|
|
3217
|
-
"broken" rather than "toggled off". */
|
|
3218
3687
|
color: var(--ide-text-muted, #858585);
|
|
3219
|
-
opacity: 0.55;
|
|
3220
3688
|
}
|
|
3221
|
-
.ide-problems-sev-chip:hover
|
|
3222
|
-
.ide-problems-sev-chip.is-on {
|
|
3223
|
-
opacity: 1;
|
|
3224
|
-
border-color: var(--ide-border, #333);
|
|
3225
|
-
background: var(--ide-input-bg, #2d2d2d);
|
|
3226
|
-
}
|
|
3227
|
-
.ide-problems-sev-chip.is-on.ide-problems-sev-error { color: var(--ide-error, #f14c4c); }
|
|
3228
|
-
.ide-problems-sev-chip.is-on.ide-problems-sev-warning { color: var(--ide-warning, #cca700); }
|
|
3229
|
-
.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); }
|
|
3230
3691
|
|
|
3231
3692
|
.ide-problems-filter {
|
|
3232
3693
|
margin-left: 8px;
|
|
3233
3694
|
background: var(--ide-input-bg, #2d2d2d);
|
|
3234
|
-
color: var(--ide-
|
|
3235
|
-
border: 1px solid var(--ide-border, #333);
|
|
3236
|
-
border-radius:
|
|
3237
|
-
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;
|
|
3238
3700
|
font-size: 12px;
|
|
3239
|
-
width:
|
|
3701
|
+
width: 140px;
|
|
3240
3702
|
}
|
|
3241
3703
|
.ide-problems-btn {
|
|
3242
3704
|
background: transparent;
|
|
3243
3705
|
border: none;
|
|
3244
|
-
color: var(--ide-
|
|
3706
|
+
color: var(--ide-text-muted, #ccc);
|
|
3245
3707
|
cursor: pointer;
|
|
3246
3708
|
padding: 2px 6px;
|
|
3247
3709
|
}
|
|
3248
|
-
.ide-problems-btn:hover { color: var(--ide-
|
|
3710
|
+
.ide-problems-btn:hover { color: var(--ide-text, #fff); }
|
|
3249
3711
|
.ide-problems-btn:disabled { opacity: 0.4; cursor: default; }
|
|
3250
|
-
.ide-problems-btn:disabled:hover { color: var(--ide-
|
|
3712
|
+
.ide-problems-btn:disabled:hover { color: var(--ide-text-muted, #ccc); }
|
|
3251
3713
|
.ide-problems-actions { display: flex; gap: 2px; }
|
|
3252
|
-
.ide-problems-actions .ide-
|
|
3253
|
-
.ide-problems-
|
|
3254
|
-
.ide-
|
|
3255
|
-
.ide-testrun-pass { color: #4ec9b0; }
|
|
3256
|
-
.ide-testrun-fail { color: #f14c4c; }
|
|
3257
|
-
.ide-testrun-raw {
|
|
3258
|
-
margin: 0;
|
|
3259
|
-
padding: 8px 14px;
|
|
3260
|
-
font-family: var(--ide-mono, monospace);
|
|
3261
|
-
font-size: 11px;
|
|
3262
|
-
line-height: 1.5;
|
|
3263
|
-
white-space: pre;
|
|
3264
|
-
overflow-x: auto;
|
|
3265
|
-
color: var(--ide-fg, #eee);
|
|
3266
|
-
}
|
|
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; }
|
|
3267
3717
|
.ide-problems-body { flex: 1; overflow: auto; padding: 4px 0; font-size: 12px; }
|
|
3268
3718
|
.ide-problems-empty {
|
|
3269
3719
|
padding: 10px 14px;
|
|
@@ -3274,9 +3724,18 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3274
3724
|
display: flex;
|
|
3275
3725
|
align-items: center;
|
|
3276
3726
|
gap: 6px;
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
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;
|
|
3280
3739
|
}
|
|
3281
3740
|
.ide-problems-file-count {
|
|
3282
3741
|
background: var(--ide-hover-bg, #2a2a2a);
|
|
@@ -3291,22 +3750,23 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3291
3750
|
align-items: baseline;
|
|
3292
3751
|
gap: 8px;
|
|
3293
3752
|
width: 100%;
|
|
3294
|
-
|
|
3753
|
+
height: 22px;
|
|
3754
|
+
padding: 0 12px 0 28px;
|
|
3295
3755
|
background: transparent;
|
|
3296
3756
|
border: none;
|
|
3297
|
-
color: var(--ide-
|
|
3757
|
+
color: var(--ide-text, #d4d4d4);
|
|
3298
3758
|
font-size: 12px;
|
|
3299
3759
|
font-family: inherit;
|
|
3300
3760
|
text-align: left;
|
|
3301
3761
|
cursor: pointer;
|
|
3302
3762
|
}
|
|
3303
|
-
.ide-problems-item:hover,
|
|
3304
|
-
.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); }
|
|
3305
3765
|
.ide-problems-icon { flex-shrink: 0; }
|
|
3306
3766
|
.ide-problems-item-error .ide-problems-icon { color: var(--ide-danger); }
|
|
3307
3767
|
.ide-problems-item-warning .ide-problems-icon { color: var(--ide-warning); }
|
|
3308
3768
|
.ide-problems-item-info .ide-problems-icon { color: var(--ide-accent, #3794ff); }
|
|
3309
|
-
.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); }
|
|
3310
3770
|
/* The offending source line, dimmed so it reads as context rather than as part
|
|
3311
3771
|
of the message. It is the one part of the row allowed to shrink, so a long
|
|
3312
3772
|
line gives way to the message and location instead of pushing them out. */
|
|
@@ -3316,7 +3776,6 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3316
3776
|
text-overflow: ellipsis;
|
|
3317
3777
|
white-space: nowrap;
|
|
3318
3778
|
color: var(--ide-text-muted, #858585);
|
|
3319
|
-
opacity: 0.8;
|
|
3320
3779
|
font-family: var(--ide-mono, monospace);
|
|
3321
3780
|
font-size: 11px;
|
|
3322
3781
|
}
|
|
@@ -3345,12 +3804,24 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3345
3804
|
margin-left: auto;
|
|
3346
3805
|
color: var(--ide-text-muted, #858585);
|
|
3347
3806
|
font-size: 11px;
|
|
3807
|
+
font-variant-numeric: tabular-nums;
|
|
3348
3808
|
}
|
|
3349
3809
|
|
|
3350
3810
|
/* ── Model graph ──────────────────────────────────────────────────────────
|
|
3351
3811
|
An SVG ER diagram of the app's ActiveRecord models. The panel is narrow, so
|
|
3352
3812
|
the SVG scrolls in both directions rather than being scaled down to
|
|
3353
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
|
+
|
|
3354
3825
|
.ide-model-graph { display: flex; flex-direction: column; height: 100%; min-height: 0; position: relative; }
|
|
3355
3826
|
.ide-model-graph-empty {
|
|
3356
3827
|
padding: 16px;
|
|
@@ -3496,18 +3967,11 @@ button:not(.pico-btn) { margin-bottom: 0; }
|
|
|
3496
3967
|
.ide-problems-frame { padding-left: 28px; }
|
|
3497
3968
|
.ide-problems-frame .ide-problems-code { opacity: 1; }
|
|
3498
3969
|
|
|
3499
|
-
/* Status-bar
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
.statusbar-
|
|
3503
|
-
.statusbar-
|
|
3504
|
-
.statusbar-lsp-degraded,
|
|
3505
|
-
.statusbar-lsp-off { color: var(--ide-warning); }
|
|
3506
|
-
|
|
3507
|
-
/* Status-bar problems indicator: bug count then warning count, VS Code style. */
|
|
3508
|
-
.statusbar-problems { display: inline-flex; align-items: center; gap: 4px; }
|
|
3509
|
-
.statusbar-problems-error-icon { color: var(--ide-danger); }
|
|
3510
|
-
.statusbar-problems-warning-icon { color: var(--ide-warning); }
|
|
3970
|
+
/* Status-bar problems indicator: bug count then warning count, VS Code style.
|
|
3971
|
+
The gap is the icon-to-its-own-number spacing; the warning icon opens the
|
|
3972
|
+
second pair, so it gets the wider separator. */
|
|
3973
|
+
.statusbar-problems { gap: 4px; }
|
|
3974
|
+
.statusbar-problems-warning-icon { margin-left: 8px; }
|
|
3511
3975
|
.statusbar-problems-count { font-variant-numeric: tabular-nums; }
|
|
3512
3976
|
|
|
3513
3977
|
/* Search decorations off across engines — Chrome/Safari draw their own
|
|
@@ -3646,6 +4110,7 @@ input.ide-model-graph-search[type="search"] {
|
|
|
3646
4110
|
/* Pair-programming diagnostics. The chip only appears when a condition pairing
|
|
3647
4111
|
needs has actually failed — an empty room is silence, not a warning. */
|
|
3648
4112
|
.mbeditor-collab-trouble { color: var(--ide-warning, #cca700); }
|
|
4113
|
+
.mbeditor-conflict-chip { color: var(--ide-error, #f48771); }
|
|
3649
4114
|
.mbeditor-modal-backdrop {
|
|
3650
4115
|
position: fixed; inset: 0; z-index: 5000;
|
|
3651
4116
|
background: rgba(0, 0, 0, 0.45);
|