@vscode/markdown-editor 0.0.2-7 → 0.0.2-71

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 (76) hide show
  1. package/README.md +26 -0
  2. package/dist/commands.d.ts +65 -0
  3. package/dist/commands.js +159 -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 +1490 -116
  11. package/dist/index.js +6170 -2006
  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 +282 -0
  17. package/dist/web-editors.js +7240 -0
  18. package/dist/web-editors.js.map +1 -0
  19. package/package.json +60 -17
  20. package/src/contrib/comments/commentInput.css +150 -0
  21. package/src/contrib/comments/comments.css +129 -0
  22. package/src/contrib/commentsVscode/vscodeCommentWidgetV2.css +171 -0
  23. package/src/contrib/find/find.css +347 -0
  24. package/src/view/editor.css +555 -25
  25. package/src/view/themes/default.css +13 -4
  26. package/src/view/themes/github.css +16 -13
  27. package/src/view/themes/vscode-default.css +397 -0
  28. package/src/view/themes/vscode-github.css +393 -0
  29. package/dist/_observables/assert.d.ts +0 -2
  30. package/dist/_observables/deps.d.ts +0 -28
  31. package/dist/_observables/disposables.d.ts +0 -19
  32. package/dist/_observables/equals.d.ts +0 -32
  33. package/dist/_observables/index.d.ts +0 -2
  34. package/dist/_observables/observableInternal/base.d.ts +0 -172
  35. package/dist/_observables/observableInternal/changeTracker.d.ts +0 -44
  36. package/dist/_observables/observableInternal/commonFacade/cancellation.d.ts +0 -24
  37. package/dist/_observables/observableInternal/commonFacade/deps.d.ts +0 -24
  38. package/dist/_observables/observableInternal/debugLocation.d.ts +0 -21
  39. package/dist/_observables/observableInternal/debugName.d.ts +0 -33
  40. package/dist/_observables/observableInternal/experimental/deferUnobserve.d.ts +0 -16
  41. package/dist/_observables/observableInternal/experimental/reducer.d.ts +0 -37
  42. package/dist/_observables/observableInternal/experimental/utils.d.ts +0 -15
  43. package/dist/_observables/observableInternal/index.d.ts +0 -25
  44. package/dist/_observables/observableInternal/logging/consoleObservableLogger.d.ts +0 -40
  45. package/dist/_observables/observableInternal/logging/debugGetDependencyGraph.d.ts +0 -4
  46. package/dist/_observables/observableInternal/logging/debugger/debuggerRpc.d.ts +0 -4
  47. package/dist/_observables/observableInternal/logging/debugger/devToolsLogger.d.ts +0 -43
  48. package/dist/_observables/observableInternal/logging/debugger/rpc.d.ts +0 -41
  49. package/dist/_observables/observableInternal/logging/debugger/utils.d.ts +0 -13
  50. package/dist/_observables/observableInternal/logging/logging.d.ts +0 -30
  51. package/dist/_observables/observableInternal/map.d.ts +0 -18
  52. package/dist/_observables/observableInternal/observables/baseObservable.d.ts +0 -58
  53. package/dist/_observables/observableInternal/observables/constObservable.d.ts +0 -5
  54. package/dist/_observables/observableInternal/observables/derived.d.ts +0 -46
  55. package/dist/_observables/observableInternal/observables/derivedImpl.d.ts +0 -83
  56. package/dist/_observables/observableInternal/observables/lazyObservableValue.d.ts +0 -27
  57. package/dist/_observables/observableInternal/observables/observableFromEvent.d.ts +0 -37
  58. package/dist/_observables/observableInternal/observables/observableSignal.d.ts +0 -11
  59. package/dist/_observables/observableInternal/observables/observableSignalFromEvent.d.ts +0 -5
  60. package/dist/_observables/observableInternal/observables/observableValue.d.ts +0 -37
  61. package/dist/_observables/observableInternal/observables/observableValueOpts.d.ts +0 -8
  62. package/dist/_observables/observableInternal/reactions/autorun.d.ts +0 -56
  63. package/dist/_observables/observableInternal/reactions/autorunImpl.d.ts +0 -53
  64. package/dist/_observables/observableInternal/set.d.ts +0 -17
  65. package/dist/_observables/observableInternal/transaction.d.ts +0 -27
  66. package/dist/_observables/observableInternal/utils/promise.d.ts +0 -75
  67. package/dist/_observables/observableInternal/utils/runOnChange.d.ts +0 -7
  68. package/dist/_observables/observableInternal/utils/utils.d.ts +0 -43
  69. package/dist/_observables/observableInternal/utils/utilsCancellation.d.ts +0 -10
  70. package/dist/_observables/observableInternal/utils/valueWithChangeEvent.d.ts +0 -10
  71. package/dist/_observables/utils.d.ts +0 -15
  72. package/dist/observables.d.ts +0 -4
  73. package/dist/observables.js +0 -439
  74. package/dist/observables.js.map +0 -1
  75. package/dist/runOnChange-C00UIwqQ.js +0 -1538
  76. 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
  *
