@synclineapi/mdx-editor 0.1.1 → 1.0.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 (55) hide show
  1. package/README.md +320 -140
  2. package/dist/core/config/EditorConfig.d.ts +5 -0
  3. package/dist/core/config/defaults.d.ts +33 -0
  4. package/dist/core/config/index.d.ts +2 -0
  5. package/dist/core/dom/editor-pane.d.ts +7 -0
  6. package/dist/core/dom/editor-root.d.ts +8 -0
  7. package/dist/core/dom/index.d.ts +11 -0
  8. package/dist/core/dom/preview-pane.d.ts +5 -0
  9. package/dist/core/dom/skip-link.d.ts +1 -0
  10. package/dist/core/dom/status-bar.d.ts +13 -0
  11. package/dist/core/dom/toolbar-dom.d.ts +5 -0
  12. package/dist/core/editor.d.ts +99 -6
  13. package/dist/core/mdx-themes.d.ts +3 -0
  14. package/dist/core/platform.d.ts +31 -0
  15. package/dist/core/plugin-manager.d.ts +1 -24
  16. package/dist/core/plugins/PluginContext.d.ts +24 -0
  17. package/dist/core/plugins/PluginManager.d.ts +33 -0
  18. package/dist/core/plugins/index.d.ts +3 -0
  19. package/dist/core/renderer/CodeRenderer.d.ts +4 -0
  20. package/dist/core/renderer/ListRenderer.d.ts +5 -0
  21. package/dist/core/renderer/MarkdownRenderer.d.ts +7 -0
  22. package/dist/core/renderer/MdxValidator.d.ts +3 -0
  23. package/dist/core/renderer/Renderer.d.ts +10 -0
  24. package/dist/core/renderer/TableRenderer.d.ts +4 -0
  25. package/dist/core/renderer/index.d.ts +7 -0
  26. package/dist/core/renderer/sanitize.d.ts +1 -0
  27. package/dist/core/renderer.d.ts +6 -28
  28. package/dist/core/toolbar.d.ts +1 -0
  29. package/dist/core/types.d.ts +72 -2
  30. package/dist/core/ui/AutocompleteController.d.ts +58 -0
  31. package/dist/core/ui/DropdownController.d.ts +8 -0
  32. package/dist/core/ui/FindReplaceController.d.ts +60 -0
  33. package/dist/core/ui/LineNumberController.d.ts +218 -0
  34. package/dist/core/ui/ModeController.d.ts +9 -0
  35. package/dist/core/ui/PreviewController.d.ts +13 -0
  36. package/dist/core/ui/ResponsiveController.d.ts +30 -0
  37. package/dist/core/ui/SplitterController.d.ts +31 -0
  38. package/dist/core/ui/StatusBarController.d.ts +16 -0
  39. package/dist/core/ui/ThemeController.d.ts +8 -0
  40. package/dist/core/ui/ToolbarController.d.ts +10 -0
  41. package/dist/core/ui/UIController.d.ts +43 -0
  42. package/dist/core/ui/index.d.ts +12 -0
  43. package/dist/index.d.ts +28 -1
  44. package/dist/plugins/basic-formatting/index.d.ts +1 -0
  45. package/dist/plugins/callouts/index.d.ts +1 -0
  46. package/dist/plugins/diagrams/index.d.ts +1 -0
  47. package/dist/plugins/index.d.ts +1 -11
  48. package/dist/plugins/layout/index.d.ts +3 -0
  49. package/dist/plugins/lists/index.d.ts +1 -0
  50. package/dist/plugins/media/index.d.ts +2 -0
  51. package/dist/plugins/utilities/index.d.ts +5 -0
  52. package/dist/style.css +1 -1
  53. package/dist/syncline-mdx-editor.js +8468 -1812
  54. package/dist/syncline-mdx-editor.umd.cjs +958 -87
  55. package/package.json +6 -12
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Virtual line-number gutter — unified scroll container approach.
3
+ *
4
+ * Only ~(visible lines + 2×OVERSCAN) DOM nodes live in the DOM at any time,
5
+ * regardless of document size. For a 10,000-line file only ~40 <span> elements
6
+ * are ever created; a 100-line file and a 10,000-line file feel identical.
7
+ *
8
+ * Layout model (unified scroll container):
9
+ *
10
+ * .smdx-scroll-wrapper overflow-y:auto — SINGLE scroll container
11
+ * ├─ .smdx-line-gutter flex-shrink:0, position:relative
12
+ * │ └─ .smdx-gutter-inner position:relative, height = totalHeight
13
+ * │ └─ <span> position:absolute, top = lineOffset + paddingTop
14
+ * └─ <textarea> flex:1, overflow:hidden, height auto-sized
15
+ *
16
+ * The gutter and textarea are flex siblings inside a shared scroll wrapper.
17
+ * When the wrapper scrolls, both children scroll together naturally — like
18
+ * a flex row per line. No JS-based transform synchronisation is needed.
19
+ *
20
+ * Virtual rendering:
21
+ * • recyclePool() computes the visible range from the scroll wrapper's
22
+ * scrollTop and clientHeight.
23
+ * • If the range hasn't changed (OVERSCAN has buffered all visible lines),
24
+ * it returns immediately — zero DOM reads, zero DOM writes.
25
+ * • Only when lines enter or leave the overscan region are a handful of
26
+ * span properties updated (style.top + textContent).
27
+ *
28
+ * Multi-line wrapping:
29
+ * • For each logical line, rowCount() measures how many visual rows it takes
30
+ * using a hidden mirror div with identical font/width settings.
31
+ * • heights[i] = rowCount(i) × lineHeightPx (full multi-row height stored).
32
+ * • The line-number span for line i is only 1 row tall — pinned to the first
33
+ * visual row (VS Code convention). offsets[] accounts for the full height
34
+ * so successive numbers are correctly spaced.
35
+ */
36
+ /** Public snapshot of the gutter's virtual-rendering state. */
37
+ export interface GutterStats {
38
+ /** Number of logical lines in the document. */
39
+ lineCount: number;
40
+ /** 1-indexed first line currently in the DOM pool. */
41
+ visibleFirst: number;
42
+ /** 1-indexed last line currently in the DOM pool. */
43
+ visibleLast: number;
44
+ /** Number of <span> elements currently in the DOM. */
45
+ domNodes: number;
46
+ /** Computed total content height (px). */
47
+ totalHeight: number;
48
+ /** Whether the gutter / virtual renderer is enabled. */
49
+ enabled: boolean;
50
+ }
51
+ export declare class LineNumberController {
52
+ private gutter;
53
+ private textarea;
54
+ /** The shared scroll wrapper (parent of gutter + textarea). */
55
+ private scrollEl;
56
+ private enabled;
57
+ private mirror;
58
+ private rafPending;
59
+ private scrollRafId;
60
+ private offsets;
61
+ private heights;
62
+ private totalHeight;
63
+ private lineCount;
64
+ private lineHeightPx;
65
+ private contentWidth;
66
+ private avgCharWidth;
67
+ private paddingTop;
68
+ private cachedClientHeight;
69
+ private static readonly WRAP_THRESHOLD;
70
+ /**
71
+ * Documents above this line count skip per-line mirror-div measurement
72
+ * in the synchronous path and use pure character-width estimation instead.
73
+ * This keeps large pastes (2000+ lines) instant while keeping the gutter
74
+ * correct for typical editing sessions.
75
+ */
76
+ private static readonly LARGE_DOC_THRESHOLD;
77
+ /**
78
+ * Delay (ms) before running the deferred precision pass for large documents.
79
+ * Short enough to feel immediate, long enough to let paste events settle.
80
+ */
81
+ private static readonly DEFERRED_UPDATE_DELAY_MS;
82
+ /**
83
+ * Minimum content-width change (px) to trigger a full geometry recompute
84
+ * on resize. Smaller changes are ignored to avoid unnecessary recalculation.
85
+ */
86
+ private static readonly WIDTH_CHANGE_THRESHOLD_PX;
87
+ /**
88
+ * Debounce timer for deferring heavy mirror-div measurement on large
89
+ * content changes (paste, setValue with 2000+ lines).
90
+ */
91
+ private deferredUpdateTimer;
92
+ /**
93
+ * Cached content width used to detect width changes on resize so we
94
+ * can trigger a full geometry recompute (wrapping changes).
95
+ */
96
+ private cachedContentWidth;
97
+ /** Cached textarea scrollHeight for optimised autoResizeTextarea(). */
98
+ private lastTextareaHeight;
99
+ private inner;
100
+ /**
101
+ * OVERSCAN — extra lines rendered above and below the visible area.
102
+ * 8 gives a comfortable buffer for fast momentum scrolling; the span-recycling
103
+ * approach (no DOM teardown) means a larger overscan has negligible cost.
104
+ */
105
+ private readonly OVERSCAN;
106
+ private spanPool;
107
+ private poolStart;
108
+ private poolEnd;
109
+ /** Called after every pool rebuild — use to drive live status-bar stats. */
110
+ onViewportChange: ((stats: GutterStats) => void) | null;
111
+ constructor(gutter: HTMLElement, textarea: HTMLTextAreaElement);
112
+ /**
113
+ * Set the shared scroll wrapper element.
114
+ * Must be called before enable() so scroll events are bound to the wrapper.
115
+ */
116
+ setScrollElement(el: HTMLElement): void;
117
+ private buildInner;
118
+ private setupMirror;
119
+ private destroyMirror;
120
+ /**
121
+ * Copy font metrics from the textarea into the mirror div.
122
+ * Returns computed layout values, or null when layout is unavailable
123
+ * (e.g. jsdom / hidden element).
124
+ */
125
+ private syncMirror;
126
+ /**
127
+ * Return the number of visual rows occupied by `line`.
128
+ * Fast path: if the line clearly fits on one row (no wrap), return 1
129
+ * without touching the mirror div. Only wrapping lines pay the
130
+ * mirror-div measurement cost.
131
+ */
132
+ private rowCount;
133
+ enable(): void;
134
+ disable(): void;
135
+ /**
136
+ * Refresh cached layout dimensions after the editor container is resized.
137
+ * Call this from a ResizeObserver on the editor pane or the scroll wrapper
138
+ * so that recyclePool() continues using accurate viewport dimensions
139
+ * without reading from the DOM on every scroll event.
140
+ *
141
+ * If the content width has changed (e.g. splitter drag, window resize),
142
+ * this triggers a full geometry recompute because wrapping may have changed.
143
+ */
144
+ notifyResize(): void;
145
+ /**
146
+ * Full recompute: called whenever the document content changes.
147
+ * Measures each line's visual height and rebuilds the geometry cache,
148
+ * then re-renders the visible viewport.
149
+ *
150
+ * For large documents (> LARGE_DOC_THRESHOLD lines), this uses fast
151
+ * character-width estimation instead of per-line mirror-div measurement.
152
+ * A deferred rAF pass can refine wrapping estimates if needed.
153
+ */
154
+ update(): void;
155
+ /**
156
+ * Deferred precision pass for large documents: uses the mirror div
157
+ * only for lines that likely wrap, then updates the geometry cache.
158
+ * Runs after a short delay so paste operations are not blocked.
159
+ */
160
+ private refineLargeDoc;
161
+ /**
162
+ * Auto-resize the textarea so its full content is visible (no internal
163
+ * scrollbar). The shared scroll wrapper provides the single scrollbar
164
+ * for both gutter and textarea.
165
+ *
166
+ * Optimised: only resets height when the content has likely changed size,
167
+ * avoiding unnecessary layout thrashing on every keystroke.
168
+ */
169
+ autoResizeTextarea(): void;
170
+ /**
171
+ * Recycle the span pool for the current viewport.
172
+ * Called after content changes and synchronously on every scroll event.
173
+ */
174
+ private renderVisible;
175
+ /**
176
+ * Recycle the span pool for the new visible range.
177
+ *
178
+ * Spans are updated in-place (style.top + textContent) — zero DOM
179
+ * add/remove during scrolling. This runs SYNCHRONOUSLY in the scroll
180
+ * handler and maintains 60fps even for 10,000+ line documents.
181
+ *
182
+ * With the unified scroll wrapper the gutter and textarea share the
183
+ * same scrollTop so no scroll-fraction mapping is needed.
184
+ */
185
+ private recyclePool;
186
+ /**
187
+ * Binary search: return the index of the logical line whose range
188
+ * contains or immediately precedes `offsetPx`.
189
+ */
190
+ private lineIndexAtOffset;
191
+ /**
192
+ * Scroll handler — fully synchronous, no rAF deferral needed.
193
+ *
194
+ * With the unified scroll wrapper, this simply reads scrollTop from
195
+ * the wrapper and recycles the span pool. No transform writes are
196
+ * needed since both gutter and textarea scroll together naturally.
197
+ */
198
+ private onScroll;
199
+ private cancelScrollRaf;
200
+ /**
201
+ * Ensure the cursor's line is visible within the scroll wrapper.
202
+ * Call after input, keyup, or any operation that may move the cursor.
203
+ */
204
+ ensureCursorVisible(): void;
205
+ /**
206
+ * Return the content-space Y offset (px) for the given 0-indexed logical line.
207
+ * Used by the editor's jumpToLine() to scroll the textarea precisely.
208
+ */
209
+ getLineOffset(lineIndex: number): number;
210
+ /**
211
+ * Return a snapshot of the virtual renderer's current state.
212
+ * Useful for live status-bar displays.
213
+ */
214
+ getStats(): GutterStats;
215
+ /** Return the scroll wrapper element, if set. */
216
+ getScrollElement(): HTMLElement | null;
217
+ destroy(): void;
218
+ }
@@ -0,0 +1,9 @@
1
+ import { EditorMode } from '../types';
2
+ export declare class ModeController {
3
+ private currentMode;
4
+ private root;
5
+ constructor(root: HTMLElement, initialMode?: EditorMode);
6
+ getMode(): EditorMode;
7
+ setMode(mode: EditorMode): void;
8
+ private applyMode;
9
+ }
@@ -0,0 +1,13 @@
1
+ import { RendererConfig, ParserConfig } from '../types';
2
+ export declare class PreviewController {
3
+ private renderer;
4
+ private contentEl;
5
+ private renderTimer;
6
+ private delay;
7
+ constructor(contentEl: HTMLElement, delay?: number);
8
+ setRenderers(renderers: RendererConfig[]): void;
9
+ setParsers(parsers: ParserConfig[]): void;
10
+ render(source: string): void;
11
+ renderImmediate(source: string): Promise<void>;
12
+ destroy(): void;
13
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * ResponsiveController
3
+ *
4
+ * Watches the editor root element's width via ResizeObserver and applies
5
+ * `smdx-is-mobile` / `smdx-is-tablet` CSS classes so that responsive
6
+ * styles work correctly for embedded editors whose width is independent
7
+ * of the viewport width.
8
+ *
9
+ * Breakpoints (mirrors the CSS @media queries in mobile.css):
10
+ * ≤ 640 px → smdx-is-mobile
11
+ * 641–1024 px → smdx-is-tablet
12
+ * > 1024 px → (no extra class)
13
+ */
14
+ export declare class ResponsiveController {
15
+ private root;
16
+ private observer;
17
+ /** Breakpoint widths in pixels – must match mobile.css */
18
+ private static readonly MOBILE_BREAKPOINT;
19
+ private static readonly TABLET_BREAKPOINT;
20
+ constructor(root: HTMLElement);
21
+ /**
22
+ * Start observing. Call once after the editor root is in the DOM.
23
+ */
24
+ start(): void;
25
+ /**
26
+ * Stop observing and clean up.
27
+ */
28
+ destroy(): void;
29
+ private applyBreakpointClasses;
30
+ }
@@ -0,0 +1,31 @@
1
+ export declare class SplitterController {
2
+ private splitter;
3
+ private left;
4
+ private right;
5
+ private container;
6
+ private isDragging;
7
+ private startX;
8
+ private startLeftWidth;
9
+ /** Percentage of container width to move per keyboard arrow press. */
10
+ private static readonly KEYBOARD_STEP_PERCENT;
11
+ /** Callback fired during drag so the editor can refresh line-number geometry. */
12
+ private onResizeCallback;
13
+ /** Throttle timer for resize callbacks during drag. */
14
+ private resizeRafId;
15
+ constructor(container: HTMLElement, left: HTMLElement, right: HTMLElement);
16
+ /** Set a callback to fire during drag (for refreshing line-number geometry). */
17
+ onResize(fn: () => void): void;
18
+ private onMouseDown;
19
+ private onMouseMove;
20
+ private onMouseUp;
21
+ private onTouchStart;
22
+ private onTouchMove;
23
+ private onTouchEnd;
24
+ private onKeyDown;
25
+ private startDrag;
26
+ private moveDrag;
27
+ private endDrag;
28
+ /** Throttled resize notification via rAF. */
29
+ private notifyResize;
30
+ destroy(): void;
31
+ }
@@ -0,0 +1,16 @@
1
+ import { EditorMode } from '../types';
2
+ export interface StatusBarControllerOptions {
3
+ bar: HTMLElement;
4
+ wordCount: HTMLElement;
5
+ lineCount: HTMLElement;
6
+ charCount: HTMLElement;
7
+ modeSwitcher: HTMLElement;
8
+ onModeChange: (mode: EditorMode) => void;
9
+ }
10
+ export declare class StatusBarController {
11
+ private opts;
12
+ constructor(opts: StatusBarControllerOptions);
13
+ private buildModeSwitcher;
14
+ updateCounts(text: string): void;
15
+ updateActiveMode(mode: EditorMode): void;
16
+ }
@@ -0,0 +1,8 @@
1
+ export declare class ThemeController {
2
+ private root;
3
+ private _isDark;
4
+ constructor(root: HTMLElement);
5
+ applyTheme(theme: Record<string, string>): void;
6
+ toggleDarkMode(dark?: boolean): void;
7
+ isDarkMode(): boolean;
8
+ }
@@ -0,0 +1,10 @@
1
+ import { ToolbarConfig, EditorAPI } from '../types';
2
+ import { PluginManager } from '../plugins/PluginManager';
3
+ import { EventEmitter } from '../events';
4
+ export declare class ToolbarController {
5
+ private toolbar;
6
+ constructor(config: ToolbarConfig, pluginManager: PluginManager, editorApi: EditorAPI, events: EventEmitter);
7
+ render(container: HTMLElement): HTMLElement;
8
+ updateActiveStates(): void;
9
+ destroy(): void;
10
+ }
@@ -0,0 +1,43 @@
1
+ import { EditorConfig, EditorMode, EditorAPI } from '../types';
2
+ import { PreviewController } from './PreviewController';
3
+ import { PluginManager } from '../plugins/PluginManager';
4
+ import { EventEmitter } from '../events';
5
+ export interface UIElements {
6
+ root: HTMLDivElement;
7
+ toolbarEl: HTMLElement;
8
+ editorPane: HTMLElement;
9
+ previewPane: HTMLElement;
10
+ textarea: HTMLTextAreaElement;
11
+ previewContent: HTMLElement;
12
+ statusBar: HTMLElement;
13
+ }
14
+ export declare class UIController {
15
+ private config;
16
+ private events;
17
+ private elements;
18
+ private modeController;
19
+ private themeController;
20
+ private statusBarController;
21
+ private lineNumberController;
22
+ previewController: PreviewController;
23
+ private splitterController?;
24
+ private responsiveController?;
25
+ private toolbar?;
26
+ private editorId;
27
+ constructor(config: EditorConfig, events: EventEmitter);
28
+ build(container: HTMLElement, pluginManager: PluginManager, editorApi: EditorAPI): UIElements;
29
+ getMode(): EditorMode;
30
+ setMode(mode: EditorMode): void;
31
+ applyTheme(theme: Record<string, string>): void;
32
+ toggleDarkMode(dark?: boolean): void;
33
+ isDarkMode(): boolean;
34
+ updateStatusBar(text: string): void;
35
+ updateToolbarActiveStates(): void;
36
+ enableLineNumbers(): void;
37
+ disableLineNumbers(): void;
38
+ updateLineNumbers(): void;
39
+ renderPreview(source: string): void;
40
+ renderPreviewImmediate(source: string): Promise<void>;
41
+ getElements(): UIElements;
42
+ destroy(): void;
43
+ }
@@ -0,0 +1,12 @@
1
+ export { UIController } from './UIController';
2
+ export type { UIElements } from './UIController';
3
+ export { ToolbarController } from './ToolbarController';
4
+ export { PreviewController } from './PreviewController';
5
+ export { ModeController } from './ModeController';
6
+ export { StatusBarController } from './StatusBarController';
7
+ export type { StatusBarControllerOptions } from './StatusBarController';
8
+ export { LineNumberController } from './LineNumberController';
9
+ export { DropdownController } from './DropdownController';
10
+ export { ThemeController } from './ThemeController';
11
+ export { SplitterController } from './SplitterController';
12
+ export { ResponsiveController } from './ResponsiveController';
package/dist/index.d.ts CHANGED
@@ -7,8 +7,35 @@ export { Toolbar } from './core/toolbar';
7
7
  export { Renderer } from './core/renderer';
8
8
  export { History } from './core/history';
9
9
  export { icons } from './core/icons';
10
- export type { EditorConfig, EditorPlugin, EditorAPI, EditorMode, PluginContext, ToolbarConfig, ToolbarRow, ToolbarGroup, ToolbarDivider, ToolbarItemConfig, ToolbarAction, ToolbarActionContext, SelectionState, RendererFn, RendererConfig, ParserConfig, ShortcutConfig, EventHandler, EditorLocale, } from './core/types';
10
+ export type { EditorConfig, EditorPlugin, EditorAPI, EditorMode, PluginContext, ToolbarConfig, ToolbarRow, ToolbarGroup, ToolbarDivider, ToolbarItemConfig, ToolbarAction, ToolbarActionContext, SelectionState, RendererFn, RendererConfig, ParserConfig, ShortcutConfig, EventHandler, EditorLocale, CompletionItem, CompletionKind, } from './core/types';
11
11
  export { headingPlugin, boldPlugin, italicPlugin, strikethroughPlugin, quotePlugin, linkPlugin, imagePlugin, codePlugin, unorderedListPlugin, orderedListPlugin, taskListPlugin, tablePlugin, highlightPlugin, admonitionPlugin, tabPlugin, imageBackgroundPlugin, imageFramePlugin, accordionPlugin, accordionGroupPlugin, multiColumnPlugin, cardPlugin, cardGroupPlugin, stepPlugin, tipPlugin, containerPlugin, copyTextPlugin, tooltipPlugin, embedVideoPlugin, embedOthersPlugin, mermaidPlugin, emojiPlugin, formulaPlugin, insertPlugin, tocPlugin, breakLinePlugin, horizontalRulePlugin, allPlugins, defaultToolbar, } from './plugins';
12
+ export { Renderer as RendererPipeline } from './core/renderer/Renderer';
13
+ export { MarkdownRenderer } from './core/renderer/MarkdownRenderer';
14
+ export { CodeRenderer } from './core/renderer/CodeRenderer';
15
+ export { TableRenderer } from './core/renderer/TableRenderer';
16
+ export { ListRenderer } from './core/renderer/ListRenderer';
17
+ export { MdxValidator } from './core/renderer/MdxValidator';
18
+ export { PluginManager as PluginManagerNew } from './core/plugins/PluginManager';
19
+ export { PluginContext as PluginContextClass } from './core/plugins/PluginContext';
20
+ export type { PluginContextOptions } from './core/plugins/PluginContext';
21
+ export { UIController } from './core/ui/UIController';
22
+ export { ModeController } from './core/ui/ModeController';
23
+ export { ThemeController } from './core/ui/ThemeController';
24
+ export { StatusBarController } from './core/ui/StatusBarController';
25
+ export { LineNumberController } from './core/ui/LineNumberController';
26
+ export { DropdownController } from './core/ui/DropdownController';
27
+ export { SplitterController } from './core/ui/SplitterController';
28
+ export { PreviewController } from './core/ui/PreviewController';
29
+ export { AutocompleteController } from './core/ui/AutocompleteController';
30
+ export { FindReplaceController } from './core/ui/FindReplaceController';
31
+ export { resolveConfig } from './core/config/EditorConfig';
32
+ export { DEFAULT_FEATURES, DEFAULT_LAYOUT } from './core/config/defaults';
33
+ export { createEditorRoot } from './core/dom/editor-root';
34
+ export { createEditorPane } from './core/dom/editor-pane';
35
+ export { createPreviewPane } from './core/dom/preview-pane';
36
+ export { createStatusBar } from './core/dom/status-bar';
37
+ export { createToolbarDOM } from './core/dom/toolbar-dom';
38
+ export { createSkipLink } from './core/dom/skip-link';
12
39
  /**
13
40
  * Quick-start factory: creates a fully-featured editor with all plugins.
14
41
  *
@@ -0,0 +1 @@
1
+ export { headingPlugin, boldPlugin, italicPlugin, strikethroughPlugin, quotePlugin, linkPlugin, imagePlugin, codePlugin } from '../basic-formatting';
@@ -0,0 +1 @@
1
+ export { highlightPlugin, admonitionPlugin } from '../highlight-admonition';
@@ -0,0 +1 @@
1
+ export { mermaidPlugin } from '../mermaid';
@@ -16,14 +16,4 @@ export { breakLinePlugin, horizontalRulePlugin } from './break-hr';
16
16
  /** Returns all built-in plugins. Use this for a fully-featured editor. */
17
17
  export declare function allPlugins(): EditorPlugin[];
18
18
  /** Default toolbar configuration matching the screenshot layout */
19
- export declare function defaultToolbar(): (string | {
20
- type: "group";
21
- label: string;
22
- icon: string;
23
- display: "dropdown";
24
- items: {
25
- type: "group";
26
- label: string;
27
- items: string[];
28
- }[];
29
- })[][];
19
+ export declare function defaultToolbar(): string[][];
@@ -0,0 +1,3 @@
1
+ export { accordionPlugin, accordionGroupPlugin, multiColumnPlugin } from '../accordion-columns';
2
+ export { cardPlugin, cardGroupPlugin } from '../card';
3
+ export { stepPlugin, tipPlugin, containerPlugin } from '../step-tip-container';
@@ -0,0 +1 @@
1
+ export { unorderedListPlugin, orderedListPlugin, taskListPlugin, tablePlugin } from '../lists-table';
@@ -0,0 +1,2 @@
1
+ export { tabPlugin, imageBackgroundPlugin, imageFramePlugin } from '../tab-media';
2
+ export { embedVideoPlugin, embedOthersPlugin } from '../embed';
@@ -0,0 +1,5 @@
1
+ export { emojiPlugin, formulaPlugin } from '../emoji-formula';
2
+ export { copyTextPlugin, tooltipPlugin } from '../copy-tooltip';
3
+ export { breakLinePlugin, horizontalRulePlugin } from '../break-hr';
4
+ export { tocPlugin } from '../toc';
5
+ export { insertPlugin } from '../insert';
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .smdx-editor{--smdx-primary: #6366f1;--smdx-primary-hover: #4f46e5;--smdx-bg: #ffffff;--smdx-bg-muted: #f8fafc;--smdx-bg-dark: #1e1e2e;--smdx-text: #1e293b;--smdx-text-muted: #64748b;--smdx-border: #e2e8f0;--smdx-border-focus: #6366f1;--smdx-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--smdx-font-mono: "SF Mono", "Fira Code", "Fira Mono", "Roboto Mono", Menlo, Consolas, monospace;--smdx-font-size: 14px;--smdx-line-height: 1.6;--smdx-radius: 8px;--smdx-radius-sm: 4px;--smdx-spacing-xs: 4px;--smdx-spacing-sm: 8px;--smdx-spacing-md: 12px;--smdx-spacing-lg: 16px;--smdx-spacing-xl: 24px;--smdx-toolbar-bg: var(--smdx-bg);--smdx-toolbar-border: var(--smdx-border);--smdx-toolbar-btn-size: 32px;--smdx-toolbar-btn-radius: 6px;--smdx-toolbar-btn-hover-bg: var(--smdx-bg-muted);--smdx-toolbar-btn-active-bg: #eef2ff;--smdx-toolbar-btn-active-color: var(--smdx-primary);--smdx-editor-bg: var(--smdx-bg);--smdx-editor-text: var(--smdx-text);--smdx-preview-bg: var(--smdx-bg);--smdx-preview-text: var(--smdx-text);--smdx-statusbar-bg: var(--smdx-bg-muted);--smdx-statusbar-text: var(--smdx-text-muted);--smdx-shadow-sm: 0 1px 2px rgba(0, 0, 0, .05);--smdx-shadow-md: 0 4px 12px rgba(0, 0, 0, .08);--smdx-shadow-lg: 0 8px 24px rgba(0, 0, 0, .12)}.smdx-editor.smdx-dark,.smdx-dark .smdx-editor{--smdx-primary: #818cf8;--smdx-primary-hover: #6366f1;--smdx-bg: #1e1e2e;--smdx-bg-muted: #2a2a3c;--smdx-text: #e2e8f0;--smdx-text-muted: #94a3b8;--smdx-border: #374151;--smdx-border-focus: #818cf8;--smdx-toolbar-btn-active-bg: #312e81;--smdx-shadow-sm: 0 1px 2px rgba(0, 0, 0, .2);--smdx-shadow-md: 0 4px 12px rgba(0, 0, 0, .3);--smdx-shadow-lg: 0 8px 24px rgba(0, 0, 0, .4)}.smdx-editor{display:flex;flex-direction:column;border:1px solid var(--smdx-border);border-radius:var(--smdx-radius);background:var(--smdx-bg);color:var(--smdx-text);font-family:var(--smdx-font-family);font-size:var(--smdx-font-size);line-height:var(--smdx-line-height);height:100%;min-height:400px;position:relative}.smdx-toolbar-container{border-bottom:1px solid var(--smdx-toolbar-border);background:var(--smdx-toolbar-bg);flex-shrink:0;position:relative;z-index:10}.smdx-toolbar{padding:var(--smdx-spacing-xs) var(--smdx-spacing-sm)}.smdx-toolbar-row{display:flex;align-items:center;flex-wrap:wrap;gap:2px;padding:var(--smdx-spacing-xs) 0}.smdx-toolbar-divider{width:1px;height:20px;background:var(--smdx-border);margin:0 var(--smdx-spacing-xs);flex-shrink:0}.smdx-toolbar-group{display:flex;align-items:center;gap:2px}.smdx-toolbar-btn{display:flex;align-items:center;justify-content:center;min-width:var(--smdx-toolbar-btn-size);height:var(--smdx-toolbar-btn-size);padding:0 var(--smdx-spacing-sm);border:none;background:none;border-radius:var(--smdx-toolbar-btn-radius);color:var(--smdx-text);cursor:pointer;transition:background .15s,color .15s;font-size:.85em;gap:4px}.smdx-toolbar-btn:hover{background:var(--smdx-toolbar-btn-hover-bg)}.smdx-toolbar-btn.smdx-active{background:var(--smdx-toolbar-btn-active-bg);color:var(--smdx-toolbar-btn-active-color)}.smdx-toolbar-btn:disabled{opacity:.4;cursor:not-allowed}.smdx-toolbar-btn svg{width:16px;height:16px;flex-shrink:0}.smdx-toolbar-btn-label{font-size:.85em;white-space:nowrap}.smdx-toolbar-dropdown{position:relative}.smdx-toolbar-dropdown-trigger{gap:4px}.smdx-dropdown-arrow{width:8px;height:8px;opacity:.5;flex-shrink:0}.smdx-toolbar-dropdown-menu{position:absolute;top:calc(100% + 4px);left:0;min-width:240px;max-height:420px;overflow-y:auto;background:var(--smdx-bg);border:1px solid var(--smdx-border);border-radius:var(--smdx-radius);box-shadow:var(--smdx-shadow-lg);z-index:100;padding:var(--smdx-spacing-xs)}.smdx-toolbar-dropdown-section{padding:var(--smdx-spacing-xs) 0}.smdx-toolbar-dropdown-section+.smdx-toolbar-dropdown-section{border-top:1px solid var(--smdx-border);margin-top:var(--smdx-spacing-xs);padding-top:var(--smdx-spacing-sm)}.smdx-toolbar-dropdown-section-label{font-size:.7em;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--smdx-text-muted);padding:var(--smdx-spacing-xs) 10px;margin-bottom:2px}.smdx-toolbar-menu-btn{display:flex;align-items:center;gap:10px;width:100%;padding:7px 10px;border:none;background:none;border-radius:var(--smdx-radius-sm);color:var(--smdx-text);cursor:pointer;font-size:.85em;text-align:left;transition:background .1s;white-space:nowrap}.smdx-toolbar-menu-btn:hover{background:var(--smdx-toolbar-btn-hover-bg)}.smdx-toolbar-menu-btn svg{width:16px;height:16px;flex-shrink:0}.smdx-toolbar-menu-btn span{flex:1;overflow:hidden;text-overflow:ellipsis}.smdx-toolbar-menu-btn .smdx-color-dot{flex:0 0 auto;overflow:visible}.smdx-shortcut-label{margin-left:auto;font-size:.75em;color:var(--smdx-text-muted);font-family:var(--smdx-font-mono)}.smdx-toolbar-submenu{position:relative}.smdx-toolbar-submenu-trigger{justify-content:flex-start}.smdx-submenu-arrow{width:6px;height:10px;opacity:.4;margin-left:auto;flex-shrink:0}.smdx-toolbar-submenu-menu{position:fixed;z-index:200;min-width:180px}.smdx-main{display:flex;flex:1;overflow:hidden;min-height:0;position:relative}.smdx-editor-pane{flex:1;display:flex;overflow:hidden;border-right:1px solid var(--smdx-border);min-height:0}.smdx-textarea{width:100%;height:100%;padding:var(--smdx-spacing-lg);border:none;outline:none;resize:none;background:var(--smdx-editor-bg);color:var(--smdx-editor-text);font-family:var(--smdx-font-mono);font-size:var(--smdx-font-size);line-height:var(--smdx-line-height);-moz-tab-size:2;tab-size:2;box-sizing:border-box;overflow-y:auto;overflow-x:hidden}.smdx-textarea::placeholder{color:var(--smdx-text-muted);opacity:.5}.smdx-preview-pane{flex:1;overflow:hidden;min-height:0;position:relative}.smdx-preview-content{height:100%;overflow-y:auto;padding:var(--smdx-spacing-lg);color:var(--smdx-preview-text);background:var(--smdx-preview-bg)}.smdx-parse-error{display:flex;align-items:center;gap:8px;padding:10px 16px;margin:0 0 8px;background:#fef2f2;border:1px solid #fecaca;border-left:4px solid #ef4444;border-radius:6px;color:#991b1b;font-size:.88em;font-family:var(--smdx-font-mono, monospace);line-height:1.5;word-break:break-word}.smdx-parse-error-icon{color:#ef4444;font-size:1.1em;flex-shrink:0}.smdx-dark .smdx-parse-error{background:#451a1a;border-color:#7f1d1d;border-left-color:#ef4444;color:#fca5a5}.smdx-dark .smdx-parse-error-icon{color:#f87171}.smdx-mode-editor .smdx-preview-pane{display:none}.smdx-mode-editor .smdx-editor-pane{border-right:none}.smdx-mode-preview .smdx-editor-pane{display:none}.smdx-mode-preview .smdx-preview-pane{border-left:none}.smdx-mode-split .smdx-editor-pane,.smdx-mode-split .smdx-preview-pane{flex:1}.smdx-status-bar{display:flex;align-items:center;gap:var(--smdx-spacing-lg);padding:var(--smdx-spacing-xs) var(--smdx-spacing-lg);background:var(--smdx-statusbar-bg);color:var(--smdx-statusbar-text);font-size:.8em;border-top:1px solid var(--smdx-border);flex-shrink:0;-webkit-user-select:none;user-select:none}.smdx-mode-switch{display:flex;margin-left:auto;gap:2px;background:var(--smdx-bg);border-radius:var(--smdx-radius-sm);padding:2px;border:1px solid var(--smdx-border)}.smdx-mode-btn{padding:2px 10px;border:none;background:none;border-radius:3px;cursor:pointer;font-size:.85em;color:var(--smdx-text-muted);transition:all .15s}.smdx-mode-btn:hover{color:var(--smdx-text)}.smdx-mode-btn.smdx-active{background:var(--smdx-primary);color:#fff}.smdx-preview-content h1{font-size:2em;font-weight:700;margin:20px 0 12px;padding-bottom:8px;border-bottom:1px solid var(--smdx-border)}.smdx-preview-content h2{font-size:1.5em;font-weight:700;margin:18px 0 10px;padding-bottom:6px;border-bottom:1px solid var(--smdx-border)}.smdx-preview-content h3{font-size:1.25em;font-weight:600;margin:16px 0 8px}.smdx-preview-content h4{font-size:1.1em;font-weight:600;margin:14px 0 6px}.smdx-preview-content h5{font-size:1em;font-weight:600;margin:12px 0 4px}.smdx-preview-content h6{font-size:.9em;font-weight:600;margin:10px 0 4px;color:var(--smdx-text-muted)}.smdx-preview-content p{margin:8px 0}.smdx-preview-content a{color:var(--smdx-primary);text-decoration:none}.smdx-preview-content a:hover{text-decoration:underline}.smdx-preview-content blockquote{border-left:4px solid var(--smdx-border);margin:12px 0;padding:8px 16px;color:var(--smdx-text-muted);background:var(--smdx-bg-muted);border-radius:0 var(--smdx-radius-sm) var(--smdx-radius-sm) 0}.smdx-preview-content ul,.smdx-preview-content ol{padding-left:24px;margin:8px 0}.smdx-preview-content li{margin:4px 0}.smdx-preview-content hr{border:none;border-top:1px solid var(--smdx-border);margin:20px 0}.smdx-preview-content strong{font-weight:700}.smdx-preview-content em{font-style:italic}.smdx-preview-content del{text-decoration:line-through;color:var(--smdx-text-muted)}.smdx-preview-content img.smdx-image{max-width:100%;border-radius:var(--smdx-radius)}.smdx-inline-code{background:var(--smdx-bg-muted);padding:2px 6px;border-radius:4px;font-family:var(--smdx-font-mono);font-size:.9em;border:1px solid var(--smdx-border)}.smdx-code-block{position:relative;margin:12px 0;border-radius:var(--smdx-radius);overflow:hidden;background:#1e1e2e;border:1px solid transparent}.smdx-dark .smdx-code-block{background:#141422;border-color:#374151}.smdx-code-header{display:flex;align-items:center;gap:12px;padding:8px 14px;background:#ffffff0d;border-bottom:1px solid rgba(255,255,255,.1);font-family:var(--smdx-font-mono);font-size:.8em;color:#94a3b8}.smdx-code-lang{color:#818cf8;font-weight:600}.smdx-code-filename{color:#94a3b8;display:flex;align-items:center;gap:6px}.smdx-code-filename svg{opacity:.6;flex-shrink:0}.smdx-code-header .smdx-copy-btn{position:static;margin-left:auto;opacity:0;transition:opacity .15s,background .15s,color .15s}.smdx-code-block:hover .smdx-code-header .smdx-copy-btn,.smdx-code-header .smdx-copy-btn:focus-visible{opacity:1}.smdx-code-block pre{margin:0;padding:16px;overflow-x:auto;background:transparent;color:#e2e8f0}.smdx-code-block code{font-family:var(--smdx-font-mono);font-size:.9em;line-height:1.6}.smdx-copy-btn{position:absolute;top:10px;right:10px;padding:6px;border:none;background:#ffffff14;border-radius:4px;color:#fff6;cursor:pointer;transition:all .15s;display:flex;align-items:center;justify-content:center}.smdx-copy-btn .smdx-check-icon,.smdx-copy-btn.smdx-copied .smdx-copy-icon{display:none}.smdx-copy-btn.smdx-copied .smdx-check-icon{display:block}.smdx-copy-btn.smdx-copied{color:#22c55e;background:#22c55e26}.smdx-copy-btn:hover{background:#ffffff26;color:#fffc}.smdx-copy-btn:focus-visible{outline:2px solid rgba(255,255,255,.6);outline-offset:1px}.smdx-code-block:hover .smdx-copy-btn,.smdx-copy-btn:focus-visible{opacity:1}.smdx-task{display:flex;align-items:center;gap:8px;margin:4px 0}.smdx-task input[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:18px;height:18px;border:2px solid var(--smdx-border);border-radius:4px;background:var(--smdx-bg);cursor:pointer;position:relative;flex-shrink:0;transition:background .15s,border-color .15s}.smdx-task input[type=checkbox]:checked{background:var(--smdx-primary);border-color:var(--smdx-primary)}.smdx-task input[type=checkbox]:checked:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;width:100%;height:100%;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='white'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2.5-2.5a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E") no-repeat center center;background-size:14px 14px}.smdx-task input[type=checkbox]:hover{border-color:var(--smdx-primary)}.smdx-table-wrapper{overflow-x:auto;margin:12px 0;border:1px solid var(--smdx-border);border-radius:var(--smdx-radius)}.smdx-table{width:100%;border-collapse:collapse}.smdx-table th,.smdx-table td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--smdx-border)}.smdx-table th{background:var(--smdx-bg-muted);font-weight:600;font-size:.9em}.smdx-table tr:last-child td{border-bottom:none}.smdx-table tr:hover td{background:var(--smdx-bg-muted)}.smdx-editor ::-webkit-scrollbar{width:8px;height:8px}.smdx-editor ::-webkit-scrollbar-track{background:transparent}.smdx-editor ::-webkit-scrollbar-thumb{background:var(--smdx-border);border-radius:4px}.smdx-editor ::-webkit-scrollbar-thumb:hover{background:var(--smdx-text-muted)}.smdx-skip-link{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;z-index:9999;background:var(--smdx-bg, #ffffff);color:var(--smdx-primary, #6366f1);padding:4px 8px;border-radius:4px;text-decoration:none;font-weight:600}.smdx-skip-link:focus{position:static;width:auto;height:auto;left:auto;overflow:visible}.smdx-toolbar-btn:focus-visible,.smdx-toolbar-menu-btn:focus-visible,.smdx-mode-btn:focus-visible{outline:2px solid var(--smdx-primary, #6366f1);outline-offset:2px;border-radius:var(--smdx-toolbar-btn-radius, 6px)}.smdx-textarea:focus-visible{outline:2px solid var(--smdx-border-focus, #6366f1);outline-offset:-2px}.smdx-code-block .hljs{color:#e2e8f0;background:transparent}.smdx-code-block .hljs-comment,.smdx-code-block .hljs-quote{color:#637777;font-style:italic}.smdx-code-block .hljs-keyword,.smdx-code-block .hljs-selector-tag,.smdx-code-block .hljs-built_in,.smdx-code-block .hljs-name,.smdx-code-block .hljs-tag{color:#c792ea}.smdx-code-block .hljs-string,.smdx-code-block .hljs-title,.smdx-code-block .hljs-section,.smdx-code-block .hljs-attribute,.smdx-code-block .hljs-literal,.smdx-code-block .hljs-template-tag,.smdx-code-block .hljs-template-variable,.smdx-code-block .hljs-type,.smdx-code-block .hljs-addition{color:#c3e88d}.smdx-code-block .hljs-deletion,.smdx-code-block .hljs-selector-attr,.smdx-code-block .hljs-selector-pseudo,.smdx-code-block .hljs-meta{color:#f07178}.smdx-code-block .hljs-doctag,.smdx-code-block .hljs-strong{font-weight:700}.smdx-code-block .hljs-emphasis{font-style:italic}.smdx-code-block .hljs-number,.smdx-code-block .hljs-symbol,.smdx-code-block .hljs-bullet,.smdx-code-block .hljs-link{color:#f78c6c}.smdx-code-block .hljs-regexp,.smdx-code-block .hljs-selector-id,.smdx-code-block .hljs-variable,.smdx-code-block .hljs-attr,.smdx-code-block .hljs-function,.smdx-code-block .hljs-title.hljs-function_{color:#82aaff}.smdx-code-block .hljs-operator,.smdx-code-block .hljs-punctuation{color:#89ddff}.smdx-code-block .hljs-property{color:#80cbc4}.smdx-code-block .hljs-params{color:#e2e8f0}.smdx-code-block .hljs-class .hljs-title,.smdx-code-block .hljs-title.hljs-class_{color:#ffcb6b}
1
+ .smdx-editor{--smdx-primary: #6366f1;--smdx-primary-hover: #4f46e5;--smdx-bg: #ffffff;--smdx-bg-muted: #f8fafc;--smdx-bg-dark: #1e1e2e;--smdx-text: #1e293b;--smdx-text-muted: #64748b;--smdx-border: #e2e8f0;--smdx-border-focus: #6366f1;--smdx-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--smdx-font-mono: "SF Mono", "Fira Code", "Fira Mono", "Roboto Mono", Menlo, Consolas, monospace;--smdx-font-size: 14px;--smdx-line-height: 1.6;--smdx-radius: 8px;--smdx-radius-sm: 4px;--smdx-spacing-xs: 4px;--smdx-spacing-sm: 8px;--smdx-spacing-md: 12px;--smdx-spacing-lg: 16px;--smdx-spacing-xl: 24px;--smdx-toolbar-bg: var(--smdx-bg);--smdx-toolbar-border: var(--smdx-border);--smdx-toolbar-btn-size: 32px;--smdx-toolbar-btn-radius: 6px;--smdx-toolbar-btn-hover-bg: var(--smdx-bg-muted);--smdx-toolbar-btn-active-bg: #eef2ff;--smdx-toolbar-btn-active-color: var(--smdx-primary);--smdx-editor-bg: var(--smdx-bg);--smdx-editor-text: var(--smdx-text);--smdx-preview-bg: var(--smdx-bg);--smdx-preview-text: var(--smdx-text);--smdx-statusbar-bg: var(--smdx-bg-muted);--smdx-statusbar-text: var(--smdx-text-muted);--smdx-shadow-sm: 0 1px 2px rgba(0, 0, 0, .05);--smdx-shadow-md: 0 4px 12px rgba(0, 0, 0, .08);--smdx-shadow-lg: 0 8px 24px rgba(0, 0, 0, .12)}.smdx-editor.smdx-dark,.smdx-dark .smdx-editor{--smdx-primary: #818cf8;--smdx-primary-hover: #6366f1;--smdx-bg: #1e1e2e;--smdx-bg-muted: #2a2a3c;--smdx-text: #e2e8f0;--smdx-text-muted: #94a3b8;--smdx-border: #374151;--smdx-border-focus: #818cf8;--smdx-toolbar-btn-active-bg: #312e81;--smdx-shadow-sm: 0 1px 2px rgba(0, 0, 0, .2);--smdx-shadow-md: 0 4px 12px rgba(0, 0, 0, .3);--smdx-shadow-lg: 0 8px 24px rgba(0, 0, 0, .4)}.smdx-editor *,.smdx-editor *:before,.smdx-editor *:after{box-sizing:border-box}.smdx-editor button,.smdx-editor input,.smdx-editor textarea{font-family:inherit;font-size:inherit}.smdx-editor{display:flex;flex-direction:column;border:1px solid var(--smdx-border);border-radius:var(--smdx-radius);background:var(--smdx-bg);color:var(--smdx-text);font-family:var(--smdx-font-family);font-size:var(--smdx-font-size);line-height:var(--smdx-line-height);height:100%;min-height:400px;position:relative}.smdx-main{display:flex;flex:1;overflow:hidden;min-height:0;position:relative}.smdx-mode-editor .smdx-preview-pane{display:none}.smdx-mode-editor .smdx-editor-pane{border-right:none}.smdx-mode-editor .smdx-splitter,.smdx-mode-preview .smdx-splitter,.smdx-mode-preview .smdx-editor-pane{display:none}.smdx-mode-preview .smdx-preview-pane{border-left:none}.smdx-mode-split .smdx-editor-pane,.smdx-mode-split .smdx-preview-pane{flex:1}.smdx-toc-open .smdx-preview-pane{flex:1;min-width:0}.smdx-splitter{flex-shrink:0;width:6px;cursor:col-resize;background:var(--smdx-border);position:relative;transition:background .15s;z-index:1}.smdx-splitter:after{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:2px;height:32px;border-left:1px dotted var(--smdx-text-muted);border-right:1px dotted var(--smdx-text-muted);opacity:.5;pointer-events:none}.smdx-splitter:hover,.smdx-splitter:active{background:var(--smdx-primary, #6366f1)}.smdx-splitter:hover:after,.smdx-splitter:active:after{opacity:0}.smdx-toolbar-container{display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--smdx-toolbar-border);background:var(--smdx-toolbar-bg);flex-shrink:0;position:relative;z-index:10;padding-right:var(--smdx-spacing-sm)}.smdx-toolbar-left{flex:1;min-width:0;overflow-x:auto}.smdx-toolbar-mode-area{display:flex;align-items:center;flex-shrink:0;padding-left:var(--smdx-spacing-sm)}.smdx-toolbar{padding:var(--smdx-spacing-xs) var(--smdx-spacing-sm)}.smdx-toolbar-row{display:flex;align-items:center;flex-wrap:wrap;gap:2px;padding:var(--smdx-spacing-xs) 0}.smdx-toolbar-divider{width:1px;height:20px;background:var(--smdx-border);margin:0 var(--smdx-spacing-xs);flex-shrink:0}.smdx-toolbar-group{display:flex;align-items:center;gap:2px}.smdx-toolbar-btn{display:flex;align-items:center;justify-content:center;min-width:var(--smdx-toolbar-btn-size);height:var(--smdx-toolbar-btn-size);padding:0 var(--smdx-spacing-sm);border:none;background:none;border-radius:var(--smdx-toolbar-btn-radius);color:var(--smdx-text);cursor:pointer;transition:background .15s,color .15s;font-size:.85em;gap:4px}.smdx-toolbar-btn:hover{background:var(--smdx-toolbar-btn-hover-bg)}.smdx-toolbar-btn.smdx-active{background:var(--smdx-toolbar-btn-active-bg);color:var(--smdx-toolbar-btn-active-color)}.smdx-toolbar-btn:disabled{opacity:.4;cursor:not-allowed}.smdx-toolbar-btn svg{width:16px;height:16px;flex-shrink:0}.smdx-toolbar-btn-label{font-size:.85em;white-space:nowrap}.smdx-toolbar-btn:after{display:none!important}.smdx-toolbar-dropdown{position:relative}.smdx-toolbar-dropdown-trigger{gap:4px}.smdx-dropdown-arrow{width:8px;height:8px;opacity:.5;flex-shrink:0}.smdx-toolbar-dropdown-menu{position:fixed;top:0;left:0;min-width:240px;max-height:420px;overflow-y:auto;background:var(--smdx-bg);border:1px solid var(--smdx-border);border-radius:var(--smdx-radius);box-shadow:var(--smdx-shadow-lg);z-index:1000;padding:var(--smdx-spacing-xs)}.smdx-toolbar-dropdown-section{padding:var(--smdx-spacing-xs) 0}.smdx-toolbar-dropdown-section+.smdx-toolbar-dropdown-section{border-top:1px solid var(--smdx-border);margin-top:var(--smdx-spacing-xs);padding-top:var(--smdx-spacing-sm)}.smdx-toolbar-dropdown-section-label{font-size:.7em;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--smdx-text-muted);padding:var(--smdx-spacing-xs) 10px;margin-bottom:2px}.smdx-toolbar-menu-btn{display:flex;align-items:center;gap:10px;width:100%;padding:7px 10px;border:none;background:none;border-radius:var(--smdx-radius-sm);color:var(--smdx-text);cursor:pointer;font-size:.85em;text-align:left;transition:background .1s;white-space:nowrap}.smdx-toolbar-menu-btn:hover{background:var(--smdx-toolbar-btn-hover-bg)}.smdx-toolbar-menu-btn svg{width:16px;height:16px;flex-shrink:0}.smdx-toolbar-menu-btn span{flex:1;overflow:hidden;text-overflow:ellipsis}.smdx-toolbar-menu-btn .smdx-color-dot{flex:0 0 auto;overflow:visible}.smdx-shortcut-label{margin-left:auto;padding:1px 5px;font-size:.72em;font-family:var(--smdx-font-mono, "SF Mono", "Fira Code", monospace);background:var(--smdx-bg-code, #e2e8f0);color:var(--smdx-text-muted, #64748b);border-radius:4px;border:1px solid var(--smdx-border, #cbd5e1);letter-spacing:.02em;white-space:nowrap;opacity:.85}.smdx-dark .smdx-shortcut-label{background:#ffffff14;color:var(--smdx-text-muted, #94a3b8);border-color:#ffffff26}.smdx-toolbar-btn[data-shortcut]:after{content:attr(data-shortcut);display:block;font-size:.7em;font-family:var(--smdx-font-mono, monospace);opacity:.7;margin-top:1px}.smdx-toolbar-submenu{position:relative}.smdx-toolbar-submenu-trigger{justify-content:flex-start}.smdx-submenu-arrow{width:6px;height:10px;opacity:.4;margin-left:auto;flex-shrink:0}.smdx-toolbar-submenu-menu{position:fixed;z-index:200;min-width:180px}.smdx-editor-pane{flex:1;display:flex;overflow:hidden;min-height:0}.smdx-scroll-wrapper{display:flex;flex:1;overflow-y:auto;overflow-x:hidden;min-height:0}.smdx-textarea{flex:1;min-height:100%;padding:16px;border:none;outline:none;resize:none;background:var(--smdx-editor-bg);color:var(--smdx-editor-text);font-family:var(--smdx-font-mono);font-size:14px;line-height:1.7rem;-moz-tab-size:2;tab-size:2;box-sizing:border-box;overflow:hidden;white-space:pre-wrap;word-wrap:break-word}.smdx-textarea::placeholder{color:var(--smdx-text-muted);opacity:.5}.smdx-line-gutter{width:48px;flex-shrink:0;display:none;position:relative;font-family:var(--smdx-font-mono);font-size:12px;background:var(--smdx-bg-muted);border-right:1px solid var(--smdx-border)}.smdx-gutter-inner{position:relative;pointer-events:none}.smdx-line-num{display:block;text-align:right;padding-right:10px;color:var(--smdx-text-muted);font-size:11px;-webkit-user-select:none;user-select:none;white-space:nowrap}.smdx-has-gutter .smdx-line-gutter{display:block}.smdx-preview-pane{flex:1;overflow:hidden;min-height:0;position:relative}.smdx-preview-content{padding:16px 24px;overflow-y:auto;height:100%;color:var(--smdx-text);line-height:1.75;font-size:15px}.smdx-preview-content h1{font-size:2rem;font-weight:600;margin-top:2rem;margin-bottom:1rem;padding-bottom:.5rem;border-bottom:1px solid var(--smdx-border)}.smdx-preview-content h2{font-size:1.5rem;font-weight:600;margin-top:1.75rem;margin-bottom:.75rem;padding-bottom:.375rem;border-bottom:1px solid var(--smdx-border)}.smdx-preview-content h3{font-size:1.25rem;font-weight:600;margin-top:1.5rem;margin-bottom:.5rem}.smdx-preview-content h4{font-size:1.1rem;font-weight:600;margin-top:1.25rem;margin-bottom:.5rem}.smdx-preview-content h5{font-size:1rem;font-weight:600;margin-top:1rem;margin-bottom:.5rem}.smdx-preview-content h6{font-size:.9rem;font-weight:600;margin-top:1rem;margin-bottom:.5rem;color:var(--smdx-text-muted)}.smdx-preview-content p{margin-bottom:1rem}.smdx-preview-content a{color:#3b82f6;text-decoration:underline}.smdx-preview-content a:hover{color:#2563eb}.smdx-preview-content strong{font-weight:600}.smdx-preview-content em{font-style:italic}.smdx-preview-content del{text-decoration:line-through;color:var(--smdx-text-muted)}.smdx-preview-content blockquote{border-left:3px solid var(--smdx-border);padding-left:1rem;color:var(--smdx-text-muted);margin:1rem 0;font-style:italic}.smdx-preview-content ul{list-style-type:disc;padding-left:1.5rem;margin:.75rem 0}.smdx-preview-content ol{list-style-type:decimal;padding-left:1.5rem;margin:.75rem 0}.smdx-preview-content li{margin-bottom:.35rem}.smdx-preview-content hr{border:none;border-top:1px solid var(--smdx-border);margin:1.5rem 0}.smdx-preview-content img{max-width:100%;border-radius:8px;margin:1rem 0}.smdx-preview-content img.smdx-image{max-width:100%;border-radius:var(--smdx-radius)}.smdx-inline-code,.smdx-preview-content :not(pre)>code{background:#ececf0;padding:.2em .4em;border-radius:4px;font-family:var(--smdx-font-mono);font-size:.85em}.smdx-preview-content pre{background:#1e1e2e;color:#cdd6f4;padding:1rem 1.25rem;border-radius:8px;overflow-x:auto;margin:1rem 0;font-size:.85rem;line-height:1.6}.smdx-preview-content pre code{background:transparent;padding:0;color:inherit;font-size:inherit}.smdx-toc-container{width:256px;min-width:256px;flex-shrink:0;display:flex;flex-direction:column;border-left:1px solid var(--smdx-border);background:var(--smdx-bg);overflow:hidden;transition:width .2s ease,min-width .2s ease}.smdx-toc-container.smdx-toc-collapsed{width:40px;min-width:40px;align-items:center}.smdx-toc-expand-btn{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;background:none;cursor:pointer;color:var(--smdx-text-muted);transition:color .15s,background .15s;margin-top:8px;border-radius:4px}.smdx-toc-expand-btn:hover{color:var(--smdx-text);background:var(--smdx-bg-muted)}.smdx-toc-header{display:flex;align-items:center;justify-content:space-between;padding:10px 12px 8px 16px;border-bottom:1px solid var(--smdx-border);flex-shrink:0}.smdx-toc-title{display:flex;align-items:center;gap:6px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:var(--smdx-text-muted)}.smdx-toc-close-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border:none;background:none;border-radius:4px;cursor:pointer;color:var(--smdx-text-muted);transition:background .15s,color .15s;padding:0}.smdx-toc-close-btn:hover{background:var(--smdx-bg-muted);color:var(--smdx-text)}.smdx-toc-body{flex:1;overflow-y:auto;padding:8px 4px}.smdx-toc-nav{display:flex;flex-direction:column;gap:1px}.smdx-toc-item{display:block;width:100%;text-align:left;background:none;border:none;border-radius:4px;padding:4px 8px;font-size:12px;line-height:1.5;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--smdx-text-muted);transition:background .1s,color .1s}.smdx-toc-item:hover{background:var(--smdx-bg-muted);color:var(--smdx-text)}.smdx-toc-item.smdx-toc-h1{color:var(--smdx-text);font-weight:600}.smdx-toc-item.smdx-toc-h2{color:var(--smdx-text);font-size:12px}.smdx-toc-empty{padding:16px;font-size:12px;color:var(--smdx-text-muted);text-align:center}.smdx-toc-footer{padding:6px 16px;border-top:1px solid var(--smdx-border);font-size:10px;color:var(--smdx-text-muted);flex-shrink:0}.smdx-code-block{position:relative;margin:12px 0;border-radius:var(--smdx-radius);overflow:hidden;background:#1e1e2e;border:1px solid transparent}.smdx-dark .smdx-code-block{background:#141422;border-color:#374151}.smdx-code-header{display:flex;align-items:center;gap:12px;padding:8px 14px;background:#ffffff0d;border-bottom:1px solid rgba(255,255,255,.1);font-family:var(--smdx-font-mono);font-size:.8em;color:#94a3b8}.smdx-code-lang{color:#818cf8;font-weight:600}.smdx-code-filename{color:#94a3b8;display:flex;align-items:center;gap:6px}.smdx-code-filename svg{opacity:.6;flex-shrink:0}.smdx-code-header .smdx-copy-btn{position:static;margin-left:auto;opacity:0;transition:opacity .15s,background .15s,color .15s}.smdx-code-block:hover .smdx-code-header .smdx-copy-btn,.smdx-code-header .smdx-copy-btn:focus-visible{opacity:1}.smdx-code-block pre{margin:0;padding:16px;overflow-x:auto;background:transparent;color:#e2e8f0}.smdx-code-block code{font-family:var(--smdx-font-mono);font-size:.9em;line-height:1.6}.smdx-copy-btn{position:absolute;top:10px;right:10px;padding:6px;border:none;background:#ffffff14;border-radius:4px;color:#fff6;cursor:pointer;transition:all .15s;display:flex;align-items:center;justify-content:center}.smdx-copy-btn .smdx-check-icon,.smdx-copy-btn.smdx-copied .smdx-copy-icon{display:none}.smdx-copy-btn.smdx-copied .smdx-check-icon{display:block}.smdx-copy-btn.smdx-copied{color:#22c55e;background:#22c55e26}.smdx-copy-btn:hover{background:#ffffff26;color:#fffc}.smdx-copy-btn:focus-visible{outline:2px solid rgba(255,255,255,.6);outline-offset:1px}.smdx-code-block:hover .smdx-copy-btn,.smdx-copy-btn:focus-visible{opacity:1}.smdx-code-block .hljs{color:#e2e8f0;background:transparent}.smdx-code-block .hljs-comment,.smdx-code-block .hljs-quote{color:#637777;font-style:italic}.smdx-code-block .hljs-keyword,.smdx-code-block .hljs-selector-tag,.smdx-code-block .hljs-built_in,.smdx-code-block .hljs-name,.smdx-code-block .hljs-tag{color:#c792ea}.smdx-code-block .hljs-string,.smdx-code-block .hljs-title,.smdx-code-block .hljs-section,.smdx-code-block .hljs-attribute,.smdx-code-block .hljs-literal,.smdx-code-block .hljs-template-tag,.smdx-code-block .hljs-template-variable,.smdx-code-block .hljs-type,.smdx-code-block .hljs-addition{color:#c3e88d}.smdx-code-block .hljs-deletion,.smdx-code-block .hljs-selector-attr,.smdx-code-block .hljs-selector-pseudo,.smdx-code-block .hljs-meta{color:#f07178}.smdx-code-block .hljs-doctag,.smdx-code-block .hljs-strong{font-weight:700}.smdx-code-block .hljs-emphasis{font-style:italic}.smdx-code-block .hljs-number,.smdx-code-block .hljs-symbol,.smdx-code-block .hljs-bullet,.smdx-code-block .hljs-link{color:#f78c6c}.smdx-code-block .hljs-regexp,.smdx-code-block .hljs-selector-id,.smdx-code-block .hljs-variable,.smdx-code-block .hljs-attr,.smdx-code-block .hljs-function,.smdx-code-block .hljs-title.hljs-function_{color:#82aaff}.smdx-code-block .hljs-operator,.smdx-code-block .hljs-punctuation{color:#89ddff}.smdx-code-block .hljs-property{color:#80cbc4}.smdx-code-block .hljs-params{color:#e2e8f0}.smdx-code-block .hljs-class .hljs-title,.smdx-code-block .hljs-title.hljs-class_{color:#ffcb6b}.smdx-table-wrapper{overflow-x:auto;margin:12px 0;border:1px solid var(--smdx-border);border-radius:var(--smdx-radius)}.smdx-table{width:100%;border-collapse:collapse}.smdx-table th,.smdx-table td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--smdx-border)}.smdx-table th{background:var(--smdx-bg-muted);font-weight:600;font-size:.9em}.smdx-table tr:last-child td{border-bottom:none}.smdx-table tr:hover td{background:var(--smdx-bg-muted)}.smdx-task{display:flex;align-items:center;gap:8px;margin:4px 0}.smdx-task-checkbox{display:inline-block;width:18px;height:18px;border:2px solid var(--smdx-border);border-radius:4px;background:var(--smdx-bg);cursor:default;position:relative;flex-shrink:0;transition:background .15s,border-color .15s}.smdx-task-checkbox.smdx-task-checked{background:var(--smdx-primary);border-color:var(--smdx-primary)}.smdx-task-checkbox.smdx-task-checked:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;width:100%;height:100%;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='white'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2.5-2.5a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E") no-repeat center center;background-size:14px 14px}.smdx-status-bar{display:flex;align-items:center;gap:var(--smdx-spacing-xs);padding:var(--smdx-spacing-xs) var(--smdx-spacing-lg);background:var(--smdx-statusbar-bg);color:var(--smdx-statusbar-text);font-size:.8em;border-top:1px solid var(--smdx-border);flex-shrink:0;-webkit-user-select:none;user-select:none;flex-wrap:wrap;row-gap:2px}.smdx-status-item{white-space:nowrap;font-size:.8em;color:var(--smdx-statusbar-text)}.smdx-status-readonly{color:var(--smdx-primary, #6366f1);font-weight:600}.smdx-status-sep{color:var(--smdx-border);padding:0 2px}.smdx-virtual-stats{display:inline-flex;align-items:center;gap:0;white-space:nowrap}.smdx-virtual-badge{display:inline-flex;align-items:center;gap:3px;font-size:.75em;font-weight:600;padding:1px 6px;border-radius:9999px;white-space:nowrap}.smdx-virtual-on{color:var(--smdx-primary, #6366f1);background:color-mix(in srgb,var(--smdx-primary, #6366f1) 12%,transparent);border:1px solid color-mix(in srgb,var(--smdx-primary, #6366f1) 30%,transparent)}.smdx-virtual-nodes{color:var(--smdx-text-muted);font-size:.75em}.smdx-jump-wrap{display:inline-flex;align-items:center;gap:3px}.smdx-jump-input{width:50px;height:16px;padding:0 4px;border:1px solid var(--smdx-border);border-radius:3px;background:var(--smdx-bg);color:var(--smdx-text);font-size:.8em;font-family:inherit;text-align:right;cursor:text;user-select:text;-webkit-user-select:text;pointer-events:auto;-moz-appearance:textfield;-webkit-appearance:textfield;appearance:textfield}.smdx-jump-input::-webkit-outer-spin-button,.smdx-jump-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.smdx-jump-input:focus{outline:1px solid var(--smdx-primary, #6366f1);border-color:var(--smdx-primary, #6366f1)}.smdx-mode-switch{display:flex;gap:2px;background:var(--smdx-bg);border-radius:var(--smdx-radius-sm);padding:2px;border:1px solid var(--smdx-border)}.smdx-mode-btn{display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border:none;background:none;border-radius:3px;cursor:pointer;font-size:.85em;color:var(--smdx-text-muted);transition:all .15s}.smdx-mode-btn:hover{color:var(--smdx-text)}.smdx-mode-btn.smdx-active{background:var(--smdx-primary);color:#fff}.smdx-readonly .smdx-toolbar-container{display:none}.smdx-readonly .smdx-textarea{background:var(--smdx-bg-muted);cursor:text}.smdx-readonly .smdx-editor-pane{border-right-color:var(--smdx-border)}.smdx-parse-error{display:flex;align-items:center;gap:8px;padding:10px 16px;margin:0 0 8px;background:#fef2f2;border:1px solid #fecaca;border-left:4px solid #ef4444;border-radius:6px;color:#991b1b;font-size:.88em;font-family:var(--smdx-font-mono, monospace);line-height:1.5;word-break:break-word}.smdx-parse-error-icon{color:#ef4444;font-size:1.1em;flex-shrink:0}.smdx-dark .smdx-parse-error{background:#451a1a;border-color:#7f1d1d;border-left-color:#ef4444;color:#fca5a5}.smdx-dark .smdx-parse-error-icon{color:#f87171}.smdx-skip-link{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;z-index:9999;background:var(--smdx-bg, #ffffff);color:var(--smdx-primary, #6366f1);padding:4px 8px;border-radius:4px;text-decoration:none;font-weight:600}.smdx-skip-link:focus{position:static;width:auto;height:auto;left:auto;overflow:visible}.smdx-toolbar-btn:focus-visible,.smdx-toolbar-menu-btn:focus-visible,.smdx-mode-btn:focus-visible{outline:2px solid var(--smdx-primary, #6366f1);outline-offset:2px;border-radius:var(--smdx-toolbar-btn-radius, 6px)}.smdx-textarea:focus-visible{outline:2px solid var(--smdx-border-focus, #6366f1);outline-offset:-2px}.smdx-editor ::-webkit-scrollbar{width:8px;height:8px}.smdx-editor ::-webkit-scrollbar-track{background:transparent}.smdx-editor ::-webkit-scrollbar-thumb{background:var(--smdx-border);border-radius:4px}.smdx-editor ::-webkit-scrollbar-thumb:hover{background:var(--smdx-text-muted)}.smdx-ac-popup{position:absolute;z-index:400;background:var(--smdx-bg, #fff);border:1px solid var(--smdx-border, #e2e8f0);border-radius:var(--smdx-radius, 8px);overflow:hidden;overflow-y:auto;box-shadow:var(--smdx-shadow-lg, 0 8px 24px rgba(0, 0, 0, .12));min-width:220px;max-width:400px;max-height:260px;animation:smdx-ac-in .1s ease;pointer-events:all}@keyframes smdx-ac-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.smdx-ac-item{display:flex;align-items:center;gap:8px;padding:5px 10px;font-size:12px;font-family:var(--smdx-font-mono, monospace);cursor:pointer;color:var(--smdx-text-muted, #64748b);transition:background .07s}.smdx-ac-item:hover,.smdx-ac-item.smdx-ac-sel{background:var(--smdx-bg-muted, #f8fafc);color:var(--smdx-text, #1e293b)}.smdx-ac-badge{display:inline-flex;align-items:center;justify-content:center;width:22px;height:18px;border-radius:3px;font-size:10px;font-weight:600;flex-shrink:0;font-family:var(--smdx-font-family, sans-serif)}.smdx-ac-tag{background:#dbeafe;color:#2563eb}.smdx-ac-md{background:#f0fdf4;color:#16a34a}.smdx-ac-html{background:#fef3c7;color:#d97706}.smdx-ac-var{background:#f1f5f9;color:#64748b}.smdx-ac-snippet{background:#ede9fe;color:#7c3aed}.smdx-ac-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:inherit}.smdx-ac-detail{font-size:10px;color:var(--smdx-text-muted, #64748b);flex-shrink:0;max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.smdx-dark .smdx-ac-popup,.smdx-editor.smdx-dark .smdx-ac-popup{background:var(--smdx-bg, #1e1e2e);border-color:var(--smdx-border, #374151)}.smdx-dark .smdx-ac-item:hover,.smdx-dark .smdx-ac-item.smdx-ac-sel,.smdx-editor.smdx-dark .smdx-ac-item:hover,.smdx-editor.smdx-dark .smdx-ac-item.smdx-ac-sel{background:var(--smdx-bg-muted, #2a2a3c)}.smdx-dark .smdx-ac-tag,.smdx-editor.smdx-dark .smdx-ac-tag{background:#1e3a5f;color:#60a5fa}.smdx-dark .smdx-ac-md,.smdx-editor.smdx-dark .smdx-ac-md{background:#14532d;color:#4ade80}.smdx-dark .smdx-ac-html,.smdx-editor.smdx-dark .smdx-ac-html{background:#451a03;color:#fbbf24}.smdx-dark .smdx-ac-var,.smdx-editor.smdx-dark .smdx-ac-var{background:#334155;color:#94a3b8}.smdx-dark .smdx-ac-snippet,.smdx-editor.smdx-dark .smdx-ac-snippet{background:#2e1065;color:#a78bfa}.smdx-find-panel{position:absolute;top:0;right:16px;z-index:300;display:flex;flex-direction:column;gap:4px;padding:8px 10px;background:var(--smdx-bg, #fff);border:1px solid var(--smdx-border, #e2e8f0);border-top:none;border-radius:0 0 var(--smdx-radius, 8px) var(--smdx-radius, 8px);box-shadow:var(--smdx-shadow-md, 0 4px 12px rgba(0, 0, 0, .08));animation:smdx-find-in .12s ease;max-width:460px;min-width:320px}@keyframes smdx-find-in{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.smdx-find-row{display:flex;align-items:center;gap:4px}.smdx-replace-row{padding-left:0}.smdx-find-input{flex:1;min-width:0;height:26px;padding:2px 8px;border:1px solid var(--smdx-border, #e2e8f0);border-radius:var(--smdx-radius-sm, 4px);background:var(--smdx-bg, #fff);color:var(--smdx-text, #1e293b);font-size:12px;font-family:var(--smdx-font-mono, monospace);outline:none;transition:border-color .15s}.smdx-find-input:focus{border-color:var(--smdx-primary, #6366f1);box-shadow:0 0 0 2px color-mix(in srgb,var(--smdx-primary, #6366f1) 20%,transparent)}.smdx-find-input::placeholder{color:var(--smdx-text-muted, #94a3b8)}.smdx-find-toggle{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border:1px solid transparent;border-radius:var(--smdx-radius-sm, 4px);background:none;color:var(--smdx-text-muted, #64748b);font-size:11px;font-weight:600;font-family:var(--smdx-font-mono, monospace);cursor:pointer;transition:all .12s;flex-shrink:0}.smdx-find-toggle:hover{background:var(--smdx-bg-muted, #f8fafc);color:var(--smdx-text, #1e293b)}.smdx-find-toggle.smdx-find-toggle-on{background:var(--smdx-primary, #6366f1);color:#fff;border-color:var(--smdx-primary, #6366f1)}.smdx-find-btn{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:26px;padding:0 4px;border:1px solid transparent;border-radius:var(--smdx-radius-sm, 4px);background:none;color:var(--smdx-text-muted, #64748b);font-size:12px;cursor:pointer;transition:all .12s;flex-shrink:0}.smdx-find-btn:hover{background:var(--smdx-bg-muted, #f8fafc);color:var(--smdx-text, #1e293b)}.smdx-find-action-text{font-size:11px;font-weight:500;padding:0 8px;border:1px solid var(--smdx-border, #e2e8f0);border-radius:var(--smdx-radius-sm, 4px)}.smdx-find-action-text:hover{background:var(--smdx-primary, #6366f1);color:#fff;border-color:var(--smdx-primary, #6366f1)}.smdx-find-close{margin-left:auto;font-size:14px}.smdx-find-count{font-size:11px;color:var(--smdx-text-muted, #64748b);white-space:nowrap;min-width:60px;text-align:center}.smdx-dark .smdx-find-panel,.smdx-editor.smdx-dark .smdx-find-panel{background:var(--smdx-bg, #1e1e2e);border-color:var(--smdx-border, #374151)}.smdx-dark .smdx-find-input,.smdx-editor.smdx-dark .smdx-find-input{background:var(--smdx-bg-muted, #2a2a3c);border-color:var(--smdx-border, #374151);color:var(--smdx-text, #e2e8f0)}.smdx-dark .smdx-find-toggle:hover,.smdx-editor.smdx-dark .smdx-find-toggle:hover,.smdx-dark .smdx-find-btn:hover,.smdx-editor.smdx-dark .smdx-find-btn:hover{background:var(--smdx-bg-muted, #2a2a3c)}.smdx-dark .smdx-find-action-text,.smdx-editor.smdx-dark .smdx-find-action-text{border-color:var(--smdx-border, #374151)}@media (max-width: 1024px){.smdx-toc-container{width:200px;min-width:200px}.smdx-toc-container.smdx-toc-collapsed{width:36px;min-width:36px}.smdx-word-count,.smdx-line-count{display:none}.smdx-toolbar-left{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}.smdx-toolbar-left::-webkit-scrollbar{display:none}.smdx-toolbar-row{flex-wrap:nowrap}}@media (max-width: 640px){.smdx-editor{min-height:300px;border-radius:0}.smdx-editor.smdx-mode-split .smdx-preview-pane{display:none}.smdx-editor.smdx-mode-split .smdx-editor-pane{flex:1;border-right:none}.smdx-editor.smdx-mode-split .smdx-splitter{display:none}.smdx-toolbar-container{flex-wrap:wrap;padding-right:0}.smdx-toolbar-left{flex:0 0 100%;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}.smdx-toolbar-left::-webkit-scrollbar{display:none}.smdx-toolbar-row{flex-wrap:nowrap;padding:var(--smdx-spacing-xs) var(--smdx-spacing-sm)}.smdx-toolbar-btn{min-width:44px;height:44px;padding:0 var(--smdx-spacing-sm)}.smdx-toolbar-btn svg{width:18px;height:18px}.smdx-toolbar-btn-label{display:none}.smdx-toolbar-mode-area{width:100%;justify-content:center;padding:var(--smdx-spacing-xs) var(--smdx-spacing-sm);border-top:1px solid var(--smdx-toolbar-border)}.smdx-textarea{padding:12px;font-size:15px}.smdx-preview-content{padding:12px 16px}.smdx-preview-content h1{font-size:1.6rem}.smdx-preview-content h2{font-size:1.3rem}.smdx-preview-content h3{font-size:1.1rem}.smdx-preview-content img{max-width:100%;height:auto}.smdx-status-bar{padding:var(--smdx-spacing-xs) var(--smdx-spacing-sm);flex-wrap:wrap;gap:var(--smdx-spacing-xs);justify-content:space-between}.smdx-word-count,.smdx-line-count,.smdx-char-count,.smdx-status-sep{display:none}.smdx-mode-btn{padding:6px 12px;min-height:36px;font-size:.8em}.smdx-mode-btn[data-mode=split]{display:none}.smdx-toc-container{position:fixed;top:0;right:0;bottom:0;width:280px;max-width:85vw;min-width:unset;z-index:200;box-shadow:var(--smdx-shadow-lg);transform:translate(100%);transition:transform .25s ease}.smdx-toc-open .smdx-toc-container{transform:translate(0)}.smdx-toc-container.smdx-toc-collapsed{width:280px;min-width:unset;transform:translate(100%)}.smdx-toc-open:before{content:"";position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;z-index:199;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.smdx-toc-open .smdx-preview-pane{flex:1}.smdx-toolbar-dropdown-menu{min-width:min(280px,calc(100vw - 16px));max-height:60vh}.smdx-toolbar-menu-btn{padding:10px 12px;min-height:44px}.smdx-toolbar-submenu-menu{min-width:min(240px,calc(100vw - 16px))}}.smdx-editor.smdx-is-mobile{min-height:300px;border-radius:0}.smdx-editor.smdx-is-mobile.smdx-mode-split .smdx-preview-pane{display:none}.smdx-editor.smdx-is-mobile.smdx-mode-split .smdx-editor-pane{flex:1;border-right:none}.smdx-editor.smdx-is-mobile.smdx-mode-split .smdx-splitter{display:none}.smdx-editor.smdx-is-mobile .smdx-toolbar-container{flex-wrap:wrap;padding-right:0}.smdx-editor.smdx-is-mobile .smdx-toolbar-left{flex:0 0 100%;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}.smdx-editor.smdx-is-mobile .smdx-toolbar-left::-webkit-scrollbar{display:none}.smdx-editor.smdx-is-mobile .smdx-toolbar-row{flex-wrap:nowrap;padding:var(--smdx-spacing-xs) var(--smdx-spacing-sm)}.smdx-editor.smdx-is-mobile .smdx-toolbar-btn{min-width:44px;height:44px;padding:0 var(--smdx-spacing-sm)}.smdx-editor.smdx-is-mobile .smdx-toolbar-btn svg{width:18px;height:18px}.smdx-editor.smdx-is-mobile .smdx-toolbar-btn-label{display:none}.smdx-editor.smdx-is-mobile .smdx-toolbar-mode-area{width:100%;justify-content:center;padding:var(--smdx-spacing-xs) var(--smdx-spacing-sm);border-top:1px solid var(--smdx-toolbar-border)}.smdx-editor.smdx-is-mobile .smdx-textarea{padding:12px;font-size:15px}.smdx-editor.smdx-is-mobile .smdx-preview-content{padding:12px 16px}.smdx-editor.smdx-is-mobile .smdx-preview-content h1{font-size:1.6rem}.smdx-editor.smdx-is-mobile .smdx-preview-content h2{font-size:1.3rem}.smdx-editor.smdx-is-mobile .smdx-preview-content h3{font-size:1.1rem}.smdx-editor.smdx-is-mobile .smdx-preview-content img{max-width:100%;height:auto}.smdx-editor.smdx-is-mobile .smdx-status-bar{padding:var(--smdx-spacing-xs) var(--smdx-spacing-sm);flex-wrap:wrap;gap:var(--smdx-spacing-xs);justify-content:space-between}.smdx-editor.smdx-is-mobile .smdx-word-count,.smdx-editor.smdx-is-mobile .smdx-line-count,.smdx-editor.smdx-is-mobile .smdx-char-count,.smdx-editor.smdx-is-mobile .smdx-status-sep{display:none}.smdx-editor.smdx-is-mobile .smdx-mode-btn{padding:6px 12px;min-height:36px;font-size:.8em}.smdx-editor.smdx-is-mobile .smdx-mode-btn[data-mode=split]{display:none}.smdx-editor.smdx-is-mobile .smdx-toc-container{position:fixed;top:0;right:0;bottom:0;width:280px;max-width:85vw;min-width:unset;z-index:200;box-shadow:var(--smdx-shadow-lg);transform:translate(100%);transition:transform .25s ease}.smdx-editor.smdx-is-mobile.smdx-toc-open .smdx-toc-container{transform:translate(0)}.smdx-editor.smdx-is-mobile .smdx-toc-container.smdx-toc-collapsed{width:280px;min-width:unset;transform:translate(100%)}.smdx-editor.smdx-is-mobile.smdx-toc-open:before{content:"";position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;z-index:199;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.smdx-editor.smdx-is-mobile.smdx-toc-open .smdx-preview-pane{flex:1}.smdx-editor.smdx-is-mobile .smdx-toolbar-dropdown-menu{min-width:min(280px,calc(100vw - 16px));max-height:60vh}.smdx-editor.smdx-is-mobile .smdx-toolbar-menu-btn{padding:10px 12px;min-height:44px}.smdx-editor.smdx-is-mobile .smdx-toolbar-submenu-menu{min-width:min(240px,calc(100vw - 16px))}.smdx-editor.smdx-is-tablet .smdx-toc-container{width:200px;min-width:200px}.smdx-editor.smdx-is-tablet .smdx-toc-container.smdx-toc-collapsed{width:36px;min-width:36px}.smdx-editor.smdx-is-tablet .smdx-word-count,.smdx-editor.smdx-is-tablet .smdx-line-count{display:none}.smdx-editor.smdx-is-tablet .smdx-toolbar-left{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}.smdx-editor.smdx-is-tablet .smdx-toolbar-left::-webkit-scrollbar{display:none}.smdx-editor.smdx-is-tablet .smdx-toolbar-row{flex-wrap:nowrap}@media (hover: none) and (pointer: coarse){.smdx-toolbar-btn:hover{background:none}.smdx-toolbar-btn:active{background:var(--smdx-toolbar-btn-hover-bg)}.smdx-toolbar-menu-btn:hover{background:none}.smdx-toolbar-menu-btn:active{background:var(--smdx-toolbar-btn-hover-bg)}.smdx-toolbar-btn{min-width:44px;height:44px}.smdx-mode-btn{min-height:40px;padding:6px 12px}.smdx-splitter{cursor:default}}