somark-js 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/LICENSE +156 -0
  2. package/README.md +32 -0
  3. package/README_CN.md +31 -0
  4. package/dist/chunk-RWOUZTFQ.mjs +236 -0
  5. package/dist/cli.mjs +1503 -0
  6. package/dist/config-GOZJZCRT.mjs +26 -0
  7. package/dist/index.cjs +1304 -0
  8. package/dist/index.d.cts +258 -0
  9. package/dist/index.d.ts +258 -0
  10. package/dist/index.mjs +1245 -0
  11. package/package.json +66 -0
  12. package/vendor/somarkdown-viewer/LICENSE +21 -0
  13. package/vendor/somarkdown-viewer/README.md +63 -0
  14. package/vendor/somarkdown-viewer/README_CN.md +63 -0
  15. package/vendor/somarkdown-viewer/index.html +112 -0
  16. package/vendor/somarkdown-viewer/lib/bi-direction-jump.js +161 -0
  17. package/vendor/somarkdown-viewer/lib/deps/highlight.js.default.min.css +11 -0
  18. package/vendor/somarkdown-viewer/lib/deps/katex.min.css +6 -0
  19. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_AMS-Regular.ttf +0 -0
  20. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_AMS-Regular.woff +0 -0
  21. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_AMS-Regular.woff2 +0 -0
  22. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  23. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  24. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  25. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  26. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  27. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  28. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  29. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Fraktur-Bold.woff +0 -0
  30. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  31. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  32. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Fraktur-Regular.woff +0 -0
  33. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  34. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-Bold.ttf +0 -0
  35. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-Bold.woff +0 -0
  36. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-Bold.woff2 +0 -0
  37. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  38. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-BoldItalic.woff +0 -0
  39. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  40. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-Italic.ttf +0 -0
  41. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-Italic.woff +0 -0
  42. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-Italic.woff2 +0 -0
  43. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-Regular.ttf +0 -0
  44. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-Regular.woff +0 -0
  45. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Main-Regular.woff2 +0 -0
  46. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  47. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Math-BoldItalic.woff +0 -0
  48. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  49. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Math-Italic.ttf +0 -0
  50. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Math-Italic.woff +0 -0
  51. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Math-Italic.woff2 +0 -0
  52. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  53. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_SansSerif-Bold.woff +0 -0
  54. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  55. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  56. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_SansSerif-Italic.woff +0 -0
  57. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  58. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  59. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_SansSerif-Regular.woff +0 -0
  60. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  61. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Script-Regular.ttf +0 -0
  62. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Script-Regular.woff +0 -0
  63. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Script-Regular.woff2 +0 -0
  64. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size1-Regular.ttf +0 -0
  65. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size1-Regular.woff +0 -0
  66. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size1-Regular.woff2 +0 -0
  67. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size2-Regular.ttf +0 -0
  68. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size2-Regular.woff +0 -0
  69. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size2-Regular.woff2 +0 -0
  70. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size3-Regular.ttf +0 -0
  71. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size3-Regular.woff +0 -0
  72. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size3-Regular.woff2 +0 -0
  73. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size4-Regular.ttf +0 -0
  74. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size4-Regular.woff +0 -0
  75. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Size4-Regular.woff2 +0 -0
  76. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  77. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Typewriter-Regular.woff +0 -0
  78. package/vendor/somarkdown-viewer/lib/deps/katex_fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  79. package/vendor/somarkdown-viewer/lib/i18n.js +81 -0
  80. package/vendor/somarkdown-viewer/lib/index.js +299 -0
  81. package/vendor/somarkdown-viewer/lib/somarkdown/VERSION +1 -0
  82. package/vendor/somarkdown-viewer/lib/somarkdown/somarkdown.css +591 -0
  83. package/vendor/somarkdown-viewer/lib/somarkdown/somarkdown.umd.min.js +59 -0
  84. package/vendor/somarkdown-viewer/lib/sync-scroll.js +147 -0
  85. package/vendor/somarkdown-viewer/style/index.css +527 -0