@@ -12,14 +15,34 @@
12
15
  * theme files (`themes/default.css`, `themes/github.css`) applied via the
13
16
  * `classNames` editor option; those selectors only ever match inside their
14
17
  * own theme class and never style the global scope.
18
+ *
19
+ * NO `--vscode-*` variables may be referenced here. This base file must stay
20
+ * theme-agnostic and know nothing about VS Code. Where a value needs to vary
21
+ * per theme, expose a local `--md-*` custom property WITH a sensible literal
22
+ * fallback (e.g. `var(--md-cursor-background, #000)`) and let a theme file set
23
+ * it. Only the `themes/vscode-*.css` themes are permitted to read `--vscode-*`
24
+ * variables and map them onto these `--md-*` properties.
15
25
  */
16
26
 
17
27
  .md-editor {
28
+ display: flow-root;
18
29
  outline: none;
19
30
  /* The editor paints its own cursor (`.md-cursor`); hide the native caret. */
20
31
  caret-color: transparent;
21
32
  }
22
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
+
23
46
  /*
24
47
  * The transient empty paragraph — the blank line conjured by pressing Enter at
25
48
  * the end of a paragraph (see `PendingParagraph` in the model). It is not part
@@ -35,18 +58,58 @@
35
58
  * overlays, which position themselves relative to this box, so it is the
36
59
  * positioning context. In limited-width mode the editor sets an inline
37
60
  * `max-width` here and the auto inline margins center it within the full-width
38
- * `.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.
39
63
  */
40
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);
41
72
  position: relative;
42
73
  margin-inline: auto;
43
- 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;
44
84
  }
45
85
 
46
86
  .md-block-active {
47
- background: #f8f8f8;
87
+ background: var(--md-block-active-background, #f8f8f8);
48
88
  border-radius: 4px;
49
- box-shadow: 0 0 0 8px #f8f8f8;
89
+ box-shadow: 0 0 0 8px var(--md-block-active-background, #f8f8f8);
90
+ }
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;
50
113
  }
51
114
 
52
115
  /*
@@ -60,6 +123,7 @@
60
123
  .md-block-active a {
61
124
  cursor: inherit;
62
125
  }
126
+
63
127
  .md-editor.md-mod-down .md-block-active a[href] {
64
128
  cursor: pointer;
65
129
  }
@@ -74,6 +138,7 @@
74
138
  .md-editor a[href]:hover {
75
139
  text-decoration: underline;
76
140
  }
141
+
77
142
  .md-editor:not(.md-mod-down) .md-block-active a[href]:hover {
78
143
  text-decoration: none;
79
144
  }
@@ -87,7 +152,13 @@
87
152
  .md-marker {
88
153
  color: #999;
89
154
  font-family: 'Cascadia Code', 'Fira Code', monospace;
90
- font-size: 0.85em;
155
+ /*
156
+ * Revealed source is painted a step smaller than body text. Published as a
157
+ * custom property because a gutter marker has to undo it to size its box
158
+ * against the body line box — see `.md-list-item-active>.md-marker-listItemMarker`.
159
+ */
160
+ --md-marker-font-scale: 0.85;
161
+ font-size: calc(1em * var(--md-marker-font-scale));
91
162
  display: inline;
92
163
  overflow: hidden;
93
164
  max-width: 100px;
@@ -113,6 +184,69 @@
113
184
  white-space: pre-wrap;
114
185
  }
115
186
 
