@vscode/markdown-editor 0.0.2-11 → 0.0.2-110

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +31 -0
  2. package/dist/commands.d.ts +67 -0
  3. package/dist/commands.js +185 -0
  4. package/dist/commands.js.map +1 -0
  5. package/dist/config-BGeaJqWk.js +286 -0
  6. package/dist/config-BGeaJqWk.js.map +1 -0
  7. package/dist/config.d.ts +10 -0
  8. package/dist/config.js +6 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/index.d.ts +1690 -140
  11. package/dist/index.js +7047 -2100
  12. package/dist/index.js.map +1 -1
  13. package/dist/markdown-editor.css +1 -0
  14. package/dist/stringEdit-CVDbCUBY.js +215 -0
  15. package/dist/stringEdit-CVDbCUBY.js.map +1 -0
  16. package/dist/web-editors.d.ts +297 -0
  17. package/dist/web-editors.js +7359 -0
  18. package/dist/web-editors.js.map +1 -0
  19. package/package.json +54 -15
  20. package/src/contrib/comments/commentInput.css +89 -0
  21. package/src/contrib/comments/commentWidget.css +60 -0
  22. package/src/contrib/find/find.css +347 -0
  23. package/src/view/editor.css +1196 -32
  24. package/src/view/themes/default.css +13 -4
  25. package/src/view/themes/github.css +16 -13
  26. package/src/view/themes/vscode-default.css +397 -0
  27. package/src/view/themes/{vscode.css → vscode-github.css} +124 -62
  28. package/dist/_observables/assert.d.ts +0 -2
  29. package/dist/_observables/deps.d.ts +0 -28
  30. package/dist/_observables/disposables.d.ts +0 -19
  31. package/dist/_observables/equals.d.ts +0 -32
  32. package/dist/_observables/index.d.ts +0 -2
  33. package/dist/_observables/observableInternal/base.d.ts +0 -172
  34. package/dist/_observables/observableInternal/changeTracker.d.ts +0 -44
  35. package/dist/_observables/observableInternal/commonFacade/cancellation.d.ts +0 -24
  36. package/dist/_observables/observableInternal/commonFacade/deps.d.ts +0 -24
  37. package/dist/_observables/observableInternal/debugLocation.d.ts +0 -21
  38. package/dist/_observables/observableInternal/debugName.d.ts +0 -33
  39. package/dist/_observables/observableInternal/experimental/deferUnobserve.d.ts +0 -16
  40. package/dist/_observables/observableInternal/experimental/reducer.d.ts +0 -37
  41. package/dist/_observables/observableInternal/experimental/utils.d.ts +0 -15
  42. package/dist/_observables/observableInternal/index.d.ts +0 -25
  43. package/dist/_observables/observableInternal/logging/consoleObservableLogger.d.ts +0 -40
  44. package/dist/_observables/observableInternal/logging/debugGetDependencyGraph.d.ts +0 -4
  45. package/dist/_observables/observableInternal/logging/debugger/debuggerRpc.d.ts +0 -4
  46. package/dist/_observables/observableInternal/logging/debugger/devToolsLogger.d.ts +0 -43
  47. package/dist/_observables/observableInternal/logging/debugger/rpc.d.ts +0 -41
  48. package/dist/_observables/observableInternal/logging/debugger/utils.d.ts +0 -13
  49. package/dist/_observables/observableInternal/logging/logging.d.ts +0 -30
  50. package/dist/_observables/observableInternal/map.d.ts +0 -18
  51. package/dist/_observables/observableInternal/observables/baseObservable.d.ts +0 -58
  52. package/dist/_observables/observableInternal/observables/constObservable.d.ts +0 -5
  53. package/dist/_observables/observableInternal/observables/derived.d.ts +0 -46
  54. package/dist/_observables/observableInternal/observables/derivedImpl.d.ts +0 -83
  55. package/dist/_observables/observableInternal/observables/lazyObservableValue.d.ts +0 -27
  56. package/dist/_observables/observableInternal/observables/observableFromEvent.d.ts +0 -37
  57. package/dist/_observables/observableInternal/observables/observableSignal.d.ts +0 -11
  58. package/dist/_observables/observableInternal/observables/observableSignalFromEvent.d.ts +0 -5
  59. package/dist/_observables/observableInternal/observables/observableValue.d.ts +0 -37
  60. package/dist/_observables/observableInternal/observables/observableValueOpts.d.ts +0 -8
  61. package/dist/_observables/observableInternal/reactions/autorun.d.ts +0 -56
  62. package/dist/_observables/observableInternal/reactions/autorunImpl.d.ts +0 -53
  63. package/dist/_observables/observableInternal/set.d.ts +0 -17
  64. package/dist/_observables/observableInternal/transaction.d.ts +0 -27
  65. package/dist/_observables/observableInternal/utils/promise.d.ts +0 -75
  66. package/dist/_observables/observableInternal/utils/runOnChange.d.ts +0 -7
  67. package/dist/_observables/observableInternal/utils/utils.d.ts +0 -43
  68. package/dist/_observables/observableInternal/utils/utilsCancellation.d.ts +0 -10
  69. package/dist/_observables/observableInternal/utils/valueWithChangeEvent.d.ts +0 -10
  70. package/dist/_observables/utils.d.ts +0 -15
  71. package/dist/observables.d.ts +0 -4
  72. package/dist/observables.js +0 -439
  73. package/dist/observables.js.map +0 -1
  74. package/dist/runOnChange-C00UIwqQ.js +0 -1538
  75. package/dist/runOnChange-C00UIwqQ.js.map +0 -1
@@ -1,3 +1,6 @@
1
+ @import '@vscode/codicons/dist/codicon.css';
2
+ @import '../contrib/find/find.css';
3
+
1
4
  /*
2
5
  * Base editor styles — ABSOLUTE MINIMUM.
3
6
  *
@@ -17,16 +20,29 @@
17
20
  * theme-agnostic and know nothing about VS Code. Where a value needs to vary
18
21
  * per theme, expose a local `--md-*` custom property WITH a sensible literal
19
22
  * fallback (e.g. `var(--md-cursor-background, #000)`) and let a theme file set
20
- * it. Only `themes/vscode.css` is permitted to read `--vscode-*` variables and
21
- * map them onto these `--md-*` properties.
23
+ * it. Only the `themes/vscode-*.css` themes are permitted to read `--vscode-*`
24
+ * variables and map them onto these `--md-*` properties.
22
25
  */
23
26
 
24
27
  .md-editor {
28
+ display: flow-root;
25
29
  outline: none;
26
30
  /* The editor paints its own cursor (`.md-cursor`); hide the native caret. */
27
31
  caret-color: transparent;
28
32
  }
29
33
 
34
+ .md-editor-a11y-status {
35
+ position: absolute;
36
+ width: 1px;
37
+ height: 1px;
38
+ padding: 0;
39
+ margin: -1px;
40
+ overflow: hidden;
41
+ clip: rect(0, 0, 0, 0);
42
+ white-space: nowrap;
43
+ border: 0;
44
+ }
45
+
30
46
  /*
31
47
  * The transient empty paragraph — the blank line conjured by pressing Enter at
32
48
  * the end of a paragraph (see `PendingParagraph` in the model). It is not part
@@ -42,12 +58,29 @@
42
58
  * overlays, which position themselves relative to this box, so it is the
43
59
  * positioning context. In limited-width mode the editor sets an inline
44
60
  * `max-width` here and the auto inline margins center it within the full-width
45
- * `.md-editor`.
61
+ * `.md-editor`. The block-start padding keeps every document clear of the top
62
+ * edge, independent of the first block's theme margins.
46
63
  */