@@ -0,0 +1,147 @@
1
+ class ScrollSync {
2
+ constructor(options) {
3
+ this.editor = options.editor;
4
+ this.previewViewport = options.previewViewport;
5
+ this.preview = options.preview;
6
+ this.lockSide = null;
7
+ this.lineMap = [];
8
+ this.editorLineHeight = 22;
9
+ this.onEditorScroll = this.onEditorScroll.bind(this);
10
+ this.onPreviewScroll = this.onPreviewScroll.bind(this);
11
+ }
12
+
13
+ clamp(value, min, max) {
14
+ return Math.min(Math.max(value, min), max);
15
+ }
16
+
17
+ start() {
18
+ this.updateEditorLineHeight();
19
+ this.editor.addEventListener("scroll", this.onEditorScroll);
20
+ this.previewViewport.addEventListener("scroll", this.onPreviewScroll);
21
+ window.addEventListener("resize", () => this.refreshMap());
22
+ }
23
+
24
+ refreshMap() {
25
+ const nodes = this.preview.querySelectorAll("[data-line]");
26
+ this.lineMap = Array.from(nodes)
27
+ .map((node) => {
28
+ const line = Number.parseInt(node.getAttribute("data-line"), 10);
29
+ const table = node.closest("table");
30
+ return {
31
+ line: Number.isNaN(line) ? null : line + 1,
32
+ top: table ? table.offsetTop : node.offsetTop
33
+ };
34
+ })
35
+ .filter((entry) => entry.line !== null)
36
+ .sort((a, b) => a.line - b.line || a.top - b.top);
37
+ }
38
+
39
+ updateEditorLineHeight() {
40
+ const lineHeight = Number.parseFloat(window.getComputedStyle(this.editor).lineHeight);
41
+ this.editorLineHeight = Number.isNaN(lineHeight) ? 22 : lineHeight;
42
+ }
43
+
44
+ onEditorScroll() {
45
+ if (this.lockSide === "preview") {
46
+ return;
47
+ }
48
+ this.lockSide = "editor";
49
+ const maxEditorScroll = Math.max(this.editor.scrollHeight - this.editor.clientHeight, 0);
50
+ const maxPreviewScroll = Math.max(this.previewViewport.scrollHeight - this.previewViewport.clientHeight, 0);
51
+ const epsilon = 1;
52
+
53
+ if (maxPreviewScroll <= 0) {
54
+ this.lockSide = null;
55
+ return;
56
+ }
57
+
58
+ if (this.editor.scrollTop <= epsilon) {
59
+ this.previewViewport.scrollTop = 0;
60
+ } else if (this.editor.scrollTop >= maxEditorScroll - epsilon) {
61
+ this.previewViewport.scrollTop = maxPreviewScroll;
62
+ } else {
63
+ const line = this.editor.scrollTop / this.editorLineHeight + 1;
64
+ const top = this.interpolateTopByLine(line);
65
+ this.previewViewport.scrollTop = this.clamp(top, 0, maxPreviewScroll);
66
+ }
67
+
68
+ window.requestAnimationFrame(() => {
69
+ this.lockSide = null;
70
+ });
71
+ }
72
+
73
+ onPreviewScroll() {
74
+ if (this.lockSide === "editor") {
75
+ return;
76
+ }
77
+ this.lockSide = "preview";
78
+ const maxEditorScroll = Math.max(this.editor.scrollHeight - this.editor.clientHeight, 0);
79
+ const maxPreviewScroll = Math.max(this.previewViewport.scrollHeight - this.previewViewport.clientHeight, 0);
80
+ const epsilon = 1;
81
+
82
+ if (maxEditorScroll <= 0) {
83
+ this.lockSide = null;
84
+ return;
85
+ }
86
+
87
+ if (this.previewViewport.scrollTop <= epsilon) {
88
+ this.editor.scrollTop = 0;
89
+ } else if (this.previewViewport.scrollTop >= maxPreviewScroll - epsilon) {
90
+ this.editor.scrollTop = maxEditorScroll;
91
+ } else {
92
+ const line = this.interpolateLineByTop(this.previewViewport.scrollTop);
93
+ const target = (line - 1) * this.editorLineHeight;
94
+ this.editor.scrollTop = this.clamp(target, 0, maxEditorScroll);
95
+ }
96
+
97
+ window.requestAnimationFrame(() => {
98
+ this.lockSide = null;
99
+ });
100
+ }
101
+
102
+ interpolateTopByLine(line) {
103
+ if (this.lineMap.length === 0) {
104
+ return 0;
105
+ }
106
+ if (line <= this.lineMap[0].line) {
107
+ return 0;
108
+ }
109
+ for (let index = 1; index < this.lineMap.length; index += 1) {
110
+ const prev = this.lineMap[index - 1];
111
+ const curr = this.lineMap[index];
112
+ if (line <= curr.line) {
113
+ const deltaLine = curr.line - prev.line;
114
+ if (deltaLine <= 0) {
115
+ return curr.top;
116
+ }
117
+ const ratio = (line - prev.line) / deltaLine;
118
+ return prev.top + (curr.top - prev.top) * ratio;
119
+ }
120
+ }
121
+ return this.lineMap[this.lineMap.length - 1].top;
122
+ }
123
+
124
+ interpolateLineByTop(top) {
125
+ if (this.lineMap.length === 0) {
126
+ return 1;
127
+ }
128
+ if (top <= this.lineMap[0].top) {
129
+ return 1;
130
+ }
131
+ for (let index = 1; index < this.lineMap.length; index += 1) {
132
+ const prev = this.lineMap[index - 1];
133
+ const curr = this.lineMap[index];
134
+ if (top <= curr.top) {
135
+ const deltaTop = curr.top - prev.top;
136
+ if (deltaTop <= 0) {
137
+ return curr.line;
138
+ }
139
+ const ratio = (top - prev.top) / deltaTop;
140
+ return prev.line + (curr.line - prev.line) * ratio;
141
+ }
142
+ }
143
+ return this.lineMap[this.lineMap.length - 1].line;
144
+ }
145
+ }
146
+
147
+ export { ScrollSync };
@@ -0,0 +1,527 @@
1
+ :root {
2
+ --bg-color: #000000;
3
+ --text-color: #ffffff;
4
+ --text-muted: #a1a1aa;
5
+ --text-muted-dim: rgba(161, 161, 170, 0.45);
6
+ --text-muted-half: rgba(161, 161, 170, 0.6);
7
+ --border-color: #262626;
8
+ --bg-navbar: #000000;
9
+ --bg-accent: rgba(239, 135, 27, 0.16);
10
+ --bg-card: #0b0b0b;
11
+ --bg-editor: #050505;
12
+ --bg-preview: #101010;
13
+ --bg-overlay: rgba(0, 0, 0, 0.45);
14
+ --ring-color: #ef871b;
15
+ --accent-color: #ef871b;
16
+ --panel-shadow: -16px 0 32px rgba(0, 0, 0, 0.45);
17
+ --input-border: #393939;
18
+ --input-hover-border: #ef871b;
19
+ --input-bg: #151515;
20
+ --input-bg-active: #1f1f1f;
21
+ --selection-bg-color: rgba(239, 135, 27, 0.3);
22
+ --jump-highlight-bg: rgb(0, 0, 0);
23
+ --transition-normal: 220ms ease;
24
+ }
25
+
26
+ body {
27
+ margin: 0;
28
+ padding: 0;
29
+ background-color: var(--bg-color);
30
+ color: var(--text-color);
31
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
32
+ }
33
+
34
+ .app-container {
35
+ height: 100vh;
36
+ display: flex;
37
+ flex-direction: column;
38
+ overflow: hidden;
39
+ position: relative;
40
+ }
41
+
42
+ .app-main {
43
+ flex: 1;
44
+ min-height: 0;
45
+ display: flex;
46
+ flex-direction: column;
47
+ transition: filter var(--transition-normal);
48
+ }
49
+
50
+ .app-container.settings-open .app-main {
51
+ filter: blur(4px);
52
+ }
53
+
54
+ .app-header {
55
+ height: 3.5rem;
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: space-between;
59
+ padding: 0 1rem;
60
+ background-color: var(--bg-navbar);
61
+ border-bottom: 1px solid var(--border-color);
62
+ flex-shrink: 0;
63
+ }
64
+
65
+ .header-left {
66
+ display: flex;
67
+ align-items: center;
68
+ gap: 0.5rem;
69
+ }
70
+
71
+ .logo-text {
72
+ color: var(--text-color);
73
+ font-weight: 600;
74
+ font-size: 1.125rem;
75
+ letter-spacing: -0.025em;
76
+ user-select: none;
77
+ display: inline-flex;
78
+ align-items: center;
79
+ cursor: pointer;
80
+ text-decoration: none;
81
+ }
82
+
83
+ .header__logo-svg {
84
+ width: 0;
85
+ height: 24px;
86
+ margin-right: 0;
87
+ opacity: 0;
88
+ transition: width 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275),
89
+ margin-right 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275),
90
+ opacity 0.4s ease;
91
+ }
92
+
93
+ .logo-text:hover .header__logo-svg {
94
+ width: 28px;
95
+ margin-right: 6px;
96
+ opacity: 1;
97
+ }
98
+
99
+ .header__logo-rect {
100
+ transform-origin: center;
101
+ opacity: 0;
102
+ transform: rotate(-90deg) scale(0);
103
+ transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275),
104
+ opacity 0.4s ease;
105
+ }
106
+
107
+ .header__logo-rect--top {
108
+ transition-delay: 0s;
109
+ }
110
+
111
+ .header__logo-rect--middle {
112
+ transition-delay: 0.1s;
113
+ }
114
+
115
+ .header__logo-rect--bottom-left,
116
+ .header__logo-rect--bottom-right {
117
+ transition-delay: 0.2s;
118
+ }
119
+
120
+ .logo-text:hover .header__logo-rect {
121
+ opacity: 1;
122
+ transform: rotate(0deg) scale(1);
123
+ }
124
+
125
+ .logo-text:hover .header__logo-rect--top {
126
+ transition-delay: 0.2s;
127
+ }
128
+
129
+ .logo-text:hover .header__logo-rect--middle {
130
+ transition-delay: 0.1s;
131
+ }
132
+
133
+ .logo-text:hover .header__logo-rect--bottom-left,
134
+ .logo-text:hover .header__logo-rect--bottom-right {
135
+ transition-delay: 0s;
136
+ }
137
+
138
+ .file-path {
139
+ color: var(--text-muted);
140
+ font-size: 0.75rem;
141
+ margin-left: 0.25rem;
142
+ max-width: min(40vw, 30rem);
143
+ text-overflow: ellipsis;
144
+ overflow: hidden;
145
+ white-space: nowrap;
146
+ }
147
+
148
+ @media (min-width: 640px) {
149
+ .file-path {
150
+ display: inline;
151
+ }
152
+ }
153
+
154
+ .header-right {
155
+ display: flex;
156
+ align-items: center;
157
+ gap: 0.25rem;
158
+ }
159
+
160
+ .icon-btn {
161
+ display: inline-flex;
162
+ align-items: center;
163
+ justify-content: center;
164
+ white-space: nowrap;
165
+ border-radius: 0.375rem;
166
+ font-size: 0.875rem;
167
+ font-weight: 500;
168
+ height: 2.5rem;
169
+ width: 2.5rem;
170
+ color: var(--text-muted);
171
+ background: transparent;
172
+ border: none;
173
+ cursor: pointer;
174
+ transition: background-color 0.2s, color 0.2s;
175
+ }
176
+
177
+ .icon-btn:hover {
178
+ background-color: var(--bg-accent);
179
+ color: var(--accent-color);
180
+ }
181
+
182
+ .icon-btn:focus-visible {
183
+ outline: none;
184
+ box-shadow: 0 0 0 2px var(--bg-color), 0 0 0 4px var(--ring-color);
185
+ }
186
+
187
+ .icon-btn:disabled {
188
+ pointer-events: none;
189
+ opacity: 0.5;
190
+ }
191
+
192
+ .icon-btn svg, .icon-btn img {
193
+ pointer-events: none;
194
+ width: 1rem;
195
+ height: 1rem;
196
+ flex-shrink: 0;
197
+ }
198
+
199
+ .markdown-content {
200
+ flex: 1;
201
+ display: flex;
202
+ min-height: 0;
203
+ }
204
+
205
+ .markdown-source {
206
+ width: 50%;
207
+ border-right: 1px solid var(--border-color);
208
+ display: flex;
209
+ flex-direction: column;
210
+ min-height: 0;
211
+ }
212
+
213
+ .markdown-source-title,
214
+ .markdown-preview-title {
215
+ display: flex;
216
+ align-items: center;
217
+ padding: 0.5rem 1rem;
218
+ border-bottom: 1px solid var(--border-color);
219
+ }
220
+
221
+ .panel-title {
222
+ color: var(--text-muted);
223
+ font-size: 0.75rem;
224
+ font-family: monospace;
225
+ text-transform: uppercase;
226
+ letter-spacing: 0.05em;
227
+ }
228
+
229
+ .line-count {
230
+ margin-left: auto;
231
+ color: var(--text-muted-half);
232
+ font-size: 0.75rem;
233
+ font-family: monospace;
234
+ }
235
+
236
+ .markdown-source-content {
237
+ flex: 1;
238
+ min-height: 0;
239
+ overflow: auto;
240
+ }
241
+
242
+ .editor-container {
243
+ display: flex;
244
+ height: 100%;
245
+ background-color: var(--bg-editor);
246
+ position: relative;
247
+ }
248
+
249
+ .line-numbers {
250
+ user-select: none;
251
+ color: var(--text-muted-dim);
252
+ text-align: right;
253
+ padding-right: 0.75rem;
254
+ padding-left: 0.75rem;
255
+ padding-top: 1rem;
256
+ font-family: monospace;
257
+ overflow: hidden;
258
+ flex-shrink: 0;
259
+ font-size: 14px;
260
+ line-height: 1.6;
261
+ }
262
+
263
+ .line-numbers-inner {
264
+ transition: transform 0ms linear;
265
+ }
266
+
267
+ .editor-textarea {
268
+ flex: 1;
269
+ padding: 1rem;
270
+ color: var(--text-color);
271
+ caret-color: #ef871b;
272
+ font-family: monospace;
273
+ width: 100%;
274
+ height: 100%;
275
+ background: transparent;
276
+ border: none;
277
+ resize: none;
278
+ outline: none;
279
+ font-size: 14px;
280
+ line-height: 1.6;
281
+ box-sizing: border-box;
282
+ }
283
+
284
+ .editor-textarea::selection {
285
+ background: var(--selection-bg-color);
286
+ color: #ffffff;
287
+ }
288
+
289
+ .editor-textarea::-moz-selection {
290
+ background: var(--selection-bg-color);
291
+ color: #ffffff;
292
+ }
293
+
294
+ .markdown-preview {
295
+ width: 50%;
296
+ display: flex;
297
+ flex-direction: column;
298
+ min-height: 0;
299
+ }
300
+
301
+ .markdown-preview-content {
302
+ overflow: auto;
303
+ flex: 1;
304
+ background-color: var(--bg-preview);
305
+ }
306
+
307
+ #markdown-preview {
308
+ padding: 1rem 2rem;
309
+ min-height: calc(100% - 2rem);
310
+ }
311
+
312
+ #markdown-preview.theme-dark {
313
+ background-color: #0f0f10;
314
+ }
315
+
316
+ #markdown-preview .bi-direction-jump__target {
317
+ transition: background-color var(--transition-normal), border-radius var(--transition-normal);
318
+ }
319
+
320
+ #markdown-preview .bi-direction-jump__target--active,
321
+ #markdown-preview .bi-direction-jump__target--hover {
322
+ background-color: var(--jump-highlight-bg);
323
+ border-radius: 0.3rem;
324
+ }
325
+
326
+ #markdown-preview .bi-direction-jump__target--active {
327
+ border-left: 3px solid var(--accent-color);
328
+ margin-left: -12px;
329
+ padding-left: 10px;
330
+ }
331
+
332
+ #markdown-preview [data-line] {
333
+ margin-top: 1rem;
334
+ margin-bottom: 1rem;
335
+ }
336
+
337
+ .setting-backdrop {
338
+ position: fixed;
339
+ inset: 0;
340
+ background: var(--bg-overlay);
341
+ opacity: 0;
342
+ pointer-events: none;
343
+ transition: opacity var(--transition-normal);
344
+ z-index: 39;
345
+ }
346
+
347
+ .app-container.settings-open .setting-backdrop {
348
+ opacity: 1;
349
+ pointer-events: auto;
350
+ }
351
+
352
+ .setting-panel {
353
+ position: fixed;
354
+ top: 0;
355
+ right: 0;
356
+ height: 100%;
357
+ width: min(22rem, 92vw);
358
+ background-color: var(--bg-card);
359
+ border-left: 1px solid var(--border-color);
360
+ z-index: 40;
361
+ transform: translateX(100%);
362
+ transition: transform var(--transition-normal);
363
+ box-shadow: var(--panel-shadow);
364
+ display: flex;
365
+ flex-direction: column;
366
+ }
367
+
368
+ .setting-panel.open {
369
+ transform: translateX(0);
370
+ }
371
+
372
+ .setting-panel-header {
373
+ display: flex;
374
+ justify-content: space-between;
375
+ align-items: center;
376
+ padding: 1rem;
377
+ border-bottom: 1px solid var(--border-color);
378
+ font-weight: 600;
379
+ }
380
+
381
+ .close-btn {
382
+ background: transparent;
383
+ border: none;
384
+ cursor: pointer;
385
+ padding: 0.5rem;
386
+ display: flex;
387
+ align-items: center;
388
+ justify-content: center;
389
+ color: var(--text-muted);
390
+ transition: background-color 0.2s, color 0.2s;
391
+ }
392
+
393
+ .close-btn:hover {
394
+ background-color: var(--bg-accent);
395
+ color: var(--accent-color);
396
+ border-radius: 0.375rem;
397
+ }
398
+
399
+ .close-btn svg {
400
+ width: 1rem;
401
+ height: 1rem;
402
+ pointer-events: none;
403
+ }
404
+
405
+ .setting-panel-content {
406
+ padding: 1rem;
407
+ overflow-y: auto;
408
+ display: flex;
409
+ flex-direction: column;
410
+ gap: 0.9rem;
411
+ }
412
+
413
+ .setting-item {
414
+ display: flex;
415
+ justify-content: space-between;
416
+ align-items: center;
417
+ color: var(--text-color);
418
+ border: 1px solid var(--border-color);
419
+ border-radius: 0.65rem;
420
+ padding: 0.8rem 0.85rem;
421
+ background-color: rgba(255, 255, 255, 0.01);
422
+ transition: border-color var(--transition-normal), background-color var(--transition-normal), transform var(--transition-normal);
423
+ }
424
+
425
+ .setting-item:hover {
426
+ border-color: var(--input-hover-border);
427
+ background-color: rgba(239, 135, 27, 0.07);
428
+ transform: translateX(-2px);
429
+ }
430
+
431
+ .setting-item input[type="checkbox"] {
432
+ width: 1.1rem;
433
+ height: 1.1rem;
434
+ accent-color: var(--accent-color);
435
+ cursor: pointer;
436
+ transition: transform var(--transition-normal);
437
+ }
438
+
439
+ .setting-item input[type="checkbox"]:active {
440
+ transform: scale(0.92);
441
+ }
442
+
443
+ .setting-item-range {
444
+ display: block;
445
+ }
446
+
447
+ .setting-item-label-row {
448
+ display: flex;
449
+ justify-content: space-between;
450
+ align-items: center;
451
+ margin-bottom: 0.65rem;
452
+ }
453
+
454
+ #toc-level-slider {
455
+ width: 100%;
456
+ accent-color: var(--accent-color);
457
+ cursor: pointer;
458
+ }
459
+
460
+ .setting-item-select {
461
+ gap: 0.9rem;
462
+ }
463
+
464
+ #language-select {
465
+ border: 1px solid var(--input-border);
466
+ border-radius: 0.5rem;
467
+ padding: 0.4rem 0.6rem;
468
+ background: var(--input-bg);
469
+ color: var(--text-color);
470
+ transition: border-color var(--transition-normal), background-color var(--transition-normal);
471
+ }
472
+
473
+ #language-select:hover {
474
+ border-color: var(--input-hover-border);
475
+ background-color: var(--input-bg-active);
476
+ }
477
+
478
+ #language-select:focus-visible,
479
+ #toc-level-slider:focus-visible,
480
+ .setting-item input[type="checkbox"]:focus-visible {
481
+ outline: none;
482
+ box-shadow: 0 0 0 2px rgba(239, 135, 27, 0.26);
483
+ border-radius: 0.4rem;
484
+ }
485
+
486
+ .setting-panel-footer {
487
+ margin-top: 2rem;
488
+ font-size: 0.875rem;
489
+ color: var(--text-muted);
490
+ line-height: 1.6;
491
+ }
492
+
493
+ .setting-panel-footer-title {
494
+ color: var(--text-color);
495
+ margin-bottom: 0.45rem;
496
+ }
497
+
498
+ @media (max-width: 960px) {
499
+ .markdown-content {
500
+ flex-direction: column;
501
+ }
502
+
503
+ .markdown-source,
504
+ .markdown-preview {
505
+ width: 100%;
506
+ min-height: 0;
507
+ }
508
+
509
+ .markdown-source {
510
+ border-right: none;
511
+ border-bottom: 1px solid var(--border-color);
512
+ }
513
+ }
514
+
515
+ /* 修复 Markdown 渲染器中徽章(Badges)和状态图标被强制拉伸的问题 */
516
+ .somarkdown-container img[src*="shields.io"],
517
+ .somarkdown-container img[src*="badge"],
518
+ .somarkdown-container img[src*="badgen.net"],
519
+ .somarkdown-container img[src*="travis-ci.org"],
520
+ .somarkdown-container img[src*="coveralls.io"] {
521
+ width: auto !important;
522
+ max-width: 100% !important;
523
+ height: auto !important;
524
+ display: inline-block !important;
525
+ box-shadow: none !important; /* 移除徽章可能带有的阴影 */
526
+ }
527
+