@barocss/math-editor 0.2.1 → 0.5.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 (202) hide show
  1. package/ADAPTERS.md +25 -14
  2. package/API-JAVASCRIPT.md +1 -1
  3. package/API-REACT.md +5 -1
  4. package/API-SESSION.md +178 -6
  5. package/API-SOLID.md +1 -1
  6. package/API-SVELTE.md +1 -1
  7. package/API-VUE.md +1 -1
  8. package/API-WEB-COMPONENT.md +3 -1
  9. package/CHANGELOG.md +106 -0
  10. package/EDITING-SCENARIOS.md +174 -0
  11. package/EMBEDDING.md +4 -0
  12. package/IMPLEMENTATION.md +122 -2
  13. package/JSON-MODEL.md +1 -0
  14. package/LATEX-GUIDE.md +30 -1
  15. package/LATEX-MODEL.md +12 -0
  16. package/LATEX-SCOPE.md +12 -3
  17. package/LICENSE +1 -3
  18. package/README.md +201 -39
  19. package/RELEASING.md +81 -10
  20. package/RENDERING-TESTS.md +79 -0
  21. package/ROADMAP.md +220 -11
  22. package/STYLING.md +157 -0
  23. package/SUPPORT.md +24 -12
  24. package/VALIDATION.md +444 -4
  25. package/dist/context-tools.d.ts +21 -0
  26. package/dist/context-tools.js +37 -0
  27. package/dist/core.d.ts +5 -1
  28. package/dist/core.js +5 -1
  29. package/dist/document-codec.d.ts +0 -1
  30. package/dist/document-codec.js +0 -1
  31. package/dist/dom/caret-geometry.d.ts +3 -0
  32. package/dist/dom/caret-geometry.js +41 -0
  33. package/dist/dom/context-keyboard.d.ts +2 -0
  34. package/dist/dom/context-keyboard.js +22 -0
  35. package/dist/dom/elements.d.ts +1 -2
  36. package/dist/dom/elements.js +2 -3
  37. package/dist/dom/latex-panel.d.ts +10 -0
  38. package/dist/dom/latex-panel.js +59 -0
  39. package/dist/dom/matrix-selection.d.ts +11 -0
  40. package/dist/dom/matrix-selection.js +30 -0
  41. package/dist/dom/menu-position.d.ts +17 -2
  42. package/dist/dom/menu-position.js +129 -16
  43. package/dist/dom/presentation-controls.d.ts +4 -0
  44. package/dist/dom/presentation-controls.js +56 -0
  45. package/dist/dom/quick-panel.d.ts +12 -0
  46. package/dist/dom/quick-panel.js +102 -0
  47. package/dist/dom/selection.d.ts +29 -0
  48. package/dist/dom/selection.js +53 -0
  49. package/dist/dom/symbol-panel.d.ts +9 -0
  50. package/dist/dom/symbol-panel.js +146 -0
  51. package/dist/dom/theme.d.ts +6 -0
  52. package/dist/dom/theme.js +68 -0
  53. package/dist/dom/toolbar-catalog.d.ts +10 -0
  54. package/dist/dom/toolbar-catalog.js +35 -0
  55. package/dist/dom/toolbar.d.ts +13 -2
  56. package/dist/dom/toolbar.js +295 -28
  57. package/dist/dom.d.ts +9 -1
  58. package/dist/dom.js +682 -151
  59. package/dist/editor-labels.d.ts +0 -1
  60. package/dist/editor-labels.js +0 -1
  61. package/dist/enter-policy.d.ts +0 -1
  62. package/dist/enter-policy.js +0 -1
  63. package/dist/fences.d.ts +0 -1
  64. package/dist/fences.js +0 -1
  65. package/dist/i18n.d.ts +0 -1
  66. package/dist/i18n.js +0 -1
  67. package/dist/index.d.ts +4 -1
  68. package/dist/index.js +4 -1
  69. package/dist/latex-insertion.d.ts +12 -0
  70. package/dist/latex-insertion.js +26 -0
  71. package/dist/latex-paste-panel.d.ts +3 -0
  72. package/dist/latex-paste-panel.js +18 -0
  73. package/dist/latex.d.ts +0 -1
  74. package/dist/latex.js +11 -1
  75. package/dist/lines.d.ts +0 -1
  76. package/dist/lines.js +0 -1
  77. package/dist/locales/en.js +39 -1
  78. package/dist/locales/en.json +39 -1
  79. package/dist/locales/ko.js +39 -1
  80. package/dist/locales/ko.json +39 -1
  81. package/dist/math-editor-toolbar.d.ts +4 -2
  82. package/dist/math-editor-toolbar.js +3 -4
  83. package/dist/math-editor.d.ts +7 -2
  84. package/dist/math-editor.js +661 -308
  85. package/dist/math-layout.d.ts +12 -0
  86. package/dist/math-layout.js +59 -0
  87. package/dist/math-spacing.d.ts +13 -0
  88. package/dist/math-spacing.js +87 -0
  89. package/dist/matrix-range.d.ts +40 -0
  90. package/dist/matrix-range.js +242 -0
  91. package/dist/matrix.d.ts +0 -1
  92. package/dist/matrix.js +0 -1
  93. package/dist/model.d.ts +4 -1
  94. package/dist/model.js +49 -5
  95. package/dist/outputs.d.ts +0 -1
  96. package/dist/outputs.js +0 -1
  97. package/dist/preferences.d.ts +24 -0
  98. package/dist/preferences.js +66 -0
  99. package/dist/presentation-controls.d.ts +10 -0
  100. package/dist/presentation-controls.js +10 -0
  101. package/dist/presentation.d.ts +13 -0
  102. package/dist/presentation.js +86 -0
  103. package/dist/quick-panel.d.ts +2 -0
  104. package/dist/quick-panel.js +17 -0
  105. package/dist/range.d.ts +2 -1
  106. package/dist/range.js +11 -1
  107. package/dist/react.d.ts +0 -1
  108. package/dist/react.js +0 -1
  109. package/dist/root-transform.d.ts +19 -0
  110. package/dist/root-transform.js +69 -0
  111. package/dist/session.d.ts +31 -2
  112. package/dist/session.js +108 -7
  113. package/dist/solid.d.ts +0 -1
  114. package/dist/solid.js +0 -1
  115. package/dist/suggestions.d.ts +13 -1
  116. package/dist/suggestions.js +153 -12
  117. package/dist/svelte.d.ts +0 -1
  118. package/dist/svelte.js +0 -1
  119. package/dist/symbol-browser.d.ts +0 -1
  120. package/dist/symbol-browser.js +0 -1
  121. package/dist/symbols.d.ts +0 -1
  122. package/dist/symbols.js +0 -1
  123. package/dist/templates.d.ts +0 -1
  124. package/dist/templates.js +0 -1
  125. package/dist/tokens.d.ts +0 -1
  126. package/dist/tokens.js +0 -1
  127. package/dist/vertical-navigation.d.ts +15 -0
  128. package/dist/vertical-navigation.js +145 -0
  129. package/dist/vue.d.ts +0 -1
  130. package/dist/vue.js +0 -1
  131. package/dist/web-component.d.ts +0 -1
  132. package/dist/web-component.js +9 -2
  133. package/package.json +11 -3
  134. package/src/fonts/KaTeX_Math-Italic.woff2 +0 -0
  135. package/src/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  136. package/src/fonts/README.md +18 -0
  137. package/src/shapes/README.md +21 -0
  138. package/src/shapes/parenthesis-bottom.svg +1 -0
  139. package/src/shapes/parenthesis-top.svg +1 -0
  140. package/src/shapes/parenthesis.svg +1 -0
  141. package/src/shapes/radical.svg +1 -0
  142. package/src/style.css +949 -173
  143. package/dist/core.d.ts.map +0 -1
  144. package/dist/core.js.map +0 -1
  145. package/dist/document-codec.d.ts.map +0 -1
  146. package/dist/document-codec.js.map +0 -1
  147. package/dist/dom/elements.d.ts.map +0 -1
  148. package/dist/dom/elements.js.map +0 -1
  149. package/dist/dom/menu-position.d.ts.map +0 -1
  150. package/dist/dom/menu-position.js.map +0 -1
  151. package/dist/dom/toolbar.d.ts.map +0 -1
  152. package/dist/dom/toolbar.js.map +0 -1
  153. package/dist/dom.d.ts.map +0 -1
  154. package/dist/dom.js.map +0 -1
  155. package/dist/editor-labels.d.ts.map +0 -1
  156. package/dist/editor-labels.js.map +0 -1
  157. package/dist/enter-policy.d.ts.map +0 -1
  158. package/dist/enter-policy.js.map +0 -1
  159. package/dist/fences.d.ts.map +0 -1
  160. package/dist/fences.js.map +0 -1
  161. package/dist/i18n.d.ts.map +0 -1
  162. package/dist/i18n.js.map +0 -1
  163. package/dist/index.d.ts.map +0 -1
  164. package/dist/index.js.map +0 -1
  165. package/dist/latex.d.ts.map +0 -1
  166. package/dist/latex.js.map +0 -1
  167. package/dist/lines.d.ts.map +0 -1
  168. package/dist/lines.js.map +0 -1
  169. package/dist/math-editor-toolbar.d.ts.map +0 -1
  170. package/dist/math-editor-toolbar.js.map +0 -1
  171. package/dist/math-editor.d.ts.map +0 -1
  172. package/dist/math-editor.js.map +0 -1
  173. package/dist/matrix.d.ts.map +0 -1
  174. package/dist/matrix.js.map +0 -1
  175. package/dist/model.d.ts.map +0 -1
  176. package/dist/model.js.map +0 -1
  177. package/dist/outputs.d.ts.map +0 -1
  178. package/dist/outputs.js.map +0 -1
  179. package/dist/range.d.ts.map +0 -1
  180. package/dist/range.js.map +0 -1
  181. package/dist/react.d.ts.map +0 -1
  182. package/dist/react.js.map +0 -1
  183. package/dist/session.d.ts.map +0 -1
  184. package/dist/session.js.map +0 -1
  185. package/dist/solid.d.ts.map +0 -1
  186. package/dist/solid.js.map +0 -1
  187. package/dist/suggestions.d.ts.map +0 -1
  188. package/dist/suggestions.js.map +0 -1
  189. package/dist/svelte.d.ts.map +0 -1
  190. package/dist/svelte.js.map +0 -1
  191. package/dist/symbol-browser.d.ts.map +0 -1
  192. package/dist/symbol-browser.js.map +0 -1
  193. package/dist/symbols.d.ts.map +0 -1
  194. package/dist/symbols.js.map +0 -1
  195. package/dist/templates.d.ts.map +0 -1
  196. package/dist/templates.js.map +0 -1
  197. package/dist/tokens.d.ts.map +0 -1
  198. package/dist/tokens.js.map +0 -1
  199. package/dist/vue.d.ts.map +0 -1
  200. package/dist/vue.js.map +0 -1
  201. package/dist/web-component.d.ts.map +0 -1
  202. package/dist/web-component.js.map +0 -1