47
64
  .md-editor-content {
65
+ --md-editor-content-inline-start-padding: 48px;
66
+ --md-readonly-toggle-width: 58px;
67
+ --md-readonly-toggle-height: 32px;
68
+ /* Leaves 16px of optical separation beyond the active block's 8px outset glow. */
69
+ --md-readonly-toggle-gap: 24px;
70
+ --md-readonly-toggle-inset: 4px;
71
+ --md-editor-content-inline-end-padding: var(--md-editor-content-inline-start-padding);
48
72
  position: relative;
49
73
  margin-inline: auto;
50
- padding: 48px;
74
+ padding-block: 24px 0;
75
+ padding-inline: var(--md-editor-content-inline-start-padding) var(--md-editor-content-inline-end-padding);
76
+ }
77
+
78
+ .md-editor-content-with-readonly-toggle {
79
+ --md-editor-content-inline-end-padding: calc(var(--md-readonly-toggle-width) + var(--md-readonly-toggle-gap) + var(--md-readonly-toggle-inset));
80
+ }
81
+
82
+ .md-editor-content-with-readonly-toggle>.md-document :is(.md-heading, .md-paragraph) {
83
+ overflow-wrap: anywhere;
51
84
  }
52
85
 
53
86
  .md-block-active {
@@ -56,6 +89,29 @@
56
89
  box-shadow: 0 0 0 8px var(--md-block-active-background, #f8f8f8);
57
90
  }
58
91
 
92
+ /*
93
+ * The whole-empty-document case. Markdown has no empty-paragraph node, so a
94
+ * document with no content parses to a single empty paragraph (see
95
+ * `_ensureBlocks` in the parser) which renders as a childless `<p>` of zero
96
+ * height. Give it one line's height so the editor presents an intentional,
97
+ * clickable empty editing surface — and so typing the first character causes no
98
+ * layout shift (a filled line is also one `lh` tall).
99
+ */
100
+ .md-paragraph:empty {
101
+ min-height: 1lh;
102
+ }
103
+
104
+ /*
105
+ * ...and never paint the active-block card over that zero-content line: with no
106
+ * text to size it, the card's background + 8px box-shadow glow would show up as
107
+ * a stray gray bar. The two extra classes outrank the base `.md-block-active`
108
+ * rule above in every theme (themes only remap `--md-block-active-background`).
109
+ */
110
+ .md-paragraph:empty.md-block-active {
111
+ background: transparent;
112
+ box-shadow: none;
113
+ }
114
+
59
115
  /*
60
116
  * Cursor mirrors the same open affordance as the underline below: the anchor's
61
117
  * pointer cursor appears exactly when a click would open the link. An inactive
@@ -87,6 +143,552 @@
87
143
  text-decoration: none;
88
144
  }
89
145
 
146
+ .md-rich-link {
147
+ display: inline-flex;
148
+ align-items: baseline;
149
+ max-width: min(100%, 52rem);
150
+ box-sizing: border-box;
151
+ gap: 0.24em;
152
+ padding: 1px 0.3em;
153
+ border: 1px solid color-mix(in srgb, var(--vscode-textLink-foreground, #0969da) 24%, transparent);
154
+ border-radius: 0.3em;
155
+ background: var(--vscode-button-secondaryBackground, #f3f3f3);
156
+ color: inherit;
157
+ font-size: 1em;
158
+ line-height: 1.25;
159
+ text-decoration: none;
160
+ vertical-align: baseline;
161
+ white-space: nowrap;
162
+ cursor: pointer;
163
+ --md-rich-link-success-color: var(--vscode-charts-green, #1f883d);
164
+ }
165
+
166
+ .md-rich-link:hover {
167
+ border-color: var(--vscode-focusBorder, color-mix(in srgb, currentColor 42%, transparent));
168
+ background: var(--vscode-button-secondaryHoverBackground, #e5e5e5);
169
+ text-decoration: none;
170
+ }
171
+
172
+ .md-rich-link:focus-visible {
173
+ outline: 1px solid var(--vscode-focusBorder, currentColor);
174
+ outline-offset: 1px;
175
+ }
176
+
177
+ .md-rich-link-icon {
178
+ flex: none;
179
+ align-self: center;
180
+ font-size: 0.92em;
181
+ color: color-mix(in srgb, var(--vscode-textLink-foreground, #0969da) 78%, currentColor);
182
+ }
183
+
184
+ .md-rich-link-label,
185
+ .md-rich-link-title,
186
+ .md-rich-link-detail {
187
+ overflow: hidden;
188
+ text-overflow: ellipsis;
189
+ }
190
+
191
+ .md-rich-link-label,
192
+ .md-rich-link-title {
193
+ flex: 0 1 auto;
194
+ min-width: 0;
195
+ color: var(--vscode-textLink-foreground, currentColor);
196
+ font-weight: 600;
197
+ }
198
+
199
+ .md-rich-link-title {
200
+ max-width: 200px;
201
+ }
202
+
203
+ .md-rich-link[data-md-rich-link-kind='session'] :is(.md-rich-link-label, .md-rich-link-title) {
204
+ max-width: 150px;
205
+ }
206
+
207
+ .md-rich-link-label[hidden],
208
+ .md-rich-link-title[hidden],
209
+ .md-rich-link-reference[hidden] {
210
+ display: none;
211
+ }
212
+
213
+ .md-rich-link-reference {
214
+ flex: none;
215
+ color: var(--vscode-descriptionForeground, color-mix(in srgb, currentColor 72%, transparent));
216
+ font-size: 0.92em;
217
+ }
218
+
219
+ .md-rich-link-detail {
220
+ flex: 1 1 auto;
221
+ min-width: 1.5em;
222
+ color: var(--vscode-descriptionForeground, color-mix(in srgb, currentColor 72%, transparent));
223
+ font-size: 0.92em;
224
+ }
225
+
226
+ .md-rich-link-detail::before {
227
+ content: '·';
228
+ margin-right: 0.28em;
229
+ }
230
+
231
+ .md-rich-link-status {
232
+ flex: none;
233
+ display: inline-flex;
234
+ align-self: center;
235
+ align-items: center;
236
+ gap: 0.22em;
237
+ margin-left: 0.04em;
238
+ color: var(--vscode-descriptionForeground, currentColor);
239
+ font-size: 0.86em;
240
+ font-weight: 600;
241
+ line-height: 1;
242
+ }
243
+
244
+ .md-rich-link-detail[hidden],
245
+ .md-rich-link-changes[hidden],
246
+ .md-rich-link-status[hidden] {
247
+ display: none;
248
+ }
249
+
250
+ .md-rich-link-changes {
251
+ flex: none;
252
+ display: inline-flex;
253
+ align-self: center;
254
+ gap: 0.28em;
255
+ font-size: 0.86em;
256
+ font-weight: 600;
257
+ line-height: 1;
258
+ }
259
+
260
+ .md-rich-link-changes::before,
261
+ .md-rich-link:not(
262
+ [data-md-rich-link-kind='issue'],
263
+ [data-md-rich-link-kind='pullRequest'],
264
+ [data-md-rich-link-kind='session']
265
+ ) .md-rich-link-primary-status::before {
266
+ content: '·';
267
+ color: var(--vscode-descriptionForeground, currentColor);
268
+ font-weight: 400;
269
+ }
270
+
271
+ .md-rich-link-insertions {
272
+ color: var(--vscode-charts-green, #1f883d);
273
+ }
274
+
275
+ .md-rich-link-deletions {
276
+ color: var(--vscode-charts-red, #cf222e);
277
+ }
278
+
279
+ .md-rich-link-status-icon {
280
+ flex: none;
281
+ align-self: center;
282
+ font-size: 1em;
283
+ }
284
+
285
+ .md-rich-link:is(
286
+ [data-md-rich-link-status='open'],
287
+ [data-md-rich-link-status='closed'],
288
+ [data-md-rich-link-status='merged'],
289
+ [data-md-rich-link-status='draft'],
290
+ [data-md-rich-link-status='notPlanned']
291
+ ) .md-rich-link-primary-status {
292
+ color: var(--md-rich-link-state-color);
293
+ }
294
+
295
+ .md-rich-link-secondary-status {
296
+ margin-left: 0.06em;
297
+ }
298
+
299
+ .md-rich-link-secondary-status::before {
300
+ content: '·';
301
+ margin-right: 0.08em;
302
+ color: var(--vscode-descriptionForeground, currentColor);
303
+ font-weight: 400;
304
+ }
305
+
306
+ .md-rich-link:is(
307
+ [data-md-rich-link-status='open'],
308
+ [data-md-rich-link-status='closed'],
309
+ [data-md-rich-link-status='merged'],
310
+ [data-md-rich-link-status='draft'],
311
+ [data-md-rich-link-status='notPlanned']
312
+ ) .md-rich-link-primary-status {
313
+ align-self: baseline;
314
+ padding: 0;
315
+ border: 0;
316
+ border-radius: 0;
317
+ background: transparent;
318
+ font-size: 1em;
319
+ line-height: inherit;
320
+ }
321
+
322
+ .md-rich-link[data-md-rich-link-status='success'] .md-rich-link-primary-status {
323
+ color: var(--vscode-charts-green, #1f883d);
324
+ }
325
+
326
+ .md-rich-link[data-md-rich-link-secondary-status='success'] .md-rich-link-secondary-status {
327
+ color: var(--md-rich-link-success-color);
328
+ }
329
+
330
+ .md-rich-link[data-md-rich-link-status='warning'] .md-rich-link-primary-status,
331
+ .md-rich-link[data-md-rich-link-secondary-status='warning'] .md-rich-link-secondary-status {
332
+ color: var(--vscode-editorWarning-foreground, #bf8700);
333
+ }
334
+
335
+ .md-rich-link[data-md-rich-link-status='error'] .md-rich-link-primary-status,
336
+ .md-rich-link[data-md-rich-link-secondary-status='error'] .md-rich-link-secondary-status {
337
+ color: var(--vscode-errorForeground, #cf222e);
338
+ }
339
+
340
+ .md-rich-link[data-md-rich-link-status='pending'] .md-rich-link-primary-status,
341
+ .md-rich-link[data-md-rich-link-secondary-status='pending'] .md-rich-link-secondary-status {
342
+ color: var(--vscode-editorWarning-foreground, #bf8700);
343
+ }
344
+
345
+ .md-rich-link[data-md-rich-link-kind='issue'] .md-rich-link-primary-status .md-rich-link-status-label,
346
+ .md-rich-link[data-md-rich-link-kind='pullRequest'] :is(
347
+ .md-rich-link-primary-status,
348
+ .md-rich-link-secondary-status
349
+ ) .md-rich-link-status-label {
350
+ display: none;
351
+ }
352
+
353
+ .md-rich-link[data-md-rich-link-status='open'] {
354
+ --md-rich-link-state-color: var(--vscode-charts-green, #1f883d);
355
+ }
356
+
357
+ .md-rich-link[data-md-rich-link-kind='issue'][data-md-rich-link-status='closed'],
358
+ .md-rich-link[data-md-rich-link-status='merged'] {
359
+ --md-rich-link-state-color: var(--vscode-charts-purple, #8250df);
360
+ }
361
+
362
+ .md-rich-link[data-md-rich-link-kind='pullRequest'][data-md-rich-link-status='closed'] {
363
+ --md-rich-link-state-color: var(--vscode-charts-red, #cf222e);
364
+ }
365
+
366
+ .md-rich-link[data-md-rich-link-status='draft'],
367
+ .md-rich-link[data-md-rich-link-status='notPlanned'] {
368
+ --md-rich-link-state-color: var(--vscode-descriptionForeground, #656d76);
369
+ }
370
+
371
+ .md-rich-link[data-md-rich-link-kind='pullRequest'][data-md-rich-link-secondary-status='error'] .md-rich-link-secondary-status {
372
+ color: var(--vscode-charts-red, var(--vscode-errorForeground, #cf222e));
373
+ }
374
+
375
+ .md-rich-link:is(
376
+ [data-md-rich-link-kind='issue'],
377
+ [data-md-rich-link-kind='pullRequest']
378
+ ) {
379
+ align-items: center;
380
+ gap: 4px;
381
+ padding: 1px 6px;
382
+ border-color: var(--vscode-button-secondaryBorder, var(--vscode-button-border, transparent));
383
+ border-radius: 4px;
384
+ background: var(--vscode-button-secondaryBackground, #f3f3f3);
385
+ color: var(--vscode-button-secondaryForeground, #242424);
386
+ font-size: 1em;
387
+ line-height: 1.25;
388
+ vertical-align: -0.5px;
389
+ }
390
+
391
+ .md-rich-link:is(
392
+ [data-md-rich-link-kind='issue'],
393
+ [data-md-rich-link-kind='pullRequest']
394
+ ):hover {
395
+ border-color: var(--vscode-button-secondaryBorder, var(--vscode-button-border, transparent));
396
+ background: var(--vscode-button-secondaryHoverBackground, #e5e5e5);
397
+ color: var(--vscode-button-secondaryForeground, #242424);
398
+ }
399
+
400
+ .md-rich-link:is(
401
+ [data-md-rich-link-kind='issue'],
402
+ [data-md-rich-link-kind='pullRequest']
403
+ ) .md-rich-link-reference {
404
+ display: none;
405
+ }
406
+
407
+ .md-rich-link:is(
408
+ [data-md-rich-link-kind='issue'],
409
+ [data-md-rich-link-kind='pullRequest']
410
+ ) :is(
411
+ .md-rich-link-label,
412
+ .md-rich-link-title,
413
+ .md-rich-link-primary-status,
414
+ .md-rich-link-secondary-status
415
+ ) {
416
+ align-self: center;
417
+ font-size: inherit;
418
+ line-height: inherit;
419
+ }
420
+
421
+ .md-rich-link:is(
422
+ [data-md-rich-link-kind='issue'],
423
+ [data-md-rich-link-kind='pullRequest']
424
+ ) :is(.md-rich-link-label, .md-rich-link-title) {
425
+ position: relative;
426
+ top: 0.25px;
427
+ max-width: 200px;
428
+ color: inherit;
429
+ font-weight: 400;
430
+ }
431
+
432
+ .md-rich-link:is(
433
+ [data-md-rich-link-kind='issue'],
434
+ [data-md-rich-link-kind='pullRequest']
435
+ ) .md-rich-link-status {
436
+ align-items: center;
437
+ height: 1.25em;
438
+ }
439
+
440
+ .md-rich-link:is(
441
+ [data-md-rich-link-kind='issue'],
442
+ [data-md-rich-link-kind='pullRequest']
443
+ ) .md-rich-link-status-icon {
444
+ display: inline-flex;
445
+ align-items: center;
446
+ justify-content: center;
447
+ width: 12px;
448
+ height: 12px;
449
+ font-size: 12px;
450
+ line-height: 12px;
451
+ }
452
+
453
+ .md-rich-link:is(
454
+ [data-md-rich-link-kind='issue'],
455
+ [data-md-rich-link-kind='pullRequest']
456
+ ) .md-rich-link-secondary-status::before {
457
+ align-self: center;
458
+ line-height: inherit;
459
+ }
460
+
461
+ .md-rich-link[data-md-rich-link-kind='session'] {
462
+ align-items: center;
463
+ gap: 4px;
464
+ padding: 1px 6px;
465
+ border-color: var(--vscode-chat-requestBorder, var(--vscode-input-border, color-mix(in srgb, currentColor 24%, transparent)));
466
+ border-radius: 4px;
467
+ background: var(--vscode-button-secondaryBackground, #f3f3f3);
468
+ color: var(--vscode-descriptionForeground, #656d76);
469
+ font-size: 1em;
470
+ font-weight: var(--vscode-agents-fontWeight-regular, 400);
471
+ line-height: 1.25;
472
+ vertical-align: baseline;
473
+ }
474
+
475
+ .md-rich-link[data-md-rich-link-kind='session']:hover {
476
+ border-color: var(--vscode-chat-requestBorder, var(--vscode-input-border, color-mix(in srgb, currentColor 24%, transparent)));
477
+ background: var(--vscode-toolbar-hoverBackground, color-mix(in srgb, currentColor 8%, transparent));
478
+ }
479
+
480
+ .md-rich-link[data-md-rich-link-kind='session'] :is(.md-rich-link-label, .md-rich-link-title) {
481
+ color: inherit;
482
+ font-weight: 400;
483
+ }
484
+
485
+ .md-rich-link[data-md-rich-link-kind='session'] .md-rich-link-primary-status {
486
+ align-self: center;
487
+ align-items: center;
488
+ width: 12px;
489
+ height: 12px;
490
+ margin: 0;
491
+ padding: 0;
492
+ border: 0;
493
+ border-radius: 0;
494
+ background: transparent;
495
+ font-size: 1em;
496
+ line-height: inherit;
497
+ }
498
+
499
+ .md-rich-link[data-md-rich-link-kind='session'] .md-rich-link-primary-status .md-rich-link-status-label {
500
+ display: none;
501
+ }
502
+
503
+ .md-rich-link[data-md-rich-link-kind='session'] .md-rich-link-status-icon:not(.monaco-pixel-spinner, [hidden]) {
504
+ display: inline-flex;
505
+ align-items: center;
506
+ justify-content: center;
507
+ width: 12px;
508
+ height: 12px;
509
+ font-size: 12px;
510
+ line-height: 12px;
511
+ }
512
+
513
+ .md-rich-link .md-rich-link-status-icon[hidden] {
514
+ display: none;
515
+ }
516
+
517
+ .md-rich-link[data-md-rich-link-kind='session'][data-md-rich-link-status='neutral'] .md-rich-link-primary-status,
518
+ .md-rich-link[data-md-rich-link-kind='session'][data-md-rich-link-status='success'] .md-rich-link-primary-status,
519
+ .md-rich-link[data-md-rich-link-kind='session'][data-md-rich-link-status='pending'] .md-rich-link-primary-status {
520
+ color: var(--vscode-descriptionForeground, #656d76);
521
+ }
522
+
523
+ .md-rich-link .monaco-pixel-spinner {
524
+ display: inline-grid;
525
+ grid-template-columns: repeat(2, 2px);
526
+ grid-template-rows: repeat(3, 2px);
527
+ column-gap: 2px;
528
+ row-gap: 2px;
529
+ place-content: center;
530
+ width: 16px;
531
+ height: 16px;
532
+ color: currentColor;
533
+ contain: layout style size paint;
534
+ isolation: isolate;
535
+ pointer-events: none;
536
+ transform: translateZ(0);
537
+ }
538
+
539
+ .md-rich-link[data-md-rich-link-kind='session'] .monaco-pixel-spinner {
540
+ width: 12px;
541
+ height: 12px;
542
+ }
543
+
544
+ .md-rich-link .monaco-pixel-spinner-dot {
545
+ display: block;
546
+ width: 2px;
547
+ height: 2px;
548
+ border-radius: 50%;
549
+ background-color: currentColor;
550
+ opacity: 0;
551
+ transform: translateY(-4px);
552
+ animation: monaco-pixel-spinner-dot-cycle 1820ms steps(6, jump-none) infinite;
553
+ }
554
+
555
+ .md-rich-link .monaco-pixel-spinner-dot:nth-child(1) {
556
+ animation-delay: 520ms;
557
+ }
558
+
559
+ .md-rich-link .monaco-pixel-spinner-dot:nth-child(2) {
560
+ animation-delay: 650ms;
561
+ }
562
+
563
+ .md-rich-link .monaco-pixel-spinner-dot:nth-child(3) {
564
+ animation-delay: 260ms;
565
+ }
566
+
567
+ .md-rich-link .monaco-pixel-spinner-dot:nth-child(4) {
568
+ animation-delay: 390ms;
569
+ }
570
+
571
+ .md-rich-link .monaco-pixel-spinner-dot:nth-child(5) {
572
+ animation-name: monaco-pixel-spinner-dot-cycle-long;
573
+ }
574
+
575
+ .md-rich-link .monaco-pixel-spinner-dot:nth-child(6) {
576
+ animation-name: monaco-pixel-spinner-dot-cycle-short;
577
+ animation-delay: 130ms;
578
+ }
579
+
580
+ .md-rich-link .monaco-pixel-spinner-ring .monaco-pixel-spinner-dot {
581
+ opacity: 0.25;
582
+ transform: none;
583
+ animation: monaco-pixel-spinner-ring-pulse 1200ms steps(4, jump-none) infinite;
584
+ }
585
+
586
+ .md-rich-link .monaco-pixel-spinner-ring .monaco-pixel-spinner-dot:nth-child(1) {
587
+ animation-delay: 0ms;
588
+ }
589
+
590
+ .md-rich-link .monaco-pixel-spinner-ring .monaco-pixel-spinner-dot:nth-child(2) {
591
+ animation-delay: 200ms;
592
+ }
593
+
594
+ .md-rich-link .monaco-pixel-spinner-ring .monaco-pixel-spinner-dot:nth-child(3) {
595
+ animation-delay: 1000ms;
596
+ }
597
+
598
+ .md-rich-link .monaco-pixel-spinner-ring .monaco-pixel-spinner-dot:nth-child(4) {
599
+ animation-delay: 400ms;
600
+ }
601
+
602
+ .md-rich-link .monaco-pixel-spinner-ring .monaco-pixel-spinner-dot:nth-child(5) {
603
+ animation-delay: 800ms;
604
+ }
605
+
606
+ .md-rich-link .monaco-pixel-spinner-ring .monaco-pixel-spinner-dot:nth-child(6) {
607
+ animation-delay: 600ms;
608
+ }
609
+
610
+ @keyframes monaco-pixel-spinner-dot-cycle {
611
+ 0% {
612
+ opacity: 0;
613
+ transform: translateY(-4px);
614
+ }
615
+ 9.34%, 57.14% {
616
+ opacity: 1;
617
+ transform: translateY(0);
618
+ }
619
+ 66.48%, 100% {
620
+ opacity: 0;
621
+ transform: translateY(7px);
622
+ }
623
+ }
624
+
625
+ @keyframes monaco-pixel-spinner-dot-cycle-long {
626
+ 0% {
627
+ opacity: 0;
628
+ transform: translateY(-4px);
629
+ }
630
+ 9.34%, 64.29% {
631
+ opacity: 1;
632
+ transform: translateY(0);
633
+ }
634
+ 73.63%, 100% {
635
+ opacity: 0;
636
+ transform: translateY(7px);
637
+ }
638
+ }
639
+
640
+ @keyframes monaco-pixel-spinner-dot-cycle-short {
641
+ 0% {
642
+ opacity: 0;
643
+ transform: translateY(-4px);
644
+ }
645
+ 9.34%, 50% {
646
+ opacity: 1;
647
+ transform: translateY(0);
648
+ }
649
+ 59.34%, 100% {
650
+ opacity: 0;
651
+ transform: translateY(7px);
652
+ }
653
+ }
654
+
655
+ @keyframes monaco-pixel-spinner-ring-pulse {
656
+ 0%, 100% {
657
+ opacity: 0.25;
658
+ transform: none;
659
+ }
660
+ 16.67% {
661
+ opacity: 1;
662
+ transform: none;
663
+ }
664
+ }
665
+
666
+ @media (prefers-reduced-motion: reduce) {
667
+ .md-rich-link .monaco-pixel-spinner-dot {
668
+ animation: none;
669
+ opacity: 1;
670
+ transform: translateY(0);
671
+ }
672
+ }
673
+
674
+ .md-rich-link[data-md-rich-link-kind='session'][data-md-rich-link-status='warning'] .md-rich-link-primary-status {
675
+ color: var(--vscode-list-warningForeground, #855f00);
676
+ }
677
+
678
+ .md-rich-link[data-md-rich-link-kind='session'][data-md-rich-link-status='warning'] {
679
+ border-color: var(--vscode-list-warningForeground, #855f00);
680
+ background-color: color-mix(in srgb, var(--vscode-list-warningForeground, #855f00) 12%, transparent);
681
+ color: var(--vscode-list-warningForeground, #855f00);
682
+ }
683
+
684
+ .md-rich-link[data-md-rich-link-kind='session'][data-md-rich-link-status='error'] .md-rich-link-primary-status {
685
+ color: var(--vscode-errorForeground, #cf222e);
686
+ }
687
+
688
+ .md-rich-link-unavailable {
689
+ border-style: dashed;
690
+ }
691
+
90
692
  .md-fence-spacer {
91
693
  visibility: hidden;
92
694
  font-family: 'Cascadia Code', 'Fira Code', monospace;
@@ -96,7 +698,13 @@
96
698
  .md-marker {
97
699
  color: #999;
98
700
  font-family: 'Cascadia Code', 'Fira Code', monospace;
99
- font-size: 0.85em;
701
+ /*
702
+ * Revealed source is painted a step smaller than body text. Published as a
703
+ * custom property because a gutter marker has to undo it to size its box
704
+ * against the body line box — see `.md-list-item-active>.md-marker-listItemMarker`.
705
+ */
706
+ --md-marker-font-scale: 0.85;
707
+ font-size: calc(1em * var(--md-marker-font-scale));
100
708
  display: inline;
101
709
  overflow: hidden;
102
710
  max-width: 100px;
@@ -122,6 +730,88 @@
122
730
  white-space: pre-wrap;
123
731
  }