187
+ /*
188
+ * An unhandled block: a construct the parser does not model (setext heading,
189
+ * an extension token). Its raw source is shown verbatim,
190
+ * styled like a code block but visibly flagged as "not understood" by a dashed
191
+ * warning border, so the content is preserved and editable rather than silently
192
+ * dropped.
193
+ *
194
+ * The wrapper is the non-scrolling box (border + block spacing); the inner
195
+ * `.md-unhandled-scroll` <pre> is the horizontal scroller.
196
+ */
197
+ .md-unhandled-block {
198
+ margin: 0.5em 0;
199
+ border: 1px dashed #d0a000;
200
+ border-radius: 4px;
201
+ }
202
+
203
+ /*
204
+ * Inner scroller. Beats the per-theme `.md-theme-* .md-code-block` box rules
205
+ * (same class count) via the extra `pre` type selector: no margin/border of its
206
+ * own (those live on the wrapper).
207
+ */
208
+ pre.md-unhandled-scroll.md-code-block {
209
+ margin: 0;
210
+ border: 0;
211
+ border-radius: 4px;
212
+ }
213
+
214
+ /*
215
+ * Complete block HTML comments are authoring metadata, not unsupported-syntax
216
+ * warnings. Keep them source-identifiable but quiet while reading, and reveal
217
+ * their exact whitespace when the block becomes active.
218
+ */
219
+ .md-html-comment {
220
+ margin: 0.125em 0 0.25em;
221
+ padding: 0.125em 0;
222
+ overflow: hidden;
223
+ color: var(--md-html-comment-foreground, #6e7378);
224
+ font-family: var(--md-html-comment-font-family, 'Cascadia Code', 'Fira Code', monospace);
225
+ font-size: 0.85em;
226
+ line-height: 1.5;
227
+ text-overflow: ellipsis;
228
+ white-space: nowrap;
229
+ transition: color 80ms ease-out;
230
+ }
231
+
232
+ .md-html-comment:not(.md-html-comment-source):hover {
233
+ color: var(--md-html-comment-hover-foreground, #45494e);
234
+ }
235
+
236
+ .md-html-comment-source {
237
+ overflow: visible;
238
+ text-overflow: clip;
239
+ white-space: pre-wrap;
240
+ }
241
+
242
+ .md-html-comment-syntax {
243
+ opacity: 0.6;
244
+ }
245
+
246
+ .md-html-comment-source .md-html-comment-syntax {
247
+ opacity: 1;
248
+ }
249
+
116
250
  /*
117
251
  * Visible whitespace indicators, shown only in the active/source view. The real
118
252
  * whitespace character stays in the DOM (so source ↔ DOM mapping and selection
@@ -212,15 +346,61 @@
212
346
  }
213
347
 
214
348
  /*
215
- * Glue (table cell pipes, the task `[x] ` source, source padding) keeps its
216
- * inline footprint when hidden so column widths and the checkbox gutter stay
217
- * identical between active and inactive states.
349
+ * Glue normally keeps its inline footprint when hidden so source padding and
350
+ * widget gutters stay identical between active and inactive states. Hidden
351
+ * table-cell glue is the exception below: leaving it in inline flow lets its
352
+ * invisible spaces wrap around long cell content.
218
353
  */
219
354
  .md-glue-hidden {
220
355
  display: inline;
221
356
  visibility: hidden;
222
357
  }
223
358
 
359
+ /*
360
+ * Inactive table pipes stay in the DOM/source tree, but leave layout and
361
+ * hit-testing entirely. Keeping an invisible rect either in the content flow or
362
+ * over the cell padding can create phantom lines or steal clicks from visible
363
+ * text. Hidden source offsets therefore collapse to the neighboring semantic
364
+ * seam, matching other display-none markers. Visible pipes retain the per-theme
365
+ * active/source layout.
366
+ */
367
+ .md-table td>.md-glue-tableCellGlue.md-glue-hidden {
368
+ display: none;
369
+ }
370
+
371
+ /*
372
+ * Active table: take each cell's TRAILING structural glue (the source space
373
+ * after the cell text, and — via the per-theme `right: 0` rule — the last
374
+ * column's closing `|`) out of the cell's inline flow. Left in flow, that glue
375
+ * wraps below long cell content (the same wrapping the hidden-glue note above
376
+ * describes), which makes the cell two lines tall: the browser's default
377
+ * `vertical-align: middle` then re-centres the other cells' single-line content
378
+ * in Y, their runs merge into one oversized VisualLine, and the caret — sized
379
+ * directly from that line box — grows far past the line height while the
380
+ * visible pipes drift apart row-to-row. Positioning the trailing glue
381
+ * absolutely removes it from wrapping flow while keeping its real client rects
382
+ * at the static (content-line) position, so caret placement, hit-testing,
383
+ * source mapping and injectivity are unchanged. `top`/`bottom: auto` keep it on
384
+ * that content line rather than the cell's top edge. This mirrors the inactive
385
+ * `display: none` above; the leading `| ` glue deliberately stays in flow (a
386
+ * relative glyph shift, per theme) so first-text X is preserved.
387
+ *
388
+ * `:not(:first-child)` restricts this to a genuine trailing glue: a non-empty
389
+ * cell emits leading + trailing glue, but an EMPTY cell parses to a single glue
390
+ * node that is simultaneously first and last child. That lone node is the
391
+ * cell's leading pipe, so it must stay in flow like every other leading pipe;
392
+ * excluding it keeps empty cells identical to their previous (base) behaviour.
393
+ */
394
+ .md-table.md-block-active td {
395
+ position: relative;
396
+ }
397
+
398
+ .md-table.md-block-active td>.md-glue-tableCellGlue:last-child:not(:first-child) {
399
+ position: absolute;
400
+ top: auto;
401
+ bottom: auto;
402
+ }
403
+
224
404
  /*
225
405
  * Inter-block glue: the run of blank lines between two top-level blocks. It is
226
406
  * mounted as the last inline child of the block that precedes it, so it sits at
@@ -257,15 +437,6 @@
257
437
  visibility: hidden;
258
438
  }
259
439
 
260
- /*
261
- * Table cell-glue pipes (`| `) keep their inline footprint when hidden so the
262
- * column widths stay identical active and inactive.
263
- */
264
- .md-marker-tableCellGlue.md-marker-hidden {
265
- display: inline;
266
- visibility: hidden;
267
- }
268
-
269
440
  /*
270
441
  * The code-block fences (```lang / ```) each sit on their own source line. When
271
442
  * hidden they keep their vertical footprint (visibility hidden, not display
@@ -300,6 +471,48 @@
300
471
  height: 16px;
301
472
  }
302
473
 
474
+ /*
475
+ * A wide table scrolls horizontally inside its wrapper (the block box) instead
476
+ * of overflowing the page and scrolling the editor's fixed left gutter away.
477
+ * The wrapper is the scroll viewport the selection/caret clipping measures (see
478
+ * `BlockViewNode.scrollElement` / `blockViewportClip`); the inner `<table>`
479
+ * keeps `width: auto` (theme-defined) so it sizes to its content and overflows.
480
+ *
481
+ * `width: fit-content` keeps the wrapper hugging the table's intrinsic width, so
482
+ * a narrow table — and the active-block glow redirected onto the wrapper below —
483
+ * stays as wide as the table (unchanged from before this wrapper existed).
484
+ * `max-width: 100%` caps it at the content column, past which the table
485
+ * overflows and scrolls locally. This is the standard responsive-table pattern
486
+ * (cf. GitHub's own `width: max-content; max-width: 100%`).
487
+ */
488
+ .md-table-wrapper {
489
+ overflow-x: auto;
490
+ width: fit-content;
491
+ max-width: 100%;
492
+ }
493
+
494
+ /*
495
+ * The active-block highlight is an *outset* glow (`box-shadow: 0 0 0 8px`).
496
+ * Making the wrapper a scroll box (`overflow-x: auto`, which also forces
497
+ * `overflow-y: auto`) clips descendant paint to its padding box, so the glow on
498
+ * the inner active `<table>` would be cut off (the table has no horizontal
499
+ * margin to give the shadow room). Render the generic active chrome on the
500
+ * wrapper instead — a scroll box's own shadow is never clipped by its own
501
+ * overflow, exactly like a code block carries the glow on its own scroller —
502
+ * and drop it from the table, which keeps `md-block-active` purely for the
503
+ * per-theme source-pipe styling.
504
+ */
505
+ .md-table-wrapper:has(> .md-table.md-block-active) {
506
+ background: var(--md-block-active-background, #f8f8f8);
507
+ border-radius: 4px;
508
+ box-shadow: 0 0 0 8px var(--md-block-active-background, #f8f8f8);
509
+ }
510
+
511
+ .md-table.md-block-active {
512
+ background: none;
513
+ box-shadow: none;
514
+ }
515
+
303
516
  .md-selection-layer {
304
517
  position: absolute;
305
518
  top: 0;
@@ -415,9 +628,26 @@
415
628
 
416
629
  .md-blockquote>.md-marker-blockQuoteMarker {
417
630
  position: absolute;
418
- right: calc(100% - var(--md-blockquote-pad, 0px));
631
+ right: calc(100% - var(--md-blockquote-pad, 0px) - 1ch);
419
632
  top: auto;
633
+ /*
634
+ * Reserve the optional-space column so adding it cannot move the `>` glyph,
635
+ * then shift and scale every active quote marker consistently to leave a
636
+ * virtual gap before body text without consuming source width. These tuned
637
+ * properties are shared by ordinary and marker-only quote lines.
638
+ */
639
+ --md-blockquote-marker-shift: -0.18ch;
640
+ --md-blockquote-marker-scale: 0.9;
641
+ display: inline-flex;
642
+ min-width: 2ch;
643
+ font-size: inherit;
644
+ line-height: inherit;
645
+ height: 1lh;
646
+ align-items: center;
647
+ text-align: left;
420
648
  white-space: pre;
649
+ transform: translateX(var(--md-blockquote-marker-shift)) scale(var(--md-blockquote-marker-scale));
650
+ transform-origin: left center;
421
651
  }
422
652
 
423
653
  /* Inactive: gone entirely (the gutter is empty, the text stays put). */
@@ -425,6 +655,16 @@
425
655
  display: none;
426
656
  }
427
657
 
658
+ /* Collapsed block-gap newlines still need one flow box per marker-only line. */
659
+ .md-blockquote-line-anchor {
660
+ display: block;
661
+ }
662
+
663
+ /* A trailing marker-only source line follows the preceding quoted line directly. */
664
+ .md-blockquote-marker-only-line>.md-paragraph:last-of-type {
665
+ margin-bottom: 0;
666
+ }
667
+
428
668
  /* Code/math blocks scroll horizontally; their look is theme-defined. */
429
669
  .md-code-block {
430
670
  overflow-x: auto;
@@ -457,19 +697,50 @@
457
697
  * before the marker. Gutter-positioning keeps the marker out of the inline
458
698
  * flow so toggling it never shifts the item's text horizontally.
459
699
  *
460
- * `line-height: inherit` makes the marker share the item's line box (its own
461
- * `.md-marker` rule shrinks it to `line-height: 1`, which floats the glyph to
462
- * the top of the taller text line); matching the line box vertically centres
463
- * the `-` with the rendered text.
700
+ * Vertical centring makes the marker box exactly the item's first line box and
701
+ * centres the glyph in it. Getting that box right is the whole trick: an
702
+ * inherited UNITLESS line-height is re-resolved against the element's own
703
+ * font-size, so a marker shrunk by `--md-marker-font-scale` also gets a
704
+ * proportionally shorter line box which, pinned at `top: 0`, floats the glyph
705
+ * above the text. Dividing `1lh` by that same scale cancels the shrink exactly,
706
+ * without touching the painted size and without a `transform` (which would
707
+ * shrink the box the caret geometry is measured from).
464
708
  */
465
709
  .md-list-item-active>.md-marker-listItemMarker {
466
710
  position: absolute;
467
711
  right: 100%;
468
712
  top: 0;
469
713
  line-height: inherit;
714
+ height: calc(1lh / var(--md-marker-font-scale));
715
+ display: inline-flex;
716
+ align-items: center;
717
+ justify-content: flex-end;
470
718
  white-space: pre;
471
719
  }
472
720
 
721
+ /*
722
+ * `display: inline-flex` above outranks the plain `.md-marker-hidden`
723
+ * (`display: none`), so — exactly as for headings — re-hide the marker here for
724
+ * the states that ask for it, otherwise the bullet could never be hidden.
725
+ */
726
+ .md-list-item-active>.md-marker-listItemMarker.md-marker-hidden {
727
+ display: none;
728
+ }
729
+
730
+ /*
731
+ * An inactive ordered item uses the browser's native `::marker`. Match its
732
+ * typography when revealing the source marker so switching the active item
733
+ * does not change the number's width or horizontal position: an ordered marker
734
+ * opts out of the muted size step entirely, which also makes the `1lh`
735
+ * compensation above a no-op for it. Keep unordered source markers in the
736
+ * standard muted monospace source style.
737
+ */
738
+ ol.md-list>.md-list-item-active>.md-marker-listItemMarker,
739
+ ol.md-list>.md-list-item-active>.md-list-gutter>.md-marker-listItemMarker {
740
+ font-family: inherit;
741
+ --md-marker-font-scale: 1;
742
+ }
743
+
473
744
  /*
474
745
  * A nested item's source indentation precedes its bullet (`␣␣- text`). The
475
746
  * indent glue and the bullet are mounted together in this gutter span, which is
@@ -502,6 +773,25 @@
502
773
  flex: 0 0 auto;
503
774
  }
504
775
 
776
+ /*
777
+ * A NESTED item's bullet is a flex child of the gutter, so the direct-child
778
+ * rule above cannot reach it and it would otherwise stretch to the gutter's
779
+ * full height with its glyph parked at the top. Centring is therefore done by
780
+ * the gutter itself: it is statically positioned (hence aligned to the item's
781
+ * first line), so making it one line box tall and centring its children puts
782
+ * the bullet and the indentation dots on that line.
783
+ *
784
+ * The gutter carries body typography, so its `1lh` needs no compensation — and
785
+ * the bullet inside keeps its own muted `font-size`, which is exactly what the
786
+ * shrink-to-fit gutter reserves. Shrinking the bullet visually instead would
787
+ * make the gutter reserve more width than the bullet paints and slide the whole
788
+ * indentation column left.
789
+ */
790
+ .md-list-item-active>.md-list-gutter {
791
+ height: 1lh;
792
+ align-items: center;
793
+ }
794
+
505
795
 
506
796
  /*
507
797
  * Re-attributed source indentation (the spaces after a line break that precede
@@ -514,6 +804,16 @@
514
804
  white-space: pre;
515
805
  }
516
806
 
807
+ /*
808
+ * A continuation-line indent inside a paragraph is source-only padding. When
809
+ * inactive, the preceding soft-break newline already collapses to the single
810
+ * rendered space Markdown requires; retaining the hidden indent would add the
811
+ * tab/space run's width on top of it.
812
+ */
813
+ .md-paragraph>.md-glue-indent.md-glue-hidden {
814
+ display: none;
815
+ }
816
+
517
817
  /*
518
818
  * A loose list item's later block (its second paragraph etc.) owns the source
519
819
  * continuation indent that precedes it as its `leadingTrivia`. Like a nested
@@ -579,6 +879,7 @@
579
879
  position: absolute;
580
880
  left: 0;
581
881
  top: 0.25em;
882
+ z-index: 1;
582
883
  cursor: pointer;
583
884
  transition: background-color 0.15s ease, border-color 0.15s ease;
584
885
  }
@@ -591,8 +892,8 @@
591
892
  .md-checkbox:checked::after {
592
893
  content: '';
593
894
  position: absolute;
594
- left: 3px;
595
- top: 0px;
895
+ left: 2.5px;
896
+ top: -1px;
596
897
  width: 5px;
597
898
  height: 9px;
598
899
  border: solid white;
@@ -617,11 +918,43 @@
617
918
  .md-cursor {
618
919
  position: absolute;
619
920
  width: 2px;
620
- background: #000;
921
+ background: var(--md-cursor-background, #000);
621
922
  pointer-events: none;
923
+ }
924
+
925
+ /*
926
+ * The painted caret is only shown while the editor is genuinely focused — focus
927
+ * rests inside it and its window is focused, mirrored onto the root as
928
+ * `.md-focused`. When unfocused, hide the caret element but keep its layout box
929
+ * (so caret geometry, selection and comment anchoring are unchanged) and stop
930
+ * the blink. Adding the animation on focus restarts it from 0% (a solid caret).
931
+ */
932
+ .md-editor:not(.md-focused) .md-cursor {
933
+ visibility: hidden;
934
+ }
935
+
936
+ .md-editor.md-focused .md-cursor {
622
937
  animation: md-cursor-blink 1s step-end infinite;
623
938
  }
624
939
 
940
+ /*
941
+ * Read-only mode retains the logical caret for selection and comment anchoring.
942
+ * Hide only its painted element so unlocking can restore it in place.
943
+ */
944
+ .md-editor.md-readonly .md-cursor {
945
+ visibility: hidden;
946
+ }
947
+
948
+ .md-editor.md-readonly-editing-attempt {
949
+ animation: md-readonly-editing-attempt 300ms ease-out;
950
+ }
951
+
952
+ @keyframes md-readonly-editing-attempt {
953
+ 50% {
954
+ box-shadow: inset 0 0 0 2px var(--md-readonly-shine-glow, rgba(255, 255, 255, 0.58));
955
+ }
956
+ }
957
+
625
958
  @keyframes md-cursor-blink {
626
959
 
627
960
  0%,
@@ -632,4 +965,201 @@
632
965
  50% {
633
966
  opacity: 0;
634
967
  }
968
+ }
969
+
970
+ /*
971
+ * Edit / read-only lock toggle.
972
+ *
973
+ * The asymmetric content padding reserves a real rail for the control:
974
+ * button width + gap + edge inset. The zero-height sticky host spans the
975
+ * document column and that rail, keeping the button beside (never over) the
976
+ * rendered document as it scrolls. Colors use local `--md-readonly-*` custom
977
+ * properties with literal fallbacks so this base file stays theme-agnostic
978
+ * (themes may override them).
979
+ */
980
+ .md-readonly-toggle-host {
981
+ position: sticky;
982
+ top: 0;
983
+ width: calc(100% + var(--md-editor-content-inline-end-padding));
984
+ height: 0;
985
+ z-index: 10;
986
+ pointer-events: none;
987
+ }
988
+
989
+ .md-readonly-toggle {
990
+ position: absolute;
991
+ top: 4px;
992
+ right: var(--md-readonly-toggle-inset);
993
+ pointer-events: auto;
994
+ display: inline-grid;
995
+ grid-template-columns: repeat(2, 24px);
996
+ align-items: center;
997
+ justify-items: center;
998
+ gap: 2px;
999
+ box-sizing: border-box;
1000
+ width: var(--md-readonly-toggle-width);
1001
+ height: var(--md-readonly-toggle-height);
1002
+ padding: 3px;
1003
+ overflow: hidden;
1004
+ direction: ltr;
1005
+ appearance: none;
1006
+ border-radius: 999px;
1007
+ border: 1px solid var(--md-readonly-border, #b8b8b8);
1008
+ background: var(--md-readonly-background, #f3f3f3);
1009
+ color: var(--md-readonly-foreground, #444444);
1010
+ font-size: 16px;
1011
+ line-height: 1;
1012
+ cursor: pointer;
1013
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 4px 12px rgba(0, 0, 0, 0.08);
1014
+ transition: background-color 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
1015
+ }
1016
+
1017
+ /*
1018
+ * Below this width there is not enough document column for the side rail to be
1019
+ * useful. Give the host its own row and stop it from sticking, so neither long
1020
+ * unbreakable content nor later content scrolled through the viewport can ever
1021
+ * pass underneath the button.
1022
+ */
1023
+ .md-editor-narrow .md-readonly-toggle-host {
1024
+ position: relative;
1025
+ height: calc(var(--md-readonly-toggle-height) + var(--md-readonly-toggle-inset) + var(--md-readonly-toggle-inset));
1026
+ }
1027
+
1028
+ .md-readonly-toggle::after {
1029
+ content: '';
1030
+ position: absolute;
1031
+ z-index: 2;
1032
+ top: -8px;
1033
+ bottom: -8px;
1034
+ left: -30px;
1035
+ width: 24px;
1036
+ background: linear-gradient(90deg,
1037
+ transparent,
1038
+ var(--md-readonly-shine-edge, rgba(255, 255, 255, 0.16)) 24%,
1039
+ var(--md-readonly-shine, #ffffff) 50%,
1040
+ var(--md-readonly-shine-edge, rgba(255, 255, 255, 0.16)) 76%,
1041
+ transparent);
1042
+ box-shadow: 0 0 8px 2px var(--md-readonly-shine-glow, rgba(255, 255, 255, 0.58));
1043
+ opacity: 0;
1044
+ pointer-events: none;
1045
+ transform: skewX(-20deg);
1046
+ }
1047
+
1048
+ .md-readonly-toggle.md-readonly-toggle-shine::after {
1049
+ animation: md-readonly-toggle-shine 2s linear;
1050
+ will-change: transform, opacity;
1051
+ }
1052
+
1053
+ @keyframes md-readonly-toggle-shine {
1054
+ 0% {
1055
+ opacity: 0;
1056
+ transform: translateX(0) skewX(-20deg);
1057
+ }
1058
+
1059
+ 12%,
1060
+ 88% {
1061
+ opacity: 1;
1062
+ }
1063
+
1064
+ 100% {
1065
+ opacity: 0;
1066
+ transform: translateX(122px) skewX(-20deg);
1067
+ }
1068
+ }
1069
+
1070
+ .md-readonly-toggle:hover {
1071
+ border-color: var(--md-readonly-border-hover, #8d8d8d);
1072
+ background: var(--md-readonly-background-hover, #e9e9e9);
1073
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 6px 16px rgba(0, 0, 0, 0.1);
1074
+ }
1075
+
1076
+ .md-readonly-toggle:focus-visible {
1077
+ outline: 2px solid var(--md-readonly-accent, #4c8bf5);
1078
+ outline-offset: 1px;
1079
+ }
1080
+
1081
+ .md-readonly-toggle .md-readonly-toggle-indicator {
1082
+ position: absolute;
1083
+ top: 50%;
1084
+ left: 3px;
1085
+ width: 24px;
1086
+ height: 24px;
1087
+ border-radius: 50%;
1088
+ background: var(--md-readonly-accent, #4c8bf5);
1089
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
1090
+ transform: translate(26px, -50%);
1091
+ transition: background-color 0.12s ease, transform 0.16s ease;
1092
+ }
1093
+
1094
+ .md-readonly-toggle .md-readonly-toggle-icon {
1095
+ position: relative;
1096
+ z-index: 1;
1097
+ display: block;
1098
+ width: 16px;
1099
+ height: 16px;
1100
+ color: var(--md-readonly-foreground, #444444);
1101
+ opacity: 0.62;
1102
+ pointer-events: none;
1103
+ transition: color 0.12s ease, opacity 0.12s ease;
1104
+ }
1105
+
1106
+ .md-readonly-toggle:not(.md-readonly-toggle-locked) .md-readonly-toggle-icon-editing,
1107
+ .md-readonly-toggle.md-readonly-toggle-locked .md-readonly-toggle-icon-locked {
1108
+ color: var(--md-readonly-accent-foreground, #ffffff);
1109
+ opacity: 1;
1110
+ }
1111
+
1112
+ .md-readonly-toggle.md-readonly-toggle-locked .md-readonly-toggle-indicator {
1113
+ transform: translate(0, -50%);
1114
+ }
1115
+
1116
+ @media (prefers-reduced-motion: reduce) {
1117
+
1118
+ .md-editor.md-readonly-editing-attempt,
1119
+ .md-readonly-toggle,
1120
+ .md-readonly-toggle .md-readonly-toggle-indicator,
1121
+ .md-readonly-toggle .md-readonly-toggle-icon,
1122
+ .md-readonly-toggle.md-readonly-toggle-shine::after {
1123
+ animation: none;
1124
+ transition: none;
1125
+ }
1126
+ }
1127
+
1128
+ @media (forced-colors: active) {
1129
+ .md-readonly-toggle {
1130
+ forced-color-adjust: none;
1131
+ border-color: ButtonText;
1132
+ background: ButtonFace;
1133
+ color: ButtonText;
1134
+ box-shadow: none;
1135
+ }
1136
+
1137
+ .md-readonly-toggle::after {
1138
+ display: none;
1139
+ }
1140
+
1141
+ .md-readonly-toggle:hover {
1142
+ border-color: Highlight;
1143
+ background: ButtonFace;
1144
+ box-shadow: none;
1145
+ }
1146
+
1147
+ .md-readonly-toggle:focus-visible {
1148
+ outline-color: Highlight;
1149
+ }
1150
+
1151
+ .md-readonly-toggle .md-readonly-toggle-indicator {
1152
+ background: Highlight;
1153
+ box-shadow: none;
1154
+ }
1155
+
1156
+ .md-readonly-toggle .md-readonly-toggle-icon {
1157
+ color: ButtonText;
1158
+ opacity: 1;
1159
+ }
1160
+
1161
+ .md-readonly-toggle:not(.md-readonly-toggle-locked) .md-readonly-toggle-icon-editing,
1162
+ .md-readonly-toggle.md-readonly-toggle-locked .md-readonly-toggle-icon-locked {
1163
+ color: HighlightText;
1164
+ }
635
1165
  }