package/ROADMAP.md CHANGED
@@ -2,6 +2,143 @@
2
2
 
3
3
  This roadmap describes priorities, not release promises. The current package is an independent editing prototype. Production integration requires the reliability work below even if additional notation is implemented first.
4
4
 
5
+
6
+
7
+ ## Current focus: continuous editing — workspace, 2026-09-10
8
+
9
+ The rendering pass is now the maintenance baseline. Further contour refinement
10
+ is deferred; keep existing checks when notation or layout changes.
11
+
12
+ EDIT-019 now runs through keyboard input, range wrapping, radical conversion,
13
+ matrix input, five-step Undo/Redo, empty-root deletion and restoration, then a
14
+ second typing/history chain without resetting the editor. React standalone block
15
+ plus Quill/Tiptap/ProseMirror/Lexical/TinyMCE/CKEditor/Slate in-place block/inline and
16
+ Editor.js/Gutenberg block pass (17 targets, 499 checkpoints). Host checks verify unchanged draft data,
17
+ Save, reload/Restore, re-edit and Cancel. One-step host Undo/Redo passes where
18
+ configured; the Editor.js demo has no host history integration. Inline also
19
+ checks Enter commit without new paragraphs, right-boundary exit and prose
20
+ continuation at the correct host position.
21
+
22
+ Run `pnpm --filter @barocss/math-editor test:editing`. Timestamped reports include
23
+ checkpoints, browser scope, fixture copy and source fingerprints. The Tiptap sample now separates document Restore from subsequent typing in host history;
24
+ TinyMCE now keeps empty formulas visible with a localized placeholder. Its
25
+ block/inline checks use an inline TinyMCE host; classic iframe mode is separate.
26
+ All nine integration demos now pass this chain. Gutenberg uses the standalone
27
+ provider demo; WordPress admin and other host configurations remain separate.
28
+ Next: range clipboard and populated/grid deletion sequences. Real OS IME
29
+ and clipboard remain deferred; this is not a release-wide certification.
30
+
31
+
32
+ ## Named-function and fraction spacing — workspace, 2026-09-10
33
+
34
+ Named functions and fractions now share horizontal spacing with adjacent text.
35
+ Repeated functions, parentheses after functions, products of functions and
36
+ repeated fractions have paired editor/KaTeX comparisons. Named-function thin
37
+ spacing remains in first and nested exponents. Fixed function glyph padding and
38
+ fraction outer margins no longer accumulate across these expressions.
39
+
40
+ Next: the remaining wrapper atom classes, longer mixed expressions, explicit
41
+ spacing commands, and full painted-bound comparisons. Passing selected anchors
42
+ does not imply whole-expression pixel equality.
43
+
44
+
45
+ ## Contextual operator layout — workspace, 2026-09-10
46
+
47
+ The shared model-to-presentation pass now distinguishes display, text, script and
48
+ scriptscript operator contexts. React and DOM use it for small glyphs, nested
49
+ bound sizes and automatic side limits. Explicit limits remain supported.
50
+
51
+ New comparisons cover numerator/denominator operators, one/two levels of
52
+ superscripts, an operator inside another bound, inline/text fractions and an
53
+ explicit stacked inline integral. Full ink alignment, all multi-operator mixtures
54
+ and narrow-host/cross-browser checks remain separate work.
55
+
56
+ ## Radical and parenthesis outlines — workspace, 2026-09-10
57
+
58
+ Root strokes and short/tall parenthesis contours now use KaTeX-derived SVG masks.
59
+ Tall parentheses retain bounded end caps and extend the straight middle. The
60
+ package includes these assets with their provenance and existing KaTeX MIT notice.
61
+ This removes the old radical polygon without adding a KaTeX runtime dependency.
62
+
63
+ Full KaTeX size-variant selection, vertical brace silhouettes, operators inside
64
+ scripts and cross-browser geometry remain separate work. The renderer continues
65
+ to reserve its existing editing boxes and caret hit areas.
66
+
67
+ ## LaTeX compatibility and nested-root layout — workspace, 2026-09-10
68
+
69
+ - Fixed math-mode literal caret/tilde export while retaining text-run JSON semantics.
70
+ - Protected complex optional root indices during export; all 55 structure kinds
71
+ now have KaTeX render and JSON round-trip regression checks in that slot.
72
+ - Added clearance between nested radical rules and a browser gap measurement.
73
+ - Still open: radical hook outlines, fence ink geometry, operators inside scripts,
74
+ explicit style combinations, broader interaction sequences and other browsers.
75
+
76
+ These are workspace changes. Browser evidence remains in the source-only rendering
77
+ ledger; a metric PASS does not mean complete visual parity or release certification.
78
+
79
+ ## Editing utilities — workspace, 2026-09-09
80
+
81
+ Included in 0.4.0:
82
+
83
+ - Native lexical-token input now matches rich React colors and offsets. Token-boundary navigation/deletion preserves surrounding text; composition retains the input until commit.
84
+ - Explicit LaTeX insertion at the caret or range, exposed as `pasteLatex`, More tools → Paste as LaTeX, and Alt+Shift+V. Parsing/placement failures preserve the document. Ordinary paste stays literal.
85
+ - Recent symbols/templates and favorites, with a shareable validated preference store. Preferences are separate from formula history; persistence belongs to the host.
86
+ - Contextual fence, fraction/binomial size, and operator-bound placement controls. Existing contents, IDs and caret are preserved with one-step Undo.
87
+
88
+ See [API and usage](API-SESSION.md#editing-utilities--workspace). No new LaTeX grammar or automatic algebraic transformation is added. Persistent vertical columns, broader browsers, performance budgets and accessibility remain open.
89
+
90
+ ## Scoped style customization — workspace, 2026-09-09
91
+
92
+ Implemented: inherited CSS variables for UI/token colors, slot backgrounds,
93
+ controls, toolbar density and floating menus. Both renderers retain per-editor
94
+ palette values on suggestion/selection portals and follow live ancestor theme
95
+ switches. Shared plugin panels/actions use the same palette; persisted host
96
+ formula sizing remains document data. The site includes default/dark/monochrome,
97
+ base-size and compact-spacing controls. See [Styling & themes](STYLING.md).
98
+
99
+
100
+ ## Selection-to-caret keyboard behavior — workspace, 2026-09-09
101
+
102
+ A visible wrapping menu owns Up/Down in both renderers. The selected formula
103
+ stays selected while the highlighted suggestion changes; Enter applies it.
104
+ Left/Right returns to the ordered start/end of the selection. Shift+arrows
105
+ continues to adjust the range. Alt+Up/Down remains supported. When the wrapping
106
+ menu is closed, plain arrows restore the caret without changing the formula.
107
+
108
+ ## Matrix rectangles and transpose — workspace, 2026-09-09
109
+
110
+ Both editing surfaces now distinguish cross-cell rectangles from text selection
111
+ inside a cell. Drag between cells or Shift+click to select a rectangle. Select
112
+ cells starts keyboard selection; Shift+arrows changes the focus corner. Copy/cut
113
+ preserves nested formula trees; paste accepts matching rectangles or grows from
114
+ a single cell within 20 × 20. One copied cell can fill a rectangle. Ragged TSV,
115
+ invalid clipboard data, mismatched shapes and oversized results are rejected
116
+ without changing the formula. Delete clears cells; Enter/Escape resumes editing.
117
+
118
+ Transpose matrix moves the entire matrix, preserving cell IDs, nested caret,
119
+ delimiters and one-step Undo. No numerical evaluation or new LaTeX grammar is
120
+ introduced. See [the API contract](API-SESSION.md#matrix-cell-selections) for payloads
121
+ and paste rules. Real OS clipboard and touch selection remain separate checks.
122
+
123
+ ## Native toolbar and selection parity — workspace, 2026-09-09
124
+
125
+ Included in 0.4.0: More tools exposes searchable All symbols,
126
+ templates, matrix/identity presets and symbol shortcuts. The active grid toolbar
127
+ offers matrix row/column operations and delimiter changes, with row operations for
128
+ aligned/cases. External toolbar handles now expose `setDisabled` alongside
129
+ `setSession` and `destroy` for composition and draft lifecycle coordination.
130
+
131
+ Native selection highlights now preserve partial text endpoints. A drag can begin
132
+ inside the active input and continue across structures as a model range. Shift+arrow
133
+ model ranges are already implemented; vertical range extension uses logical line
134
+ offsets. The new work does not add LaTeX syntax.
135
+
136
+ Remaining work includes persistent vertical preferred
137
+ columns, and wider browser/accessibility coverage. English/Korean remain the complete
138
+ bundled locale packs; additional complete packs remain open. Native OS IME validation
139
+ is still deferred at the user's request. See [renderer parity](ADAPTERS.md#current-renderer-parity)
140
+ and [validation](VALIDATION.md) for the current boundary and evidence.
141
+
5
142
  ## Remaining LaTeX priorities: workspace review, 2026-09-08
6
143
 
7
144
  These are proposals, not accepted import syntax. Complete each feature through the model, parser, exporter, suggestions and both editing surfaces before calling it supported.
@@ -53,7 +190,7 @@ Norms are implemented in the workspace. Triple and contour integrals are impleme
53
190
  | Host Enter/commit/cancel contract and modal suggestions | Implemented | Product selection/undo integration and real IME/browser matrix |
54
191
  | Layout lab: inline, next-block flow, popup draft/cancel/apply | Implemented | Integrate the actual Note node view first |
55
192
  | Note/Word/Site/Slide persistence adapters | Note workspace popup trial implemented | Validate other browsers and real host caret/undo workflows; Word/Site/Slide adapters and OMML conversion remain open |
56
- | Downloadable SVG/PNG output | Not implemented | Dedicated renderer/export contract, fonts and scaling |
193
+ | Reusable library SVG/PNG output | Not implemented | Dedicated renderer/export contract, fonts and scaling; the website already provides sized PNG download/copy from its preview |
57
194
 
58
195
  See [Embedding](EMBEDDING.md) for existing Note/Word model boundaries. Note has a popup integration trial. The user confirmed that Note inline editing is resolved. This release focuses on math-editor; product-specific validation is tracked separately.
59
196
 
@@ -62,15 +199,15 @@ See [Embedding](EMBEDDING.md) for existing Note/Word model boundaries. Note has
62
199
  | Work | Status | Remaining gate |
63
200
  |---|---|---|
64
201
  | Framework-free session / public commands | Implemented | Host-wide undo integration, performance and document validation |
65
- | Native DOM surface / pure JS entry | Integration preview | Rich React selection, catalog and composition parity |
202
+ | Native DOM surface / pure JS entry | Integration preview | Native discovery/context tools and precise pointer ranges implemented in workspace; token-level input/color is implemented; wider composition coverage remains |
66
203
  | Web Component / Vue / Svelte / Solid / React native wrappers | Implemented | Wider framework-version matrix and SSR/hydration strategy |
67
- | Optional and separately mounted toolbar | Implemented in native surface | Context-sensitive professional toolbar and symbol browser |
204
+ | Optional and separately mounted toolbar | Implemented in native surface | Symbol browser, templates/presets and grid context controls added in workspace; broader context grouping and user customization remain |
68
205
  | Inline single-top-level-line policy | Implemented in native surface | Real product prose integration, baseline/keyboard exit UX |
69
206
  | External locale dictionary / aliases / fallback / direction | Implemented | Complete extra language packs and RTL audit |
70
207
  | ESM subpath distribution / optional framework peers | Implemented | Release approval, registry publication, bundle budgets |
71
208
  | Rich React renderer remains available | Preserved | Move main export only after measured parity |
72
209
 
73
- Next integration work: finish the native symbol panel and precise range highlights; unify token editing/composition behavior; add keyboard structural selection. Measure load/typing cost in host products; Note inline editing is already resolved. Do not add new notation to both renderers independently before shared behavior is stable. See [adapter parity and API](ADAPTERS.md).
210
+ Next integration work: verify the new active-input parity across more browsers, extend browser/accessibility coverage, and measure load/typing cost in host products. The native symbol panel, precise range highlights, active-input cross-structure drag and Shift+arrow model selection are implemented in the workspace. Note inline editing is already resolved. Do not add new notation to both renderers independently before shared behavior is stable. See [adapter parity and API](ADAPTERS.md).
74
211
 
75
212
  ## Delivered baseline
76
213
 
@@ -86,8 +223,8 @@ Next integration work: finish the native symbol panel and precise range highligh
86
223
  | Work | Acceptance criteria |
87
224
  |---|---|
88
225
  | Real input-method matrix | macOS and Windows Korean composition, cancellation, blur and locale change preserve text and commit once; currently deferred by user request |
89
- | Keyboard model ranges | Shift+arrows extend/collapse across tokens and structures; typing replaces selection; undo restores a predictable caret |
90
- | Structural navigation | Predictable up/down movement in fractions, roots and scripts; direction and selection affinity covered by tests |
226
+ | Keyboard model ranges — implemented | Shift+arrows extend/collapse across text and structures; typing replaces selection; wider browser/IME coverage and pixel-column vertical extension remain |
227
+ | Structural navigation — implemented in workspace | Shared React/native Up/Down movement for fractions, scripts, indexed roots and operator slots; nearest rendered horizontal caret, inner-structure precedence and matrix columns covered by model tests. Persistent preferred-column state and wider browser coverage remain open |
91
228
  | Saved-document validation | Shape/duplicate-ID validation is implemented; version migration and host recovery remain |
92
229
  | Host session adapter | Enter/exit and save work in one target product; a single coherent undo path across host and formula |
93
230
  | Browser/accessibility coverage | Safari, Firefox and Windows Chromium; screen-reader names and suggestion announcements; touch selection and narrow layouts |
@@ -114,8 +251,8 @@ See the [LaTeX editing guide](LATEX-GUIDE.md) for supported examples and the nex
114
251
  | Feature | Acceptance criteria |
115
252
  |---|---|
116
253
  | Subset LaTeX import — implemented in workspace | Extend the documented grammar incrementally; preserve unsupported input without changing the existing formula |
117
- | Rectangular cell selection | Row/column geometry, copy/paste shape rules, partial destination handling and undo |
118
- | Matrix transformations | Transpose and delimiter changes preserve all cell contents and caret; no implicit numeric computation |
254
+ | Rectangular cell selection — implemented in workspace | Cross-cell drag, Shift+click, keyboard expansion, shape-checked copy/paste, clear and one-step Undo; external clipboard/touch validation remains |
255
+ | Matrix transformations — implemented in workspace | Delimiter changes and full-matrix transpose preserve cell contents, nested caret and Undo; selected-submatrix transforms and numeric computation are not included |
119
256
  | Drag matrix size picker | Accessible keyboard equivalent, touch behavior, 1–20 bounds and one-step insertion |
120
257
  | Multi-alignment and multiline wrapping | Explicit grouping semantics; do not flatten lines or move relation signs unexpectedly |
121
258
  | External clipboard compatibility | Verify custom-format survival and LaTeX fallback across target browsers and applications |
@@ -164,7 +301,7 @@ the npm version and deployed runtime artifact are unchanged.
164
301
  - [x] Vector, hat and overline accents with editable bodies and selection wrapping.
165
302
  - [x] Additional delimiters, mixed/invisible ends and overset/underset annotations.
166
303
  - [x] Over/under brace annotations with editable annotation/body slots.
167
- - [x] Explicit side-placement import/export (`\nolimits`); a dedicated toolbar switch remains open.
304
+ - [x] Explicit side-placement import/export (`\nolimits`) and contextual toolbar placement controls.
168
305
 
169
306
  - [x] Workspace: `limit` condition/body model, LaTeX import/export, localized suggestions and React/native editing.
170
307
  - [x] Semantic function color for named/custom operators and the limit glyph.
@@ -188,10 +325,82 @@ Seven rich React/KaTeX comparisons are complete; production fixes are pending. P
188
325
 
189
326
  Spacing follow-up implemented: shared grid fence shapes, tighter grid/fraction/script/accent layouts, bounded nested fraction sizes, and a smaller boundary focus target. Chromium import/edit checks pass; the measured first-boundary expansion fell from 20px to 8px. Full recursive math-style sizing, additional browser/accessibility checks and eliminating all cursor-induced movement remain open.
190
327
 
191
- Workspace toolbar overflow is implemented: configurable structure-button limits and More/Fewer controls, rich React/native filtering, and always-visible history actions. Context-sensitive grouping and user-persisted toolbar customization remain future work.
328
+ Workspace toolbar overflow is implemented: configurable structure-button limits and More/Fewer controls, rich React/native filtering, and always-visible history actions. Native symbol/template discovery and grid context controls are also implemented as described above. Broader context-sensitive grouping and user-persisted toolbar customization remain future work.
192
329
 
193
330
  Locale regression: misplaced alphabet/arrow messages moved inside `messages`; pack-shape/build validation and en/ko browser coverage added.
194
331
 
195
332
  ### 0.2.1
196
333
 
197
- Keyboard model selection with Shift+arrows and `{` cases discovery are implemented. The dedicated demo adds sized PNG download/copy and fit preview; image generation remains site-only. Pixel-column vertical selection and rectangular grid ranges remain future work.
334
+ Keyboard model selection with Shift+arrows and `{` cases discovery are implemented. The dedicated demo adds sized PNG download/copy and fit preview; image generation remains site-only. Pixel-column vertical selection remains future work. Matrix cell rectangles and transpose are implemented in the workspace; aligned/cases retain structural ranges.
335
+
336
+ ## Tiptap / ProseMirror integration preview (2026-09-08)
337
+
338
+ A separate private development package, `packages/math-editor-integrations`, now
339
+ provides Tiptap 3 and ProseMirror 1 math nodes using the existing DOM editor. It
340
+ supports direct editing in the text flow, optional panel editing, JSON/LaTeX storage,
341
+ HTML clipboard round trips, Apply/Cancel, and host Undo. The sample runs from
342
+ `apps/math-integrations` at port 5185.
343
+
344
+ As of 2026-09-09, the integration preview covers nine hosts in one sample page.
345
+ Site staging includes `/integrations/` and rendered integration documentation.
346
+ The shared source package stays private; nine host-specific npm packages have
347
+ separate Changesets and artifact preparation. The release set is core `0.4.0` and plugins `0.1.0`. The
348
+ core and all nine plugins now use MIT, with a LICENSE file in each package.
349
+ Plugin publication remains pending. See the [integration roadmap](../math-editor-integrations/ROADMAP.md),
350
+ [validation record](../math-editor-integrations/VALIDATION.md), and
351
+ [release guide](../math-editor-integrations/docs/RELEASING.md).
352
+
353
+ ## Radical conversions — workspace, 2026-09-09
354
+
355
+ Implemented contextual square-root/indexed-root conversion suggestions in React
356
+ and native DOM. The radicand tree and IDs are retained; conversion adds a selected
357
+ index `2`. Square-root conversion accepts only an empty index or `2`. Changes
358
+ participate in normal Undo/Redo and use English/Korean locale messages. Other
359
+ structure conversions are not included in this step.
360
+
361
+ ## Editing scenario register — workspace, 2026-09-09
362
+
363
+ [Editing scenarios](EDITING-SCENARIOS.md) defines EDIT-001 through EDIT-020,
364
+ expected behavior, test mappings, environment scope and a run-record template.
365
+ It distinguishes historical evidence from current verification. The EDIT-019
366
+ sustained chain and source-fingerprinted runner were added on 2026-09-10. Other
367
+ scenario assertions and CI/release enforcement remain separate work.
368
+
369
+ ## Rendering regression baseline — workspace, 2026-09-09
370
+
371
+ [Rendering checks](RENDERING-TESTS.md) now defines executable size and position
372
+ comparisons for fractional exponents/subscripts and a tall indexed-root base.
373
+ React and native DOM share compact script-fraction rules. Empty non-grid slots
374
+ now remove their wrapper with Delete or Backspace and retain other content.
375
+ Next: paired scripts, multi-line collision, explicit style overrides and other
376
+ notation families. Current checks do not implement an automated CI release gate.
377
+
378
+ ## Contextual structure footer — workspace, 2026-09-09
379
+
380
+ Added query-independent radical actions, index editing, disabled explanations,
381
+ F6/Escape access and embedding opt-out. EDIT-021 through EDIT-028 extend the
382
+ scenario register with discovery, target, focus, locale, composition guard and
383
+ lifecycle cases. Future work: context actions for additional structure families,
384
+ explicit Tab-order assertions and broader framework/device coverage.
385
+
386
+ ## Inline-first fence transformations — workspace, 2026-09-09
387
+
388
+ Implemented eight fence presentations through the existing suggestion list,
389
+ Alt+Down discovery/reopening, nearest-wrapper targeting, retained caret/content
390
+ and one-step conversion history. Optional footer controls support F6 and horizontal
391
+ navigation. EDIT-029 through EDIT-032 add keyboard, cancellation, iframe, locale
392
+ and no-toolbar coverage. Additional transformation families and the proposed
393
+ optional radial menu remain future work; the list layout remains the default.
394
+
395
+ ## Horizontal text spacing — workspace, 2026-09-10
396
+
397
+ Replaced fixed inter-token gaps with shared binary/relation/punctuation spacing,
398
+ including unary-sign context and compact script rows. Removed per-token padding
399
+ from mathematical glyph measurement. Empty expression inputs remain available;
400
+ inactive structural caret boundaries are narrower. VIS-066 through VIS-073 add
401
+ addition, equality, unary signs, parentheses, named functions, fractions,
402
+ punctuation and script comparisons at 22 px and 36 px in React and native DOM.
403
+
404
+ Next: longer expressions, complete atom classification across structure wrappers,
405
+ named-function boundaries, explicit spacing commands and browser font differences.
406
+ The source-only rendering ledger records measured limits and remaining work.
package/STYLING.md ADDED
@@ -0,0 +1,157 @@
1
+ # Styling and themes
2
+
3
+ The editor exposes CSS custom properties for presentation. Set them on a wrapper around an editor, or on a shared ancestor for multiple editors. This works with React, native JavaScript, the light-DOM Web Component, Vue, Svelte and Solid. No theme provider or additional runtime is required. Styling does not change the JSON model, exported LaTeX or undo history.
4
+
5
+ Import the package stylesheet once, then add your application stylesheet:
6
+
7
+ ```js
8
+ import '@barocss/math-editor/style.css';
9
+ import './math-theme.css';
10
+ ```
11
+
12
+ ```css
13
+ .product-math {
14
+ --me-font-size: 18px;
15
+ --me-accent: #6b4bb3;
16
+ --me-variable: #385ea1;
17
+ --me-number: #a65316;
18
+ --me-symbol: #8056ad;
19
+ --me-function: #147d77;
20
+ --me-surface-padding: 24px 16px;
21
+ --me-surface-min-height: 100px;
22
+ --me-toolbar-padding: 6px;
23
+ --me-control-radius: 4px;
24
+ }
25
+ ```
26
+
27
+ ```tsx
28
+ // Rich React editor. Native framework adapters use the same wrapper pattern.
29
+ <div className="product-math">
30
+ <MathEditor onChange={(document, latex) => save(document, latex)} />
31
+ </div>
32
+ ```
33
+
34
+ ```js
35
+ // Native JavaScript. The wrapper may already carry application theme variables.
36
+ const host = document.querySelector('.product-math');
37
+ const editor = mountMathEditor(host, { onChange: save });
38
+ host.style.setProperty('--me-font-size', '20px');
39
+ // On unmount:
40
+ editor.destroy();
41
+ ```
42
+
43
+ ```html
44
+ <!-- Register with defineMathEditor() first. This component uses light DOM. -->
45
+ <barocss-math-editor class="product-math" locale="en"></barocss-math-editor>
46
+ ```
47
+
48
+ Try the website's **Theme**, **Math size** and **Compact spacing** controls in the [playground](https://math-editor.barocss.com/#playground). These are application examples, not required library presets.
49
+
50
+ ## Public CSS variables
51
+
52
+ Unset variables preserve the existing default appearance. Some controls intentionally have slightly different default shades/radii; a supplied token unifies them. Set lengths such as the base font size in `px` or `rem` when the editor and its portal have different parents.
53
+
54
+ | Variable | Controls | Default behavior |
55
+ | --- | --- | --- |
56
+ | `--me-font-size` | Base formula text and relative script sizes | `22px` in standalone editors |
57
+ | `--me-ui-font-family` | Toolbars, menus and helper text | `system-ui, sans-serif` |
58
+ | `--me-text` | UI text and neutral math glyphs | Dark green/gray |
59
+ | `--me-muted` | Help text, line numbers, menu details | Muted gray/green |
60
+ | `--me-accent` | Buttons, active borders, matrix selection | Green |
61
+ | `--me-line` | Toolbar separators and control/menu borders | Pale gray/green |
62
+ | `--me-background` | Editor root | Transparent |
63
+ | `--me-panel-background` | Suggestion menus, symbol cards, inputs/selects in toolbars | White |
64
+ | `--me-toolbar-background` | Main toolbar | Transparent |
65
+ | `--me-subtle-background` | Symbol browser and grid tools | Pale neutral |
66
+ | `--me-hover-background` | Toolbar hover | Pale green |
67
+ | `--me-active-background` | Selected suggestion and active controls | Pale green |
68
+ | `--me-variable` | Variable tokens, including focused inputs | Blue |
69
+ | `--me-number` | Numeric tokens (`constant` token kind) | Brown/orange |
70
+ | `--me-symbol` | Symbol tokens | Purple |
71
+ | `--me-function` | Function/operator names and their legend | Teal |
72
+ | `--me-input-background` | Editing slot background | Context-specific slot tint |
73
+ | `--me-input-focus-background` | Focused/hovered slot background | Stronger context-specific tint |
74
+ | `--me-selection-background` | Text and structural range selection | Blue |
75
+ | `--me-selection-color` | Native selected input text | White |
76
+ | `--me-focus-color` | Keyboard focus indicator | Blue |
77
+ | `--me-radius` | Suggestion panel corners | `10px` |
78
+ | `--me-control-radius` | Buttons and toolbar fields | `4px`–`7px` depending on control |
79
+ | `--me-surface-padding` | Block editing area padding | `48px 32px` |
80
+ | `--me-inline-padding` | Native inline area padding | `2px 4px`; plugin compact fields `0 2px` |
81
+ | `--me-surface-min-height` | Block area minimum height | Standalone `190px`; plugin panels `60px` |
82
+ | `--me-toolbar-padding` | Main toolbar padding | `12px` |
83
+ | `--me-toolbar-gap` | Gap between main toolbar controls | `4px` |
84
+ | `--me-line-gap` | Gap between top-level equation rows | `18px` |
85
+ | `--me-menu-shadow` | Floating menu shadow | Soft dark shadow |
86
+ | `--me-menu-z-index` | Suggestion menu stacking level | `1000` |
87
+
88
+ Inline mode retains its content-driven minimum height. Explicit LaTeX sizing commands and specialty mathematical fonts retain their own metrics; the base-size token is not an image scaling API. Formula export/KaTeX rendering is owned by the consumer and does not inherit semantic editing colors automatically.
89
+
90
+ ## Dark and monochrome themes
91
+
92
+ Define a theme in your own stylesheet. Supply foregrounds and backgrounds together so active inputs, selection and menus remain readable.
93
+
94
+ ```css
95
+ .product-math[data-theme='dark'] {
96
+ color-scheme: dark;
97
+ --me-background: #18232c;
98
+ --me-text: #e5edf3;
99
+ --me-muted: #a4b5c2;
100
+ --me-line: #435565;
101
+ --me-panel-background: #202f3b;
102
+ --me-subtle-background: #243441;
103
+ --me-hover-background: #334857;
104
+ --me-active-background: #354e61;
105
+ --me-accent: #83d5bc;
106
+ --me-variable: #9ac7ff;
107
+ --me-number: #ffc28b;
108
+ --me-symbol: #d0b7ff;
109
+ --me-function: #7bddd5;
110
+ --me-input-background: #223444;
111
+ --me-input-focus-background: #334d63;
112
+ --me-selection-background: #436483;
113
+ --me-selection-color: #fff;
114
+ --me-focus-color: #9ac7ff;
115
+ }
116
+
117
+ .product-math[data-theme='mono'] {
118
+ --me-variable: #303740;
119
+ --me-number: #303740;
120
+ --me-symbol: #303740;
121
+ --me-function: #303740;
122
+ --me-input-background: #f1f2f4;
123
+ --me-input-focus-background: #e0e4e9;
124
+ }
125
+ ```
126
+
127
+ Change `data-theme`, an ancestor class, or inline custom properties without remounting. The semantic model remains intact even when all token colors match.
128
+
129
+ ## Suggestions, separate toolbars and iframes
130
+
131
+ Suggestion and selection-wrapping menus usually mount under `document.body` or the nearest dialog. Both renderers copy the owning editor's resolved presentation tokens to these menus. Two editors can use different themes without applying a global `.me-suggestion-panel` rule. Ancestor attribute changes, window resizing and preferred color-scheme changes refresh the menu theme. Dynamic stylesheet replacement without those events is picked up on the next menu render/open; prefer changing a scoped class or custom property.
132
+
133
+ Host integrations keep menus inside the math node's event boundary. They use the same glyphs, labels and details as the main React editor. Pointer movement highlights candidates; a stationary pointer does not replace keyboard choices when the list scrolls or redraws. Menu text does not inherit paragraph alignment or letter spacing. Ordinary scrolling text areas do not reduce the fixed menu's height; dialogs and clipping containers that establish a local containing block still constrain it. In a short dialog, the native menu hides its guidance before reducing the space for selectable rows.
134
+
135
+ An independently mounted toolbar inherits from **its own host**. Put it under the same themed ancestor or apply the same theme class to the editor and toolbar containers. A toolbar shared between different themes does not automatically switch to the selected editor's theme.
136
+
137
+ CSS does not cross document boundaries. For a TinyMCE classic iframe, load both core and plugin stylesheets using `content_css` and load your theme CSS into that iframe too. Apply the theme to its body or a wrapper within that document. Style a shared toolbar outside the iframe separately. The menu bridge uses the editor's owner document; it does not copy parent-page CSS into an iframe. See [TinyMCE integration](../math-editor-integrations/docs/TINYMCE.md).
138
+
139
+ ## Editor plugin chrome
140
+
141
+ Import the chosen plugin's `style.css` alongside the core CSS. Shared plugin panels, Apply/Cancel buttons, size controls and hover states use the same `--me-*` palette. Additional host chrome variables are:
142
+
143
+ | Variable | Controls |
144
+ | --- | --- |
145
+ | `--bme-inline-background` | Background behind an in-place math draft |
146
+ | `--bme-action-color` | Text on the primary Apply button (default white) |
147
+ | `--bme-error-color` | Draft validation messages |
148
+
149
+ Formula size in host integrations is a **document attribute**: the plugin measures surrounding prose and combines it with the formula's saved percentage. Use the plugin's `fontSize` attribute/size controls for persisted math size. The internal `--bme-font-size` is computed from that value; setting a standalone `--me-font-size` on a wrapper does not override persisted host sizing.
150
+
151
+ For dark plugin fields, also set `--bme-inline-background: #223444` and choose a readable `--bme-action-color` for your accent. Themes style editor UI, not the surrounding host editor's own menu bar or rendered formula HTML.
152
+
153
+ ## Custom toolbar and layout
154
+
155
+ Use `toolbar: false` for editor-only embedding, a list of structure kinds to limit commands, or `toolbarMaxItems` for overflow. A completely custom toolbar can call `session.execute(...)`. See [embedding](EMBEDDING.md) and the [session API](API-SESSION.md).
156
+
157
+ Treat internal `.me-*` and `.bme-*` layout selectors as implementation details. Prefer these variables over overriding fractions, scripts, radical paths, integral glyphs, or input positioning: those metrics are coordinated for editing and KaTeX comparison. Theme changes should be checked with keyboard focus, selections, suggestions and tall nested formulas, as well as at rest.
package/SUPPORT.md CHANGED
@@ -46,7 +46,7 @@ See the [LaTeX editing guide](LATEX-GUIDE.md) for input examples and prioritized
46
46
  | Product | Lower limit, upper limit, body | `\prod_{i=1}^{n}x` | No evaluation |
47
47
  | Triple / contour integrals | Three editable slots; side bounds or explicit limits | `\iiint`, `\oint` | No computation; `\nolimits` supported in workspace |
48
48
  | Integral | Lower limit, upper limit, integrand | `\int_{a}^{b}x` | Differential entered as text; no integration engine |
49
- | Matrices / vectors | Editable nested cells; row/column changes | `matrix`, `pmatrix`, `bmatrix`, `Bmatrix`, `vmatrix`, `Vmatrix` | 1–20 rows and columns; no rectangular cell clipboard |
49
+ | Matrices / vectors | Editable nested cells; row/column changes | `matrix`, `pmatrix`, `bmatrix`, `Bmatrix`, `vmatrix`, `Vmatrix` | 1–20 rows and columns; workspace rectangular clipboard and full-matrix transpose |
50
50
  | Aligned equations | Two columns, left side right-aligned and right side left-aligned | `aligned` | 1–20 rows, one alignment point; type the relation explicitly |
51
51
  | Cases | Expression and condition columns, left brace | `cases` | 1–20 rows; conditions accept math and literal text nodes |
52
52
  | Multiple document lines | Split/join top-level rows | `gathered` | No wrapping several document lines into one structure |
@@ -56,17 +56,19 @@ See the [LaTeX editing guide](LATEX-GUIDE.md) for input examples and prioritized
56
56
  | Area | Supported | Remaining boundary |
57
57
  |---|---|---|
58
58
  | Languages | Korean and English UI, demo, accessible names, hints and suggestions | Custom host labels require host translation |
59
+ | Recent / favorites | Shared UI preference store for known symbols/templates, up to 12 recent and 100 favorites | Optional host persistence; no effect on formula JSON or Undo |
60
+ | Presentation changes | Fence type, fraction/binomial size and operator limits from the contextual toolbar | Existing notation only; no arbitrary fonts or dimensions |
59
61
  | Discovery | All-symbol grid with English/Korean/glyph/LaTeX search, click to insert | Scroll through the complete 117-symbol catalog |
60
62
  | Line numbers | UI gutter for multiple top-level rows, optional prop | Excluded from math output and clipboard |
61
63
  | Aliases | English and Korean in both locales; longest symbolic trigger first | Substring matching with exact matches first; no natural-language parsing |
62
64
  | Native input | Active token only; composition draft held stable | Real OS IME validation deferred |
63
65
  | Roles | Variables, numeric literals, symbols, spaces | Lexical colors are not semantic declarations |
64
- | Selection | Partial text, drag across tokens/structures, whole document in preview | No keyboard Shift-arrow model expansion or rectangular cell selection |
66
+ | Selection | Partial text, drag across tokens/structures, whole document in preview | Shift+arrow model ranges and workspace rectangular cell selection; touch/OS clipboard validation remains |
65
67
  | Wrapping | Fraction, root, power, subscript, parentheses, brackets, absolute value | One balanced row; cross-slot range expands to common structure |
66
- | Clipboard | Structured internal fragment plus LaTeX text; cut/paste replacement | External LaTeX is literal text; nested multiline paste rejected |
67
- | History | Undo/redo of model changes and caret, up to 100 prior states | No shared host undo adapter yet |
68
+ | Clipboard | Structured internal fragment plus LaTeX text; cut/paste replacement | Ordinary paste is literal; explicit LaTeX insertion parses at the caret/range; nested multiline paste rejected |
69
+ | History | Undo/redo of model changes and caret, up to 100 prior states | Shared host adapters commit one formula edit; per-host history support varies |
68
70
  | Deletion | Text boundaries, line join, structure unwrap, two-step filled-grid deletion | General structural deletion rules are still limited |
69
- | Serialization | Version-1 JSON document and change callback | No persistence service, saved-document validator or migrations |
71
+ | Serialization | Version-1 JSON document and change callback | `parseMathDocument` validates shape and IDs; persistence and future version migrations remain host work |
70
72
  | Preview | Demo-only KaTeX view | Library renders its own editable presentation |
71
73
  | Accessibility | Localized labels, combobox suggestions, keyboard slot navigation | Not a complete mathematical screen-reader implementation |
72
74
  | Computation | None | No solving, simplification, units engine or collaboration |
@@ -75,9 +77,9 @@ See the [LaTeX editing guide](LATEX-GUIDE.md) for input examples and prioritized
75
77
 
76
78
  | Template / preset | Sizes | Discovery | Behavior |
77
79
  |---|---|---|---|
78
- | Empty matrix | 2×2, 3×3, 4×4 | `matrix`, `행`, `행렬`; matrix menu | Editable empty cells |
79
- | Identity matrix | 2×2, 3×3, 4×4 | `identity`, `단위`, `단위행렬`; matrix menu | Diagonal 1, other entries 0 |
80
- | Zero matrix | 2×2, 3×3, 4×4 | `zero`, `영행렬`; template menu | All entries 0, editable |
80
+ | Empty matrix | 1–20 rows × 1–20 columns via size shortcuts; 2×2/3×3/4×4 menu presets | `matrix`, `행`, `행렬`; matrix menu | Editable empty cells |
81
+ | Identity matrix | Square sizes 1–20 via size shortcuts; 2×2/3×3/4×4 menu presets | `identity`, `단위`, `단위행렬`; matrix menu | Diagonal 1, other entries 0 |
82
+ | Zero matrix | 1–20 rows × 1–20 columns via size shortcuts; 2×2/3×3/4×4 templates | `zero`, `영행렬`; template menu | All entries 0, editable |
81
83
  | Column vector | 2×1, 3×1 | `vector`, `column`, `벡터`, `열벡터`; template menu | Empty editable column; existing generic matrix candidates may also match |
82
84
  | Quadratic formula | One expression | `quadratic`, `근의공식`; template menu | `x=(-b±√(b²−4ac))/(2a)` using fraction/root/power nodes; assumes a≠0 mathematically, does not enforce it |
83
85
  | Pythagorean theorem | One expression | `pythagorean`, `피타고라스`; template menu | `a²+b²=c²` using editable power nodes |
@@ -212,7 +214,7 @@ Catalog size: **117 symbols**.
212
214
 
213
215
  ## Renderer availability
214
216
 
215
- This formula catalog describes the shared model and the existing rich React editor. New native DOM/framework surfaces share the notation model but have a smaller interaction UI. See the [renderer parity table](ADAPTERS.md#current-renderer-parity) before choosing an adapter.
217
+ This formula catalog describes the shared model and the existing rich React editor. Native DOM/framework surfaces share the notation model, token editing, discovery and presentation utilities; host integration policies remain separate. See the [renderer parity table](ADAPTERS.md#current-renderer-parity) before choosing an adapter.
216
218
 
217
219
  ### Combined scripts (workspace)
218
220
 
@@ -253,12 +255,12 @@ Type `quad` / `qquad` (or `간격` / `큰간격`) for an explicit gap. The caret
253
255
 
254
256
  Select an expression and choose a fence or annotation in the regular suggestion menu. Fences wrap the expression and resume after it. Annotations keep the selected expression in the body and focus the empty annotation slot. Nested fractions, scripts and other editable structures are allowed in both annotation slots. Backspace after a structure removes its wrapper while preserving its content; Undo restores it.
255
257
 
256
- All structured fences scale with their contents. Short angle notation normalizes to scalable `\left\langle…\right\rangle` on export. Supported physical ends are `(`, `)`, `[`, `]`, `{`, `}`, `⟨`, `⟩`, `|` and `.`. Plain punctuation stays literal unless imported with a structural command. Double norm bars, `\big`/`\Big`, `\overbrace` and `\underbrace` remain unsupported.
258
+ All structured fences scale with their contents. Short angle notation normalizes to scalable `\left\langle…\right\rangle` on export. Supported physical ends are `(`, `)`, `[`, `]`, `{`, `}`, `⟨`, `⟩`, `|` and `.`. Plain punctuation stays literal unless imported with a structural command. Double norm bars and brace annotations are supported. Explicit `\big`/`\Big` sizing remains unsupported.
257
259
 
258
260
 
259
261
  ### Double integrals (workspace)
260
262
 
261
- `\iint_R f(x,y)` imports as `doubleIntegral` with exactly three slots: `[lower/domain, upper, body]`, matching integral navigation. Missing bounds remain editable empty slots. `\iint\limits` preserves the explicit placement directive. Export uses `\iint_{lower}^{upper}{body}`. Search `iint`, `이중적분` or `∬` to insert; Tab visits the domain, upper bound and body in order. The reported expression with `\rm dx \rm dy`, `\xi`, `\eta` and `\text{Area}` is covered by import/round-trip and browser editing fixtures. This is notation support, not numerical integration. Triple and contour integrals remain outside this addition.
263
+ `\iint_R f(x,y)` imports as `doubleIntegral` with exactly three slots: `[lower/domain, upper, body]`, matching integral navigation. Missing bounds remain editable empty slots. `\iint\limits` preserves the explicit placement directive. Export uses `\iint_{lower}^{upper}{body}`. Search `iint`, `이중적분` or `∬` to insert; Tab visits the domain, upper bound and body in order. The reported expression with `\rm dx \rm dy`, `\xi`, `\eta` and `\text{Area}` is covered by import/round-trip and browser editing fixtures. This is notation support, not numerical integration. Triple and contour integrals are also supported.
262
264
 
263
265
  Fine spacing: `\,`, `\:`, `\;`, `\!` are preserved as zero-slot structures. Positive spacing expands and negative thin spacing contracts the next boundary; these are not editable text spaces.
264
266
 
@@ -276,6 +278,16 @@ Fine spacing: `\,`, `\:`, `\;`, `\!` are preserved as zero-slot structures. Posi
276
278
 
277
279
  ## Keyboard ranges and brace discovery (0.2.1)
278
280
 
279
- Shift+Left/Right extends or shrinks the same model range used by dragging. Structures are crossed as balanced units; copied and deleted ranges use existing model normalization. Shift+Up/Down extends to an adjacent top-level document line, using a logical text offset rather than pixel-based column matching; grid-cell rectangular selection is not added. Copy, cut, wrapping, deletion and Undo use the existing range behavior. IME composition and modifier shortcuts retain their existing handling.
281
+ Shift+Left/Right extends or shrinks the same model range used by dragging. Structures are crossed as balanced units; copied and deleted ranges use existing model normalization. Shift+Up/Down extends to an adjacent top-level document line, using a logical text offset rather than pixel-based column matching; an active matrix-cell selection instead uses Shift+arrows to move its rectangular focus corner. Copy, cut, wrapping, deletion and Undo use the existing range behavior. IME composition and modifier shortcuts retain their existing handling.
282
+
283
+ After a model selection, plain Left/Up restores the caret at its document-ordered
284
+ start; Right/Down restores it at the end. The same rule applies to reverse drags
285
+ and Shift+arrow selections, without consuming another character or changing the
286
+ formula. Alt+Up/Down browses the wrapping suggestions while retaining the range;
287
+ Enter applies a candidate. Ordinary input suggestions still use Up/Down.
280
288
 
281
289
  Typing `{` offers both paired braces and cases. Paired braces remain the first candidate; choose Cases explicitly to insert its editable grid.
290
+
291
+ ## Presentation customization
292
+
293
+ CSS variables support scoped palettes, token colors, slot focus/selection, toolbar density and menu chrome in both renderers and all framework adapters. Portaled suggestions follow their owning editor. See [Styling & themes](STYLING.md); host integrations retain their own persisted formula-size attributes.