124
732
 
733
+ .md-video-wrapper {
734
+ max-width: 100%;
735
+ }
736
+
737
+ .md-video {
738
+ display: block;
739
+ max-width: 100%;
740
+ max-height: 100%;
741
+ }
742
+
743
+ .md-editor:not(.md-readonly) .md-video:not([controls]) {
744
+ cursor: text;
745
+ }
746
+
747
+ .md-video-source {
748
+ overflow-wrap: anywhere;
749
+ white-space: pre-wrap;
750
+ }
751
+
752
+ /*
753
+ * An unhandled block: a construct the parser does not model (setext heading,
754
+ * an extension token). Its raw source is shown verbatim,
755
+ * styled like a code block but visibly flagged as "not understood" by a dashed
756
+ * warning border, so the content is preserved and editable rather than silently
757
+ * dropped.
758
+ *
759
+ * The wrapper is the non-scrolling box (border + block spacing); the inner
760
+ * `.md-unhandled-scroll` <pre> is the horizontal scroller.
761
+ */
762
+ .md-unhandled-block {
763
+ margin: 0.5em 0;
764
+ border: 1px dashed #d0a000;
765
+ border-radius: 4px;
766
+ }
767
+
768
+ /*
769
+ * Inner scroller. Beats the per-theme `.md-theme-* .md-code-block` box rules
770
+ * (same class count) via the extra `pre` type selector: no margin/border of its
771
+ * own (those live on the wrapper).
772
+ */
773
+ pre.md-unhandled-scroll.md-code-block {
774
+ margin: 0;
775
+ border: 0;
776
+ border-radius: 4px;
777
+ }
778
+
779
+ /*
780
+ * Complete block HTML comments are authoring metadata, not unsupported-syntax
781
+ * warnings. Keep them source-identifiable but quiet while reading, and reveal
782
+ * their exact whitespace when the block becomes active.
783
+ */
784
+ .md-html-comment {
785
+ margin: 0.125em 0 0.25em;
786
+ padding: 0.125em 0;
787
+ overflow: hidden;
788
+ color: var(--md-html-comment-foreground, #6e7378);
789
+ font-family: var(--md-html-comment-font-family, 'Cascadia Code', 'Fira Code', monospace);
790
+ font-size: 0.85em;
791
+ line-height: 1.5;
792
+ text-overflow: ellipsis;
793
+ white-space: nowrap;
794
+ transition: color 80ms ease-out;
795
+ }
796
+
797
+ .md-html-comment:not(.md-html-comment-source):hover {
798
+ color: var(--md-html-comment-hover-foreground, #45494e);
799
+ }
800
+
801
+ .md-html-comment-source {
802
+ overflow: visible;
803
+ text-overflow: clip;
804
+ white-space: pre-wrap;
805
+ }
806
+
807
+ .md-html-comment-syntax {
808
+ opacity: 0.6;
809
+ }
810
+
811
+ .md-html-comment-source .md-html-comment-syntax {
812
+ opacity: 1;
813
+ }
814
+
125
815
  /*
126
816
  * Visible whitespace indicators, shown only in the active/source view. The real
127
817
  * whitespace character stays in the DOM (so source ↔ DOM mapping and selection
@@ -221,15 +911,79 @@
221
911
  }
222
912
 
223
913
  /*
224
- * Glue (table cell pipes, the task `[x] ` source, source padding) keeps its
225
- * inline footprint when hidden so column widths and the checkbox gutter stay
226
- * identical between active and inactive states.
914
+ * A soft ending followed by an explicit blockquote continuation marker renders
915
+ * a real line break in both views. Its source newline is still mapped and is
916
+ * revealed while editing, but contributes no hidden width in rendered mode.
917
+ */
918
+ .md-blockquote-linebreak-source-hidden {
919
+ display: none;
920
+ }
921
+
922
+ /*
923
+ * Structural quote prefixes between child blocks can be owned by a source gap
924
+ * instead of an inline continuation marker. Keep the exact gap for active
925
+ * editing, but remove it entirely from inactive layout and hit testing.
926
+ */
927
+ .md-glue-blockQuoteSourceGap.md-glue-hidden {
928
+ display: none;
929
+ }
930
+
931
+ /*
932
+ * Glue normally keeps its inline footprint when hidden so source padding and
933
+ * widget gutters stay identical between active and inactive states. Hidden
934
+ * table-cell glue is the exception below: leaving it in inline flow lets its
935
+ * invisible spaces wrap around long cell content.
227
936
  */
228
937
  .md-glue-hidden {
229
938
  display: inline;
230
939
  visibility: hidden;
231
940
  }
232
941
 
942
+ /*
943
+ * Inactive table pipes stay in the DOM/source tree, but leave layout and
944
+ * hit-testing entirely. Keeping an invisible rect either in the content flow or
945
+ * over the cell padding can create phantom lines or steal clicks from visible
946
+ * text. Hidden source offsets therefore collapse to the neighboring semantic
947
+ * seam, matching other display-none markers. Visible pipes retain the per-theme
948
+ * active/source layout.
949
+ */
950
+ .md-table td>.md-glue-tableCellGlue.md-glue-hidden {
951
+ display: none;
952
+ }
953
+
954
+ /*
955
+ * Active table: take each cell's TRAILING structural glue (the source space
956
+ * after the cell text, and — via the per-theme `right: 0` rule — the last
957
+ * column's closing `|`) out of the cell's inline flow. Left in flow, that glue
958
+ * wraps below long cell content (the same wrapping the hidden-glue note above
959
+ * describes), which makes the cell two lines tall: the browser's default
960
+ * `vertical-align: middle` then re-centres the other cells' single-line content
961
+ * in Y, their runs merge into one oversized VisualLine, and the caret — sized
962
+ * directly from that line box — grows far past the line height while the
963
+ * visible pipes drift apart row-to-row. Positioning the trailing glue
964
+ * absolutely removes it from wrapping flow while keeping its real client rects
965
+ * at the static (content-line) position, so caret placement, hit-testing,
966
+ * source mapping and injectivity are unchanged. `top`/`bottom: auto` keep it on
967
+ * that content line rather than the cell's top edge. This mirrors the inactive
968
+ * `display: none` above; the leading `| ` glue deliberately stays in flow (a
969
+ * relative glyph shift, per theme) so first-text X is preserved.
970
+ *
971
+ * `:not(:first-child)` restricts this to a genuine trailing glue: a non-empty
972
+ * cell emits leading + trailing glue, but an EMPTY cell parses to a single glue
973
+ * node that is simultaneously first and last child. That lone node is the
974
+ * cell's leading pipe, so it must stay in flow like every other leading pipe;
975
+ * excluding it keeps empty cells identical to their previous (base) behaviour.
976
+ */
977
+ .md-table.md-block-active td {
978
+ position: relative;
979
+ }
980
+
981
+ .md-table.md-block-active td>.md-glue-tableCellGlue:last-child:not(:first-child) {
982
+ position: absolute;
983
+ top: auto;
984
+ bottom: auto;
985
+ }
986
+
233
987
  /*
234
988
  * Inter-block glue: the run of blank lines between two top-level blocks. It is
235
989
  * mounted as the last inline child of the block that precedes it, so it sits at
@@ -240,7 +994,8 @@
240
994
  * adds no line break and no height — active and inactive therefore have the
241
995
  * same height. When hidden it collapses to nothing.
242
996
  */
243
- .md-glue-blockGap {
997
+ .md-glue-blockGap,
998
+ .md-glue-blockQuoteSourceGap {
244
999
  white-space: normal;
245
1000
  }
246
1001
 
@@ -266,15 +1021,6 @@
266
1021
  visibility: hidden;
267
1022
  }
268
1023
 
269
- /*
270
- * Table cell-glue pipes (`| `) keep their inline footprint when hidden so the
271
- * column widths stay identical active and inactive.
272
- */
273
- .md-marker-tableCellGlue.md-marker-hidden {
274
- display: inline;
275
- visibility: hidden;
276
- }
277
-
278
1024
  /*
279
1025
  * The code-block fences (```lang / ```) each sit on their own source line. When
280
1026
  * hidden they keep their vertical footprint (visibility hidden, not display
@@ -309,6 +1055,48 @@
309
1055
  height: 16px;
310
1056
  }
311
1057
 
1058
+ /*
1059
+ * A wide table scrolls horizontally inside its wrapper (the block box) instead
1060
+ * of overflowing the page and scrolling the editor's fixed left gutter away.
1061
+ * The wrapper is the scroll viewport the selection/caret clipping measures (see
1062
+ * `BlockViewNode.scrollElement` / `blockViewportClip`); the inner `<table>`
1063
+ * keeps `width: auto` (theme-defined) so it sizes to its content and overflows.
1064
+ *
1065
+ * `width: fit-content` keeps the wrapper hugging the table's intrinsic width, so
1066
+ * a narrow table — and the active-block glow redirected onto the wrapper below —
1067
+ * stays as wide as the table (unchanged from before this wrapper existed).
1068
+ * `max-width: 100%` caps it at the content column, past which the table
1069
+ * overflows and scrolls locally. This is the standard responsive-table pattern
1070
+ * (cf. GitHub's own `width: max-content; max-width: 100%`).
1071
+ */
1072
+ .md-table-wrapper {
1073
+ overflow-x: auto;
1074
+ width: fit-content;
1075
+ max-width: 100%;
1076
+ }
1077
+
1078
+ /*
1079
+ * The active-block highlight is an *outset* glow (`box-shadow: 0 0 0 8px`).
1080
+ * Making the wrapper a scroll box (`overflow-x: auto`, which also forces
1081
+ * `overflow-y: auto`) clips descendant paint to its padding box, so the glow on
1082
+ * the inner active `<table>` would be cut off (the table has no horizontal
1083
+ * margin to give the shadow room). Render the generic active chrome on the
1084
+ * wrapper instead — a scroll box's own shadow is never clipped by its own
1085
+ * overflow, exactly like a code block carries the glow on its own scroller —
1086
+ * and drop it from the table, which keeps `md-block-active` purely for the
1087
+ * per-theme source-pipe styling.
1088
+ */
1089
+ .md-table-wrapper:has(> .md-table.md-block-active) {
1090
+ background: var(--md-block-active-background, #f8f8f8);
1091
+ border-radius: 4px;
1092
+ box-shadow: 0 0 0 8px var(--md-block-active-background, #f8f8f8);
1093
+ }
1094
+
1095
+ .md-table.md-block-active {
1096
+ background: none;
1097
+ box-shadow: none;
1098
+ }
1099
+
312
1100
  .md-selection-layer {
313
1101
  position: absolute;
314
1102
  top: 0;
@@ -424,9 +1212,26 @@
424
1212
 
425
1213
  .md-blockquote>.md-marker-blockQuoteMarker {
426
1214
  position: absolute;
427
- right: calc(100% - var(--md-blockquote-pad, 0px));
1215
+ right: calc(100% - var(--md-blockquote-pad, 0px) - 1ch);
428
1216
  top: auto;
1217
+ /*
1218
+ * Reserve the optional-space column so adding it cannot move the `>` glyph,
1219
+ * then shift and scale every active quote marker consistently to leave a
1220
+ * virtual gap before body text without consuming source width. These tuned
1221
+ * properties are shared by ordinary and marker-only quote lines.
1222
+ */
1223
+ --md-blockquote-marker-shift: -0.18ch;
1224
+ --md-blockquote-marker-scale: 0.9;
1225
+ display: inline-flex;
1226
+ min-width: 2ch;
1227
+ font-size: inherit;
1228
+ line-height: inherit;
1229
+ height: 1lh;
1230
+ align-items: center;
1231
+ text-align: left;
429
1232
  white-space: pre;
1233
+ transform: translateX(var(--md-blockquote-marker-shift)) scale(var(--md-blockquote-marker-scale));
1234
+ transform-origin: left center;
430
1235
  }
431
1236
 
432
1237
  /* Inactive: gone entirely (the gutter is empty, the text stays put). */
@@ -434,6 +1239,16 @@
434
1239
  display: none;
435
1240
  }
436
1241
 
1242
+ /* Collapsed block-gap newlines still need one flow box per marker-only line. */
1243
+ .md-blockquote-line-anchor {
1244
+ display: block;
1245
+ }
1246
+
1247
+ /* A trailing marker-only source line follows the preceding quoted line directly. */
1248
+ .md-blockquote-marker-only-line>.md-paragraph:last-of-type {
1249
+ margin-bottom: 0;
1250
+ }
1251
+
437
1252
  /* Code/math blocks scroll horizontally; their look is theme-defined. */
438
1253
  .md-code-block {
439
1254
  overflow-x: auto;
@@ -466,19 +1281,50 @@
466
1281
  * before the marker. Gutter-positioning keeps the marker out of the inline
467
1282
  * flow so toggling it never shifts the item's text horizontally.
468
1283
  *
469
- * `line-height: inherit` makes the marker share the item's line box (its own
470
- * `.md-marker` rule shrinks it to `line-height: 1`, which floats the glyph to
471
- * the top of the taller text line); matching the line box vertically centres
472
- * the `-` with the rendered text.
1284
+ * Vertical centring makes the marker box exactly the item's first line box and
1285
+ * centres the glyph in it. Getting that box right is the whole trick: an
1286
+ * inherited UNITLESS line-height is re-resolved against the element's own
1287
+ * font-size, so a marker shrunk by `--md-marker-font-scale` also gets a
1288
+ * proportionally shorter line box which, pinned at `top: 0`, floats the glyph
1289
+ * above the text. Dividing `1lh` by that same scale cancels the shrink exactly,
1290
+ * without touching the painted size and without a `transform` (which would
1291
+ * shrink the box the caret geometry is measured from).
473
1292
  */
474
1293
  .md-list-item-active>.md-marker-listItemMarker {
475
1294
  position: absolute;
476
1295
  right: 100%;
477
1296
  top: 0;
478
1297
  line-height: inherit;
1298
+ height: calc(1lh / var(--md-marker-font-scale));
1299
+ display: inline-flex;
1300
+ align-items: center;
1301
+ justify-content: flex-end;
479
1302
  white-space: pre;
480
1303
  }
481
1304
 
1305
+ /*
1306
+ * `display: inline-flex` above outranks the plain `.md-marker-hidden`
1307
+ * (`display: none`), so — exactly as for headings — re-hide the marker here for
1308
+ * the states that ask for it, otherwise the bullet could never be hidden.
1309
+ */
1310
+ .md-list-item-active>.md-marker-listItemMarker.md-marker-hidden {
1311
+ display: none;
1312
+ }
1313
+
1314
+ /*
1315
+ * An inactive ordered item uses the browser's native `::marker`. Match its
1316
+ * typography when revealing the source marker so switching the active item
1317
+ * does not change the number's width or horizontal position: an ordered marker
1318
+ * opts out of the muted size step entirely, which also makes the `1lh`
1319
+ * compensation above a no-op for it. Keep unordered source markers in the
1320
+ * standard muted monospace source style.
1321
+ */
1322
+ ol.md-list>.md-list-item-active>.md-marker-listItemMarker,
1323
+ ol.md-list>.md-list-item-active>.md-list-gutter>.md-marker-listItemMarker {
1324
+ font-family: inherit;
1325
+ --md-marker-font-scale: 1;
1326
+ }
1327
+
482
1328
  /*
483
1329
  * A nested item's source indentation precedes its bullet (`␣␣- text`). The
484
1330
  * indent glue and the bullet are mounted together in this gutter span, which is
@@ -511,6 +1357,25 @@
511
1357
  flex: 0 0 auto;
512
1358
  }
513
1359
 
1360
+ /*
1361
+ * A NESTED item's bullet is a flex child of the gutter, so the direct-child
1362
+ * rule above cannot reach it and it would otherwise stretch to the gutter's
1363
+ * full height with its glyph parked at the top. Centring is therefore done by
1364
+ * the gutter itself: it is statically positioned (hence aligned to the item's
1365
+ * first line), so making it one line box tall and centring its children puts
1366
+ * the bullet and the indentation dots on that line.
1367
+ *
1368
+ * The gutter carries body typography, so its `1lh` needs no compensation — and
1369
+ * the bullet inside keeps its own muted `font-size`, which is exactly what the
1370
+ * shrink-to-fit gutter reserves. Shrinking the bullet visually instead would
1371
+ * make the gutter reserve more width than the bullet paints and slide the whole
1372
+ * indentation column left.
1373
+ */
1374
+ .md-list-item-active>.md-list-gutter {
1375
+ height: 1lh;
1376
+ align-items: center;
1377
+ }
1378
+
514
1379
 
515
1380
  /*
516
1381
  * Re-attributed source indentation (the spaces after a line break that precede
@@ -523,6 +1388,16 @@
523
1388
  white-space: pre;
524
1389
  }
525
1390
 
1391
+ /*
1392
+ * A continuation-line indent inside a paragraph is source-only padding. When
1393
+ * inactive, the preceding soft-break newline already collapses to the single
1394
+ * rendered space Markdown requires; retaining the hidden indent would add the
1395
+ * tab/space run's width on top of it.
1396
+ */
1397
+ .md-paragraph>.md-glue-indent.md-glue-hidden {
1398
+ display: none;
1399
+ }
1400
+
526
1401
  /*
527
1402
  * A loose list item's later block (its second paragraph etc.) owns the source
528
1403
  * continuation indent that precedes it as its `leadingTrivia`. Like a nested
@@ -556,14 +1431,20 @@
556
1431
  }
557
1432
 
558
1433
  /*
559
- * Reserve the marker column after the `[x]`/`[ ]` source marker (the first glue
560
- * in a task item's paragraph) so the rendered checkbox widget overlaid on it has
561
- * a comfortable gap before the text. The fixed width applies in both active and
562
- * inactive states, so the first text character does not drift horizontally when
563
- * markers toggle (see the compare fixture's `checkMarkedTextX` assertion).
1434
+ * Reserve the marker column on the paragraph rather than only on its first
1435
+ * inline child. This gives every wrapped line the same content edge. The
1436
+ * source marker glue is positioned over that reserved column, as is the
1437
+ * rendered checkbox, so activating the item does not shift its text (see the
1438
+ * compare fixture's `checkMarkedTextX` assertion).
564
1439
  */
565
- .md-task-list-item .md-paragraph>.md-glue:first-child {
566
- display: inline-block;
1440
+ .md-task-list-item>.md-paragraph {
1441
+ padding-left: var(--md-task-marker-width);
1442
+ }
1443
+
1444
+ .md-task-list-item>.md-paragraph>.md-glue:first-child {
1445
+ position: absolute;
1446
+ top: 0;
1447
+ left: 0;
567
1448
  width: var(--md-task-marker-width);
568
1449
  }
569
1450
 
@@ -588,6 +1469,7 @@
588
1469
  position: absolute;
589
1470
  left: 0;
590
1471
  top: 0.25em;
1472
+ z-index: 1;
591
1473
  cursor: pointer;
592
1474
  transition: background-color 0.15s ease, border-color 0.15s ease;
593
1475
  }
@@ -600,8 +1482,8 @@
600
1482
  .md-checkbox:checked::after {
601
1483
  content: '';
602
1484
  position: absolute;
603
- left: 3px;
604
- top: 0px;
1485
+ left: 2.5px;
1486
+ top: -1px;
605
1487
  width: 5px;
606
1488
  height: 9px;
607
1489
  border: solid white;
@@ -613,6 +1495,39 @@
613
1495
  border-color: #888;
614
1496
  }
615
1497
 
1498
+ /*
1499
+ * The rotating "broken rounded-square" progress ring for an inactive task item
1500
+ * whose text begins with the hidden `:running:` marker (see
1501
+ * `ListItemViewData.isRunning`). Rendered as a conic-gradient ring — masked so
1502
+ * only the ring (not its center) paints — with a transparent gap that spins,
1503
+ * reading as a segmented spinner rather than a checked/unchecked box.
1504
+ */
1505
+ .md-checkbox-running,
1506
+ .md-checkbox-running:checked {
1507
+ padding: 2px;
1508
+ border: 0;
1509
+ border-radius: 4px;
1510
+ background: conic-gradient(
1511
+ transparent 0deg 42deg,
1512
+ #bbb 62deg 360deg
1513
+ );
1514
+ -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
1515
+ -webkit-mask-composite: xor;
1516
+ mask-composite: exclude;
1517
+ animation: md-checkbox-spin 0.8s linear infinite;
1518
+ opacity: 1;
1519
+ }
1520
+
1521
+ @keyframes md-checkbox-spin {
1522
+ to {
1523
+ transform: rotate(360deg);
1524
+ }
1525
+ }
1526
+
1527
+ .md-checkbox-running:hover {
1528
+ border-color: transparent;
1529
+ }
1530
+
616
1531
  .md-checkbox:checked:hover {
617
1532
  background-color: #3a73d4;
618
1533
  border-color: #3a73d4;
@@ -623,14 +1538,66 @@
623
1538
  opacity: 0.6;
624
1539
  }
625
1540
 
1541
+ .md-checkbox-running:disabled {
1542
+ opacity: 1;
1543
+ }
1544
+
1545
+ @media (prefers-reduced-motion: reduce) {
1546
+ .md-checkbox-running {
1547
+ animation: none !important;
1548
+ }
1549
+ }
1550
+
1551
+ /*
1552
+ * The `:running:` marker hidden from an inactive task item's rendered text
1553
+ * (see `TextViewData.hiddenPrefixLength`). It stays real, selectable source —
1554
+ * only visually hidden, per "Hidden markers remain real source" — so it takes
1555
+ * no layout space in either state.
1556
+ */
1557
+ .md-runner-marker {
1558
+ display: none;
1559
+ }
1560
+
626
1561
  .md-cursor {
627
1562
  position: absolute;
628
1563
  width: 2px;
629
1564
  background: var(--md-cursor-background, #000);
630
1565
  pointer-events: none;
1566
+ }
1567
+
1568
+ /*
1569
+ * The painted caret is only shown while the editor is genuinely focused — focus
1570
+ * rests inside it and its window is focused, mirrored onto the root as
1571
+ * `.md-focused`. When unfocused, hide the caret element but keep its layout box
1572
+ * (so caret geometry, selection and comment anchoring are unchanged) and stop
1573
+ * the blink. Adding the animation on focus restarts it from 0% (a solid caret).
1574
+ */
1575
+ .md-editor:not(.md-focused) .md-cursor {
1576
+ visibility: hidden;
1577
+ }
1578
+
1579
+ .md-editor.md-focused .md-cursor {
631
1580
  animation: md-cursor-blink 1s step-end infinite;
632
1581
  }
633
1582
 
1583
+ /*
1584
+ * Read-only mode retains the logical caret for selection and comment anchoring.
1585
+ * Hide only its painted element so unlocking can restore it in place.
1586
+ */
1587
+ .md-editor.md-readonly .md-cursor {
1588
+ visibility: hidden;
1589
+ }
1590
+
1591
+ .md-editor.md-readonly-editing-attempt {
1592
+ animation: md-readonly-editing-attempt 300ms ease-out;
1593
+ }
1594
+
1595
+ @keyframes md-readonly-editing-attempt {
1596
+ 50% {
1597
+ box-shadow: inset 0 0 0 2px var(--md-readonly-shine-glow, rgba(255, 255, 255, 0.58));
1598
+ }
1599
+ }
1600
+
634
1601
  @keyframes md-cursor-blink {
635
1602
 
636
1603
  0%,
@@ -641,4 +1608,201 @@
641
1608
  50% {
642
1609
  opacity: 0;
643
1610
  }
1611
+ }
1612
+
1613
+ /*
1614
+ * Edit / read-only lock toggle.
1615
+ *
1616
+ * The asymmetric content padding reserves a real rail for the control:
1617
+ * button width + gap + edge inset. The zero-height sticky host spans the
1618
+ * document column and that rail, keeping the button beside (never over) the
1619
+ * rendered document as it scrolls. Colors use local `--md-readonly-*` custom
1620
+ * properties with literal fallbacks so this base file stays theme-agnostic
1621
+ * (themes may override them).
1622
+ */
1623
+ .md-readonly-toggle-host {
1624
+ position: sticky;
1625
+ top: 0;
1626
+ width: calc(100% + var(--md-editor-content-inline-end-padding));
1627
+ height: 0;
1628
+ z-index: 10;
1629
+ pointer-events: none;
1630
+ }
1631
+
1632
+ .md-readonly-toggle {
1633
+ position: absolute;
1634
+ top: 4px;
1635
+ right: var(--md-readonly-toggle-inset);
1636
+ pointer-events: auto;
1637
+ display: inline-grid;
1638
+ grid-template-columns: repeat(2, 24px);
1639
+ align-items: center;
1640
+ justify-items: center;
1641
+ gap: 2px;
1642
+ box-sizing: border-box;
1643
+ width: var(--md-readonly-toggle-width);
1644
+ height: var(--md-readonly-toggle-height);
1645
+ padding: 3px;
1646
+ overflow: hidden;
1647
+ direction: ltr;
1648
+ appearance: none;
1649
+ border-radius: 999px;
1650
+ border: 1px solid var(--md-readonly-border, #b8b8b8);
1651
+ background: var(--md-readonly-background, #f3f3f3);
1652
+ color: var(--md-readonly-foreground, #444444);
1653
+ font-size: 16px;
1654
+ line-height: 1;
1655
+ cursor: pointer;
1656
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.08);
1657
+ transition: background-color 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
1658
+ }
1659
+
1660
+ /*
1661
+ * Below this width there is not enough document column for the side rail to be
1662
+ * useful. Give the host its own row and stop it from sticking, so neither long
1663
+ * unbreakable content nor later content scrolled through the viewport can ever
1664
+ * pass underneath the button.
1665
+ */
1666
+ .md-editor-narrow .md-readonly-toggle-host {
1667
+ position: relative;
1668
+ height: calc(var(--md-readonly-toggle-height) + var(--md-readonly-toggle-inset) + var(--md-readonly-toggle-inset));
1669
+ }
1670
+
1671
+ .md-readonly-toggle::after {
1672
+ content: '';
1673
+ position: absolute;
1674
+ z-index: 2;
1675
+ top: -8px;
1676
+ bottom: -8px;
1677
+ left: -30px;
1678
+ width: 24px;
1679
+ background: linear-gradient(90deg,
1680
+ transparent,
1681
+ var(--md-readonly-shine-edge, rgba(255, 255, 255, 0.16)) 24%,
1682
+ var(--md-readonly-shine, #ffffff) 50%,
1683
+ var(--md-readonly-shine-edge, rgba(255, 255, 255, 0.16)) 76%,
1684
+ transparent);
1685
+ box-shadow: 0 0 8px 2px var(--md-readonly-shine-glow, rgba(255, 255, 255, 0.58));
1686
+ opacity: 0;
1687
+ pointer-events: none;
1688
+ transform: skewX(-20deg);
1689
+ }
1690
+
1691
+ .md-readonly-toggle.md-readonly-toggle-shine::after {
1692
+ animation: md-readonly-toggle-shine 2s linear;
1693
+ will-change: transform, opacity;
1694
+ }
1695
+
1696
+ @keyframes md-readonly-toggle-shine {
1697
+ 0% {
1698
+ opacity: 0;
1699
+ transform: translateX(0) skewX(-20deg);
1700
+ }
1701
+
1702
+ 12%,
1703
+ 88% {
1704
+ opacity: 1;
1705
+ }
1706
+
1707
+ 100% {
1708
+ opacity: 0;
1709
+ transform: translateX(122px) skewX(-20deg);
1710
+ }
1711
+ }
1712
+
1713
+ .md-readonly-toggle:hover {
1714
+ border-color: var(--md-readonly-border-hover, #8d8d8d);
1715
+ background: var(--md-readonly-background-hover, #e9e9e9);
1716
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 6px 16px rgba(0, 0, 0, 0.1);
1717
+ }
1718
+
1719
+ .md-readonly-toggle:focus-visible {
1720
+ outline: 2px solid var(--md-readonly-accent, #4c8bf5);
1721
+ outline-offset: 1px;
1722
+ }
1723
+
1724
+ .md-readonly-toggle .md-readonly-toggle-indicator {
1725
+ position: absolute;
1726
+ top: 50%;
1727
+ left: 3px;
1728
+ width: 24px;
1729
+ height: 24px;
1730
+ border-radius: 50%;
1731
+ background: var(--md-readonly-accent, #4c8bf5);
1732
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
1733
+ transform: translate(26px, -50%);
1734
+ transition: background-color 0.12s ease, transform 0.16s ease;
1735
+ }
1736
+
1737
+ .md-readonly-toggle .md-readonly-toggle-icon {
1738
+ position: relative;
1739
+ z-index: 1;
1740
+ display: block;
1741
+ width: 16px;
1742
+ height: 16px;
1743
+ color: var(--md-readonly-foreground, #444444);
1744
+ opacity: 0.62;
1745
+ pointer-events: none;
1746
+ transition: color 0.12s ease, opacity 0.12s ease;
1747
+ }
1748
+
1749
+ .md-readonly-toggle:not(.md-readonly-toggle-locked) .md-readonly-toggle-icon-editing,
1750
+ .md-readonly-toggle.md-readonly-toggle-locked .md-readonly-toggle-icon-locked {
1751
+ color: var(--md-readonly-accent-foreground, #ffffff);
1752
+ opacity: 1;
1753
+ }
1754
+
1755
+ .md-readonly-toggle.md-readonly-toggle-locked .md-readonly-toggle-indicator {
1756
+ transform: translate(0, -50%);
1757
+ }
1758
+
1759
+ @media (prefers-reduced-motion: reduce) {
1760
+
1761
+ .md-editor.md-readonly-editing-attempt,
1762
+ .md-readonly-toggle,
1763
+ .md-readonly-toggle .md-readonly-toggle-indicator,
1764
+ .md-readonly-toggle .md-readonly-toggle-icon,
1765
+ .md-readonly-toggle.md-readonly-toggle-shine::after {
1766
+ animation: none;
1767
+ transition: none;
1768
+ }
1769
+ }
1770
+
1771
+ @media (forced-colors: active) {
1772
+ .md-readonly-toggle {
1773
+ forced-color-adjust: none;
1774
+ border-color: ButtonText;
1775
+ background: ButtonFace;
1776
+ color: ButtonText;
1777
+ box-shadow: none;
1778
+ }
1779
+
1780
+ .md-readonly-toggle::after {
1781
+ display: none;
1782
+ }
1783
+
1784
+ .md-readonly-toggle:hover {
1785
+ border-color: Highlight;
1786
+ background: ButtonFace;
1787
+ box-shadow: none;
1788
+ }
1789
+
1790
+ .md-readonly-toggle:focus-visible {
1791
+ outline-color: Highlight;
1792
+ }
1793
+
1794
+ .md-readonly-toggle .md-readonly-toggle-indicator {
1795
+ background: Highlight;
1796
+ box-shadow: none;
1797
+ }
1798
+
1799
+ .md-readonly-toggle .md-readonly-toggle-icon {
1800
+ color: ButtonText;
1801
+ opacity: 1;
1802
+ }
1803
+
1804
+ .md-readonly-toggle:not(.md-readonly-toggle-locked) .md-readonly-toggle-icon-editing,
1805
+ .md-readonly-toggle.md-readonly-toggle-locked .md-readonly-toggle-icon-locked {
1806
+ color: HighlightText;
1807
+ }
644
1808
  }