@beyondwork/docx-react-component 1.0.29 → 1.0.31

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 (383) hide show
  1. package/package.json +65 -96
  2. package/src/README.md +85 -0
  3. package/src/api/README.md +26 -0
  4. package/src/api/public-types.ts +1952 -0
  5. package/src/api/session-state.ts +62 -0
  6. package/src/compare/diff-engine.ts +623 -0
  7. package/src/compare/export-redlines.ts +280 -0
  8. package/src/compare/index.ts +25 -0
  9. package/src/compare/snapshot.ts +97 -0
  10. package/src/component-inventory.md +99 -0
  11. package/src/core/README.md +10 -0
  12. package/src/core/commands/README.md +3 -0
  13. package/{dist/chunk-TJBP2K4T.js → src/core/commands/formatting-commands.ts} +536 -196
  14. package/src/core/commands/image-commands.ts +373 -0
  15. package/src/core/commands/index.ts +1879 -0
  16. package/src/core/commands/list-commands.ts +565 -0
  17. package/src/core/commands/paragraph-layout-commands.ts +339 -0
  18. package/src/core/commands/review-commands.ts +108 -0
  19. package/{dist/core/commands/section-layout-commands.cjs → src/core/commands/section-layout-commands.ts} +340 -137
  20. package/src/core/commands/structural-helpers.ts +309 -0
  21. package/{dist/core/commands/style-commands.cjs → src/core/commands/style-commands.ts} +113 -65
  22. package/src/core/commands/table-structure-commands.ts +854 -0
  23. package/{dist/chunk-UZXBISGO.js → src/core/commands/text-commands.ts} +142 -86
  24. package/src/core/schema/README.md +3 -0
  25. package/src/core/schema/text-schema.ts +516 -0
  26. package/src/core/search/search-text.ts +357 -0
  27. package/src/core/selection/README.md +3 -0
  28. package/src/core/selection/mapping.ts +289 -0
  29. package/src/core/selection/review-anchors.ts +183 -0
  30. package/src/core/state/README.md +3 -0
  31. package/src/core/state/editor-state.ts +892 -0
  32. package/src/core/state/text-transaction.ts +869 -0
  33. package/src/formats/xlsx/io/parse-shared-strings.ts +41 -0
  34. package/src/formats/xlsx/io/parse-sheet.ts +459 -0
  35. package/src/formats/xlsx/io/parse-styles.ts +59 -0
  36. package/src/formats/xlsx/io/parse-workbook.ts +75 -0
  37. package/src/formats/xlsx/io/serialize-shared-strings.ts +72 -0
  38. package/src/formats/xlsx/io/serialize-sheet.ts +333 -0
  39. package/src/formats/xlsx/io/serialize-styles.ts +98 -0
  40. package/src/formats/xlsx/io/serialize-workbook.ts +429 -0
  41. package/src/formats/xlsx/io/xlsx-session.ts +314 -0
  42. package/src/formats/xlsx/model/cell.ts +189 -0
  43. package/src/formats/xlsx/model/sheet.ts +326 -0
  44. package/src/formats/xlsx/model/styles.ts +118 -0
  45. package/src/formats/xlsx/model/workbook.ts +453 -0
  46. package/src/formats/xlsx/runtime/cell-commands.ts +567 -0
  47. package/src/formats/xlsx/runtime/sheet-commands.ts +206 -0
  48. package/src/formats/xlsx/runtime/workbook-runtime.ts +177 -0
  49. package/src/formats/xlsx/runtime/workbook-transaction.ts +822 -0
  50. package/src/index.ts +142 -0
  51. package/src/io/README.md +10 -0
  52. package/src/io/docx-session.ts +3175 -0
  53. package/src/io/export/README.md +3 -0
  54. package/src/io/export/export-session.ts +220 -0
  55. package/src/io/export/minimal-docx.ts +115 -0
  56. package/src/io/export/reattach-preserved-parts.ts +54 -0
  57. package/src/io/export/serialize-comments.ts +947 -0
  58. package/src/io/export/serialize-footnotes.ts +394 -0
  59. package/src/io/export/serialize-headers-footers.ts +368 -0
  60. package/src/io/export/serialize-main-document.ts +1342 -0
  61. package/src/io/export/serialize-numbering.ts +218 -0
  62. package/src/io/export/serialize-revisions.ts +389 -0
  63. package/src/io/export/serialize-runtime-revisions.ts +463 -0
  64. package/src/io/export/serialize-tables.ts +174 -0
  65. package/src/io/export/split-review-boundaries.ts +356 -0
  66. package/src/io/export/split-story-blocks-for-runtime-revisions.ts +252 -0
  67. package/src/io/export/table-properties-xml.ts +318 -0
  68. package/src/io/normalize/README.md +3 -0
  69. package/src/io/normalize/normalize-text.ts +670 -0
  70. package/src/io/ooxml/README.md +3 -0
  71. package/src/io/ooxml/highlight-colors.ts +39 -0
  72. package/src/io/ooxml/numbering-sentinels.ts +44 -0
  73. package/src/io/ooxml/parse-comments.ts +852 -0
  74. package/src/io/ooxml/parse-complex-content.ts +287 -0
  75. package/src/io/ooxml/parse-fields.ts +834 -0
  76. package/src/io/ooxml/parse-footnotes.ts +952 -0
  77. package/src/io/ooxml/parse-headers-footers.ts +1212 -0
  78. package/src/io/ooxml/parse-inline-media.ts +461 -0
  79. package/src/io/ooxml/parse-main-document.ts +2947 -0
  80. package/src/io/ooxml/parse-numbering.ts +747 -0
  81. package/src/io/ooxml/parse-revisions.ts +1045 -0
  82. package/src/io/ooxml/parse-settings.ts +184 -0
  83. package/src/io/ooxml/parse-shapes.ts +296 -0
  84. package/src/io/ooxml/parse-styles.ts +639 -0
  85. package/src/io/ooxml/parse-tables.ts +627 -0
  86. package/src/io/ooxml/parse-theme.ts +346 -0
  87. package/src/io/ooxml/part-manifest.ts +136 -0
  88. package/src/io/ooxml/revision-boundaries.ts +475 -0
  89. package/src/io/ooxml/workflow-payload.ts +544 -0
  90. package/src/io/opc/README.md +3 -0
  91. package/src/io/opc/corrupt-package.ts +166 -0
  92. package/src/io/opc/docx-package.ts +74 -0
  93. package/src/io/opc/package-reader.ts +325 -0
  94. package/src/io/opc/package-writer.ts +273 -0
  95. package/src/io/source-package-provenance.ts +241 -0
  96. package/{dist/chunk-RMH72RZI.js → src/legal/bookmarks.ts} +130 -44
  97. package/src/legal/cross-references.ts +414 -0
  98. package/src/legal/defined-terms.ts +203 -0
  99. package/src/legal/index.ts +32 -0
  100. package/src/legal/signature-blocks.ts +259 -0
  101. package/src/model/README.md +3 -0
  102. package/src/model/canonical-document.ts +2722 -0
  103. package/src/model/cds-1.0.0.ts +212 -0
  104. package/src/model/snapshot.ts +760 -0
  105. package/src/preservation/README.md +3 -0
  106. package/src/preservation/markup-compatibility.ts +48 -0
  107. package/src/preservation/opaque-fragment-store.ts +89 -0
  108. package/src/preservation/opaque-region.ts +233 -0
  109. package/src/preservation/package-preservation.ts +113 -0
  110. package/src/preservation/preserved-part-manifest.ts +56 -0
  111. package/src/preservation/relationship-retention.ts +57 -0
  112. package/src/preservation/store.ts +255 -0
  113. package/src/review/README.md +16 -0
  114. package/src/review/store/README.md +3 -0
  115. package/src/review/store/comment-anchors.ts +70 -0
  116. package/src/review/store/comment-remapping.ts +154 -0
  117. package/src/review/store/comment-store.ts +349 -0
  118. package/src/review/store/comment-thread.ts +109 -0
  119. package/src/review/store/revision-actions.ts +423 -0
  120. package/src/review/store/revision-store.ts +323 -0
  121. package/src/review/store/revision-types.ts +182 -0
  122. package/src/review/store/runtime-comment-store.ts +43 -0
  123. package/src/runtime/README.md +3 -0
  124. package/src/runtime/ai-action-policy.ts +764 -0
  125. package/src/runtime/context-analytics.ts +824 -0
  126. package/src/runtime/document-layout.ts +332 -0
  127. package/src/runtime/document-locations.ts +521 -0
  128. package/src/runtime/document-navigation.ts +616 -0
  129. package/src/runtime/document-outline.ts +440 -0
  130. package/src/runtime/document-runtime.ts +4055 -0
  131. package/src/runtime/document-search.ts +145 -0
  132. package/src/runtime/event-refresh-hints.ts +137 -0
  133. package/src/runtime/numbering-prefix.ts +244 -0
  134. package/src/runtime/page-layout-estimation.ts +305 -0
  135. package/src/runtime/read-only-diagnostics-runtime.ts +241 -0
  136. package/src/runtime/resolved-numbering-geometry.ts +293 -0
  137. package/src/runtime/review-runtime.ts +44 -0
  138. package/src/runtime/revision-runtime.ts +107 -0
  139. package/src/runtime/session-capabilities.ts +192 -0
  140. package/src/runtime/story-context.ts +164 -0
  141. package/src/runtime/story-targeting.ts +162 -0
  142. package/src/runtime/suggestions-snapshot.ts +137 -0
  143. package/src/runtime/surface-projection.ts +1553 -0
  144. package/src/runtime/table-commands.ts +173 -0
  145. package/src/runtime/table-schema.ts +309 -0
  146. package/src/runtime/table-style-resolver.ts +409 -0
  147. package/src/runtime/view-state.ts +493 -0
  148. package/src/runtime/virtualized-rendering.ts +258 -0
  149. package/src/runtime/workflow-markup.ts +393 -0
  150. package/src/ui/README.md +30 -0
  151. package/src/ui/WordReviewEditor.tsx +5268 -0
  152. package/src/ui/browser-export.ts +52 -0
  153. package/src/ui/comments/README.md +3 -0
  154. package/src/ui/compatibility/README.md +3 -0
  155. package/src/ui/editor-command-bag.ts +127 -0
  156. package/src/ui/editor-runtime-boundary.ts +1558 -0
  157. package/src/ui/editor-shell-view.tsx +144 -0
  158. package/src/ui/editor-surface/README.md +3 -0
  159. package/src/ui/editor-surface-controller.tsx +66 -0
  160. package/src/ui/headless/comment-decoration-model.ts +124 -0
  161. package/src/ui/headless/preserve-editor-selection.ts +5 -0
  162. package/src/ui/headless/revision-decoration-model.ts +128 -0
  163. package/src/ui/headless/selection-helpers.ts +54 -0
  164. package/src/ui/headless/selection-tool-context.ts +19 -0
  165. package/src/ui/headless/selection-tool-resolver.ts +752 -0
  166. package/src/ui/headless/selection-tool-types.ts +129 -0
  167. package/src/ui/headless/selection-toolbar-model.ts +11 -0
  168. package/src/ui/headless/use-editor-keyboard.ts +103 -0
  169. package/src/ui/review/README.md +3 -0
  170. package/src/ui/runtime-shortcut-dispatch.ts +365 -0
  171. package/src/ui/runtime-snapshot-selectors.ts +197 -0
  172. package/src/ui/shared/revision-filters.ts +31 -0
  173. package/src/ui/status/README.md +3 -0
  174. package/src/ui/theme/README.md +3 -0
  175. package/src/ui/toolbar/README.md +3 -0
  176. package/src/ui/workflow-surface-blocked-rails.ts +94 -0
  177. package/src/ui-tailwind/chrome/chrome-preset-model.ts +107 -0
  178. package/src/ui-tailwind/chrome/chrome-preset-toolbar.tsx +15 -0
  179. package/src/ui-tailwind/chrome/responsive-chrome.ts +46 -0
  180. package/src/ui-tailwind/chrome/review-queue-bar.tsx +97 -0
  181. package/src/ui-tailwind/chrome/tw-alert-banner.tsx +64 -0
  182. package/src/ui-tailwind/chrome/tw-context-analytics-summary.tsx +122 -0
  183. package/src/ui-tailwind/chrome/tw-image-context-toolbar.tsx +121 -0
  184. package/src/ui-tailwind/chrome/tw-layout-panel.tsx +114 -0
  185. package/src/ui-tailwind/chrome/tw-object-context-toolbar.tsx +30 -0
  186. package/src/ui-tailwind/chrome/tw-page-ruler.tsx +365 -0
  187. package/src/ui-tailwind/chrome/tw-selection-tool-blocked.tsx +23 -0
  188. package/src/ui-tailwind/chrome/tw-selection-tool-comment.tsx +35 -0
  189. package/src/ui-tailwind/chrome/tw-selection-tool-formatting.tsx +37 -0
  190. package/src/ui-tailwind/chrome/tw-selection-tool-host.tsx +303 -0
  191. package/src/ui-tailwind/chrome/tw-selection-tool-structure.tsx +116 -0
  192. package/src/ui-tailwind/chrome/tw-selection-tool-suggestion.tsx +29 -0
  193. package/src/ui-tailwind/chrome/tw-selection-tool-workflow.tsx +27 -0
  194. package/src/ui-tailwind/chrome/tw-selection-toolbar.tsx +186 -0
  195. package/src/ui-tailwind/chrome/tw-suggestion-card.tsx +139 -0
  196. package/src/ui-tailwind/chrome/tw-table-context-toolbar.tsx +250 -0
  197. package/src/ui-tailwind/chrome/tw-unsaved-modal.tsx +58 -0
  198. package/src/ui-tailwind/chrome/use-before-unload.ts +20 -0
  199. package/src/ui-tailwind/editor-surface/perf-probe.ts +179 -0
  200. package/src/ui-tailwind/editor-surface/pm-command-bridge.ts +189 -0
  201. package/src/ui-tailwind/editor-surface/pm-contextual-ui.ts +31 -0
  202. package/src/ui-tailwind/editor-surface/pm-decorations.ts +411 -0
  203. package/src/ui-tailwind/editor-surface/pm-position-map.ts +123 -0
  204. package/src/ui-tailwind/editor-surface/pm-schema.ts +927 -0
  205. package/src/ui-tailwind/editor-surface/pm-state-from-snapshot.ts +567 -0
  206. package/src/ui-tailwind/editor-surface/search-plugin.ts +168 -0
  207. package/src/ui-tailwind/editor-surface/surface-build-keys.ts +63 -0
  208. package/src/ui-tailwind/editor-surface/tw-caret.tsx +12 -0
  209. package/src/ui-tailwind/editor-surface/tw-editor-surface.tsx +150 -0
  210. package/src/ui-tailwind/editor-surface/tw-inline-token.tsx +129 -0
  211. package/src/ui-tailwind/editor-surface/tw-opaque-block.tsx +58 -0
  212. package/src/ui-tailwind/editor-surface/tw-paragraph-block.tsx +151 -0
  213. package/src/ui-tailwind/editor-surface/tw-prosemirror-surface.tsx +1047 -0
  214. package/src/ui-tailwind/editor-surface/tw-segment-view.tsx +111 -0
  215. package/src/ui-tailwind/editor-surface/tw-table-node-view.tsx +503 -0
  216. package/src/ui-tailwind/index.ts +62 -0
  217. package/src/ui-tailwind/page-chrome-model.ts +27 -0
  218. package/src/ui-tailwind/review/tw-comment-sidebar.tsx +406 -0
  219. package/src/ui-tailwind/review/tw-health-panel.tsx +149 -0
  220. package/src/ui-tailwind/review/tw-review-rail.tsx +130 -0
  221. package/src/ui-tailwind/review/tw-revision-sidebar.tsx +164 -0
  222. package/src/ui-tailwind/status/tw-status-bar.tsx +65 -0
  223. package/{dist → src}/ui-tailwind/theme/editor-theme.css +58 -40
  224. package/src/ui-tailwind/toolbar/toolbar-layout.ts +47 -0
  225. package/src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx +52 -0
  226. package/src/ui-tailwind/toolbar/tw-toolbar.tsx +1478 -0
  227. package/src/ui-tailwind/tw-review-workspace.tsx +1587 -0
  228. package/src/validation/README.md +3 -0
  229. package/src/validation/compatibility-engine.ts +878 -0
  230. package/src/validation/compatibility-report.ts +161 -0
  231. package/src/validation/diagnostics.ts +204 -0
  232. package/src/validation/docx-comment-proof.ts +720 -0
  233. package/src/validation/import-diagnostics.ts +128 -0
  234. package/src/validation/low-priority-word-surfaces.ts +373 -0
  235. package/dist/canonical-document-BLEbzL2J.d.cts +0 -844
  236. package/dist/canonical-document-BLEbzL2J.d.ts +0 -844
  237. package/dist/chunk-2FJS5GZM.js +0 -763
  238. package/dist/chunk-2FJS5GZM.js.map +0 -1
  239. package/dist/chunk-2OQBZS3F.js +0 -446
  240. package/dist/chunk-2OQBZS3F.js.map +0 -1
  241. package/dist/chunk-2S7W4KFO.js +0 -127
  242. package/dist/chunk-2S7W4KFO.js.map +0 -1
  243. package/dist/chunk-2TG72QSW.js +0 -3874
  244. package/dist/chunk-2TG72QSW.js.map +0 -1
  245. package/dist/chunk-36QNIZBO.js +0 -532
  246. package/dist/chunk-36QNIZBO.js.map +0 -1
  247. package/dist/chunk-4AQOYAW4.js +0 -3069
  248. package/dist/chunk-4AQOYAW4.js.map +0 -1
  249. package/dist/chunk-4D5EWJ3P.js +0 -77
  250. package/dist/chunk-4D5EWJ3P.js.map +0 -1
  251. package/dist/chunk-5FN54NDH.js +0 -2257
  252. package/dist/chunk-5FN54NDH.js.map +0 -1
  253. package/dist/chunk-BOYGQYRQ.js +0 -7306
  254. package/dist/chunk-BOYGQYRQ.js.map +0 -1
  255. package/dist/chunk-CN3XMECL.js +0 -212
  256. package/dist/chunk-CN3XMECL.js.map +0 -1
  257. package/dist/chunk-EBI3BX6U.js +0 -164
  258. package/dist/chunk-EBI3BX6U.js.map +0 -1
  259. package/dist/chunk-EILUG3VB.js +0 -1275
  260. package/dist/chunk-EILUG3VB.js.map +0 -1
  261. package/dist/chunk-FUDY333O.js +0 -70
  262. package/dist/chunk-FUDY333O.js.map +0 -1
  263. package/dist/chunk-GBVOWFIK.js +0 -1237
  264. package/dist/chunk-GBVOWFIK.js.map +0 -1
  265. package/dist/chunk-H4TQ3H3Y.js +0 -262
  266. package/dist/chunk-H4TQ3H3Y.js.map +0 -1
  267. package/dist/chunk-JGB3IXZO.js +0 -189
  268. package/dist/chunk-JGB3IXZO.js.map +0 -1
  269. package/dist/chunk-KD2QRQPY.js +0 -4342
  270. package/dist/chunk-KD2QRQPY.js.map +0 -1
  271. package/dist/chunk-KLMXQVYK.js +0 -369
  272. package/dist/chunk-KLMXQVYK.js.map +0 -1
  273. package/dist/chunk-KZUG5KFQ.js +0 -214
  274. package/dist/chunk-KZUG5KFQ.js.map +0 -1
  275. package/dist/chunk-QDAQ4CJU.js +0 -345
  276. package/dist/chunk-QDAQ4CJU.js.map +0 -1
  277. package/dist/chunk-RMH72RZI.js.map +0 -1
  278. package/dist/chunk-SWKWQZXM.js +0 -117
  279. package/dist/chunk-SWKWQZXM.js.map +0 -1
  280. package/dist/chunk-TJBP2K4T.js.map +0 -1
  281. package/dist/chunk-TLCEAQDQ.js +0 -542
  282. package/dist/chunk-TLCEAQDQ.js.map +0 -1
  283. package/dist/chunk-UZXBISGO.js.map +0 -1
  284. package/dist/chunk-WGBAKP3Q.js +0 -3220
  285. package/dist/chunk-WGBAKP3Q.js.map +0 -1
  286. package/dist/compare/index.cjs +0 -5475
  287. package/dist/compare/index.cjs.map +0 -1
  288. package/dist/compare/index.d.cts +0 -114
  289. package/dist/compare/index.d.ts +0 -114
  290. package/dist/compare/index.js +0 -731
  291. package/dist/compare/index.js.map +0 -1
  292. package/dist/core/commands/formatting-commands.cjs +0 -828
  293. package/dist/core/commands/formatting-commands.cjs.map +0 -1
  294. package/dist/core/commands/formatting-commands.d.cts +0 -63
  295. package/dist/core/commands/formatting-commands.d.ts +0 -63
  296. package/dist/core/commands/formatting-commands.js +0 -37
  297. package/dist/core/commands/formatting-commands.js.map +0 -1
  298. package/dist/core/commands/image-commands.cjs +0 -2023
  299. package/dist/core/commands/image-commands.cjs.map +0 -1
  300. package/dist/core/commands/image-commands.d.cts +0 -58
  301. package/dist/core/commands/image-commands.d.ts +0 -58
  302. package/dist/core/commands/image-commands.js +0 -18
  303. package/dist/core/commands/image-commands.js.map +0 -1
  304. package/dist/core/commands/section-layout-commands.cjs.map +0 -1
  305. package/dist/core/commands/section-layout-commands.d.cts +0 -62
  306. package/dist/core/commands/section-layout-commands.d.ts +0 -62
  307. package/dist/core/commands/section-layout-commands.js +0 -21
  308. package/dist/core/commands/section-layout-commands.js.map +0 -1
  309. package/dist/core/commands/style-commands.cjs.map +0 -1
  310. package/dist/core/commands/style-commands.d.cts +0 -13
  311. package/dist/core/commands/style-commands.d.ts +0 -13
  312. package/dist/core/commands/style-commands.js +0 -9
  313. package/dist/core/commands/style-commands.js.map +0 -1
  314. package/dist/core/commands/table-structure-commands.cjs +0 -1883
  315. package/dist/core/commands/table-structure-commands.cjs.map +0 -1
  316. package/dist/core/commands/table-structure-commands.d.cts +0 -59
  317. package/dist/core/commands/table-structure-commands.d.ts +0 -59
  318. package/dist/core/commands/table-structure-commands.js +0 -12
  319. package/dist/core/commands/table-structure-commands.js.map +0 -1
  320. package/dist/core/commands/text-commands.cjs +0 -2391
  321. package/dist/core/commands/text-commands.cjs.map +0 -1
  322. package/dist/core/commands/text-commands.d.cts +0 -24
  323. package/dist/core/commands/text-commands.d.ts +0 -24
  324. package/dist/core/commands/text-commands.js +0 -28
  325. package/dist/core/commands/text-commands.js.map +0 -1
  326. package/dist/core/selection/mapping.cjs +0 -200
  327. package/dist/core/selection/mapping.cjs.map +0 -1
  328. package/dist/core/selection/mapping.d.cts +0 -2
  329. package/dist/core/selection/mapping.d.ts +0 -2
  330. package/dist/core/selection/mapping.js +0 -31
  331. package/dist/core/selection/mapping.js.map +0 -1
  332. package/dist/core/state/editor-state.cjs +0 -2278
  333. package/dist/core/state/editor-state.cjs.map +0 -1
  334. package/dist/core/state/editor-state.d.cts +0 -2
  335. package/dist/core/state/editor-state.d.ts +0 -2
  336. package/dist/core/state/editor-state.js +0 -26
  337. package/dist/core/state/editor-state.js.map +0 -1
  338. package/dist/index.cjs +0 -38553
  339. package/dist/index.cjs.map +0 -1
  340. package/dist/index.d.cts +0 -15
  341. package/dist/index.d.ts +0 -15
  342. package/dist/index.js +0 -7856
  343. package/dist/index.js.map +0 -1
  344. package/dist/io/docx-session.cjs +0 -16236
  345. package/dist/io/docx-session.cjs.map +0 -1
  346. package/dist/io/docx-session.d.cts +0 -21
  347. package/dist/io/docx-session.d.ts +0 -21
  348. package/dist/io/docx-session.js +0 -18
  349. package/dist/io/docx-session.js.map +0 -1
  350. package/dist/legal/index.cjs +0 -3900
  351. package/dist/legal/index.cjs.map +0 -1
  352. package/dist/legal/index.d.cts +0 -86
  353. package/dist/legal/index.d.ts +0 -86
  354. package/dist/legal/index.js +0 -616
  355. package/dist/legal/index.js.map +0 -1
  356. package/dist/public-types-7ZL_94cz.d.ts +0 -1573
  357. package/dist/public-types-CeMaDueh.d.cts +0 -1573
  358. package/dist/public-types.cjs +0 -19
  359. package/dist/public-types.cjs.map +0 -1
  360. package/dist/public-types.d.cts +0 -2
  361. package/dist/public-types.d.ts +0 -2
  362. package/dist/public-types.js +0 -1
  363. package/dist/public-types.js.map +0 -1
  364. package/dist/runtime/document-runtime.cjs +0 -11140
  365. package/dist/runtime/document-runtime.cjs.map +0 -1
  366. package/dist/runtime/document-runtime.d.cts +0 -231
  367. package/dist/runtime/document-runtime.d.ts +0 -231
  368. package/dist/runtime/document-runtime.js +0 -21
  369. package/dist/runtime/document-runtime.js.map +0 -1
  370. package/dist/structural-helpers-CilgOVhh.d.cts +0 -10
  371. package/dist/structural-helpers-q0Gd-eBN.d.ts +0 -10
  372. package/dist/ui-tailwind/editor-surface/search-plugin.cjs +0 -313
  373. package/dist/ui-tailwind/editor-surface/search-plugin.cjs.map +0 -1
  374. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +0 -67
  375. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +0 -67
  376. package/dist/ui-tailwind/editor-surface/search-plugin.js +0 -23
  377. package/dist/ui-tailwind/editor-surface/search-plugin.js.map +0 -1
  378. package/dist/ui-tailwind/index.cjs +0 -4833
  379. package/dist/ui-tailwind/index.cjs.map +0 -1
  380. package/dist/ui-tailwind/index.d.cts +0 -617
  381. package/dist/ui-tailwind/index.d.ts +0 -617
  382. package/dist/ui-tailwind/index.js +0 -575
  383. package/dist/ui-tailwind/index.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/session-capabilities.ts","../src/ui-tailwind/chrome/tw-alert-banner.tsx","../src/ui-tailwind/chrome/tw-selection-toolbar.tsx","../src/ui/headless/preserve-editor-selection.ts","../src/ui-tailwind/review/tw-comment-sidebar.tsx","../src/ui-tailwind/review/tw-revision-sidebar.tsx","../src/ui/shared/revision-filters.ts","../src/ui-tailwind/review/tw-review-rail.tsx","../src/ui-tailwind/status/tw-status-bar.tsx","../src/ui-tailwind/review/tw-health-panel.tsx","../src/ui-tailwind/toolbar/tw-toolbar-icon-button.tsx","../src/ui-tailwind/toolbar/tw-toolbar.tsx","../src/ui-tailwind/tw-review-workspace.tsx","../src/ui-tailwind/page-chrome-model.ts","../src/ui-tailwind/chrome/tw-image-context-toolbar.tsx","../src/ui-tailwind/chrome/tw-layout-panel.tsx","../src/ui-tailwind/chrome/tw-object-context-toolbar.tsx","../src/ui-tailwind/chrome/tw-page-ruler.tsx","../src/ui-tailwind/chrome/tw-suggestion-card.tsx","../src/ui-tailwind/chrome/tw-table-context-toolbar.tsx","../src/ui/headless/comment-decoration-model.ts","../src/ui/headless/revision-decoration-model.ts","../src/ui/headless/selection-helpers.ts"],"sourcesContent":["import type { RuntimeRenderSnapshot, WorkflowScopeSnapshot } from \"../api/public-types\";\nimport {\n createDetachedAnchor,\n createNodeAnchor,\n createRangeAnchor,\n} from \"../core/selection/mapping.ts\";\nimport { canCreateDocxCommentAnchor } from \"../core/selection/review-anchors\";\n\n/**\n * Session capabilities derived from the runtime snapshot.\n *\n * All fields are computed from `RuntimeRenderSnapshot` — no local component\n * state. The UI reads these to decide what controls to enable/disable, what\n * chrome to show, and what mode the editor is in.\n */\nexport interface SessionCapabilities {\n // ── Session phase ──\n /** Current lifecycle phase of the editor session. */\n phase: \"loading\" | \"ready\" | \"diagnostics\" | \"error\";\n\n /** Effective editor mode after accounting for runtime state. */\n mode: \"editing\" | \"review\" | \"read-only-diagnostics\";\n\n // ── Document mode ──\n /** Runtime document mode — editing authority, distinct from view/workspace mode. */\n documentMode: \"editing\" | \"suggesting\" | \"viewing\";\n\n // ── Command capabilities ──\n canUndo: boolean;\n canRedo: boolean;\n canEdit: boolean;\n canAddComment: boolean;\n canExport: boolean;\n canAcceptChange: boolean;\n canRejectChange: boolean;\n canAcceptAll: boolean;\n canRejectAll: boolean;\n\n // ── Review visibility ──\n /** Whether the review rail should be visible by default. */\n reviewRailVisible: boolean;\n\n /** Whether tracked changes exist in the document (display toggle is meaningful). */\n trackChangesSupported: boolean;\n\n // ── Trust posture ──\n exportBlocked: boolean;\n preserveOnlyCount: number;\n unsupportedFatalCount: number;\n\n // ── Protection posture ──\n /** Whether the source package declares document-level protection. */\n hasDocumentProtection: boolean;\n /** Count of permission ranges from the source package. */\n protectedRangeCount: number;\n\n // ── Health ──\n /** Total count of health issues (preserve-only + unsupported-fatal + warnings). */\n healthIssueCount: number;\n\n // ── Workflow ──\n /** Whether a workflow overlay is currently applied. */\n workflowOverlayPresent: boolean;\n /** Whether the current selection is blocked by workflow scope enforcement. */\n workflowBlocked: boolean;\n\n // ── Status ──\n isDirty: boolean;\n isReady: boolean;\n hasFatalError: boolean;\n}\n\n/**\n * Derive UI capabilities from the runtime snapshot and requested review mode.\n *\n * This is a pure function with no side effects. Call it on every render to\n * get the current capability state.\n */\nexport function deriveCapabilities(\n snapshot: RuntimeRenderSnapshot,\n reviewMode: \"editing\" | \"review\",\n workflowScope?: WorkflowScopeSnapshot | null,\n): SessionCapabilities {\n const hasFatalError = Boolean(snapshot.fatalError);\n const isReady = snapshot.isReady;\n const isReadOnly = snapshot.readOnly;\n const exportBlocked = snapshot.compatibility.blockExport;\n const activeStory = snapshot.activeStory ?? { kind: \"main\" as const };\n const documentMode = snapshot.documentMode ?? \"editing\";\n\n // Phase derivation\n const phase: SessionCapabilities[\"phase\"] = !isReady\n ? \"loading\"\n : hasFatalError\n ? \"diagnostics\"\n : \"ready\";\n\n // Mode derivation: if diagnostics or read-only, override the requested mode\n const mode: SessionCapabilities[\"mode\"] =\n phase === \"diagnostics\"\n ? \"read-only-diagnostics\"\n : reviewMode;\n\n // Command capabilities — document mode \"viewing\" disables editing\n const canEdit = isReady && !isReadOnly && !hasFatalError && documentMode !== \"viewing\";\n const canUndo = snapshot.commandState.canUndo && canEdit;\n const canRedo = snapshot.commandState.canRedo && canEdit;\n const canAddComment =\n canEdit &&\n activeStory.kind === \"main\" &&\n !snapshot.selection.isCollapsed &&\n Boolean(snapshot.surface) &&\n canCreateDocxCommentAnchor(snapshot.surface, toRuntimeAnchor(snapshot.selection.activeRange));\n const canExport = isReady && !exportBlocked && !hasFatalError;\n\n // Revision capabilities\n const actionableRevisions = snapshot.trackedChanges.revisions.filter(\n (r) => r.status === \"active\" && r.actionability === \"actionable\",\n );\n const canAcceptChange = canEdit && actionableRevisions.some((r) => r.canAccept);\n const canRejectChange = canEdit && actionableRevisions.some((r) => r.canReject);\n const canAcceptAll = canEdit && actionableRevisions.length > 0;\n const canRejectAll = canEdit && actionableRevisions.length > 0;\n\n // Trust posture (computed before review visibility since it depends on these)\n const preserveOnlyCount = snapshot.compatibility.featureEntries.filter(\n (e) => e.featureClass === \"preserve-only\",\n ).length;\n const unsupportedFatalCount = snapshot.compatibility.featureEntries.filter(\n (e) => e.featureClass === \"unsupported-fatal\",\n ).length;\n const workflowOverlayPresent = workflowScope?.overlayPresent ?? false;\n const workflowBlocked = (workflowScope?.blockedReasons?.length ?? 0) > 0;\n\n // Review visibility\n const trackChangesSupported = snapshot.trackedChanges.totalCount > 0;\n // Rail visible in review/diagnostics mode always.\n // In editing mode, rail stays visible when there are trust/health concerns\n // that the user must be able to reach (per DESIGN.md: health/trust info\n // stays reachable in both modes).\n const hasTrustConcerns = exportBlocked || preserveOnlyCount > 0 || unsupportedFatalCount > 0\n || snapshot.warnings.length > 0 || hasFatalError;\n const reviewRailVisible = workflowOverlayPresent\n ? false\n : mode === \"review\" || mode === \"read-only-diagnostics\"\n || (mode === \"editing\" && hasTrustConcerns);\n\n const healthIssueCount = preserveOnlyCount + unsupportedFatalCount + snapshot.warnings.length;\n\n const protection = snapshot.protectionSnapshot;\n const hasDocumentProtection = protection?.hasDocumentProtection ?? false;\n const protectedRangeCount = protection?.ranges?.length ?? 0;\n\n return {\n phase,\n mode,\n documentMode,\n canUndo,\n canRedo,\n canEdit,\n canAddComment,\n canExport,\n canAcceptChange,\n canRejectChange,\n canAcceptAll,\n canRejectAll,\n reviewRailVisible,\n trackChangesSupported,\n exportBlocked,\n preserveOnlyCount,\n unsupportedFatalCount,\n hasDocumentProtection,\n protectedRangeCount,\n healthIssueCount,\n workflowOverlayPresent,\n workflowBlocked,\n isDirty: snapshot.isDirty,\n isReady,\n hasFatalError,\n };\n}\n\nfunction toRuntimeAnchor(anchor: RuntimeRenderSnapshot[\"selection\"][\"activeRange\"]) {\n switch (anchor.kind) {\n case \"range\":\n return createRangeAnchor(anchor.from, anchor.to, anchor.assoc);\n case \"node\":\n return createNodeAnchor(anchor.at, anchor.assoc);\n case \"detached\":\n return createDetachedAnchor(anchor.lastKnownRange, anchor.reason);\n }\n}\n","import React from \"react\";\nimport { AlertTriangle, XCircle } from \"lucide-react\";\n\nimport type { RuntimeRenderSnapshot, WorkflowBlockedCommandReason } from \"../../api/public-types\";\n\nexport interface TwAlertBannerProps {\n snapshot: RuntimeRenderSnapshot;\n preserveOnlyCount: number;\n workflowBlockedReasons?: WorkflowBlockedCommandReason[];\n}\n\nexport function TwAlertBanner(props: TwAlertBannerProps) {\n const { snapshot, preserveOnlyCount, workflowBlockedReasons = [] } = props;\n\n if (snapshot.fatalError) {\n return (\n <div className=\"flex items-center gap-2 px-3 py-1.5 bg-danger-soft text-danger text-xs\">\n <XCircle className=\"h-3.5 w-3.5 shrink-0\" />\n <span>{snapshot.fatalError.message}</span>\n </div>\n );\n }\n\n if (snapshot.compatibility.blockExport) {\n return (\n <div className=\"flex items-center gap-2 px-3 py-1.5 bg-danger-soft text-danger text-xs\">\n <XCircle className=\"h-3.5 w-3.5 shrink-0\" />\n <span>\n Export blocked &mdash;{\" \"}\n {snapshot.compatibility.blockExportReasons[0] ?? \"unsupported content\"}\n </span>\n </div>\n );\n }\n\n if (preserveOnlyCount > 0) {\n return (\n <div className=\"flex items-center gap-2 px-3 py-1.5 bg-warning-soft text-comment text-xs\">\n <AlertTriangle className=\"h-3.5 w-3.5 shrink-0\" />\n <span>\n {preserveOnlyCount} preserve-only feature\n {preserveOnlyCount !== 1 ? \"s\" : \"\"} detected\n </span>\n </div>\n );\n }\n\n if (workflowBlockedReasons.length > 0) {\n const firstReason = workflowBlockedReasons[0];\n return (\n <div className=\"flex items-center gap-2 px-3 py-1.5 bg-amber-50 text-amber-700 text-xs\">\n <AlertTriangle className=\"h-3.5 w-3.5 shrink-0\" />\n <span>\n {firstReason.message}\n {workflowBlockedReasons.length > 1\n ? ` (+${workflowBlockedReasons.length - 1} more)`\n : \"\"}\n </span>\n </div>\n );\n }\n\n return null;\n}\n","import React, { forwardRef } from \"react\";\nimport type { FocusEventHandler } from \"react\";\nimport * as Tooltip from \"@radix-ui/react-tooltip\";\nimport { Baseline, Bold, Highlighter, Italic, MessageSquare, Underline } from \"lucide-react\";\n\nimport type { SelectionToolbarModel } from \"../../ui/headless/selection-toolbar-model\";\nimport { preserveEditorSelectionMouseDown } from \"../../ui/headless/preserve-editor-selection\";\n\nexport interface TwSelectionToolbarProps {\n model: SelectionToolbarModel;\n disabledReason?: string;\n onFocusCapture?: FocusEventHandler<HTMLDivElement>;\n onBlurCapture?: FocusEventHandler<HTMLDivElement>;\n onToggleBold?: () => void;\n onToggleItalic?: () => void;\n onToggleUnderline?: () => void;\n onSetTextColor?: (color: string) => void;\n onSetHighlightColor?: (color: string | null) => void;\n onAddComment?: () => void;\n}\n\nconst focusRingClass =\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas\";\n\nexport const TwSelectionToolbar = forwardRef<HTMLDivElement, TwSelectionToolbarProps>(function TwSelectionToolbar(props, ref) {\n const { model } = props;\n const addCommentDisabled = !model.canAddComment;\n const formattingDisabled = !model.canToggleFormatting;\n const contextLabel = summarizeSelectionContext(model);\n const tooltipLabel = addCommentDisabled\n ? props.disabledReason ?? \"Select text within one paragraph to add a DOCX comment\"\n : \"Add comment\";\n\n return (\n <div\n ref={ref}\n data-testid=\"selection-toolbar\"\n className=\"inline-flex max-w-[min(24rem,calc(100vw-2rem))] items-center gap-1.5 rounded-xl border border-border/80 bg-canvas px-1.5 py-1.5 shadow-lg ring-1 ring-border/80\"\n role=\"toolbar\"\n aria-label=\"Selection actions\"\n onFocusCapture={props.onFocusCapture}\n onBlurCapture={props.onBlurCapture}\n >\n <ToolbarActionButton\n icon={<Bold className=\"h-3.5 w-3.5\" />}\n label=\"Bold selection\"\n pressed={model.boldActive}\n disabled={formattingDisabled}\n onClick={props.onToggleBold}\n />\n <ToolbarActionButton\n icon={<Italic className=\"h-3.5 w-3.5\" />}\n label=\"Italic selection\"\n pressed={model.italicActive}\n disabled={formattingDisabled}\n onClick={props.onToggleItalic}\n />\n <ToolbarActionButton\n icon={<Underline className=\"h-3.5 w-3.5\" />}\n label=\"Underline selection\"\n pressed={model.underlineActive}\n disabled={formattingDisabled}\n onClick={props.onToggleUnderline}\n />\n <ToolbarActionButton\n icon={<Baseline className=\"h-3.5 w-3.5\" />}\n label=\"Text color blue\"\n pressed={false}\n disabled={formattingDisabled}\n onClick={() => props.onSetTextColor?.(\"#1660a8\")}\n />\n <ToolbarActionButton\n icon={<Highlighter className=\"h-3.5 w-3.5\" />}\n label=\"Highlight yellow\"\n pressed={false}\n disabled={formattingDisabled}\n onClick={() => props.onSetHighlightColor?.(\"#ffff00\")}\n />\n\n <div className=\"mx-0.5 h-4 w-px bg-border\" />\n\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label=\"Add comment from selection\"\n disabled={addCommentDisabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onAddComment}\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md transition-colors text-accent hover:bg-accent-soft disabled:cursor-not-allowed disabled:opacity-30 ${focusRingClass}`}\n >\n <MessageSquare className=\"h-3.5 w-3.5\" />\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content\n className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\"\n sideOffset={6}\n >\n {tooltipLabel}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n\n {model.previewText ? (\n <>\n <div className=\"mx-0.5 h-4 w-px bg-border\" />\n <span className=\"max-w-[8rem] truncate text-[11px] text-secondary\">\n {model.previewText}\n </span>\n </>\n ) : null}\n\n {contextLabel ? (\n <>\n {!model.previewText ? <div className=\"mx-0.5 h-4 w-px bg-border\" /> : null}\n <span\n className={`min-w-0 max-w-[11rem] truncate rounded-full px-2 py-0.5 text-[10px] font-medium tracking-[0.08em] ${\n model.badges.some((badge) => badge.tone === \"accent\")\n ? \"bg-accent-soft text-accent\"\n : \"bg-surface text-tertiary\"\n }`}\n >\n {contextLabel}\n </span>\n </>\n ) : null}\n </div>\n );\n});\n\nfunction summarizeSelectionContext(model: SelectionToolbarModel): string | null {\n if (model.badges.length === 0) {\n return null;\n }\n\n const accentBadges = model.badges.filter((badge) => badge.tone === \"accent\");\n const source = accentBadges.length > 0 ? accentBadges : model.badges;\n const labels = source.slice(0, 2).map((badge) => badge.label.trim()).filter(Boolean);\n if (labels.length === 0) {\n return null;\n }\n\n const summary = labels.join(\" · \");\n return summary.length > 30 ? `${summary.slice(0, 27)}...` : summary;\n}\n\ninterface ToolbarActionButtonProps {\n icon: React.ReactNode;\n label: string;\n pressed: boolean;\n disabled: boolean;\n onClick?: () => void;\n}\n\nfunction ToolbarActionButton(props: ToolbarActionButtonProps) {\n return (\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label={props.label}\n aria-pressed={props.pressed}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onClick}\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md transition-colors disabled:cursor-not-allowed disabled:opacity-30 ${\n props.pressed\n ? \"bg-accent-soft text-accent\"\n : \"text-secondary hover:bg-surface\"\n } ${focusRingClass}`}\n >\n {props.icon}\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content\n className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\"\n sideOffset={6}\n >\n {props.label}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n}\n","import type { MouseEvent } from \"react\";\n\nexport function preserveEditorSelectionMouseDown(event: MouseEvent<HTMLElement>): void {\n event.preventDefault();\n}\n","import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Check, CornerDownRight, RotateCcw } from \"lucide-react\";\n\nimport type { CommentSidebarSnapshot, CommentSidebarThreadSnapshot } from \"../../api/public-types\";\n\nexport interface TwCommentSidebarProps {\n comments: CommentSidebarSnapshot;\n activeCommentId?: string;\n currentUserId?: string;\n onOpenComment?: (thread: CommentSidebarThreadSnapshot) => void;\n onResolveComment?: (commentId: string) => void;\n onReopenComment?: (commentId: string) => void;\n onAddReply?: (commentId: string, body: string) => void;\n onEditBody?: (commentId: string, body: string) => void;\n}\n\nconst focusRingClass =\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas\";\n\nexport function TwCommentSidebar(props: TwCommentSidebarProps) {\n const { comments, activeCommentId, currentUserId } = props;\n\n return (\n <div className=\"outline-none\">\n <div className=\"mb-2 flex items-center gap-2 text-[10px] text-tertiary\">\n <span>{comments.openCommentIds.length} open</span>\n <span className=\"text-border\">·</span>\n <span>{comments.resolvedCommentIds.length} resolved</span>\n {comments.detachedCommentIds.length > 0 && (\n <>\n <span className=\"text-border\">·</span>\n <span>{comments.detachedCommentIds.length} detached</span>\n </>\n )}\n </div>\n {comments.threads.length > 0 ? (\n <div className=\"space-y-1.5\">\n {comments.threads.map((thread) => (\n <CommentThreadCard\n key={thread.commentId}\n thread={thread}\n isActive={activeCommentId === thread.commentId}\n currentUserId={currentUserId}\n onOpenComment={props.onOpenComment}\n onResolveComment={props.onResolveComment}\n onReopenComment={props.onReopenComment}\n onAddReply={props.onAddReply}\n onEditBody={props.onEditBody}\n />\n ))}\n </div>\n ) : (\n <div className=\"rounded-lg border border-dashed border-border bg-surface/60 px-2.5 py-3 text-[10px] leading-4 text-tertiary\">\n No comment threads yet. Select text and add one from the toolbar.\n </div>\n )}\n </div>\n );\n}\n\nfunction CommentThreadCard(props: {\n thread: CommentSidebarThreadSnapshot;\n isActive: boolean;\n currentUserId?: string;\n onOpenComment?: (thread: CommentSidebarThreadSnapshot) => void;\n onResolveComment?: (commentId: string) => void;\n onReopenComment?: (commentId: string) => void;\n onAddReply?: (commentId: string, body: string) => void;\n onEditBody?: (commentId: string, body: string) => void;\n}) {\n const { thread, isActive } = props;\n const leadEntry = thread.entries[0];\n const isDraftThread = thread.status === \"open\" && thread.entryCount === 1 && isEmptyCommentBody(leadEntry?.body);\n const isOwnComment = props.currentUserId != null && leadEntry?.authorId === props.currentUserId;\n const canEdit = isOwnComment && thread.status === \"open\" && props.onEditBody != null;\n const hasNoBody = isEmptyCommentBody(leadEntry?.body);\n const showExcerpt = Boolean(thread.excerpt) && !isDraftThread && thread.excerpt !== \"Empty thread\";\n\n const scrollRef = useCallback(\n (node: HTMLDivElement | null) => {\n if (node && isActive && typeof node.scrollIntoView === \"function\") {\n node.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }\n },\n [isActive],\n );\n\n return (\n <div\n ref={scrollRef}\n data-comment-thread-id={thread.commentId}\n data-comment-thread-status={thread.status}\n role=\"button\"\n tabIndex={0}\n className={[\n \"cursor-pointer rounded-lg border px-2 py-1.5 transition-colors\",\n focusRingClass,\n isActive\n ? \"border-accent/25 bg-accent-soft/35\"\n : \"border-border bg-canvas hover:border-border-strong hover:bg-surface/70\",\n thread.status === \"detached\" ? \"opacity-70\" : \"\",\n ].join(\" \")}\n onClick={() => props.onOpenComment?.(thread)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n props.onOpenComment?.(thread);\n }\n }}\n >\n {/* Header row: avatar + author + date + status */}\n <div className=\"mb-1 flex items-center gap-1.5\">\n <span className=\"inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-full bg-accent/10 text-[8px] font-semibold text-accent\">\n {thread.createdBy.charAt(0).toUpperCase()}\n </span>\n <span className=\"truncate text-[10px] font-medium text-primary\">{thread.createdBy}</span>\n <span data-comment-thread-created-at=\"true\" className=\"text-[9px] text-tertiary\">\n {formatCommentDate(thread.createdAt)}\n </span>\n <span className=\"flex-1\" />\n {isDraftThread ? <StatusBadge label=\"draft\" tone=\"draft\" /> : null}\n {thread.status === \"resolved\" ? <StatusBadge label=\"resolved\" tone=\"resolved\" /> : null}\n {thread.status === \"detached\" ? <StatusBadge label=\"detached\" tone=\"detached\" /> : null}\n </div>\n\n {/* Excerpt — anchored text from document */}\n {showExcerpt ? (\n <p className=\"mb-1 rounded-md border-l-2 border-comment/25 bg-comment-soft/30 px-2 py-1 text-[9px] leading-4 text-comment/80 italic whitespace-pre-wrap break-words line-clamp-2\">\n {thread.excerpt}\n </p>\n ) : null}\n\n {/* Comment body */}\n {canEdit && (isActive || hasNoBody) ? (\n <InlineEditableBody\n body={leadEntry?.body ?? \"\"}\n autoFocus={isActive && hasNoBody}\n onSave={(newBody) => props.onEditBody?.(thread.commentId, newBody)}\n label={isDraftThread ? \"New comment\" : undefined}\n />\n ) : leadEntry?.body ? (\n <p\n className=\"text-[10px] leading-[1.1rem] text-secondary whitespace-pre-wrap break-words line-clamp-4\"\n data-comment-thread-body=\"true\"\n >\n {leadEntry.body}\n </p>\n ) : canEdit ? (\n <p\n className=\"cursor-text text-[10px] italic text-tertiary\"\n onClick={(e) => {\n e.stopPropagation();\n props.onOpenComment?.(thread);\n }}\n >\n New comment\n </p>\n ) : null}\n\n {/* Reply entries (compact) */}\n {thread.entries.slice(1).map((entry) => (\n <div key={entry.entryId} className=\"mt-1.5 ml-4 border-l border-border/50 pl-2.5\">\n <div className=\"mb-0.5 flex items-center gap-1\">\n <span className=\"text-[9px] font-medium text-secondary\">{entry.authorId}</span>\n <span className=\"text-[9px] text-tertiary\">{formatCommentDate(entry.createdAt)}</span>\n </div>\n <p\n className=\"text-[10px] leading-4 text-secondary whitespace-pre-wrap break-words line-clamp-3\"\n data-comment-reply-body=\"true\"\n >\n {entry.body}\n </p>\n </div>\n ))}\n\n {thread.entryCount > thread.entries.length ? (\n <p className=\"mt-1 text-[9px] text-tertiary\">\n +{thread.entryCount - thread.entries.length} more\n </p>\n ) : null}\n\n {/* Inline actions — compact, horizontal */}\n <div className=\"mt-1 flex items-center gap-0.5\">\n {thread.status === \"open\" && (\n <>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-0.5 rounded px-1 py-0.5 text-[9px] font-medium text-insert hover:bg-insert-soft transition-colors\"\n onClick={(e) => { e.stopPropagation(); props.onResolveComment?.(thread.commentId); }}\n >\n <Check className=\"h-2 w-2\" /> Resolve\n </button>\n {props.onAddReply && (\n <ReplyInput commentId={thread.commentId} onAddReply={props.onAddReply} />\n )}\n </>\n )}\n {thread.status === \"resolved\" && (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-0.5 rounded px-1 py-0.5 text-[9px] font-medium text-secondary hover:bg-surface transition-colors\"\n data-comment-thread-action=\"reopen\"\n onClick={(e) => { e.stopPropagation(); props.onReopenComment?.(thread.commentId); }}\n >\n <RotateCcw className=\"h-2 w-2\" /> Reopen\n </button>\n )}\n {thread.status === \"detached\" && (\n <span className=\"text-[9px] text-comment\">Detached</span>\n )}\n </div>\n </div>\n );\n}\n\nfunction InlineEditableBody(props: {\n body: string;\n autoFocus?: boolean;\n label?: string;\n onSave: (newBody: string) => void;\n}) {\n const [isEditing, setIsEditing] = useState(props.autoFocus || props.body === \"\");\n const [draft, setDraft] = useState(props.body);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n if (isEditing && textareaRef.current) {\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(draft.length, draft.length);\n }\n }, [isEditing]);\n\n if (!isEditing) {\n return (\n <p\n className={`cursor-text rounded px-1 text-[10px] leading-[1.15rem] -mx-1 transition-colors hover:bg-surface ${props.body ? \"text-secondary\" : \"text-tertiary italic\"}`}\n onClick={(e) => {\n e.stopPropagation();\n setDraft(props.body);\n setIsEditing(true);\n }}\n title=\"Click to edit\"\n >\n {props.body || \"Click to add comment\\u2026\"}\n </p>\n );\n }\n\n return (\n <div className=\"space-y-1\">\n {props.label ? (\n <span className=\"block text-[10px] font-medium uppercase tracking-[0.08em] text-tertiary\">\n {props.label}\n </span>\n ) : null}\n <textarea\n ref={textareaRef}\n className=\"w-full resize-none rounded-md border border-border bg-surface px-2 py-1.5 text-[10px] leading-4 text-primary placeholder:text-tertiary focus:outline-none focus:ring-1 focus:ring-accent\"\n rows={2}\n value={draft}\n placeholder=\"Type your comment...\"\n onClick={(e) => e.stopPropagation()}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={() => {\n if (draft.trim() && draft.trim() !== props.body) {\n props.onSave(draft.trim());\n }\n setIsEditing(false);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n if (draft.trim() && draft.trim() !== props.body) {\n props.onSave(draft.trim());\n }\n setIsEditing(false);\n }\n if (e.key === \"Escape\") {\n setDraft(props.body);\n setIsEditing(false);\n }\n e.stopPropagation();\n }}\n />\n </div>\n );\n}\n\nfunction ReplyInput(props: { commentId: string; onAddReply: (commentId: string, body: string) => void }) {\n const [body, setBody] = useState(\"\");\n const [isOpen, setIsOpen] = useState(false);\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n if (isOpen && inputRef.current) {\n inputRef.current.focus();\n }\n }, [isOpen]);\n\n if (!isOpen) {\n return (\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-0.5 rounded px-1.5 py-0.5 text-[10px] font-medium text-tertiary hover:text-secondary hover:bg-surface transition-colors\"\n onClick={(e) => {\n e.stopPropagation();\n setIsOpen(true);\n }}\n >\n <CornerDownRight className=\"h-2.5 w-2.5\" /> Reply\n </button>\n );\n }\n\n return (\n <div className=\"w-full mt-1.5\" onClick={(e) => e.stopPropagation()}>\n <textarea\n ref={inputRef}\n className=\"w-full rounded border border-border bg-surface px-2 py-1 text-[11px] text-primary placeholder:text-tertiary resize-none focus:outline-none focus:ring-1 focus:ring-accent\"\n rows={2}\n placeholder=\"Reply...\"\n value={body}\n onChange={(e) => setBody(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey && body.trim()) {\n e.preventDefault();\n props.onAddReply(props.commentId, body.trim());\n setBody(\"\");\n setIsOpen(false);\n }\n if (e.key === \"Escape\") {\n setBody(\"\");\n setIsOpen(false);\n }\n e.stopPropagation();\n }}\n />\n <div className=\"flex gap-1 mt-0.5\">\n <button\n type=\"button\"\n disabled={!body.trim()}\n className=\"rounded px-1.5 py-0.5 text-[10px] font-medium text-accent hover:bg-accent-soft transition-colors disabled:opacity-40\"\n onClick={() => {\n if (body.trim()) {\n props.onAddReply(props.commentId, body.trim());\n setBody(\"\");\n setIsOpen(false);\n }\n }}\n >\n Send\n </button>\n <button\n type=\"button\"\n className=\"rounded px-1.5 py-0.5 text-[10px] text-tertiary hover:bg-surface transition-colors\"\n onClick={() => { setBody(\"\"); setIsOpen(false); }}\n >\n Cancel\n </button>\n </div>\n </div>\n );\n}\n\nfunction formatCommentDate(raw: string): string {\n try {\n const date = new Date(raw);\n if (Number.isNaN(date.getTime())) return raw;\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMin = Math.floor(diffMs / 60000);\n if (diffMin < 1) return \"just now\";\n if (diffMin < 60) return `${diffMin}m ago`;\n const diffHours = Math.floor(diffMin / 60);\n if (diffHours < 24) return `${diffHours}h ago`;\n const diffDays = Math.floor(diffHours / 24);\n if (diffDays < 7) return `${diffDays}d ago`;\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: date.getFullYear() !== now.getFullYear() ? \"numeric\" : undefined,\n }).format(date);\n } catch {\n return raw;\n }\n}\n\nfunction StatusBadge(props: { label: string; tone: \"resolved\" | \"detached\" | \"draft\" }) {\n const styles: Record<string, string> = {\n resolved: \"text-insert bg-insert-soft\",\n detached: \"text-comment bg-warning-soft\",\n draft: \"text-secondary bg-subtle\",\n };\n return (\n <span\n className={`shrink-0 rounded px-1 py-px text-[8px] font-medium uppercase tracking-[0.08em] ${styles[props.tone] ?? \"text-secondary bg-subtle\"}`}\n data-comment-thread-badge={props.tone}\n >\n {props.label}\n </span>\n );\n}\n\nfunction isEmptyCommentBody(body: string | undefined): boolean {\n return !body || body.trim() === \"\";\n}\n","import React from \"react\";\nimport { Check, X } from \"lucide-react\";\n\nimport type { TrackedChangesSnapshot, TrackedChangeEntrySnapshot } from \"../../api/public-types\";\nimport { selectVisibleRevisions } from \"../../ui/shared/revision-filters\";\nimport type { MarkupDisplay } from \"../../ui/headless/comment-decoration-model\";\n\nexport interface TwRevisionSidebarProps {\n trackedChanges: TrackedChangesSnapshot;\n markupDisplay: MarkupDisplay;\n activeRevisionId?: string;\n onOpenRevision?: (revision: TrackedChangeEntrySnapshot) => void;\n onAcceptRevision?: (revisionId: string) => void;\n onRejectRevision?: (revisionId: string) => void;\n onAcceptAllChanges?: () => void;\n onRejectAllChanges?: () => void;\n}\n\nconst focusRingClass =\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas\";\n\nexport function TwRevisionSidebar(props: TwRevisionSidebarProps) {\n const { trackedChanges, markupDisplay, activeRevisionId } = props;\n const visibleRevisions = selectVisibleRevisions(trackedChanges.revisions, markupDisplay);\n const actionablePendingCount = trackedChanges.revisions.filter(\n (r) => r.status === \"active\" && r.actionability === \"actionable\",\n ).length;\n\n return (\n <div className=\"outline-none\">\n <p className=\"mb-2 text-[10px] text-tertiary\">\n {trackedChanges.pendingChangeIds.length} active · {trackedChanges.acceptedChangeIds.length} accepted · {trackedChanges.preserveOnlyChangeIds.length} preserve-only\n </p>\n\n {/* Bulk actions */}\n <div className=\"mb-2 flex gap-1\">\n <button\n type=\"button\"\n disabled={actionablePendingCount === 0}\n className=\"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] font-semibold text-accent hover:bg-accent-soft transition-colors disabled:opacity-30 disabled:cursor-not-allowed\"\n onClick={props.onAcceptAllChanges}\n >\n Accept all ({actionablePendingCount})\n </button>\n <button\n type=\"button\"\n disabled={actionablePendingCount === 0}\n className=\"inline-flex items-center gap-1 rounded-md px-2 py-1 text-[10px] text-secondary hover:bg-surface transition-colors disabled:opacity-30 disabled:cursor-not-allowed\"\n onClick={props.onRejectAllChanges}\n >\n Reject all\n </button>\n </div>\n\n {visibleRevisions.length > 0 ? (\n <div className=\"space-y-1\">\n {visibleRevisions.map((rev) => {\n const isActive = activeRevisionId === rev.revisionId;\n\n return (\n <div\n key={rev.revisionId}\n role=\"button\"\n tabIndex={0}\n className={`flex rounded-lg transition-colors cursor-pointer ${focusRingClass} ${isActive ? \"bg-accent-soft\" : \"hover:bg-surface\"}`}\n onClick={() => props.onOpenRevision?.(rev)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n props.onOpenRevision?.(rev);\n }\n }}\n >\n <div className={`w-0.5 shrink-0 rounded-l-lg ${\n rev.kind === \"insertion\" ? \"bg-insert\"\n : rev.kind === \"deletion\" ? \"bg-danger\"\n : \"bg-tertiary\"\n }`} />\n <div className=\"p-2 flex-1 min-w-0\">\n <div className=\"mb-0.5 flex items-start justify-between gap-2\">\n <span className=\"text-[11px] font-medium text-primary\">{rev.anchorLabel}</span>\n <RevisionBadge status={rev.status} actionability={rev.actionability} />\n </div>\n <p className=\"mb-1 text-[10px] text-tertiary\">{rev.authorId} · {rev.createdAt}</p>\n {rev.excerpt ? (\n <p className={`text-[11px] ${\n rev.kind === \"insertion\" ? \"text-insert\"\n : rev.kind === \"deletion\" ? \"text-danger line-through\"\n : \"text-secondary\"\n }`}>\n {rev.excerpt}\n </p>\n ) : (\n <p className=\"text-[11px] text-secondary\">{rev.label}</p>\n )}\n {rev.detail ? (\n <p className=\"mt-1 text-[10px] text-secondary\">{rev.detail}</p>\n ) : null}\n <div className=\"mt-1.5 flex gap-1\">\n {rev.actionability === \"actionable\" ? (\n <>\n <button\n type=\"button\"\n disabled={!rev.canAccept || rev.status === \"accepted\"}\n className=\"inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] text-insert hover:bg-insert-soft transition-colors disabled:opacity-30 disabled:cursor-not-allowed\"\n onClick={(e) => {\n e.stopPropagation();\n props.onAcceptRevision?.(rev.revisionId);\n }}\n >\n <Check className=\"h-3 w-3\" /> Accept\n </button>\n <button\n type=\"button\"\n disabled={!rev.canReject || rev.status === \"rejected\"}\n className=\"inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] text-danger hover:bg-delete-soft transition-colors disabled:opacity-30 disabled:cursor-not-allowed\"\n onClick={(e) => {\n e.stopPropagation();\n props.onRejectRevision?.(rev.revisionId);\n }}\n >\n <X className=\"h-3 w-3\" /> Reject\n </button>\n </>\n ) : (\n <span className=\"px-1.5 py-0.5 text-[10px] text-tertiary\">Preserve-only</span>\n )}\n </div>\n </div>\n </div>\n );\n })}\n </div>\n ) : (\n <p className=\"text-xs text-tertiary py-4\">\n {trackedChanges.totalCount > 0\n ? \"Switch to Full markup to see all tracked changes.\"\n : \"Tracked change cards will appear here when present.\"}\n </p>\n )}\n </div>\n );\n}\n\nfunction RevisionBadge(props: { status: string; actionability: string }) {\n if (props.actionability === \"preserve-only\") {\n return (\n <span className=\"inline-flex items-center rounded px-1.5 py-0.5 text-[10px] font-medium text-comment bg-warning-soft\">\n preserve-only\n </span>\n );\n }\n const styles: Record<string, string> = {\n active: \"text-secondary bg-subtle\",\n accepted: \"text-insert bg-insert-soft\",\n rejected: \"text-danger bg-delete-soft\",\n detached: \"text-comment bg-warning-soft\",\n };\n return (\n <span className={`inline-flex items-center rounded px-1.5 py-0.5 text-[10px] font-medium ${styles[props.status] ?? \"text-secondary bg-subtle\"}`}>\n {props.status}\n </span>\n );\n}\n","import type { RuntimeRenderSnapshot } from \"../../api/public-types\";\n\ntype Revision = RuntimeRenderSnapshot[\"trackedChanges\"][\"revisions\"][number];\ntype MarkupDisplay = \"clean\" | \"simple\" | \"all\";\n\nexport function selectVisibleRevisions(\n revisions: readonly Revision[],\n markupDisplay: MarkupDisplay,\n): Revision[] {\n switch (markupDisplay) {\n case \"clean\":\n case \"simple\":\n return revisions.filter(\n (revision) =>\n revision.status === \"active\" && revision.actionability === \"actionable\",\n );\n case \"all\":\n return [...revisions];\n }\n}\n\nexport function describeEmptyRevisionState(\n markupDisplay: MarkupDisplay,\n totalCount: number,\n): string {\n if ((markupDisplay === \"clean\" || markupDisplay === \"simple\") && totalCount > 0) {\n return \"Simple markup keeps the rail focused on actionable live changes. Switch to All to inspect preserve-only or historical revision records.\";\n }\n\n return \"Runtime-backed change cards will appear here when tracked changes are present.\";\n}\n","import React from \"react\";\n\nimport * as Tabs from \"@radix-ui/react-tabs\";\nimport * as ScrollArea from \"@radix-ui/react-scroll-area\";\n\nimport type {\n CommentSidebarSnapshot,\n CommentSidebarThreadSnapshot,\n CompatibilityPanelSnapshot,\n EditorWarning,\n TrackedChangesSnapshot,\n TrackedChangeEntrySnapshot,\n} from \"../../api/public-types\";\nimport type { MarkupDisplay } from \"../../ui/headless/comment-decoration-model\";\nimport { TwCommentSidebar } from \"./tw-comment-sidebar\";\nimport { TwRevisionSidebar } from \"./tw-revision-sidebar\";\nimport { TwHealthPanel } from \"./tw-health-panel\";\n\nexport type ReviewRailTab = \"comments\" | \"changes\";\n\nexport interface TwReviewRailProps {\n activeTab: ReviewRailTab;\n currentUserId?: string;\n comments: CommentSidebarSnapshot;\n trackedChanges: TrackedChangesSnapshot;\n compatibility: CompatibilityPanelSnapshot;\n warnings: EditorWarning[];\n markupDisplay: MarkupDisplay;\n activeCommentId?: string;\n activeRevisionId?: string;\n onActiveTabChange: (tab: ReviewRailTab) => void;\n onOpenComment?: (thread: CommentSidebarThreadSnapshot) => void;\n onResolveComment?: (commentId: string) => void;\n onReopenComment?: (commentId: string) => void;\n onAddReply?: (commentId: string, body: string) => void;\n onEditBody?: (commentId: string, body: string) => void;\n onOpenRevision?: (revision: TrackedChangeEntrySnapshot) => void;\n onAcceptRevision?: (revisionId: string) => void;\n onRejectRevision?: (revisionId: string) => void;\n onAcceptAllChanges?: () => void;\n onRejectAllChanges?: () => void;\n}\n\nconst focusRingClass =\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas\";\n\nexport function TwReviewRail(props: TwReviewRailProps) {\n const warningCount = props.compatibility.featureEntries.filter(\n (e) => e.featureClass !== \"supported-roundtrip\",\n ).length + props.warnings.length;\n\n return (\n <aside\n aria-label=\"Review rail\"\n className=\"flex w-[304px] shrink-0 flex-col border-l border-border bg-canvas\"\n >\n <Tabs.Root\n value={props.activeTab}\n onValueChange={(v: string) => props.onActiveTabChange(v as ReviewRailTab)}\n className=\"flex flex-1 flex-col min-h-0\"\n >\n <Tabs.List className=\"flex shrink-0 border-b border-border px-2\">\n <Tabs.Trigger\n value=\"comments\"\n className={`flex-1 py-2 text-xs text-tertiary font-medium transition-colors data-[state=active]:text-primary data-[state=active]:font-semibold data-[state=active]:shadow-[inset_0_-2px_0_var(--color-accent)] outline-none ${focusRingClass}`}\n >\n Comments{\" \"}\n <span className=\"ml-1 inline-flex min-w-[14px] items-center justify-center rounded-full bg-subtle px-1.5 py-px text-[10px] font-medium text-tertiary\">{props.comments.totalCount}</span>\n </Tabs.Trigger>\n <Tabs.Trigger\n value=\"changes\"\n className={`flex-1 py-2 text-xs text-tertiary font-medium transition-colors data-[state=active]:text-primary data-[state=active]:font-semibold data-[state=active]:shadow-[inset_0_-2px_0_var(--color-accent)] outline-none ${focusRingClass}`}\n >\n Changes{\" \"}\n <span className=\"ml-1 inline-flex min-w-[14px] items-center justify-center rounded-full bg-subtle px-1.5 py-px text-[10px] font-medium text-tertiary\">{props.trackedChanges.totalCount}</span>\n </Tabs.Trigger>\n {/* Health moved to toolbar popover */}\n </Tabs.List>\n\n <ScrollArea.Root className=\"flex-1 min-h-0\">\n <ScrollArea.Viewport className=\"h-full w-full\">\n <Tabs.Content value=\"comments\" className=\"p-2.5 outline-none\">\n <TwCommentSidebar\n currentUserId={props.currentUserId}\n comments={props.comments}\n activeCommentId={props.activeCommentId}\n onOpenComment={props.onOpenComment}\n onResolveComment={props.onResolveComment}\n onReopenComment={props.onReopenComment}\n onAddReply={props.onAddReply}\n onEditBody={props.onEditBody}\n />\n </Tabs.Content>\n\n <Tabs.Content value=\"changes\" className=\"p-2.5 outline-none\">\n <TwRevisionSidebar\n trackedChanges={props.trackedChanges}\n markupDisplay={props.markupDisplay}\n activeRevisionId={props.activeRevisionId}\n onOpenRevision={props.onOpenRevision}\n onAcceptRevision={props.onAcceptRevision}\n onRejectRevision={props.onRejectRevision}\n onAcceptAllChanges={props.onAcceptAllChanges}\n onRejectAllChanges={props.onRejectAllChanges}\n />\n </Tabs.Content>\n\n {/* Health panel moved to toolbar popover */}\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar\n orientation=\"vertical\"\n className=\"flex w-1.5 touch-none select-none p-0.5\"\n >\n <ScrollArea.Thumb className=\"relative flex-1 rounded-full bg-black/[0.12]\" />\n </ScrollArea.Scrollbar>\n </ScrollArea.Root>\n </Tabs.Root>\n </aside>\n );\n}\n","import React from \"react\";\n\nexport interface TwStatusBarProps {\n isDirty: boolean;\n isExportBlocked: boolean;\n preserveOnlyCount: number;\n commentCount: number;\n changeCount: number;\n sessionId: string;\n}\n\nexport function TwStatusBar(props: TwStatusBarProps) {\n const saveState = props.isExportBlocked\n ? \"Read-only\"\n : props.isDirty\n ? \"Unsaved\"\n : \"Ready\";\n const exportState = props.isExportBlocked\n ? \"Blocked\"\n : props.preserveOnlyCount > 0\n ? \"Warnings\"\n : \"Ready\";\n\n return (\n <footer\n data-testid=\"status-bar\"\n className=\"flex h-7 shrink-0 items-center gap-4 border-t border-border px-3 text-xs text-tertiary\"\n >\n <span className=\"flex items-center gap-1.5\">\n <span\n className={`inline-block h-1.5 w-1.5 rounded-full ${\n props.isExportBlocked\n ? \"bg-danger\"\n : props.isDirty\n ? \"bg-comment\"\n : \"bg-insert\"\n }`}\n />\n {saveState}\n </span>\n <span className=\"flex items-center gap-1.5\">\n <span\n className={`inline-block h-1.5 w-1.5 rounded-full ${\n props.isExportBlocked\n ? \"bg-danger\"\n : props.preserveOnlyCount > 0\n ? \"bg-comment\"\n : \"bg-insert\"\n }`}\n />\n Export {exportState.toLowerCase()}\n </span>\n <span>\n {props.commentCount} comment{props.commentCount !== 1 ? \"s\" : \"\"} ·{\" \"}\n {props.changeCount} change{props.changeCount !== 1 ? \"s\" : \"\"}\n </span>\n <span className=\"flex-1\" />\n <span>{props.sessionId}</span>\n </footer>\n );\n}\n","import React from \"react\";\nimport { AlertTriangle, Info, Shield, ShieldAlert, ShieldCheck } from \"lucide-react\";\n\nimport type {\n CompatibilityFeatureEntry,\n CompatibilityPanelSnapshot,\n EditorWarning,\n WorkflowBlockedCommandReason,\n} from \"../../api/public-types\";\n\nexport interface TwHealthPanelProps {\n compatibility: CompatibilityPanelSnapshot;\n warnings: EditorWarning[];\n blockedReasons?: WorkflowBlockedCommandReason[];\n}\n\nexport function TwHealthPanel(props: TwHealthPanelProps) {\n const { compatibility, warnings, blockedReasons = [] } = props;\n const supportedCount = compatibility.featureEntries.filter(\n (e) => e.featureClass === \"supported-roundtrip\",\n ).length;\n const preserveOnlyCount = compatibility.featureEntries.filter(\n (e) => e.featureClass === \"preserve-only\",\n ).length;\n const blockedCount = compatibility.featureEntries.filter(\n (e) => e.featureClass === \"unsupported-fatal\",\n ).length;\n\n return (\n <div className=\"outline-none\">\n <p className=\"text-xs text-tertiary mb-3\">\n {supportedCount} supported · {preserveOnlyCount} preserve-only · {blockedCount} blocked\n {warnings.length > 0 ? ` · ${warnings.length} warning${warnings.length !== 1 ? \"s\" : \"\"}` : \"\"}\n </p>\n\n <div className=\"space-y-1\">\n {compatibility.featureEntries.map((entry) => (\n <div key={entry.featureEntryId} className=\"flex rounded-lg transition-colors hover:bg-surface\">\n {entry.featureClass !== \"supported-roundtrip\" ? (\n <div className={`w-0.5 shrink-0 rounded-l-lg ${\n entry.featureClass === \"unsupported-fatal\" ? \"bg-danger\" : \"bg-comment\"\n }`} />\n ) : null}\n <div className=\"flex items-start gap-2 p-2.5 flex-1\">\n <HealthIcon featureClass={entry.featureClass} />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"text-sm font-medium text-primary\">{entry.message}</span>\n <FeatureClassBadge featureClass={entry.featureClass} />\n </div>\n <p className=\"text-xs text-tertiary mt-0.5\">{entry.featureKey}</p>\n </div>\n </div>\n </div>\n ))}\n\n {warnings.map((warning) => (\n <div key={warning.warningId} className=\"flex rounded-lg transition-colors hover:bg-surface\">\n <div className={`w-0.5 shrink-0 rounded-l-lg ${\n warning.severity === \"warning\" ? \"bg-comment\" : \"bg-accent\"\n }`} />\n <div className=\"flex items-start gap-2 p-2.5 flex-1\">\n {warning.severity === \"warning\" ? (\n <AlertTriangle className=\"h-4 w-4 text-comment shrink-0 mt-0.5\" />\n ) : (\n <Info className=\"h-4 w-4 text-accent shrink-0 mt-0.5\" />\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"text-sm font-medium text-primary\">{warning.message}</span>\n <span className={`inline-flex items-center rounded px-1.5 py-0.5 text-[10px] font-medium ${\n warning.severity === \"warning\"\n ? \"text-comment bg-warning-soft\"\n : \"text-accent bg-accent-soft\"\n }`}>\n {warning.code.replace(/_/g, \" \")}\n </span>\n </div>\n <p className=\"text-xs text-tertiary mt-0.5\">{warning.source}</p>\n </div>\n </div>\n </div>\n ))}\n\n {blockedReasons.length > 0 ? (\n <>\n <div className=\"border-t border-border mt-2 pt-2\">\n <p className=\"text-xs font-medium text-tertiary mb-1\">Workflow blocked reasons</p>\n </div>\n {blockedReasons.map((reason, index) => (\n <div key={`blocked-${index}`} className=\"flex rounded-lg transition-colors hover:bg-surface\">\n <div className=\"w-0.5 shrink-0 rounded-l-lg bg-amber-400\" />\n <div className=\"flex items-start gap-2 p-2.5 flex-1\">\n <ShieldAlert className=\"h-4 w-4 text-amber-500 shrink-0 mt-0.5\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"text-sm font-medium text-primary\">{reason.message}</span>\n <span className=\"inline-flex items-center rounded px-1.5 py-0.5 text-[10px] font-medium text-amber-700 bg-amber-100\">\n {reason.code.replace(/_/g, \" \")}\n </span>\n </div>\n {reason.scopeId ? (\n <p className=\"text-xs text-tertiary mt-0.5\">scope: {reason.scopeId}</p>\n ) : null}\n </div>\n </div>\n </div>\n ))}\n </>\n ) : null}\n\n {compatibility.featureEntries.length === 0 && warnings.length === 0 && blockedReasons.length === 0 ? (\n <p className=\"text-xs text-tertiary py-4\">\n No compatibility entries or warnings to display.\n </p>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction HealthIcon(props: { featureClass: CompatibilityFeatureEntry[\"featureClass\"] }) {\n switch (props.featureClass) {\n case \"supported-roundtrip\":\n return <ShieldCheck className=\"h-4 w-4 text-insert shrink-0 mt-0.5\" />;\n case \"preserve-only\":\n return <Shield className=\"h-4 w-4 text-comment shrink-0 mt-0.5\" />;\n case \"unsupported-fatal\":\n return <ShieldAlert className=\"h-4 w-4 text-danger shrink-0 mt-0.5\" />;\n }\n}\n\nfunction FeatureClassBadge(props: { featureClass: CompatibilityFeatureEntry[\"featureClass\"] }) {\n const styles: Record<string, string> = {\n \"supported-roundtrip\": \"text-insert bg-insert-soft\",\n \"preserve-only\": \"text-comment bg-warning-soft\",\n \"unsupported-fatal\": \"text-danger bg-delete-soft\",\n };\n const labels: Record<string, string> = {\n \"supported-roundtrip\": \"supported\",\n \"preserve-only\": \"preserve-only\",\n \"unsupported-fatal\": \"blocked\",\n };\n return (\n <span className={`inline-flex items-center rounded px-1.5 py-0.5 text-[10px] font-medium ${styles[props.featureClass]}`}>\n {labels[props.featureClass]}\n </span>\n );\n}\n","import React from \"react\";\nimport * as Tooltip from \"@radix-ui/react-tooltip\";\n\nimport { preserveEditorSelectionMouseDown } from \"../../ui/headless/preserve-editor-selection\";\n\nexport interface TwToolbarIconButtonProps {\n icon: React.ComponentType<{ className?: string }>;\n label: string;\n disabled?: boolean;\n active?: boolean;\n emphasis?: boolean;\n onClick?: () => void;\n}\n\nconst focusRingClass =\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas\";\n\nexport function TwToolbarIconButton(props: TwToolbarIconButtonProps) {\n return (\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label={props.label}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onClick}\n className={[\n \"inline-flex h-7 w-7 items-center justify-center rounded-md transition-colors outline-none\",\n \"disabled:opacity-30 disabled:cursor-not-allowed\",\n props.emphasis\n ? \"text-accent hover:bg-accent-soft\"\n : props.active\n ? \"bg-accent-soft text-accent\"\n : \"text-secondary hover:bg-surface hover:text-primary\",\n focusRingClass,\n ].join(\" \")}\n >\n <props.icon className=\"h-4 w-4\" />\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content\n className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\"\n sideOffset={6}\n >\n {props.label}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n}\n","import React from \"react\";\n\nimport * as Popover from \"@radix-ui/react-popover\";\nimport * as Select from \"@radix-ui/react-select\";\nimport * as Toggle from \"@radix-ui/react-toggle\";\nimport * as ToggleGroup from \"@radix-ui/react-toggle-group\";\nimport * as Tooltip from \"@radix-ui/react-tooltip\";\nimport {\n AlignCenter,\n AlignJustify,\n AlignLeft,\n AlignRight,\n Baseline,\n Bold,\n ChevronDown,\n Download,\n Eye,\n EyeOff,\n FileText,\n Highlighter,\n ImagePlus,\n Indent,\n Italic,\n MessageSquare,\n Minus,\n Monitor,\n MoreHorizontal,\n Outdent,\n Plus,\n Redo2,\n Rows3,\n Strikethrough,\n Subscript,\n Superscript,\n ShieldAlert,\n ShieldCheck,\n Underline,\n Undo2,\n} from \"lucide-react\";\n\nimport type {\n CompatibilityPanelSnapshot,\n EditorStoryTarget,\n EditorWarning,\n FormattingStateSnapshot,\n FormattingAlignment,\n InsertImageOptions,\n SectionBreakType,\n StyleCatalogSnapshot,\n WorkflowBlockedCommandReason,\n WorkspaceMode,\n ZoomLevel,\n} from \"../../api/public-types\";\nimport type { SessionCapabilities } from \"../../runtime/session-capabilities\";\nimport { preserveEditorSelectionMouseDown } from \"../../ui/headless/preserve-editor-selection\";\nimport { TwHealthPanel } from \"../review/tw-health-panel\";\nimport { TwToolbarIconButton } from \"./tw-toolbar-icon-button\";\n\nexport interface TwToolbarProps {\n sourceLabel?: string;\n capabilities?: SessionCapabilities;\n compatibility?: CompatibilityPanelSnapshot;\n warnings?: EditorWarning[];\n blockedReasons?: WorkflowBlockedCommandReason[];\n interactionPolicy?: ToolbarInteractionPolicy;\n workspaceMode: WorkspaceMode;\n zoomLevel?: ZoomLevel;\n formattingState?: FormattingStateSnapshot;\n styleCatalog?: StyleCatalogSnapshot;\n /** Display toggle for tracked change decorations (not a runtime mutation toggle). */\n showTrackedChanges: boolean;\n /** Active story target — shows a breadcrumb when editing a secondary story. */\n activeStory?: EditorStoryTarget;\n /** Called when the user clicks the story breadcrumb to return to main body. */\n onCloseStory?: () => void;\n onUndo: () => void;\n onRedo: () => void;\n onSetParagraphStyle?: (styleId: string) => void;\n onToggleBold?: () => void;\n onToggleItalic?: () => void;\n onToggleUnderline?: () => void;\n onToggleStrikethrough?: () => void;\n onToggleSuperscript?: () => void;\n onToggleSubscript?: () => void;\n onSetFontFamily?: (fontFamily: string) => void;\n onSetFontSize?: (fontSize: number) => void;\n onSetTextColor?: (color: string) => void;\n onSetHighlightColor?: (color: string | null) => void;\n onSetAlignment?: (alignment: FormattingAlignment) => void;\n onOutdent?: () => void;\n onIndent?: () => void;\n onAddComment: () => void;\n onInsertPageBreak?: () => void;\n onInsertTable?: () => void;\n onInsertSectionBreak?: (type: SectionBreakType) => void;\n onInsertImage?: (options: InsertImageOptions) => void;\n onExport: () => void;\n onWorkspaceModeChange: (value: WorkspaceMode) => void;\n onZoomChange?: (level: ZoomLevel) => void;\n onShowTrackedChangesChange: (show: boolean) => void;\n}\n\nexport interface ToolbarInteractionPolicy {\n mode: \"edit\" | \"suggest\" | \"comment\" | \"view\" | \"blocked\";\n canFormatText: boolean;\n canInsertStructural: boolean;\n canAddComment: boolean;\n}\n\nexport function getSupportedZoomPresets(): ReadonlyArray<number> {\n return [75, 100, 125, 150];\n}\n\nconst focusRingClass =\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas\";\n\nconst FONT_FAMILIES = [\"Arial\", \"Times New Roman\", \"Calibri\", \"Cambria\", \"Georgia\", \"Verdana\"];\nconst FONT_SIZES = [8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 36];\nconst TEXT_COLORS = [\"#000000\", \"#434343\", \"#1660a8\", \"#1a7f37\", \"#cf222e\", \"#7a4f00\"];\nconst HIGHLIGHT_COLORS = [\n { value: \"#ffff00\", label: \"Yellow\" },\n { value: \"#00ff00\", label: \"Green\" },\n { value: \"#00ffff\", label: \"Cyan\" },\n { value: \"#ff69b4\", label: \"Pink\" },\n { value: null, label: \"None\" },\n] as const;\n\nexport function TwToolbar(props: TwToolbarProps) {\n const caps = props.capabilities;\n const workspaceMode = props.workspaceMode;\n const isPageMode = workspaceMode === \"page\";\n const paragraphStyles = props.styleCatalog?.paragraphs ?? [];\n const zoomLevel = props.zoomLevel ?? 100;\n const canEdit = props.interactionPolicy?.canFormatText ?? (caps ? caps.canEdit : false);\n const canInsertStructural = props.interactionPolicy?.canInsertStructural ?? canEdit;\n const canAddComment = props.interactionPolicy?.canAddComment ?? (caps ? caps.canAddComment : false);\n const zoomLabel =\n typeof zoomLevel === \"number\"\n ? `${zoomLevel}%`\n : zoomLevel === \"pageWidth\"\n ? \"Fit width\"\n : \"Fit page\";\n\n return (\n <header className=\"flex h-10 shrink-0 items-center gap-1 border-b border-border px-2\">\n {/* Left cluster: undo/redo + formatting */}\n <div className=\"flex items-center gap-0.5\">\n <TwToolbarIconButton\n icon={Undo2}\n label=\"Undo\"\n disabled={caps ? !caps.canUndo : true}\n onClick={props.onUndo}\n />\n <TwToolbarIconButton\n icon={Redo2}\n label=\"Redo\"\n disabled={caps ? !caps.canRedo : true}\n onClick={props.onRedo}\n />\n <div className=\"mx-1 h-4 w-px bg-border\" />\n\n <ToolbarParagraphStyleSelect\n disabled={!canEdit || paragraphStyles.length === 0 || !props.onSetParagraphStyle}\n styles={paragraphStyles}\n value={props.formattingState?.paragraphStyleId}\n onValueChange={props.onSetParagraphStyle}\n />\n\n <ToolbarFontFamilySelect\n disabled={!canEdit || !props.onSetFontFamily}\n value={props.formattingState?.fontFamily}\n onValueChange={props.onSetFontFamily}\n />\n <ToolbarFontSizeSelect\n disabled={!canEdit || !props.onSetFontSize}\n value={props.formattingState?.fontSize}\n onValueChange={props.onSetFontSize}\n />\n\n <div className=\"mx-1 h-4 w-px bg-border\" />\n\n <TwToolbarIconButton\n icon={Bold}\n label=\"Bold\"\n active={props.formattingState?.bold ?? false}\n disabled={!canEdit}\n onClick={props.onToggleBold}\n />\n <TwToolbarIconButton\n icon={Italic}\n label=\"Italic\"\n active={props.formattingState?.italic ?? false}\n disabled={!canEdit}\n onClick={props.onToggleItalic}\n />\n <TwToolbarIconButton\n icon={Underline}\n label=\"Underline\"\n active={props.formattingState?.underline ?? false}\n disabled={!canEdit}\n onClick={props.onToggleUnderline}\n />\n <ToolbarFormattingOverflow\n disabled={!canEdit}\n formattingState={props.formattingState}\n onToggleStrikethrough={props.onToggleStrikethrough}\n onToggleSuperscript={props.onToggleSuperscript}\n onToggleSubscript={props.onToggleSubscript}\n />\n <ToolbarColorPopover\n ariaLabel=\"Text color\"\n colors={TEXT_COLORS.map((value) => ({ value, label: value }))}\n disabled={!canEdit || !props.onSetTextColor}\n icon={<Baseline className=\"h-3.5 w-3.5\" />}\n onSelect={(value) => {\n if (value) {\n props.onSetTextColor?.(value);\n }\n }}\n title=\"Text color\"\n />\n <ToolbarColorPopover\n ariaLabel=\"Highlight color\"\n colors={HIGHLIGHT_COLORS.map((entry) => ({ value: entry.value, label: entry.label }))}\n disabled={!canEdit || !props.onSetHighlightColor}\n icon={<Highlighter className=\"h-3.5 w-3.5\" />}\n onSelect={(value) => props.onSetHighlightColor?.(value)}\n title=\"Highlight color\"\n />\n <ToolbarAlignmentPopover\n activeAlignment={props.formattingState?.alignment}\n disabled={!canEdit || !props.onSetAlignment}\n onSelect={(alignment) => props.onSetAlignment?.(alignment)}\n />\n\n <div className=\"mx-1 h-4 w-px bg-border\" />\n\n <TwToolbarIconButton\n icon={Outdent}\n label=\"Outdent\"\n disabled={!canEdit}\n onClick={props.onOutdent}\n />\n <TwToolbarIconButton\n icon={Indent}\n label=\"Indent\"\n disabled={!canEdit}\n onClick={props.onIndent}\n />\n <ToolbarInsertMenu\n disabled={!canInsertStructural}\n onInsertImage={props.onInsertImage}\n onInsertPageBreak={props.onInsertPageBreak}\n onInsertSectionBreak={props.onInsertSectionBreak}\n onInsertTable={props.onInsertTable}\n />\n\n {/* Story focus breadcrumb — visible when editing a secondary story */}\n {props.activeStory && props.activeStory.kind !== \"main\" ? (\n <>\n <div className=\"mx-1 h-4 w-px bg-border\" />\n <button\n type=\"button\"\n onClick={props.onCloseStory}\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 text-xs font-medium text-accent hover:bg-accent-soft transition-colors outline-none ${focusRingClass}`}\n aria-label={`Editing ${storyLabel(props.activeStory)} — click to return to main body`}\n >\n <span className=\"text-secondary\">&larr;</span>\n {storyLabel(props.activeStory)}\n </button>\n </>\n ) : null}\n </div>\n\n {/* Center: document title */}\n <div className=\"flex-1 text-center min-w-0\">\n <span className=\"text-sm font-medium truncate block\">\n {props.sourceLabel ?? \"Untitled\"}\n </span>\n </div>\n\n {/* Right cluster: comment, track changes, markup, view, export */}\n <div className=\"flex items-center gap-0.5\">\n <TwToolbarIconButton\n icon={MessageSquare}\n label=\"Add comment\"\n disabled={!canAddComment}\n emphasis\n onClick={props.onAddComment}\n />\n\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <Toggle.Root\n pressed={props.showTrackedChanges}\n onPressedChange={props.onShowTrackedChangesChange}\n disabled={caps ? !caps.trackChangesSupported : false}\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface data-[state=on]:bg-accent-soft data-[state=on]:text-accent outline-none disabled:opacity-40 ${focusRingClass}`}\n >\n {props.showTrackedChanges ? <Eye className=\"h-4 w-4\" /> : <EyeOff className=\"h-4 w-4\" />}\n </Toggle.Root>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content\n className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\"\n sideOffset={6}\n >\n {props.showTrackedChanges ? \"Hide tracked changes\" : \"Show tracked changes\"}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n\n <div className=\"mx-1 h-4 w-px bg-border\" />\n\n {/* View mode toggle group: Canvas (clean, flowing) / Page (layout-sensitive) */}\n <ToggleGroup.Root\n type=\"single\"\n value={workspaceMode}\n onValueChange={(v: string) => {\n if (v) props.onWorkspaceModeChange(v as WorkspaceMode);\n }}\n className=\"flex items-center gap-0.5\"\n >\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <ToggleGroup.Item\n value=\"canvas\"\n aria-label=\"Canvas workspace\"\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface data-[state=on]:bg-accent-soft data-[state=on]:text-accent outline-none ${focusRingClass}`}\n >\n <Monitor className=\"h-3.5 w-3.5\" />\n </ToggleGroup.Item>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n Canvas — clean flowing text\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <ToggleGroup.Item\n value=\"page\"\n aria-label=\"Page workspace\"\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface data-[state=on]:bg-accent-soft data-[state=on]:text-accent outline-none ${focusRingClass}`}\n >\n <FileText className=\"h-3.5 w-3.5\" />\n </ToggleGroup.Item>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n Page — layout-sensitive view\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n </ToggleGroup.Root>\n\n {/* Zoom controls — visible in page mode */}\n {isPageMode && props.onZoomChange ? (\n <>\n <div className=\"mx-1 h-4 w-px bg-border\" />\n <div className=\"flex items-center gap-0.5\">\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label=\"Zoom out\"\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none ${focusRingClass}`}\n disabled={typeof zoomLevel === \"number\" && zoomLevel <= 50}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => {\n const current = typeof zoomLevel === \"number\" ? zoomLevel : 100;\n props.onZoomChange!(Math.max(50, current - 10));\n }}\n >\n <Minus className=\"h-3 w-3\" />\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n Zoom out\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n\n <Popover.Root>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n aria-label={`Zoom: ${zoomLabel}`}\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`inline-flex h-7 items-center justify-center rounded-md px-1.5 text-[11px] font-medium text-secondary transition-colors hover:bg-surface outline-none ${focusRingClass}`}\n >\n {zoomLabel}\n </button>\n </Popover.Trigger>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n Zoom level\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n <Popover.Portal>\n <Popover.Content\n className=\"w-[140px] rounded-lg bg-canvas shadow-lg ring-1 ring-border p-1 z-50\"\n sideOffset={8}\n align=\"center\"\n >\n {getSupportedZoomPresets().map((preset) => {\n const label = `${preset}%`;\n return (\n <Popover.Close key={preset} asChild>\n <button\n type=\"button\"\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`w-full rounded-md px-3 py-1.5 text-left text-xs transition-colors hover:bg-surface ${\n zoomLevel === preset ? \"font-semibold text-accent\" : \"text-primary\"\n }`}\n onClick={() => props.onZoomChange!(preset)}\n >\n {label}\n </button>\n </Popover.Close>\n );\n })}\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label=\"Zoom in\"\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none ${focusRingClass}`}\n disabled={typeof zoomLevel === \"number\" && zoomLevel >= 200}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => {\n const current = typeof zoomLevel === \"number\" ? zoomLevel : 100;\n props.onZoomChange!(Math.min(200, current + 10));\n }}\n >\n <Plus className=\"h-3 w-3\" />\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n Zoom in\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n </div>\n </>\n ) : null}\n\n {/* Health indicator */}\n {props.compatibility && props.warnings ? (\n <Popover.Root>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <Popover.Trigger asChild>\n <button\n type=\"button\"\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`relative inline-flex h-7 w-7 items-center justify-center rounded-md transition-colors hover:bg-surface hover:text-primary outline-none ${focusRingClass} ${\n (caps?.healthIssueCount ?? 0) > 0 ? \"text-secondary\" : \"text-secondary\"\n }`}\n >\n {(caps?.healthIssueCount ?? 0) > 0\n ? <ShieldAlert className=\"h-4 w-4\" />\n : <ShieldCheck className=\"h-4 w-4\" />\n }\n {(caps?.healthIssueCount ?? 0) > 0 ? (\n <span className=\"absolute -top-0.5 -right-0.5 flex h-3 min-w-[12px] items-center justify-center rounded-full bg-tertiary text-[8px] font-medium text-white\">\n {caps?.healthIssueCount}\n </span>\n ) : null}\n </button>\n </Popover.Trigger>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n {(caps?.healthIssueCount ?? 0) > 0\n ? `Document health — ${caps?.healthIssueCount} issue${(caps?.healthIssueCount ?? 0) !== 1 ? \"s\" : \"\"}`\n : \"Document health — no issues\"\n }\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n <Popover.Portal>\n <Popover.Content\n className=\"w-[360px] max-h-[480px] overflow-y-auto rounded-lg bg-canvas shadow-lg ring-1 ring-border p-3 z-50\"\n sideOffset={8}\n align=\"end\"\n >\n <TwHealthPanel\n blockedReasons={props.blockedReasons}\n compatibility={props.compatibility}\n warnings={props.warnings}\n />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n ) : null}\n\n <div className=\"mx-1 h-4 w-px bg-border\" />\n\n {/* Export button */}\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n disabled={caps ? !caps.canExport : true}\n onMouseDown={preserveEditorSelectionMouseDown}\n className={[\n \"inline-flex h-7 items-center gap-1.5 rounded-md px-2.5 text-xs font-semibold transition-colors outline-none\",\n focusRingClass,\n caps?.exportBlocked\n ? \"cursor-not-allowed text-danger opacity-50\"\n : \"text-accent hover:bg-accent-soft\",\n ].join(\" \")}\n onClick={props.onExport}\n >\n <Download className=\"h-3.5 w-3.5\" />\n Export .docx\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n {caps?.exportBlocked\n ? \"Export blocked by unsupported content\"\n : \"Export document\"}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n </div>\n </header>\n );\n}\n\nfunction ToolbarParagraphStyleSelect(props: {\n styles: StyleCatalogSnapshot[\"paragraphs\"];\n value?: string;\n disabled: boolean;\n onValueChange?: (styleId: string) => void;\n}) {\n const resolvedValue =\n props.value && props.styles.some((style) => style.styleId === props.value)\n ? props.value\n : \"\";\n\n return (\n <Select.Root\n disabled={props.disabled}\n onValueChange={(value) => props.onValueChange?.(value)}\n value={resolvedValue}\n >\n <Select.Trigger\n aria-label=\"Paragraph style\"\n aria-disabled={props.disabled || undefined}\n data-disabled={props.disabled ? \"\" : undefined}\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`inline-flex h-7 min-w-[8.5rem] items-center justify-between gap-2 rounded-md border border-border bg-canvas px-2.5 text-xs font-medium text-primary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}\n >\n <Select.Value placeholder=\"Style\" />\n <Select.Icon>\n <ChevronDown className=\"h-3.5 w-3.5 text-tertiary\" />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n align=\"start\"\n className=\"z-50 overflow-hidden rounded-lg bg-canvas shadow-lg ring-1 ring-border\"\n position=\"popper\"\n sideOffset={8}\n >\n <Select.Viewport className=\"p-1\">\n {props.styles.map((style) => (\n <Select.Item\n className={`flex cursor-pointer items-center rounded-md px-2.5 py-1.5 text-xs text-primary outline-none data-[highlighted]:bg-surface data-[state=checked]:bg-accent-soft data-[state=checked]:text-accent ${focusRingClass}`}\n key={style.styleId}\n value={style.styleId}\n >\n <Select.ItemText>{style.displayName}</Select.ItemText>\n </Select.Item>\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n}\n\nfunction ToolbarFontFamilySelect(props: {\n value?: string;\n disabled: boolean;\n onValueChange?: (fontFamily: string) => void;\n}) {\n const resolvedValue = props.value && FONT_FAMILIES.includes(props.value) ? props.value : \"\";\n\n return (\n <Select.Root\n disabled={props.disabled}\n onValueChange={(value) => props.onValueChange?.(value)}\n value={resolvedValue}\n >\n <Select.Trigger\n aria-label=\"Font family\"\n aria-disabled={props.disabled || undefined}\n data-disabled={props.disabled ? \"\" : undefined}\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`inline-flex h-7 min-w-[7rem] items-center justify-between gap-2 rounded-md border border-border bg-canvas px-2 text-xs font-medium text-primary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}\n >\n <Select.Value placeholder=\"Font\" />\n <Select.Icon>\n <ChevronDown className=\"h-3.5 w-3.5 text-tertiary\" />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n align=\"start\"\n className=\"z-50 overflow-hidden rounded-lg bg-canvas shadow-lg ring-1 ring-border\"\n position=\"popper\"\n sideOffset={8}\n >\n <Select.Viewport className=\"p-1\">\n {FONT_FAMILIES.map((font) => (\n <Select.Item\n className={`flex cursor-pointer items-center rounded-md px-2.5 py-1.5 text-xs text-primary outline-none data-[highlighted]:bg-surface data-[state=checked]:bg-accent-soft data-[state=checked]:text-accent ${focusRingClass}`}\n key={font}\n value={font}\n >\n <Select.ItemText>{font}</Select.ItemText>\n </Select.Item>\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n}\n\nfunction ToolbarFontSizeSelect(props: {\n value?: number;\n disabled: boolean;\n onValueChange?: (fontSize: number) => void;\n}) {\n const resolvedValue =\n typeof props.value === \"number\" && FONT_SIZES.includes(props.value) ? String(props.value) : \"\";\n\n return (\n <Select.Root\n disabled={props.disabled}\n onValueChange={(value) => props.onValueChange?.(Number(value))}\n value={resolvedValue}\n >\n <Select.Trigger\n aria-label=\"Font size\"\n aria-disabled={props.disabled || undefined}\n data-disabled={props.disabled ? \"\" : undefined}\n onMouseDown={preserveEditorSelectionMouseDown}\n className={`inline-flex h-7 min-w-[4rem] items-center justify-between gap-2 rounded-md border border-border bg-canvas px-2 text-xs font-medium text-primary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}\n >\n <Select.Value placeholder=\"Size\" />\n <Select.Icon>\n <ChevronDown className=\"h-3.5 w-3.5 text-tertiary\" />\n </Select.Icon>\n </Select.Trigger>\n <Select.Portal>\n <Select.Content\n align=\"start\"\n className=\"z-50 overflow-hidden rounded-lg bg-canvas shadow-lg ring-1 ring-border\"\n position=\"popper\"\n sideOffset={8}\n >\n <Select.Viewport className=\"p-1\">\n {FONT_SIZES.map((size) => (\n <Select.Item\n className={`flex cursor-pointer items-center rounded-md px-2.5 py-1.5 text-xs text-primary outline-none data-[highlighted]:bg-surface data-[state=checked]:bg-accent-soft data-[state=checked]:text-accent ${focusRingClass}`}\n key={size}\n value={String(size)}\n >\n <Select.ItemText>{size}</Select.ItemText>\n </Select.Item>\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n );\n}\n\nfunction ToolbarFormattingOverflow(props: {\n disabled: boolean;\n formattingState?: FormattingStateSnapshot;\n onToggleStrikethrough?: () => void;\n onToggleSuperscript?: () => void;\n onToggleSubscript?: () => void;\n}) {\n const [open, setOpen] = React.useState(false);\n\n return (\n <div className=\"relative\">\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label=\"More text formatting\"\n aria-expanded={open}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => setOpen((value) => !value)}\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}\n >\n <MoreHorizontal className=\"h-3.5 w-3.5\" />\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n More text formatting\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n {open ? (\n <div className=\"absolute left-0 top-9 z-50 w-[220px] rounded-lg bg-canvas p-2 shadow-lg ring-1 ring-border\">\n <div className=\"mb-1 px-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-tertiary\">\n Text styling\n </div>\n <div className=\"grid grid-cols-3 gap-1\">\n <ToolbarPopoverActionButton\n active={props.formattingState?.strikethrough ?? false}\n ariaLabel=\"Strikethrough\"\n disabled={props.disabled}\n icon={<Strikethrough className=\"h-3.5 w-3.5\" />}\n onClick={() => {\n props.onToggleStrikethrough?.();\n setOpen(false);\n }}\n />\n <ToolbarPopoverActionButton\n active={props.formattingState?.superscript ?? false}\n ariaLabel=\"Superscript\"\n disabled={props.disabled}\n icon={<Superscript className=\"h-3.5 w-3.5\" />}\n onClick={() => {\n props.onToggleSuperscript?.();\n setOpen(false);\n }}\n />\n <ToolbarPopoverActionButton\n active={props.formattingState?.subscript ?? false}\n ariaLabel=\"Subscript\"\n disabled={props.disabled}\n icon={<Subscript className=\"h-3.5 w-3.5\" />}\n onClick={() => {\n props.onToggleSubscript?.();\n setOpen(false);\n }}\n />\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction ToolbarColorPopover(props: {\n ariaLabel: string;\n colors: ReadonlyArray<{ value: string | null; label: string }>;\n disabled: boolean;\n icon: React.ReactNode;\n title: string;\n onSelect: (value: string | null) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n\n return (\n <div className=\"relative\">\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label={props.ariaLabel}\n aria-expanded={open}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => setOpen((value) => !value)}\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}\n >\n {props.icon}\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n {props.title}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n {open ? (\n <div className=\"absolute left-0 top-9 z-50 w-[180px] rounded-lg bg-canvas p-2 shadow-lg ring-1 ring-border\">\n <div className=\"mb-1 px-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-tertiary\">\n {props.title}\n </div>\n <div className=\"grid grid-cols-3 gap-1\">\n {props.colors.map((color) => (\n <button\n key={`${props.ariaLabel}-${color.label}`}\n type=\"button\"\n aria-label={`${props.title} ${color.label}`}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => {\n props.onSelect(color.value);\n setOpen(false);\n }}\n className={`inline-flex h-8 items-center justify-center rounded-md border border-border text-[10px] font-medium text-primary transition-transform hover:scale-[1.04] disabled:cursor-not-allowed disabled:opacity-40 ${\n color.value ? \"\" : \"bg-surface\"\n } ${focusRingClass}`}\n style={color.value ? { backgroundColor: color.value } : undefined}\n >\n {color.value ? <span className=\"sr-only\">{color.label}</span> : \"None\"}\n </button>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction ToolbarAlignmentPopover(props: {\n activeAlignment?: FormattingAlignment;\n disabled: boolean;\n onSelect: (alignment: FormattingAlignment) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n const alignments = [\n { value: \"left\" as const, label: \"Align left\", icon: <AlignLeft className=\"h-3.5 w-3.5\" /> },\n { value: \"center\" as const, label: \"Align center\", icon: <AlignCenter className=\"h-3.5 w-3.5\" /> },\n { value: \"right\" as const, label: \"Align right\", icon: <AlignRight className=\"h-3.5 w-3.5\" /> },\n { value: \"justify\" as const, label: \"Align justify\", icon: <AlignJustify className=\"h-3.5 w-3.5\" /> },\n ];\n\n return (\n <div className=\"relative\">\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label=\"Paragraph alignment\"\n aria-expanded={open}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => setOpen((value) => !value)}\n className={`inline-flex h-7 w-7 items-center justify-center rounded-md text-secondary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}\n >\n {(alignments.find((entry) => entry.value === props.activeAlignment) ?? alignments[0])?.icon}\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n Paragraph alignment\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n {open ? (\n <div className=\"absolute left-0 top-9 z-50 w-[220px] rounded-lg bg-canvas p-2 shadow-lg ring-1 ring-border\">\n <div className=\"mb-1 px-1 text-[10px] font-semibold uppercase tracking-[0.12em] text-tertiary\">\n Paragraph alignment\n </div>\n <div className=\"grid grid-cols-2 gap-1\">\n {alignments.map((entry) => (\n <ToolbarPopoverActionButton\n key={entry.value}\n active={props.activeAlignment === entry.value}\n ariaLabel={entry.label}\n disabled={props.disabled}\n icon={entry.icon}\n onClick={() => {\n props.onSelect(entry.value);\n setOpen(false);\n }}\n />\n ))}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction ToolbarInsertMenu(props: {\n disabled: boolean;\n onInsertPageBreak?: () => void;\n onInsertTable?: () => void;\n onInsertSectionBreak?: (type: SectionBreakType) => void;\n onInsertImage?: (options: InsertImageOptions) => void;\n}) {\n const [open, setOpen] = React.useState(false);\n\n async function handleImageChange(event: React.ChangeEvent<HTMLInputElement>): Promise<void> {\n const file = event.target.files?.[0];\n if (!file || props.disabled || !props.onInsertImage) {\n event.target.value = \"\";\n return;\n }\n const data = new Uint8Array(await file.arrayBuffer());\n props.onInsertImage({\n data,\n mimeType: file.type || \"image/png\",\n altText: file.name,\n });\n setOpen(false);\n event.target.value = \"\";\n }\n\n return (\n <div className=\"relative\">\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label=\"Insert\"\n aria-expanded={open}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => setOpen((value) => !value)}\n className={`inline-flex h-7 items-center gap-1 rounded-md border border-border bg-canvas px-2 text-xs font-medium text-primary transition-colors hover:bg-surface outline-none disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}\n >\n Insert\n <ChevronDown className=\"h-3.5 w-3.5 text-tertiary\" />\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n Insert\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n {open ? (\n <div className=\"absolute left-0 top-9 z-50 w-[220px] rounded-lg bg-canvas p-2 shadow-lg ring-1 ring-border\">\n <div className=\"space-y-1\">\n <ToolbarMenuButton\n ariaLabel=\"Insert page break\"\n disabled={props.disabled || !props.onInsertPageBreak}\n icon={<Minus className=\"h-3.5 w-3.5\" />}\n label=\"Page break\"\n onClick={() => {\n props.onInsertPageBreak?.();\n setOpen(false);\n }}\n />\n <ToolbarMenuButton\n ariaLabel=\"Insert table\"\n disabled={props.disabled || !props.onInsertTable}\n icon={<Rows3 className=\"h-3.5 w-3.5\" />}\n label=\"Table\"\n onClick={() => {\n props.onInsertTable?.();\n setOpen(false);\n }}\n />\n <label\n className={`flex h-8 cursor-pointer items-center gap-2 rounded-md px-2 text-xs font-medium text-primary transition-colors hover:bg-surface ${\n props.disabled || !props.onInsertImage ? \"pointer-events-none opacity-40\" : \"\"\n }`}\n >\n <ImagePlus className=\"h-3.5 w-3.5 text-secondary\" />\n <span>Image</span>\n <input\n accept=\"image/png,image/jpeg,image/gif\"\n aria-label=\"Insert image\"\n className=\"sr-only\"\n disabled={props.disabled || !props.onInsertImage}\n type=\"file\"\n onChange={(event) => {\n void handleImageChange(event);\n }}\n />\n </label>\n <ToolbarMenuButton\n ariaLabel=\"Insert next-page section break\"\n disabled={props.disabled || !props.onInsertSectionBreak}\n icon={<FileText className=\"h-3.5 w-3.5\" />}\n label=\"Next-page section break\"\n onClick={() => {\n props.onInsertSectionBreak?.(\"nextPage\");\n setOpen(false);\n }}\n />\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction ToolbarPopoverActionButton(props: {\n active: boolean;\n ariaLabel: string;\n disabled: boolean;\n icon: React.ReactNode;\n onClick?: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={props.ariaLabel}\n aria-pressed={props.active}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onClick}\n className={`inline-flex h-8 items-center justify-center rounded-md border border-border transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${\n props.active ? \"bg-accent-soft text-accent\" : \"bg-canvas text-secondary hover:bg-surface\"\n } ${focusRingClass}`}\n >\n {props.icon}\n </button>\n );\n}\n\nfunction ToolbarMenuButton(props: {\n ariaLabel: string;\n disabled: boolean;\n icon: React.ReactNode;\n label: string;\n onClick?: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={props.ariaLabel}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onClick}\n className={`flex h-8 w-full items-center gap-2 rounded-md px-2 text-left text-xs font-medium text-primary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}\n >\n <span className=\"text-secondary\">{props.icon}</span>\n <span>{props.label}</span>\n </button>\n );\n}\n\nfunction storyLabel(target: EditorStoryTarget): string {\n switch (target.kind) {\n case \"header\":\n return `Header (${target.variant})`;\n case \"footer\":\n return `Footer (${target.variant})`;\n case \"footnote\":\n return \"Footnote\";\n case \"endnote\":\n return \"Endnote\";\n default:\n return \"Document\";\n }\n}\n","import React, {\n type CSSProperties,\n type FocusEventHandler,\n type ReactNode,\n type Ref,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport * as Tooltip from \"@radix-ui/react-tooltip\";\nimport { ChevronLeft, ChevronRight, List } from \"lucide-react\";\n\nimport type {\n CommentSidebarThreadSnapshot,\n DocumentNavigationSnapshot,\n EditorViewStateSnapshot,\n FormattingStateSnapshot,\n FormattingAlignment,\n HeaderFooterLinkPatch,\n InteractionGuardSnapshot,\n InsertImageOptions,\n RuntimeRenderSnapshot,\n SectionPageNumberingPatch,\n SectionBreakType,\n StyleCatalogSnapshot,\n SurfaceBlockSnapshot,\n TrackedChangeEntrySnapshot,\n WordReviewEditorChromeVisibility,\n WorkflowScopeSnapshot,\n WorkspaceMode,\n ZoomLevel,\n} from \"../api/public-types\";\nimport { findPageForOffset } from \"../runtime/document-navigation.ts\";\nimport {\n DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP,\n estimateBlockHeight,\n estimateParagraphLineCount,\n estimateParagraphLineHeight,\n getUsableColumnWidth,\n} from \"../runtime/page-layout-estimation.ts\";\nimport {\n incrementInvalidationCounter,\n recordPerfSample,\n} from \"./editor-surface/perf-probe.ts\";\nimport { computeLineMarkersIfEnabled } from \"./page-chrome-model.ts\";\nimport type { SessionCapabilities } from \"../runtime/session-capabilities\";\nimport type {\n SelectionToolbarAnchor,\n SelectionToolbarModel,\n SuggestionCardModel,\n} from \"../ui/headless/selection-toolbar-model\";\nimport type { MarkupDisplay } from \"../ui/headless/comment-decoration-model\";\nimport type { EditorCommandBag } from \"../ui/editor-command-bag.ts\";\nimport { preserveEditorSelectionMouseDown } from \"../ui/headless/preserve-editor-selection\";\nimport { TwAlertBanner } from \"./chrome/tw-alert-banner\";\nimport { TwImageContextToolbar, type ActiveImageContext } from \"./chrome/tw-image-context-toolbar\";\nimport { TwLayoutPanel } from \"./chrome/tw-layout-panel\";\nimport { TwObjectContextToolbar, type ActiveObjectContext } from \"./chrome/tw-object-context-toolbar\";\nimport { TwPageRuler } from \"./chrome/tw-page-ruler\";\nimport { TwSelectionToolbar } from \"./chrome/tw-selection-toolbar\";\nimport { TwSuggestionCard } from \"./chrome/tw-suggestion-card\";\nimport { TwTableContextToolbar } from \"./chrome/tw-table-context-toolbar\";\nimport { TwReviewRail, type ReviewRailTab } from \"./review/tw-review-rail\";\nimport { TwStatusBar } from \"./status/tw-status-bar\";\nimport { TwToolbar, type ToolbarInteractionPolicy } from \"./toolbar/tw-toolbar\";\n\nexport type ReviewWorkspaceChromeVisibility = WordReviewEditorChromeVisibility;\n\nexport interface TwReviewWorkspaceProps {\n snapshot: RuntimeRenderSnapshot;\n viewState: EditorViewStateSnapshot;\n markupDisplay: MarkupDisplay;\n currentUserId?: string;\n capabilities?: SessionCapabilities;\n reviewMode?: \"editing\" | \"review\";\n document: ReactNode;\n workspaceMode: WorkspaceMode;\n zoomLevel?: ZoomLevel;\n formattingState?: FormattingStateSnapshot;\n styleCatalog?: StyleCatalogSnapshot;\n activeRailTab: ReviewRailTab;\n activeCommentId?: string;\n activeRevisionId?: string;\n showTrackedChanges: boolean;\n workflowScopeSnapshot?: WorkflowScopeSnapshot | null;\n interactionGuardSnapshot?: InteractionGuardSnapshot;\n commands: EditorCommandBag;\n selectionToolbar?: SelectionToolbarModel | null;\n suggestionCard?: SuggestionCardModel | null;\n selectionToolbarAnchor?: SelectionToolbarAnchor | null;\n documentNavigation?: DocumentNavigationSnapshot;\n onWorkspaceModeChange?: (value: WorkspaceMode) => void;\n onZoomChange?: (level: ZoomLevel) => void;\n onActiveRailTabChange?: (value: ReviewRailTab) => void;\n onShowTrackedChangesChange?: (show: boolean) => void;\n onUndo?: () => void;\n onRedo?: () => void;\n onSetParagraphStyle?: (styleId: string) => void;\n onToggleBold?: () => void;\n onToggleItalic?: () => void;\n onToggleUnderline?: () => void;\n onSetSelectionTextColor?: (color: string) => void;\n onSetSelectionHighlightColor?: (color: string | null) => void;\n onToggleStrikethrough?: () => void;\n onToggleSuperscript?: () => void;\n onToggleSubscript?: () => void;\n onSetFontFamily?: (fontFamily: string) => void;\n onSetFontSize?: (fontSize: number) => void;\n onSetTextColor?: (color: string) => void;\n onSetHighlightColor?: (color: string | null) => void;\n onSetAlignment?: (alignment: FormattingAlignment) => void;\n onOutdent?: () => void;\n onIndent?: () => void;\n onAddComment?: () => void;\n onInsertPageBreak?: () => void;\n onInsertTable?: () => void;\n onInsertSectionBreak?: (type: SectionBreakType) => void;\n onInsertImage?: (options: InsertImageOptions) => void;\n onSetTableStyle?: (styleId: string) => void;\n onAddRowBefore?: () => void;\n onAddRowAfter?: () => void;\n onAddColumnBefore?: () => void;\n onAddColumnAfter?: () => void;\n onDeleteRow?: () => void;\n onDeleteColumn?: () => void;\n onDeleteTable?: () => void;\n onMergeCells?: () => void;\n onSplitCell?: () => void;\n onSetCellBackground?: (color: string) => void;\n activeImageContext?: ActiveImageContext | null;\n activeObjectContext?: ActiveObjectContext | null;\n onSetImageLayout?: (\n mediaId: string,\n dimensions: { widthEmu: number; heightEmu: number },\n ) => void;\n onSetImageFrame?: (\n mediaId: string,\n offsets: { horizontalOffsetEmu?: number; verticalOffsetEmu?: number },\n ) => void;\n onDeleteSectionBreak?: (sectionIndex: number) => void;\n onUpdateSectionLayout?: (\n sectionIndex: number,\n patch: {\n pageSize?: { width?: number; height?: number; orientation?: \"portrait\" | \"landscape\" };\n pageMargins?: {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n header?: number;\n footer?: number;\n gutter?: number;\n };\n columns?: {\n count?: number;\n space?: number;\n equalWidth?: boolean;\n columns?: Array<{ width: number; space?: number }>;\n separator?: boolean;\n };\n titlePage?: boolean;\n sectionType?: SectionBreakType;\n },\n ) => void;\n onSetSectionPageNumbering?: (\n sectionIndex: number,\n patch: SectionPageNumberingPatch | null,\n ) => void;\n onSetHeaderFooterLink?: (\n sectionIndex: number,\n patch: HeaderFooterLinkPatch,\n ) => void;\n onAddCommentFromSelection?: () => void;\n onExport?: () => void;\n onDismissSelectionToolbar?: () => void;\n onAcceptSuggestion?: () => void;\n onRejectSuggestion?: () => void;\n onEditSuggestion?: () => void;\n onAddCommentFromSuggestion?: () => void;\n onSelectionToolbarFocusCapture?: FocusEventHandler<HTMLDivElement>;\n onSelectionToolbarBlurCapture?: FocusEventHandler<HTMLDivElement>;\n selectionToolbarRef?: Ref<HTMLDivElement>;\n onOpenComment?: (thread: CommentSidebarThreadSnapshot) => void;\n onResolveComment?: (commentId: string) => void;\n onReopenComment?: (commentId: string) => void;\n onAddReply?: (commentId: string, body: string) => void;\n onEditBody?: (commentId: string, body: string) => void;\n onOpenRevision?: (revision: TrackedChangeEntrySnapshot) => void;\n onAcceptRevision?: (revisionId: string) => void;\n onRejectRevision?: (revisionId: string) => void;\n onAcceptAllChanges?: () => void;\n onRejectAllChanges?: () => void;\n onCloseStory?: () => void;\n onOpenHeaderStory?: () => void;\n onOpenFooterStory?: () => void;\n onSetParagraphIndentation?: (indentation: {\n left?: number;\n right?: number;\n firstLine?: number;\n hanging?: number;\n }) => void;\n onSetParagraphTabStops?: (tabStops: Array<{ pos: number; val?: string; leader?: string }>) => void;\n onRestartNumbering?: () => void;\n onContinueNumbering?: () => void;\n onNavigateHeading?: (headingId: string) => void;\n chromeVisibility?: Partial<ReviewWorkspaceChromeVisibility>;\n}\n\nexport function TwReviewWorkspace(inputProps: TwReviewWorkspaceProps) {\n const props = {\n ...inputProps,\n ...inputProps.commands,\n } as TwReviewWorkspaceProps & EditorCommandBag;\n const { snapshot, viewState } = props;\n const selectionToolbarRootRef = useRef<HTMLDivElement>(null);\n const caps = props.capabilities;\n const isPageWorkspace = props.workspaceMode === \"page\";\n const markupDisplay = props.markupDisplay;\n const [navOpen, setNavOpen] = useState(false);\n const [layoutToolsOpen, setLayoutToolsOpen] = useState(false);\n const zoomLevel = props.zoomLevel ?? 100;\n const zoomScale = typeof zoomLevel === \"number\" ? zoomLevel / 100 : 1;\n const preserveOnlyCount = caps?.preserveOnlyCount ??\n snapshot.compatibility.featureEntries.filter(\n (entry) => entry.featureClass === \"preserve-only\",\n ).length;\n const blockedReasons =\n props.interactionGuardSnapshot?.blockedReasons ??\n props.workflowScopeSnapshot?.blockedReasons ??\n [];\n const chromeVisibility: ReviewWorkspaceChromeVisibility = {\n toolbar: true,\n alerts: true,\n selectionOverlay: true,\n contextToolbars: true,\n pageChrome: true,\n statusBar: true,\n reviewRail: true,\n ...props.chromeVisibility,\n };\n const showReviewRail = chromeVisibility.reviewRail && (caps?.reviewRailVisible ?? true);\n const headings = props.documentNavigation?.headings ?? [];\n const headerVariant = snapshot.pageLayout?.headerVariants[0]?.variant ?? \"default\";\n const footerVariant = snapshot.pageLayout?.footerVariants[0]?.variant ?? \"default\";\n const selectionPosition =\n viewState.selection.activeRange.kind === \"node\"\n ? viewState.selection.activeRange.at\n : viewState.selection.head;\n const activeParagraphLayout = useMemo(\n () => resolveActiveParagraphLayout(snapshot.surface, selectionPosition),\n [selectionPosition, snapshot.surface],\n );\n const isTableContext = Boolean(\n props.formattingState?.breadcrumb.some((item) => item.kind === \"table\" || item.kind === \"table_cell\" || item.kind === \"table_row\"),\n );\n const contextualSurface =\n props.activeImageContext\n ? \"image\"\n : props.activeObjectContext\n ? \"object\"\n : isTableContext\n ? \"table\"\n : null;\n const pageChromeModel = useMemo(\n () =>\n buildPageChromeModel(\n snapshot.surface,\n snapshot.pageLayout,\n props.documentNavigation,\n snapshot.activeStory,\n ),\n [props.documentNavigation, snapshot.activeStory, snapshot.pageLayout, snapshot.surface],\n );\n const selectionToolbarPlacement = resolveSelectionToolbarPlacement(\n props.selectionToolbarAnchor,\n selectionToolbarRootRef.current,\n zoomScale,\n );\n const activePage = props.documentNavigation?.pages[props.documentNavigation.activePageIndex] ?? null;\n const pageShellMetrics = useMemo(\n () => buildPageShellMetrics(snapshot.pageLayout),\n [snapshot.pageLayout],\n );\n const hidePageBorderForActiveEditing =\n isPageWorkspace &&\n snapshot.activeStory.kind === \"main\" &&\n shouldHidePageBorderForSelection(viewState.selection);\n const effectiveSelectionMode = props.interactionGuardSnapshot?.effectiveMode ?? \"edit\";\n const allowLocalChromeMutations = Boolean(caps?.canEdit) && effectiveSelectionMode === \"edit\";\n const pageChromeReadOnly =\n snapshot.readOnly ||\n snapshot.activeStory.kind !== \"main\" ||\n effectiveSelectionMode !== \"edit\";\n const toolbarInteractionPolicy: ToolbarInteractionPolicy | undefined = caps\n ? {\n mode: effectiveSelectionMode,\n canFormatText: caps.canEdit && effectiveSelectionMode === \"edit\",\n canInsertStructural: caps.canEdit && effectiveSelectionMode === \"edit\",\n canAddComment:\n caps.canAddComment &&\n effectiveSelectionMode !== \"view\" &&\n effectiveSelectionMode !== \"blocked\",\n }\n : undefined;\n\n useEffect(() => {\n recordPerfSample(\"workspace.chrome\");\n incrementInvalidationCounter(\"workspace.chrome.recomputes\");\n }, [activeParagraphLayout, pageChromeModel, pageShellMetrics]);\n\n useEffect(() => {\n if (isPageWorkspace && snapshot.activeStory.kind !== \"main\") {\n setLayoutToolsOpen(true);\n }\n }, [isPageWorkspace, snapshot.activeStory.kind]);\n\n const dismissSelectionToolbar = useCallback(() => {\n props.onDismissSelectionToolbar?.();\n }, [props.onDismissSelectionToolbar]);\n\n const runWithSelectionToolbarDismiss = useCallback(\n (action?: () => void) => () => {\n dismissSelectionToolbar();\n action?.();\n },\n [dismissSelectionToolbar],\n );\n\n return (\n <Tooltip.Provider delayDuration={400}>\n <div className=\"flex h-full flex-col bg-canvas text-primary\">\n {chromeVisibility.toolbar ? <TwToolbar\n sourceLabel={snapshot.sourceLabel}\n capabilities={caps}\n compatibility={snapshot.compatibility}\n warnings={snapshot.warnings}\n interactionPolicy={toolbarInteractionPolicy}\n workspaceMode={props.workspaceMode}\n zoomLevel={props.zoomLevel}\n formattingState={props.formattingState}\n styleCatalog={props.styleCatalog}\n showTrackedChanges={props.showTrackedChanges}\n onUndo={runWithSelectionToolbarDismiss(props.onUndo)}\n onRedo={runWithSelectionToolbarDismiss(props.onRedo)}\n onSetParagraphStyle={props.onSetParagraphStyle\n ? (styleId) => {\n dismissSelectionToolbar();\n props.onSetParagraphStyle?.(styleId);\n }\n : undefined}\n onToggleBold={runWithSelectionToolbarDismiss(props.onToggleBold)}\n onToggleItalic={runWithSelectionToolbarDismiss(props.onToggleItalic)}\n onToggleUnderline={runWithSelectionToolbarDismiss(props.onToggleUnderline)}\n onToggleStrikethrough={runWithSelectionToolbarDismiss(props.onToggleStrikethrough)}\n onToggleSuperscript={runWithSelectionToolbarDismiss(props.onToggleSuperscript)}\n onToggleSubscript={runWithSelectionToolbarDismiss(props.onToggleSubscript)}\n onSetFontFamily={props.onSetFontFamily\n ? (fontFamily) => {\n dismissSelectionToolbar();\n props.onSetFontFamily?.(fontFamily);\n }\n : undefined}\n onSetFontSize={props.onSetFontSize\n ? (fontSize) => {\n dismissSelectionToolbar();\n props.onSetFontSize?.(fontSize);\n }\n : undefined}\n onSetTextColor={props.onSetTextColor\n ? (color) => {\n dismissSelectionToolbar();\n props.onSetTextColor?.(color);\n }\n : undefined}\n onSetHighlightColor={props.onSetHighlightColor\n ? (color) => {\n dismissSelectionToolbar();\n props.onSetHighlightColor?.(color);\n }\n : undefined}\n onSetAlignment={props.onSetAlignment\n ? (alignment) => {\n dismissSelectionToolbar();\n props.onSetAlignment?.(alignment);\n }\n : undefined}\n onOutdent={runWithSelectionToolbarDismiss(props.onOutdent)}\n onIndent={runWithSelectionToolbarDismiss(props.onIndent)}\n onAddComment={runWithSelectionToolbarDismiss(props.onAddComment)}\n onInsertPageBreak={runWithSelectionToolbarDismiss(props.onInsertPageBreak)}\n onInsertTable={runWithSelectionToolbarDismiss(props.onInsertTable)}\n onInsertSectionBreak={props.onInsertSectionBreak\n ? (type) => {\n dismissSelectionToolbar();\n props.onInsertSectionBreak?.(type);\n }\n : undefined}\n onInsertImage={props.onInsertImage\n ? (options) => {\n dismissSelectionToolbar();\n props.onInsertImage?.(options);\n }\n : undefined}\n onExport={runWithSelectionToolbarDismiss(props.onExport)}\n activeStory={snapshot.activeStory}\n onCloseStory={props.onCloseStory\n ? runWithSelectionToolbarDismiss(props.onCloseStory)\n : undefined}\n onWorkspaceModeChange={(value) => {\n dismissSelectionToolbar();\n props.onWorkspaceModeChange(value);\n }}\n onZoomChange={props.onZoomChange\n ? (level) => {\n dismissSelectionToolbar();\n props.onZoomChange?.(level);\n }\n : undefined}\n onShowTrackedChangesChange={(show) => {\n dismissSelectionToolbar();\n props.onShowTrackedChangesChange(show);\n }}\n blockedReasons={blockedReasons}\n /> : null}\n\n {chromeVisibility.alerts ? <TwAlertBanner\n snapshot={snapshot}\n preserveOnlyCount={preserveOnlyCount}\n workflowBlockedReasons={blockedReasons}\n /> : null}\n\n <div className=\"flex flex-1 min-h-0\">\n {/* Collapsible document navigator — page mode only */}\n {isPageWorkspace && chromeVisibility.pageChrome ? (\n <aside\n aria-label=\"Document navigator\"\n className={`shrink-0 border-r border-border bg-surface transition-[width] duration-200 ${\n navOpen ? \"w-48\" : \"w-0\"\n } overflow-hidden`}\n >\n {navOpen ? (\n <div className=\"flex h-full flex-col\">\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-border\">\n <span className=\"text-xs font-medium text-secondary uppercase tracking-wider\">Navigator</span>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label=\"Collapse navigator\"\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => {\n dismissSelectionToolbar();\n setNavOpen(false);\n }}\n className=\"inline-flex h-6 w-6 items-center justify-center rounded-md text-secondary hover:bg-surface-hover transition-colors\"\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n Collapse navigator\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n </div>\n <nav className=\"flex-1 overflow-y-auto px-2 py-2\" aria-label=\"Document headings\">\n {headings.length > 0 ? (\n <ul className=\"space-y-0.5\">\n {headings.map((entry) => (\n <li key={entry.headingId}>\n <button\n type=\"button\"\n className=\"block w-full truncate rounded-md px-2 py-1 text-left text-xs text-primary hover:bg-surface-hover\"\n style={{ paddingLeft: `${8 + (entry.level - 1) * 12}px` }}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => {\n dismissSelectionToolbar();\n props.onNavigateHeading?.(entry.headingId);\n setNavOpen(false);\n }}\n >\n {entry.text}\n </button>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"px-2 py-4 text-xs text-tertiary\">No headings found.</p>\n )}\n </nav>\n </div>\n ) : null}\n </aside>\n ) : null}\n\n {/* Navigator expand toggle — page mode only when collapsed */}\n {isPageWorkspace && chromeVisibility.pageChrome && !navOpen ? (\n <div className=\"shrink-0 flex items-start pt-2 pl-1\">\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label=\"Open document navigator\"\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => {\n dismissSelectionToolbar();\n setNavOpen(true);\n }}\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-md text-secondary hover:bg-surface-hover transition-colors\"\n >\n <List className=\"h-3.5 w-3.5\" />\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\" sideOffset={6}>\n Open document navigator\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n </div>\n ) : null}\n\n {/* Document column */}\n <div className=\"flex flex-1 flex-col min-w-0\">\n <div\n className={`flex-1 overflow-y-auto ${isPageWorkspace ? \"bg-surface\" : \"bg-canvas\"}`}\n data-wre-scroll-root=\"true\"\n >\n <div\n ref={selectionToolbarRootRef}\n className={`mx-auto min-h-full ${\n isPageWorkspace\n ? \"wre-page-chrome wre-page-surface relative max-w-[840px] my-8 overflow-hidden\"\n : \"wre-canvas-surface relative bg-canvas\"\n }`}\n style={isPageWorkspace && zoomScale !== 1 ? { transform: `scale(${zoomScale})`, transformOrigin: \"top center\" } : undefined}\n >\n {isPageWorkspace && chromeVisibility.pageChrome && snapshot.pageLayout ? (\n <div className=\"border-b border-border/70 bg-surface/65 px-5 py-3\" data-testid=\"page-context-summary\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <div className=\"flex flex-wrap items-center gap-2 text-xs text-secondary\">\n <span className=\"rounded-full bg-canvas px-2 py-1 font-medium text-primary\">\n {activePage\n ? `Page ${activePage.pageIndex + 1} of ${props.documentNavigation?.pageCount ?? 1}`\n : \"Page workspace\"}\n </span>\n <span>{`Section ${snapshot.pageLayout.sectionIndex + 1}`}</span>\n <span className=\"uppercase tracking-[0.12em] text-tertiary\">\n {snapshot.pageLayout.orientation}\n </span>\n </div>\n <div className=\"flex items-center gap-2\">\n {snapshot.activeStory.kind !== \"main\" ? (\n <button\n type=\"button\"\n aria-label=\"Return to document body\"\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={runWithSelectionToolbarDismiss(props.onCloseStory)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border bg-canvas px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface\"\n >\n Body\n </button>\n ) : null}\n {snapshot.activeStory.kind === \"main\" && snapshot.pageLayout.sectionIndex > 0 ? (\n <>\n <button\n type=\"button\"\n aria-label=\"Link header to previous\"\n disabled={!props.onSetHeaderFooterLink || !allowLocalChromeMutations}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => {\n dismissSelectionToolbar();\n props.onSetHeaderFooterLink?.(snapshot.pageLayout!.sectionIndex, {\n kind: \"header\",\n variant: headerVariant,\n linkToPrevious: true,\n });\n }}\n className=\"inline-flex items-center gap-1 rounded-md border border-border bg-canvas px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40\"\n >\n Link header\n </button>\n <button\n type=\"button\"\n aria-label=\"Link footer to previous\"\n disabled={!props.onSetHeaderFooterLink || !allowLocalChromeMutations}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => {\n dismissSelectionToolbar();\n props.onSetHeaderFooterLink?.(snapshot.pageLayout!.sectionIndex, {\n kind: \"footer\",\n variant: footerVariant,\n linkToPrevious: true,\n });\n }}\n className=\"inline-flex items-center gap-1 rounded-md border border-border bg-canvas px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40\"\n >\n Link footer\n </button>\n </>\n ) : null}\n <button\n type=\"button\"\n aria-label=\"Toggle layout tools\"\n aria-expanded={layoutToolsOpen}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => {\n dismissSelectionToolbar();\n setLayoutToolsOpen((open) => !open);\n }}\n className=\"inline-flex items-center gap-1 rounded-md border border-border bg-canvas px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface\"\n >\n <ChevronRight className={`h-3.5 w-3.5 transition-transform ${layoutToolsOpen ? \"rotate-90\" : \"\"}`} />\n Layout tools\n </button>\n </div>\n </div>\n </div>\n ) : null}\n {isPageWorkspace && chromeVisibility.pageChrome && snapshot.pageLayout && layoutToolsOpen ? (\n <div className=\"px-5 pt-3\">\n <TwPageRuler\n pageLayout={snapshot.pageLayout}\n viewState={viewState}\n paragraphLayout={activeParagraphLayout}\n readOnly={pageChromeReadOnly}\n onReturnToBody={props.onCloseStory\n ? runWithSelectionToolbarDismiss(props.onCloseStory)\n : () => undefined}\n onOpenHeader={props.onOpenHeaderStory\n ? runWithSelectionToolbarDismiss(props.onOpenHeaderStory)\n : undefined}\n onOpenFooter={props.onOpenFooterStory\n ? runWithSelectionToolbarDismiss(props.onOpenFooterStory)\n : undefined}\n onSetIndentation={props.onSetParagraphIndentation\n ? (indentation) => {\n dismissSelectionToolbar();\n props.onSetParagraphIndentation?.(indentation);\n }\n : undefined}\n onSetTabStops={props.onSetParagraphTabStops\n ? (tabStops) => {\n dismissSelectionToolbar();\n props.onSetParagraphTabStops?.(tabStops);\n }\n : undefined}\n onRestartNumbering={props.onRestartNumbering\n ? runWithSelectionToolbarDismiss(props.onRestartNumbering)\n : undefined}\n onContinueNumbering={props.onContinueNumbering\n ? runWithSelectionToolbarDismiss(props.onContinueNumbering)\n : undefined}\n />\n <TwLayoutPanel\n pageLayout={snapshot.pageLayout}\n readOnly={pageChromeReadOnly}\n onInsertSectionBreak={props.onInsertSectionBreak\n ? (type) => {\n dismissSelectionToolbar();\n props.onInsertSectionBreak?.(type);\n }\n : undefined}\n onDeleteSectionBreak={props.onDeleteSectionBreak\n ? (sectionIndex) => {\n dismissSelectionToolbar();\n props.onDeleteSectionBreak?.(sectionIndex);\n }\n : undefined}\n onUpdateSectionLayout={props.onUpdateSectionLayout\n ? (sectionIndex, patch) => {\n dismissSelectionToolbar();\n props.onUpdateSectionLayout?.(sectionIndex, patch);\n }\n : undefined}\n onSetSectionPageNumbering={props.onSetSectionPageNumbering\n ? (sectionIndex, patch) => {\n dismissSelectionToolbar();\n props.onSetSectionPageNumbering?.(sectionIndex, patch);\n }\n : undefined}\n />\n </div>\n ) : null}\n {chromeVisibility.contextToolbars && contextualSurface ? (\n <div className=\"px-5 pt-3 space-y-3\">\n {contextualSurface === \"table\" ? (\n <TwTableContextToolbar\n disabled={!allowLocalChromeMutations}\n tableStyles={props.styleCatalog?.tables ?? []}\n onSetTableStyle={props.onSetTableStyle\n ? (styleId) => {\n dismissSelectionToolbar();\n props.onSetTableStyle?.(styleId);\n }\n : undefined}\n onAddRowBefore={runWithSelectionToolbarDismiss(props.onAddRowBefore)}\n onAddRowAfter={runWithSelectionToolbarDismiss(props.onAddRowAfter)}\n onAddColumnBefore={runWithSelectionToolbarDismiss(props.onAddColumnBefore)}\n onAddColumnAfter={runWithSelectionToolbarDismiss(props.onAddColumnAfter)}\n onDeleteRow={runWithSelectionToolbarDismiss(props.onDeleteRow)}\n onDeleteColumn={runWithSelectionToolbarDismiss(props.onDeleteColumn)}\n onDeleteTable={runWithSelectionToolbarDismiss(props.onDeleteTable)}\n onMergeCells={runWithSelectionToolbarDismiss(props.onMergeCells)}\n onSplitCell={runWithSelectionToolbarDismiss(props.onSplitCell)}\n onSetCellBackground={props.onSetCellBackground\n ? (color) => {\n dismissSelectionToolbar();\n props.onSetCellBackground?.(color);\n }\n : undefined}\n />\n ) : null}\n {contextualSurface === \"image\" && props.activeImageContext ? (\n <TwImageContextToolbar\n activeImage={props.activeImageContext}\n disabled={!allowLocalChromeMutations}\n onSetImageLayout={props.onSetImageLayout\n ? (mediaId, dimensions) => {\n dismissSelectionToolbar();\n props.onSetImageLayout?.(mediaId, dimensions);\n }\n : undefined}\n onSetImageFrame={props.onSetImageFrame\n ? (mediaId, offsets) => {\n dismissSelectionToolbar();\n props.onSetImageFrame?.(mediaId, offsets);\n }\n : undefined}\n />\n ) : null}\n {contextualSurface === \"object\" && props.activeObjectContext ? (\n <TwObjectContextToolbar activeObject={props.activeObjectContext} />\n ) : null}\n </div>\n ) : null}\n {chromeVisibility.selectionOverlay && props.suggestionCard && selectionToolbarPlacement ? (\n <div className=\"pointer-events-none absolute inset-0 z-20\" data-testid=\"suggestion-card-overlay\">\n <div\n className=\"pointer-events-auto absolute\"\n data-placement={selectionToolbarPlacement.placement}\n style={selectionToolbarPlacement.style}\n >\n <TwSuggestionCard\n model={props.suggestionCard}\n onFocusCapture={props.onSelectionToolbarFocusCapture}\n onBlurCapture={props.onSelectionToolbarBlurCapture}\n onAccept={props.onAcceptSuggestion}\n onReject={props.onRejectSuggestion}\n onEditSuggestion={props.onEditSuggestion}\n onAddComment={props.onAddCommentFromSuggestion ?? props.onAddComment}\n />\n </div>\n </div>\n ) : null}\n {chromeVisibility.selectionOverlay && props.suggestionCard && !selectionToolbarPlacement ? (\n <div\n className=\"pointer-events-none absolute inset-x-0 top-0 z-20 flex justify-center px-4 pt-3\"\n data-testid=\"suggestion-card-fallback\"\n >\n <div className=\"pointer-events-auto\" data-placement=\"fallback\">\n <TwSuggestionCard\n model={props.suggestionCard}\n onFocusCapture={props.onSelectionToolbarFocusCapture}\n onBlurCapture={props.onSelectionToolbarBlurCapture}\n onAccept={props.onAcceptSuggestion}\n onReject={props.onRejectSuggestion}\n onEditSuggestion={props.onEditSuggestion}\n onAddComment={props.onAddCommentFromSuggestion ?? props.onAddComment}\n />\n </div>\n </div>\n ) : null}\n {chromeVisibility.selectionOverlay && props.selectionToolbar && !props.suggestionCard && selectionToolbarPlacement ? (\n <div className=\"pointer-events-none absolute inset-0 z-20\" data-testid=\"selection-toolbar-overlay\">\n <div\n className=\"pointer-events-auto absolute\"\n data-placement={selectionToolbarPlacement.placement}\n style={selectionToolbarPlacement.style}\n >\n <TwSelectionToolbar\n ref={props.selectionToolbarRef}\n model={props.selectionToolbar}\n disabledReason={props.selectionToolbar.disabledReason}\n onFocusCapture={props.onSelectionToolbarFocusCapture}\n onBlurCapture={props.onSelectionToolbarBlurCapture}\n onToggleBold={props.onToggleBold}\n onToggleItalic={props.onToggleItalic}\n onToggleUnderline={props.onToggleUnderline}\n onSetTextColor={props.onSetSelectionTextColor}\n onSetHighlightColor={props.onSetSelectionHighlightColor}\n onAddComment={props.onAddCommentFromSelection ?? props.onAddComment}\n />\n </div>\n </div>\n ) : null}\n {chromeVisibility.selectionOverlay && props.selectionToolbar && !props.suggestionCard && !selectionToolbarPlacement ? (\n <div\n className=\"pointer-events-none absolute inset-x-0 top-0 z-20 flex justify-center px-4 pt-3\"\n data-testid=\"selection-toolbar-fallback\"\n >\n <div className=\"pointer-events-auto\" data-placement=\"fallback\">\n <TwSelectionToolbar\n ref={props.selectionToolbarRef}\n model={props.selectionToolbar}\n disabledReason={props.selectionToolbar.disabledReason}\n onFocusCapture={props.onSelectionToolbarFocusCapture}\n onBlurCapture={props.onSelectionToolbarBlurCapture}\n onToggleBold={props.onToggleBold}\n onToggleItalic={props.onToggleItalic}\n onToggleUnderline={props.onToggleUnderline}\n onSetTextColor={props.onSetSelectionTextColor}\n onSetHighlightColor={props.onSetSelectionHighlightColor}\n onAddComment={props.onAddCommentFromSelection ?? props.onAddComment}\n />\n </div>\n </div>\n ) : null}\n <div\n className={isPageWorkspace ? \"relative\" : undefined}\n data-line-numbering={pageChromeModel.lineNumberingEnabled ? \"enabled\" : \"disabled\"}\n >\n {isPageWorkspace && chromeVisibility.pageChrome && pageChromeModel.lineNumberingEnabled ? (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-y-0 left-0 z-10\"\n data-testid=\"page-line-number-gutter\"\n style={{ width: `${pageChromeModel.gutterWidthPx}px` }}\n >\n {pageChromeModel.lineMarkers.map((marker) => (\n <span\n key={marker.id}\n className=\"absolute right-2 font-[family-name:var(--font-legal-sans)] text-[10px] font-medium tabular-nums tracking-[0.12em] text-tertiary/80\"\n style={{ top: `${marker.topPx}px` }}\n >\n {marker.label}\n </span>\n ))}\n </div>\n ) : null}\n <div\n className={isPageWorkspace && chromeVisibility.pageChrome && pageChromeModel.lineNumberingEnabled ? \"pl-12\" : undefined}\n style={isPageWorkspace ? pageShellMetrics.contentInsetStyle : undefined}\n >\n <div\n className={isPageWorkspace ? \"relative\" : undefined}\n data-document-grid={pageChromeModel.documentGridType}\n data-page-border-display={pageChromeModel.pageBorderDisplay}\n style={isPageWorkspace\n ? {\n ...pageChromeModel.documentGridStyle,\n ...pageShellMetrics.pageFrameStyle,\n }\n : pageChromeModel.documentGridStyle}\n >\n {isPageWorkspace && chromeVisibility.pageChrome ? (\n <div\n data-testid=\"page-header-band\"\n className=\"relative z-10 flex items-center justify-between border-b border-dashed border-border/60 px-4 text-[11px] text-secondary\"\n style={pageShellMetrics.headerBandStyle}\n >\n <span className=\"uppercase tracking-[0.12em] text-tertiary\">Header</span>\n {snapshot.pageLayout?.headerVariants[0] ? (\n <button\n type=\"button\"\n aria-label=\"Open header story\"\n onClick={props.onOpenHeaderStory}\n className=\"rounded-md px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface\"\n >\n Edit header\n </button>\n ) : null}\n </div>\n ) : null}\n {isPageWorkspace && chromeVisibility.pageChrome && pageChromeModel.showPageBorder && !hidePageBorderForActiveEditing ? (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 z-0 rounded-[2px]\"\n data-testid=\"page-border-overlay\"\n style={pageChromeModel.pageBorderStyle}\n />\n ) : null}\n <div className={isPageWorkspace ? \"relative z-10\" : undefined}>\n {props.document}\n </div>\n {isPageWorkspace && chromeVisibility.pageChrome ? (\n <div\n data-testid=\"page-footer-band\"\n className=\"relative z-10 flex items-center justify-between border-t border-dashed border-border/60 px-4 text-[11px] text-secondary\"\n style={pageShellMetrics.footerBandStyle}\n >\n <span className=\"uppercase tracking-[0.12em] text-tertiary\">Footer</span>\n {snapshot.pageLayout?.footerVariants[0] ? (\n <button\n type=\"button\"\n aria-label=\"Open footer story\"\n onClick={props.onOpenFooterStory}\n className=\"rounded-md px-2 py-1 text-xs font-medium text-primary transition-colors hover:bg-surface\"\n >\n Edit footer\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {chromeVisibility.statusBar ? (\n <TwStatusBar\n isDirty={snapshot.isDirty}\n isExportBlocked={snapshot.compatibility.blockExport}\n preserveOnlyCount={preserveOnlyCount}\n commentCount={snapshot.comments.totalCount}\n changeCount={snapshot.trackedChanges.totalCount}\n sessionId={snapshot.sessionId}\n />\n ) : null}\n </div>\n\n {/* Review rail — hidden in editing mode unless toggled */}\n {showReviewRail ? <TwReviewRail\n activeTab={props.activeRailTab}\n currentUserId={props.currentUserId}\n comments={snapshot.comments}\n trackedChanges={snapshot.trackedChanges}\n compatibility={snapshot.compatibility}\n warnings={snapshot.warnings}\n markupDisplay={markupDisplay}\n activeCommentId={props.activeCommentId}\n activeRevisionId={props.activeRevisionId}\n onActiveTabChange={props.onActiveRailTabChange}\n onOpenComment={props.onOpenComment}\n onResolveComment={props.onResolveComment}\n onReopenComment={props.onReopenComment}\n onAddReply={props.onAddReply}\n onEditBody={props.onEditBody}\n onOpenRevision={props.onOpenRevision}\n onAcceptRevision={props.onAcceptRevision}\n onRejectRevision={props.onRejectRevision}\n onAcceptAllChanges={props.onAcceptAllChanges}\n onRejectAllChanges={props.onRejectAllChanges}\n /> : null}\n </div>\n </div>\n </Tooltip.Provider>\n );\n}\n\nfunction shouldHidePageBorderForSelection(\n selection: EditorViewStateSnapshot[\"selection\"],\n): boolean {\n if (selection.isCollapsed) {\n return false;\n }\n\n return selection.activeRange.kind === \"range\";\n}\n\nfunction resolveActiveParagraphLayout(\n surface: RuntimeRenderSnapshot[\"surface\"],\n position: number,\n): {\n leftIndent: number;\n rightIndent: number;\n firstLineOffset: number;\n tabStops: Array<{ pos: number; val?: string; leader?: string }>;\n} | null {\n const paragraph = surface ? findActiveParagraph(surface.blocks, position) : null;\n if (!paragraph) {\n return null;\n }\n\n return {\n leftIndent: paragraph.indentation?.left ?? 0,\n rightIndent: paragraph.indentation?.right ?? 0,\n firstLineOffset:\n paragraph.indentation?.firstLine ??\n (paragraph.indentation?.hanging ? -paragraph.indentation.hanging : 0),\n tabStops: paragraph.tabStops ? [...paragraph.tabStops] : [],\n };\n}\n\nfunction findActiveParagraph(\n blocks: readonly SurfaceBlockSnapshot[],\n position: number,\n): Extract<SurfaceBlockSnapshot, { kind: \"paragraph\" }> | null {\n for (const block of blocks) {\n if (block.kind === \"paragraph\" && position >= block.from && position <= block.to) {\n return block;\n }\n if (block.kind === \"table\") {\n for (const row of block.rows) {\n for (const cell of row.cells) {\n const paragraph = findActiveParagraph(cell.content, position);\n if (paragraph) {\n return paragraph;\n }\n }\n }\n }\n if (block.kind === \"sdt_block\") {\n const paragraph = findActiveParagraph(block.children, position);\n if (paragraph) {\n return paragraph;\n }\n }\n }\n return null;\n}\n\ninterface PageChromeModel {\n lineNumberingEnabled: boolean;\n gutterWidthPx: number;\n lineMarkers: Array<{ id: string; label: string; topPx: number }>;\n showPageBorder: boolean;\n pageBorderDisplay: string;\n pageBorderStyle: CSSProperties | undefined;\n documentGridType: string;\n documentGridStyle: CSSProperties | undefined;\n}\n\nconst EMPTY_PAGE_CHROME_MODEL: PageChromeModel = {\n lineNumberingEnabled: false,\n gutterWidthPx: 0,\n lineMarkers: [],\n showPageBorder: false,\n pageBorderDisplay: \"none\",\n pageBorderStyle: undefined,\n documentGridType: \"none\",\n documentGridStyle: undefined,\n};\n\nconst DOCUMENT_CONTENT_TOP_PADDING_PX = 40;\n\ninterface PageShellMetrics {\n contentInsetStyle: CSSProperties;\n pageFrameStyle: CSSProperties;\n headerBandStyle: CSSProperties;\n footerBandStyle: CSSProperties;\n}\n\nfunction buildPageChromeModel(\n surface: RuntimeRenderSnapshot[\"surface\"] | undefined,\n pageLayout: RuntimeRenderSnapshot[\"pageLayout\"] | undefined,\n navigation: DocumentNavigationSnapshot | undefined,\n activeStory: RuntimeRenderSnapshot[\"activeStory\"],\n): PageChromeModel {\n if (!surface || !pageLayout || !navigation || activeStory.kind !== \"main\") {\n return EMPTY_PAGE_CHROME_MODEL;\n }\n\n const lineMarkers = computeLineMarkersIfEnabled({\n pageLayout,\n surfaceBlocks: surface.blocks,\n pages: navigation.pages,\n buildLineNumberMarkers,\n });\n const lineNumberingEnabled =\n Boolean(pageLayout.lineNumbering) && lineMarkers.length > 0;\n const distance = pageLayout.lineNumbering?.distance ?? 0;\n const gutterWidthPx = lineNumberingEnabled\n ? Math.max(40, Math.min(88, 24 + Math.round(distance * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP)))\n : 0;\n const showPageBorder = shouldRenderPageBorder(pageLayout, navigation.pages, navigation.activePageIndex);\n\n return {\n lineNumberingEnabled,\n gutterWidthPx,\n lineMarkers,\n showPageBorder,\n pageBorderDisplay: pageLayout.pageBorders?.display ?? \"none\",\n pageBorderStyle: showPageBorder ? buildPageBorderStyle(pageLayout) : undefined,\n documentGridType: pageLayout.documentGrid?.type ?? \"none\",\n documentGridStyle: buildDocumentGridStyle(pageLayout.documentGrid),\n };\n}\n\nfunction buildPageShellMetrics(\n pageLayout: RuntimeRenderSnapshot[\"pageLayout\"] | undefined,\n): PageShellMetrics {\n if (!pageLayout) {\n return {\n contentInsetStyle: {},\n pageFrameStyle: {},\n headerBandStyle: {},\n footerBandStyle: {},\n };\n }\n\n const horizontalInsetPx = Math.max(\n 24,\n Math.min(120, Math.round(pageLayout.marginLeft * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP)),\n );\n const verticalInsetPx = Math.max(\n 24,\n Math.min(140, Math.round(pageLayout.marginTop * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP)),\n );\n const headerBandHeightPx = Math.max(\n 40,\n Math.min(96, Math.round(pageLayout.headerMargin * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP + 16)),\n );\n const footerBandHeightPx = Math.max(\n 40,\n Math.min(96, Math.round(pageLayout.footerMargin * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP + 16)),\n );\n\n return {\n contentInsetStyle: {\n paddingLeft: `${horizontalInsetPx}px`,\n paddingRight: `${horizontalInsetPx}px`,\n paddingTop: `${Math.max(20, verticalInsetPx - 12)}px`,\n paddingBottom: `${Math.max(20, Math.round(pageLayout.marginBottom * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP) - 12)}px`,\n },\n pageFrameStyle: {\n backgroundColor: \"var(--color-page-bg)\",\n },\n headerBandStyle: {\n minHeight: `${headerBandHeightPx}px`,\n },\n footerBandStyle: {\n minHeight: `${footerBandHeightPx}px`,\n },\n };\n}\n\nfunction buildLineNumberMarkers(\n blocks: readonly SurfaceBlockSnapshot[],\n pages: ReadonlyArray<DocumentNavigationSnapshot[\"pages\"][number]>,\n): Array<{ id: string; label: string; topPx: number }> {\n const markers: Array<{ id: string; label: string; topPx: number }> = [];\n if (pages.length === 0) {\n return markers;\n }\n\n let currentTopTwips = 0;\n let lineNumber = 1;\n let lastPageIndex = -1;\n let lastSectionIndex = -1;\n\n for (const block of blocks) {\n const pageIndex = findPageForOffset(pages, block.from);\n const page = pages[pageIndex];\n if (!page) {\n continue;\n }\n\n const lineNumbering = page.layout.lineNumbering;\n const restartMode = lineNumbering?.restart ?? \"newPage\";\n const restartStart = lineNumbering?.start ?? 1;\n const countBy = Math.max(1, lineNumbering?.countBy ?? 1);\n const columnWidth = getUsableColumnWidth(page.layout);\n\n if (pageIndex !== lastPageIndex) {\n if (restartMode === \"newPage\" || lastPageIndex === -1) {\n lineNumber = restartStart;\n }\n lastPageIndex = pageIndex;\n }\n if (page.sectionIndex !== lastSectionIndex) {\n if (restartMode === \"newSection\" || lastSectionIndex === -1) {\n lineNumber = restartStart;\n }\n lastSectionIndex = page.sectionIndex;\n }\n\n if (block.kind === \"paragraph\" && lineNumbering) {\n const lineCount = estimateParagraphLineCount(block, columnWidth);\n const lineHeight = estimateParagraphLineHeight(block);\n const suppress = block.suppressLineNumbers === true;\n for (let lineIndex = 0; lineIndex < lineCount; lineIndex += 1) {\n if (!suppress && (lineNumber - restartStart) % countBy === 0) {\n markers.push({\n id: `${block.blockId}-${lineIndex}`,\n label: String(lineNumber),\n topPx:\n DOCUMENT_CONTENT_TOP_PADDING_PX +\n (currentTopTwips + lineIndex * lineHeight) * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP,\n });\n }\n if (!suppress) {\n lineNumber += 1;\n }\n }\n }\n\n currentTopTwips += estimateBlockHeight(block, columnWidth);\n }\n\n return markers;\n}\n\nfunction shouldRenderPageBorder(\n pageLayout: RuntimeRenderSnapshot[\"pageLayout\"],\n pages: ReadonlyArray<DocumentNavigationSnapshot[\"pages\"][number]>,\n activePageIndex: number,\n): boolean {\n const display = pageLayout?.pageBorders?.display ?? \"allPages\";\n const activePage = pages[activePageIndex];\n if (!pageLayout?.pageBorders || !activePage) {\n return false;\n }\n\n switch (display) {\n case \"firstPage\":\n return activePage.pageInSection === 0;\n case \"notFirstPage\":\n return activePage.pageInSection > 0;\n default:\n return true;\n }\n}\n\nfunction buildPageBorderStyle(\n pageLayout: NonNullable<RuntimeRenderSnapshot[\"pageLayout\"]>,\n): CSSProperties | undefined {\n const pageBorders = pageLayout.pageBorders;\n if (!pageBorders) {\n return undefined;\n }\n\n const leftInset = createInsetValue(\n pageBorders.left?.space,\n pageBorders.offsetFrom === \"text\"\n ? (pageLayout.marginLeft / Math.max(1, pageLayout.pageWidth)) * 100\n : 1.25,\n );\n const rightInset = createInsetValue(\n pageBorders.right?.space,\n pageBorders.offsetFrom === \"text\"\n ? (pageLayout.marginRight / Math.max(1, pageLayout.pageWidth)) * 100\n : 1.25,\n );\n const topInset = createInsetValue(\n pageBorders.top?.space,\n pageBorders.offsetFrom === \"text\"\n ? (pageLayout.marginTop / Math.max(1, pageLayout.pageHeight)) * 100\n : 1.5,\n );\n const bottomInset = createInsetValue(\n pageBorders.bottom?.space,\n pageBorders.offsetFrom === \"text\"\n ? (pageLayout.marginBottom / Math.max(1, pageLayout.pageHeight)) * 100\n : 1.5,\n );\n\n return {\n top: topInset,\n right: rightInset,\n bottom: bottomInset,\n left: leftInset,\n borderTop: toBorderCss(pageBorders.top),\n borderRight: toBorderCss(pageBorders.right),\n borderBottom: toBorderCss(pageBorders.bottom),\n borderLeft: toBorderCss(pageBorders.left),\n boxSizing: \"border-box\",\n mixBlendMode: pageBorders.zOrder === \"back\" ? \"multiply\" : undefined,\n };\n}\n\nfunction buildDocumentGridStyle(\n documentGrid: NonNullable<RuntimeRenderSnapshot[\"pageLayout\"]>[\"documentGrid\"] | undefined,\n): CSSProperties | undefined {\n if (!documentGrid || !documentGrid.type || documentGrid.type === \"default\") {\n return undefined;\n }\n\n const linePitchPx = Math.max(\n 18,\n Math.round((documentGrid.linePitch ?? 360) * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP),\n );\n const charSpacePx = Math.max(\n 12,\n Math.round((documentGrid.charSpace ?? 204) * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP),\n );\n const gridColor = \"rgba(15, 23, 42, 0.06)\";\n const backgrounds: string[] = [];\n\n if (\n documentGrid.type === \"lines\" ||\n documentGrid.type === \"linesAndChars\" ||\n documentGrid.type === \"snapToChars\"\n ) {\n backgrounds.push(\n `repeating-linear-gradient(to bottom, ${gridColor} 0, ${gridColor} 1px, transparent 1px, transparent ${linePitchPx}px)`,\n );\n }\n if (\n documentGrid.type === \"linesAndChars\" ||\n documentGrid.type === \"snapToChars\"\n ) {\n backgrounds.push(\n `repeating-linear-gradient(to right, rgba(15, 23, 42, 0.04) 0, rgba(15, 23, 42, 0.04) 1px, transparent 1px, transparent ${charSpacePx}px)`,\n );\n }\n\n if (backgrounds.length === 0) {\n return undefined;\n }\n\n return {\n backgroundImage: backgrounds.join(\", \"),\n backgroundOrigin: \"content-box\",\n };\n}\n\nfunction createInsetValue(spaceTwips: number | undefined, percent: number): string {\n const spacingPx = Math.max(0, Math.round((spaceTwips ?? 0) * DEFAULT_PAGE_ESTIMATE_PX_PER_TWIP));\n return `calc(${percent.toFixed(2)}% + ${spacingPx}px)`;\n}\n\nfunction resolveSelectionToolbarPlacement(\n anchor: SelectionToolbarAnchor | null | undefined,\n root: HTMLDivElement | null,\n zoomScale: number,\n): { placement: \"right\" | \"left\" | \"above\" | \"below\"; style: CSSProperties } | null {\n if (!anchor || !root) {\n return null;\n }\n\n const rootRect = root.getBoundingClientRect();\n if (rootRect.width <= 0 || rootRect.height <= 0 || zoomScale <= 0) {\n return null;\n }\n\n const centerX = (anchor.left + anchor.right) / 2;\n const centerY = (anchor.top + anchor.bottom) / 2;\n const localLeftEdge = (anchor.left - rootRect.left) / zoomScale;\n const localRightEdge = (anchor.right - rootRect.left) / zoomScale;\n const localLeft = (centerX - rootRect.left) / zoomScale;\n const localCenterY = (centerY - rootRect.top) / zoomScale;\n const localTop = (anchor.top - rootRect.top) / zoomScale;\n const localBottom = (anchor.bottom - rootRect.top) / zoomScale;\n const edgePadding = 16 / zoomScale;\n const containerWidth = rootRect.width / zoomScale;\n const containerHeight = rootRect.height / zoomScale;\n const gapPx = 12 / zoomScale;\n const estimatedToolbarWidth = Math.min(260 / zoomScale, Math.max(168 / zoomScale, containerWidth * 0.32));\n const estimatedToolbarHeight = 44 / zoomScale;\n const clampedCenterLeft = Math.max(\n edgePadding,\n Math.min(localLeft, Math.max(edgePadding, containerWidth - edgePadding)),\n );\n const clampedCenterY = Math.max(\n edgePadding + estimatedToolbarHeight / 2,\n Math.min(localCenterY, Math.max(edgePadding + estimatedToolbarHeight / 2, containerHeight - edgePadding - estimatedToolbarHeight / 2)),\n );\n const rightClearance = containerWidth - localRightEdge - gapPx - edgePadding;\n const leftClearance = localLeftEdge - gapPx - edgePadding;\n\n if (rightClearance >= estimatedToolbarWidth) {\n return {\n placement: \"right\",\n style: {\n left: `${localRightEdge}px`,\n top: `${clampedCenterY}px`,\n maxWidth: `${Math.max(220, containerWidth - edgePadding * 2)}px`,\n transform: `translate(${gapPx}px, -50%)`,\n },\n };\n }\n\n if (leftClearance >= estimatedToolbarWidth) {\n return {\n placement: \"left\",\n style: {\n left: `${localLeftEdge}px`,\n top: `${clampedCenterY}px`,\n maxWidth: `${Math.max(220, containerWidth - edgePadding * 2)}px`,\n transform: `translate(calc(-100% - ${gapPx}px), -50%)`,\n },\n };\n }\n\n const placement = localTop < estimatedToolbarHeight + gapPx + edgePadding ? \"below\" : \"above\";\n\n return {\n placement,\n style: {\n left: `${clampedCenterLeft}px`,\n top: `${placement === \"above\" ? localTop : localBottom}px`,\n maxWidth: `${Math.max(220, containerWidth - edgePadding * 2)}px`,\n transform:\n placement === \"above\"\n ? `translate(-50%, calc(-100% - ${gapPx}px))`\n : `translate(-50%, ${gapPx}px)`,\n },\n };\n}\n\nfunction toBorderCss(\n border:\n | NonNullable<NonNullable<RuntimeRenderSnapshot[\"pageLayout\"]>[\"pageBorders\"]>[\"top\"]\n | undefined,\n): string | undefined {\n if (!border || border.value === \"none\" || border.value === \"nil\") {\n return undefined;\n }\n\n const width = border.size ? `${Math.max(1, Math.round(border.size / 8))}px` : \"1px\";\n const style =\n border.value === \"double\"\n ? \"double\"\n : border.value === \"dotted\"\n ? \"dotted\"\n : border.value === \"dashed\" || border.value === \"dashSmallGap\"\n ? \"dashed\"\n : \"solid\";\n const color = border.color && border.color !== \"auto\" ? `#${border.color}` : \"rgba(31, 31, 31, 0.28)\";\n return `${width} ${style} ${color}`;\n}\n","import type {\n DocumentNavigationSnapshot,\n PageLayoutSnapshot,\n SurfaceBlockSnapshot,\n} from \"../api/public-types.ts\";\n\nexport interface LineMarker {\n id: string;\n label: string;\n topPx: number;\n}\n\nexport function computeLineMarkersIfEnabled(input: {\n pageLayout: PageLayoutSnapshot | undefined;\n surfaceBlocks: readonly SurfaceBlockSnapshot[];\n pages: ReadonlyArray<DocumentNavigationSnapshot[\"pages\"][number]>;\n buildLineNumberMarkers: (\n blocks: readonly SurfaceBlockSnapshot[],\n pages: ReadonlyArray<DocumentNavigationSnapshot[\"pages\"][number]>,\n ) => LineMarker[];\n}): LineMarker[] {\n if (!input.pageLayout?.lineNumbering) {\n return [];\n }\n\n return input.buildLineNumberMarkers(input.surfaceBlocks, input.pages);\n}\n","import React from \"react\";\n\nimport { preserveEditorSelectionMouseDown } from \"../../ui/headless/preserve-editor-selection\";\n\nexport interface ActiveImageContext {\n mediaId: string;\n display: \"inline\" | \"floating\";\n widthEmu?: number;\n heightEmu?: number;\n horizontalOffsetEmu?: number;\n verticalOffsetEmu?: number;\n}\n\nexport interface TwImageContextToolbarProps {\n activeImage: ActiveImageContext;\n disabled: boolean;\n onSetImageLayout?: (\n mediaId: string,\n dimensions: { widthEmu: number; heightEmu: number },\n ) => void;\n onSetImageFrame?: (\n mediaId: string,\n offsets: { horizontalOffsetEmu?: number; verticalOffsetEmu?: number },\n ) => void;\n}\n\nconst IMAGE_SIZE_PRESETS = [\n { label: \"Small image\", widthEmu: 1828800, heightEmu: 914400 },\n { label: \"Medium image\", widthEmu: 2743200, heightEmu: 1371600 },\n { label: \"Large image\", widthEmu: 3657600, heightEmu: 1828800 },\n] as const;\n\nconst NUDGE_EMU = 228600;\n\nexport function TwImageContextToolbar(props: TwImageContextToolbarProps) {\n const { activeImage } = props;\n\n return (\n <div\n data-testid=\"image-context-toolbar\"\n className=\"flex flex-wrap items-center gap-2 rounded-xl border border-border bg-canvas px-3 py-2 shadow-sm\"\n >\n <span className=\"text-[10px] font-semibold uppercase tracking-[0.12em] text-tertiary\">\n Image\n </span>\n <span className=\"rounded-full bg-surface px-2 py-1 text-[10px] font-medium uppercase tracking-[0.1em] text-secondary\">\n {activeImage.display}\n </span>\n {IMAGE_SIZE_PRESETS.map((preset) => (\n <ToolbarButton\n key={preset.label}\n ariaLabel={preset.label}\n disabled={props.disabled || !props.onSetImageLayout}\n onClick={() =>\n props.onSetImageLayout?.(activeImage.mediaId, {\n widthEmu: preset.widthEmu,\n heightEmu: preset.heightEmu,\n })}\n >\n {preset.label.replace(\" image\", \"\")}\n </ToolbarButton>\n ))}\n {activeImage.display === \"floating\" ? (\n <>\n <ToolbarButton\n ariaLabel=\"Nudge image left\"\n disabled={props.disabled || !props.onSetImageFrame}\n onClick={() =>\n props.onSetImageFrame?.(activeImage.mediaId, {\n horizontalOffsetEmu: (activeImage.horizontalOffsetEmu ?? 0) - NUDGE_EMU,\n })}\n >\n Left\n </ToolbarButton>\n <ToolbarButton\n ariaLabel=\"Nudge image right\"\n disabled={props.disabled || !props.onSetImageFrame}\n onClick={() =>\n props.onSetImageFrame?.(activeImage.mediaId, {\n horizontalOffsetEmu: (activeImage.horizontalOffsetEmu ?? 0) + NUDGE_EMU,\n })}\n >\n Right\n </ToolbarButton>\n <ToolbarButton\n ariaLabel=\"Nudge image up\"\n disabled={props.disabled || !props.onSetImageFrame}\n onClick={() =>\n props.onSetImageFrame?.(activeImage.mediaId, {\n verticalOffsetEmu: (activeImage.verticalOffsetEmu ?? 0) - NUDGE_EMU,\n })}\n >\n Up\n </ToolbarButton>\n <ToolbarButton\n ariaLabel=\"Nudge image down\"\n disabled={props.disabled || !props.onSetImageFrame}\n onClick={() =>\n props.onSetImageFrame?.(activeImage.mediaId, {\n verticalOffsetEmu: (activeImage.verticalOffsetEmu ?? 0) + NUDGE_EMU,\n })}\n >\n Down\n </ToolbarButton>\n </>\n ) : null}\n </div>\n );\n}\n\nfunction ToolbarButton(props: {\n ariaLabel: string;\n children: React.ReactNode;\n disabled: boolean;\n onClick?: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={props.ariaLabel}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onClick}\n className=\"inline-flex h-8 items-center rounded-md px-2 text-xs font-medium text-primary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {props.children}\n </button>\n );\n}\n","import React from \"react\";\n\nimport type {\n PageLayoutSnapshot,\n SectionPageNumberingPatch,\n SectionBreakType,\n SectionLayoutPatch,\n} from \"../../api/public-types\";\nimport { preserveEditorSelectionMouseDown } from \"../../ui/headless/preserve-editor-selection\";\n\nexport interface TwLayoutPanelProps {\n pageLayout: PageLayoutSnapshot;\n readOnly: boolean;\n onInsertSectionBreak?: (type: SectionBreakType) => void;\n onDeleteSectionBreak?: (sectionIndex: number) => void;\n onUpdateSectionLayout?: (sectionIndex: number, patch: SectionLayoutPatch) => void;\n onSetSectionPageNumbering?: (\n sectionIndex: number,\n patch: SectionPageNumberingPatch | null,\n ) => void;\n}\n\nexport function TwLayoutPanel(props: TwLayoutPanelProps) {\n const nextOrientation = props.pageLayout.orientation === \"portrait\" ? \"landscape\" : \"portrait\";\n const titlePageEnabled = props.pageLayout.differentFirstPage;\n\n return (\n <div className=\"mt-3 flex flex-wrap items-center gap-2 rounded-xl border border-border bg-canvas px-3 py-2 shadow-sm\">\n <span className=\"text-[10px] font-semibold uppercase tracking-[0.12em] text-tertiary\">\n Section\n </span>\n <ToolbarButton\n ariaLabel=\"Insert next-page section break\"\n disabled={props.readOnly || !props.onInsertSectionBreak}\n onClick={() => props.onInsertSectionBreak?.(\"nextPage\")}\n >\n Next-page break\n </ToolbarButton>\n <ToolbarButton\n ariaLabel={`Switch section to ${nextOrientation}`}\n disabled={props.readOnly || !props.onUpdateSectionLayout}\n onClick={() =>\n props.onUpdateSectionLayout?.(props.pageLayout.sectionIndex, {\n pageSize: {\n orientation: nextOrientation,\n width: props.pageLayout.pageHeight,\n height: props.pageLayout.pageWidth,\n },\n })}\n >\n {nextOrientation === \"landscape\" ? \"Landscape\" : \"Portrait\"}\n </ToolbarButton>\n <ToolbarButton\n ariaLabel=\"Delete current section break\"\n disabled={props.readOnly || props.pageLayout.sectionIndex === 0 || !props.onDeleteSectionBreak}\n onClick={() => props.onDeleteSectionBreak?.(props.pageLayout.sectionIndex)}\n >\n Delete break\n </ToolbarButton>\n <ToolbarButton\n ariaLabel=\"Restart page numbering at 1\"\n disabled={props.readOnly || !props.onSetSectionPageNumbering}\n onClick={() =>\n props.onSetSectionPageNumbering?.(props.pageLayout.sectionIndex, {\n ...(props.pageLayout.pageNumbering ?? {}),\n start: 1,\n })}\n >\n Restart numbering\n </ToolbarButton>\n <ToolbarButton\n ariaLabel=\"Use roman page numbering\"\n disabled={props.readOnly || !props.onSetSectionPageNumbering}\n onClick={() =>\n props.onSetSectionPageNumbering?.(props.pageLayout.sectionIndex, {\n ...(props.pageLayout.pageNumbering ?? {}),\n format: \"roman\",\n })}\n >\n Roman numerals\n </ToolbarButton>\n <ToolbarButton\n ariaLabel=\"Toggle different first page\"\n disabled={props.readOnly || !props.onUpdateSectionLayout}\n onClick={() =>\n props.onUpdateSectionLayout?.(props.pageLayout.sectionIndex, {\n titlePage: !titlePageEnabled,\n })}\n >\n {titlePageEnabled ? \"Same first page\" : \"Different first page\"}\n </ToolbarButton>\n </div>\n );\n}\n\nfunction ToolbarButton(props: {\n ariaLabel: string;\n children: React.ReactNode;\n disabled: boolean;\n onClick?: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={props.ariaLabel}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onClick}\n className=\"inline-flex h-8 items-center rounded-md px-2 text-xs font-medium text-primary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {props.children}\n </button>\n );\n}\n","import React from \"react\";\n\nexport interface ActiveObjectContext {\n kind: \"textbox\" | \"shape\";\n display: \"inline\" | \"floating\";\n}\n\nexport interface TwObjectContextToolbarProps {\n activeObject: ActiveObjectContext;\n}\n\nexport function TwObjectContextToolbar(props: TwObjectContextToolbarProps) {\n const label = props.activeObject.kind === \"textbox\" ? \"Text box\" : \"Shape\";\n\n return (\n <div\n data-testid=\"object-context-toolbar\"\n className=\"flex flex-wrap items-center gap-2 rounded-xl border border-border bg-canvas px-3 py-2 shadow-sm\"\n >\n <span className=\"text-[10px] font-semibold uppercase tracking-[0.12em] text-tertiary\">\n Object\n </span>\n <span className=\"rounded-full bg-surface px-2 py-1 text-[10px] font-medium uppercase tracking-[0.1em] text-secondary\">\n {label}\n </span>\n <span className=\"rounded-full bg-surface px-2 py-1 text-[10px] font-medium uppercase tracking-[0.1em] text-secondary\">\n {props.activeObject.display}\n </span>\n <span className=\"text-xs text-secondary\">\n Object selection is active.\n </span>\n </div>\n );\n}\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport type {\n EditorViewStateSnapshot,\n PageLayoutSnapshot,\n} from \"../../api/public-types\";\n\ninterface ActiveParagraphLayout {\n leftIndent: number;\n rightIndent: number;\n firstLineOffset: number;\n tabStops: Array<{ pos: number; val?: string; leader?: string }>;\n}\n\nexport interface TwPageRulerProps {\n pageLayout: PageLayoutSnapshot;\n viewState: EditorViewStateSnapshot;\n paragraphLayout: ActiveParagraphLayout | null;\n readOnly: boolean;\n onReturnToBody: () => void;\n onOpenHeader?: () => void;\n onOpenFooter?: () => void;\n onSetIndentation?: (indentation: {\n left?: number;\n right?: number;\n firstLine?: number;\n hanging?: number;\n }) => void;\n onSetTabStops?: (tabStops: Array<{ pos: number; val?: string; leader?: string }>) => void;\n onRestartNumbering?: () => void;\n onContinueNumbering?: () => void;\n}\n\ntype DragKind = \"left-indent\" | \"first-line\";\n\nconst MIN_HANDLE_TWIPS = 0;\nconst HANDLE_OVERLAP_THRESHOLD_PERCENT = 1.4;\nconst HANDLE_OFFSET_PERCENT = 0.9;\nconst MARKER_HALF_PX = 8;\n\nexport function TwPageRuler(props: TwPageRulerProps) {\n const trackRef = useRef<HTMLDivElement | null>(null);\n const dragCleanupRef = useRef<(() => void) | null>(null);\n const [, setDragState] = useState<{\n kind: DragKind;\n startClientX: number;\n startLeftIndent: number;\n startFirstLineOffset: number;\n } | null>(null);\n const [previewLayout, setPreviewLayout] = useState<ActiveParagraphLayout | null>(null);\n\n const effectiveLayout = previewLayout ?? props.paragraphLayout;\n const activeRegion = props.viewState.activePageRegion?.region ?? \"body\";\n const isBodyParagraphContext =\n activeRegion === \"body\" && Boolean(props.paragraphLayout);\n const availableHeader = props.pageLayout.headerVariants[0];\n const availableFooter = props.pageLayout.footerVariants[0];\n\n const usablePageWidth = Math.max(\n 1440,\n props.pageLayout.pageWidth - props.pageLayout.marginLeft - props.pageLayout.marginRight,\n );\n\n useEffect(() => {\n return () => {\n dragCleanupRef.current?.();\n };\n }, []);\n\n function beginDrag(kind: DragKind, clientX: number): void {\n if (!isBodyParagraphContext || !props.paragraphLayout || props.readOnly) {\n return;\n }\n\n dragCleanupRef.current?.();\n const activeDrag = {\n kind,\n startClientX: clientX,\n startLeftIndent: props.paragraphLayout.leftIndent,\n startFirstLineOffset: props.paragraphLayout.firstLineOffset,\n };\n setDragState(activeDrag);\n\n const handleMouseMove = (event: MouseEvent): void => {\n const track = trackRef.current;\n if (!track) {\n return;\n }\n const rect = track.getBoundingClientRect();\n const deltaPx = event.clientX - activeDrag.startClientX;\n const deltaTwips = pxToTwips(deltaPx, rect.width, usablePageWidth);\n\n if (activeDrag.kind === \"left-indent\") {\n setPreviewLayout({\n ...props.paragraphLayout!,\n leftIndent: clampTwips(activeDrag.startLeftIndent + deltaTwips),\n firstLineOffset: activeDrag.startFirstLineOffset,\n });\n return;\n }\n\n setPreviewLayout({\n ...props.paragraphLayout!,\n leftIndent: activeDrag.startLeftIndent,\n firstLineOffset: activeDrag.startFirstLineOffset + deltaTwips,\n });\n };\n\n const handleMouseUp = (event: MouseEvent): void => {\n const track = trackRef.current;\n if (!track || !props.onSetIndentation) {\n cleanupDrag();\n setDragState(null);\n setPreviewLayout(null);\n return;\n }\n\n const rect = track.getBoundingClientRect();\n const deltaPx = event.clientX - activeDrag.startClientX;\n const deltaTwips = pxToTwips(deltaPx, rect.width, usablePageWidth);\n const leftIndent =\n activeDrag.kind === \"left-indent\"\n ? clampTwips(activeDrag.startLeftIndent + deltaTwips)\n : activeDrag.startLeftIndent;\n const firstLineOffset =\n activeDrag.kind === \"first-line\"\n ? activeDrag.startFirstLineOffset + deltaTwips\n : activeDrag.startFirstLineOffset;\n\n cleanupDrag();\n props.onSetIndentation(\n composeIndentation(leftIndent, effectiveLayout?.rightIndent ?? props.paragraphLayout?.rightIndent ?? 0, firstLineOffset),\n );\n setDragState(null);\n setPreviewLayout(null);\n };\n\n const cleanupDrag = (): void => {\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n if (dragCleanupRef.current === cleanupDrag) {\n dragCleanupRef.current = null;\n }\n };\n\n dragCleanupRef.current = cleanupDrag;\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n }\n\n const markerLayout = useMemo(() => {\n if (!effectiveLayout || !isBodyParagraphContext) {\n return null;\n }\n return {\n leftIndent: twipsToPercent(effectiveLayout.leftIndent, usablePageWidth),\n firstLine: twipsToPercent(\n Math.max(MIN_HANDLE_TWIPS, effectiveLayout.leftIndent + effectiveLayout.firstLineOffset),\n usablePageWidth,\n ),\n tabStops: effectiveLayout.tabStops.map((tabStop, index) => ({\n id: `${tabStop.pos}-${index}`,\n left: twipsToPercent(tabStop.pos, usablePageWidth),\n })),\n };\n }, [effectiveLayout, isBodyParagraphContext, usablePageWidth]);\n const handlesOverlap = markerLayout\n ? Math.abs(markerLayout.leftIndent - markerLayout.firstLine) < HANDLE_OVERLAP_THRESHOLD_PERCENT\n : false;\n const leftIndentHandleLeft = markerLayout\n ? offsetHandlePercent(markerLayout.leftIndent, handlesOverlap ? -HANDLE_OFFSET_PERCENT : 0)\n : 0;\n const firstLineHandleLeft = markerLayout\n ? offsetHandlePercent(markerLayout.firstLine, handlesOverlap ? HANDLE_OFFSET_PERCENT : 0)\n : 0;\n\n return (\n <div\n aria-label=\"Page ruler\"\n className=\"mb-4 rounded-2xl border border-border bg-surface/80 px-4 py-3 shadow-sm\"\n >\n <div className=\"mb-3 flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Return to document body\"\n title=\"Return to document body\"\n onClick={props.onReturnToBody}\n className={regionButtonClass(activeRegion === \"body\")}\n >\n Body\n </button>\n {availableHeader ? (\n <button\n type=\"button\"\n aria-label=\"Open header story\"\n title=\"Open header story\"\n onClick={props.onOpenHeader}\n className={regionButtonClass(activeRegion === \"header\")}\n >\n Header\n </button>\n ) : null}\n {availableFooter ? (\n <button\n type=\"button\"\n aria-label=\"Open footer story\"\n title=\"Open footer story\"\n onClick={props.onOpenFooter}\n className={regionButtonClass(activeRegion === \"footer\")}\n >\n Footer\n </button>\n ) : null}\n {props.viewState.activeListContext ? (\n <>\n <div className=\"h-4 w-px bg-border\" />\n <button\n type=\"button\"\n aria-label=\"Continue numbering\"\n title=\"Continue numbering from previous list\"\n disabled={props.readOnly}\n onClick={props.onContinueNumbering}\n className={controlButtonClass}\n >\n Continue\n </button>\n <button\n type=\"button\"\n aria-label=\"Restart numbering\"\n title=\"Restart numbering at 1\"\n disabled={props.readOnly}\n onClick={props.onRestartNumbering}\n className={controlButtonClass}\n >\n Restart\n </button>\n </>\n ) : null}\n </div>\n\n <div\n className=\"mb-2 flex items-center justify-between\"\n aria-label={`Section ${props.pageLayout.sectionIndex + 1}, ${props.pageLayout.orientation}`}\n title={`Section ${props.pageLayout.sectionIndex + 1} · ${props.pageLayout.orientation}`}\n >\n <span className=\"sr-only\">Page ruler</span>\n </div>\n\n <div\n ref={trackRef}\n aria-label=\"Page ruler track\"\n className=\"relative h-14 overflow-hidden rounded-xl border border-border bg-canvas\"\n onClick={(event) => {\n if (\n props.readOnly ||\n !isBodyParagraphContext ||\n !props.paragraphLayout ||\n !props.onSetTabStops\n ) {\n return;\n }\n if ((event.target as HTMLElement).dataset.handle === \"true\") {\n return;\n }\n const rect = event.currentTarget.getBoundingClientRect();\n const nextPos = clampTwips(pxToTwips(event.clientX - rect.left, rect.width, usablePageWidth));\n props.onSetTabStops(\n [...props.paragraphLayout.tabStops, { pos: nextPos, val: \"left\" }]\n .sort((left, right) => left.pos - right.pos),\n );\n }}\n >\n <div className=\"absolute inset-x-4 top-2 h-px bg-border\" />\n <div className=\"absolute inset-x-4 top-7 h-px bg-border/70\" />\n {Array.from({ length: 8 }, (_, index) => (\n <div\n key={`tick-${index}`}\n className=\"absolute top-1 h-3 w-px bg-border/80\"\n style={{ left: `${12 + index * 12}%` }}\n />\n ))}\n\n {markerLayout ? (\n <>\n <button\n type=\"button\"\n data-handle=\"true\"\n aria-label=\"Left indent handle\"\n title={`Left indent: ${effectiveLayout?.leftIndent ?? 0} twips`}\n disabled={props.readOnly}\n className={`absolute top-8 h-4 w-4 -translate-x-1/2 rounded-[5px] border border-accent/40 bg-accent-soft shadow-sm transition-opacity ${\n handlesOverlap ? \"opacity-80 z-10\" : \"\"\n }`}\n style={{ left: markerLeftStyle(leftIndentHandleLeft) }}\n onMouseDown={(event) => {\n event.preventDefault();\n beginDrag(\"left-indent\", event.clientX);\n }}\n />\n <button\n type=\"button\"\n data-handle=\"true\"\n aria-label=\"First line indent handle\"\n title={`First line offset: ${effectiveLayout?.firstLineOffset ?? 0} twips`}\n disabled={props.readOnly}\n className={`absolute top-1 h-4 w-4 -translate-x-1/2 rotate-45 rounded-[4px] border border-primary/30 bg-surface-raised shadow-sm transition-opacity ${\n handlesOverlap ? \"opacity-80 z-20\" : \"\"\n }`}\n style={{ left: markerLeftStyle(firstLineHandleLeft) }}\n onMouseDown={(event) => {\n event.preventDefault();\n beginDrag(\"first-line\", event.clientX);\n }}\n />\n {markerLayout.tabStops.map((tabStop) => (\n <div\n key={tabStop.id}\n data-handle=\"true\"\n aria-label={`Tab stop at ${tabStop.left.toFixed(0)}%`}\n title={`Tab stop`}\n className=\"absolute top-5 h-4 w-4 -translate-x-1/2 rounded-sm border border-border bg-surface-raised shadow-sm\"\n style={{ left: markerLeftStyle(tabStop.left) }}\n />\n ))}\n </>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction composeIndentation(leftIndent: number, rightIndent: number, firstLineOffset: number) {\n const indentation: {\n left?: number;\n right?: number;\n firstLine?: number;\n hanging?: number;\n } = {};\n if (leftIndent > 0) {\n indentation.left = leftIndent;\n }\n if (rightIndent > 0) {\n indentation.right = rightIndent;\n }\n if (firstLineOffset > 0) {\n indentation.firstLine = Math.round(firstLineOffset);\n } else if (firstLineOffset < 0) {\n indentation.hanging = Math.round(Math.abs(firstLineOffset));\n }\n return indentation;\n}\n\nfunction regionButtonClass(active: boolean): string {\n return `inline-flex items-center rounded-full border px-3 py-1 text-xs transition-colors ${\n active\n ? \"border-accent/30 bg-accent-soft text-accent\"\n : \"border-border bg-canvas text-secondary hover:bg-surface\"\n }`;\n}\n\nconst controlButtonClass =\n \"inline-flex items-center rounded-full border border-border bg-canvas px-3 py-1 text-xs text-secondary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-50\";\n\nfunction twipsToPercent(value: number, usablePageWidth: number): number {\n return Math.max(0, Math.min(100, (value / usablePageWidth) * 100));\n}\n\nfunction pxToTwips(px: number, width: number, usablePageWidth: number): number {\n if (width <= 0) {\n return 0;\n }\n return Math.round((px / width) * usablePageWidth);\n}\n\nfunction clampTwips(value: number): number {\n return Math.max(MIN_HANDLE_TWIPS, Math.round(value));\n}\n\nfunction offsetHandlePercent(value: number, offset: number): number {\n return Math.max(0, Math.min(100, value + offset));\n}\n\nfunction markerLeftStyle(value: number): string {\n const clamped = Math.max(0, Math.min(100, value));\n return `clamp(${MARKER_HALF_PX}px, ${clamped}%, calc(100% - ${MARKER_HALF_PX}px))`;\n}\n","import React from \"react\";\nimport type { FocusEventHandler } from \"react\";\nimport * as Tooltip from \"@radix-ui/react-tooltip\";\nimport { Check, MessageSquare, Pencil, X } from \"lucide-react\";\n\nimport type { SuggestionCardModel } from \"../../ui/headless/selection-toolbar-model\";\nimport { preserveEditorSelectionMouseDown } from \"../../ui/headless/preserve-editor-selection\";\n\nexport interface TwSuggestionCardProps {\n model: SuggestionCardModel;\n onFocusCapture?: FocusEventHandler<HTMLDivElement>;\n onBlurCapture?: FocusEventHandler<HTMLDivElement>;\n onAccept?: () => void;\n onReject?: () => void;\n onEditSuggestion?: () => void;\n onAddComment?: () => void;\n}\n\nconst focusRingClass =\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2 focus-visible:ring-offset-canvas\";\n\nexport function TwSuggestionCard(props: TwSuggestionCardProps) {\n const contextLabel = summarizeSuggestionContext(props.model);\n const commentDisabled = !props.model.canAddComment;\n const tooltipLabel = commentDisabled\n ? props.model.disabledReason ?? \"Commenting is unavailable for this selection\"\n : \"Comment on suggestion\";\n\n return (\n <div\n data-testid=\"suggestion-card\"\n className=\"inline-flex max-w-[min(28rem,calc(100vw-2rem))] flex-col gap-2 rounded-2xl border border-border/80 bg-canvas px-3 py-2 shadow-xl ring-1 ring-border/80\"\n onFocusCapture={props.onFocusCapture}\n onBlurCapture={props.onBlurCapture}\n role=\"group\"\n aria-label=\"Suggestion actions\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"text-[11px] font-semibold uppercase tracking-[0.12em] text-warning\">\n {props.model.kindLabel}\n </div>\n <div className=\"mt-1 max-w-[16rem] truncate text-sm text-primary\">\n {props.model.previewText}\n </div>\n </div>\n {contextLabel ? (\n <div className=\"shrink-0 rounded-full bg-accent-soft px-2 py-0.5 text-[10px] font-medium uppercase tracking-[0.08em] text-accent\">\n {contextLabel}\n </div>\n ) : null}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <SuggestionActionButton\n icon={<Check className=\"h-3.5 w-3.5\" />}\n label=\"Accept suggestion\"\n disabled={!props.model.canAccept}\n tone=\"accept\"\n onClick={props.onAccept}\n />\n <SuggestionActionButton\n icon={<X className=\"h-3.5 w-3.5\" />}\n label=\"Reject suggestion\"\n disabled={!props.model.canReject}\n tone=\"reject\"\n onClick={props.onReject}\n />\n <SuggestionActionButton\n icon={<Pencil className=\"h-3.5 w-3.5\" />}\n label=\"Edit suggestion\"\n disabled={!props.model.canEditSuggestion}\n tone=\"neutral\"\n onClick={props.onEditSuggestion}\n />\n <Tooltip.Root>\n <Tooltip.Trigger asChild>\n <button\n type=\"button\"\n aria-label=\"Comment on suggestion\"\n disabled={commentDisabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onAddComment}\n className={`inline-flex h-8 items-center gap-1 rounded-lg border border-border px-2.5 text-xs font-medium text-secondary transition-colors hover:bg-surface disabled:cursor-not-allowed disabled:opacity-40 ${focusRingClass}`}\n >\n <MessageSquare className=\"h-3.5 w-3.5\" />\n Comment\n </button>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content\n className=\"rounded-md bg-primary px-2 py-1 text-xs text-white shadow-md z-50\"\n sideOffset={6}\n >\n {tooltipLabel}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n </div>\n </div>\n );\n}\n\nfunction summarizeSuggestionContext(model: SuggestionCardModel): string | null {\n const labels = model.badges.map((badge) => badge.label.trim()).filter(Boolean);\n if (labels.length === 0) {\n return null;\n }\n const summary = labels.slice(0, 2).join(\" · \");\n return summary.length > 36 ? `${summary.slice(0, 33)}...` : summary;\n}\n\nfunction SuggestionActionButton(props: {\n icon: React.ReactNode;\n label: string;\n disabled: boolean;\n tone: \"accept\" | \"reject\" | \"neutral\";\n onClick?: () => void;\n}) {\n const toneClass = props.tone === \"accept\"\n ? \"border-emerald-500/30 bg-emerald-500/10 text-emerald-700 hover:bg-emerald-500/15 dark:text-emerald-300\"\n : props.tone === \"reject\"\n ? \"border-rose-500/30 bg-rose-500/10 text-rose-700 hover:bg-rose-500/15 dark:text-rose-300\"\n : \"border-border text-secondary hover:bg-surface\";\n\n return (\n <button\n type=\"button\"\n aria-label={props.label}\n disabled={props.disabled}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onClick}\n className={`inline-flex h-8 items-center gap-1 rounded-lg border px-2.5 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${toneClass} ${focusRingClass}`}\n >\n {props.icon}\n {props.label.replace(\" suggestion\", \"\").replace(\" on suggestion\", \"\")}\n </button>\n );\n}\n","import React from \"react\";\n\nimport type { StyleCatalogSnapshot } from \"../../api/public-types\";\nimport { preserveEditorSelectionMouseDown } from \"../../ui/headless/preserve-editor-selection\";\n\nexport interface TwTableContextToolbarProps {\n disabled: boolean;\n tableStyles: StyleCatalogSnapshot[\"tables\"];\n onSetTableStyle?: (styleId: string) => void;\n onAddRowBefore?: () => void;\n onAddRowAfter?: () => void;\n onAddColumnBefore?: () => void;\n onAddColumnAfter?: () => void;\n onDeleteRow?: () => void;\n onDeleteColumn?: () => void;\n onMergeCells?: () => void;\n onSplitCell?: () => void;\n onSetCellBackground?: (color: string) => void;\n onDeleteTable?: () => void;\n}\n\nconst CELL_COLORS = [\n \"#ffffff\",\n \"#f0f0ee\",\n \"#dbeafe\",\n \"#fef3c7\",\n \"#dcfce7\",\n \"#fce7f3\",\n] as const;\n\nexport function TwTableContextToolbar(props: TwTableContextToolbarProps) {\n return (\n <div\n data-testid=\"table-context-toolbar\"\n className=\"flex flex-wrap items-center gap-2 rounded-xl border border-border bg-canvas px-3 py-2 shadow-sm\"\n >\n <span className=\"text-[10px] font-semibold uppercase tracking-[0.12em] text-tertiary\">\n Table\n </span>\n\n <select\n aria-label=\"Table style\"\n className=\"h-8 rounded-md border border-border bg-canvas px-2 text-xs text-primary disabled:opacity-40\"\n disabled={props.disabled || props.tableStyles.length === 0 || !props.onSetTableStyle}\n onMouseDown={preserveEditorSelectionMouseDown}\n onChange={(event) => props.onSetTableStyle?.(event.target.value)}\n defaultValue=\"\"\n >\n <option value=\"\" disabled>Table style</option>\n {props.tableStyles.map((style) => (\n <option key={style.styleId} value={style.styleId}>\n {style.displayName}\n </option>\n ))}\n </select>\n\n <ToolbarButton ariaLabel=\"Add row above\" disabled={props.disabled} onClick={props.onAddRowBefore}>\n Row above\n </ToolbarButton>\n <ToolbarButton ariaLabel=\"Add row below\" disabled={props.disabled} onClick={props.onAddRowAfter}>\n Row below\n </ToolbarButton>\n <ToolbarButton ariaLabel=\"Delete row\" disabled={props.disabled} onClick={props.onDeleteRow}>\n Delete row\n </ToolbarButton>\n <ToolbarButton ariaLabel=\"Add column left\" disabled={props.disabled} onClick={props.onAddColumnBefore}>\n Column left\n </ToolbarButton>\n <ToolbarButton ariaLabel=\"Add column right\" disabled={props.disabled} onClick={props.onAddColumnAfter}>\n Column right\n </ToolbarButton>\n <ToolbarButton ariaLabel=\"Delete column\" disabled={props.disabled} onClick={props.onDeleteColumn}>\n Delete column\n </ToolbarButton>\n <ToolbarButton ariaLabel=\"Merge cells\" disabled={props.disabled} onClick={props.onMergeCells}>\n Merge\n </ToolbarButton>\n <ToolbarButton ariaLabel=\"Split cell\" disabled={props.disabled} onClick={props.onSplitCell}>\n Split\n </ToolbarButton>\n\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[11px] text-secondary\">Fill</span>\n {CELL_COLORS.map((color) => (\n <button\n key={color}\n type=\"button\"\n aria-label={`Set cell fill ${color}`}\n disabled={props.disabled || !props.onSetCellBackground}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={() => props.onSetCellBackground?.(color)}\n className=\"h-6 w-6 rounded border border-border disabled:opacity-40\"\n style={{ backgroundColor: color }}\n />\n ))}\n </div>\n\n <ToolbarButton ariaLabel=\"Delete table\" danger disabled={props.disabled} onClick={props.onDeleteTable}>\n Delete table\n </ToolbarButton>\n </div>\n );\n}\n\nfunction ToolbarButton(props: {\n ariaLabel: string;\n children: React.ReactNode;\n danger?: boolean;\n disabled: boolean;\n onClick?: () => void;\n}) {\n return (\n <button\n type=\"button\"\n aria-label={props.ariaLabel}\n disabled={props.disabled || !props.onClick}\n onMouseDown={preserveEditorSelectionMouseDown}\n onClick={props.onClick}\n className={`inline-flex h-8 items-center rounded-md px-2 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 ${\n props.danger\n ? \"text-danger hover:bg-danger/10\"\n : \"text-primary hover:bg-surface\"\n }`}\n >\n {props.children}\n </button>\n );\n}\n","import type { CommentSidebarSnapshot } from \"../../api/public-types\";\n\nexport interface CommentDecorationModel {\n threads: CommentDecorationThread[];\n activeCommentId?: string;\n}\n\nexport interface CommentDecorationThread {\n commentId: string;\n from: number;\n to: number;\n status: CommentSidebarSnapshot[\"threads\"][number][\"status\"];\n isActive: boolean;\n}\n\nexport interface CommentRangeState {\n hasComments: boolean;\n hasOpen: boolean;\n hasResolved: boolean;\n hasActive: boolean;\n count: number;\n overlapping: CommentDecorationThread[];\n}\n\nexport function createCommentDecorationModel(\n snapshot?: CommentSidebarSnapshot,\n): CommentDecorationModel | undefined {\n if (!snapshot) {\n return undefined;\n }\n\n return {\n activeCommentId: snapshot.activeCommentId,\n threads: snapshot.threads\n .filter((thread) => thread.anchor.kind !== \"detached\")\n .map((thread) => {\n const anchor = thread.anchor;\n const from = anchor.kind === \"range\" ? anchor.from : anchor.kind === \"node\" ? anchor.at : 0;\n const to = anchor.kind === \"range\" ? anchor.to : anchor.kind === \"node\" ? anchor.at : 0;\n return {\n commentId: thread.commentId,\n from,\n to,\n status: thread.status,\n isActive: thread.isActive,\n };\n }),\n };\n}\n\nexport function getCommentRangeState(\n model: CommentDecorationModel | undefined,\n from: number,\n to: number,\n): CommentRangeState {\n if (!model) {\n return {\n hasComments: false,\n hasOpen: false,\n hasResolved: false,\n hasActive: false,\n count: 0,\n overlapping: [],\n };\n }\n\n const overlapping = model.threads.filter((thread) =>\n rangesOverlap(thread.from, thread.to, from, to),\n );\n return {\n hasComments: overlapping.length > 0,\n hasOpen: overlapping.some((thread) => thread.status === \"open\"),\n hasResolved: overlapping.some((thread) => thread.status === \"resolved\"),\n hasActive: overlapping.some((thread) => thread.isActive),\n count: overlapping.length,\n overlapping,\n };\n}\n\nexport type MarkupDisplay = \"clean\" | \"simple\" | \"all\";\n\nexport function getCommentHighlightClass(\n model: CommentDecorationModel | undefined,\n from: number,\n to: number,\n markupDisplay: MarkupDisplay = \"all\",\n): string {\n const state = getCommentRangeState(model, from, to);\n if (!state.hasComments) {\n return \"\";\n }\n\n switch (markupDisplay) {\n case \"clean\":\n return state.hasActive ? \"bg-comment-soft\" : \"\";\n case \"simple\":\n if (state.hasActive) {\n return \"underline decoration-comment decoration-2 underline-offset-4\";\n }\n if (state.hasOpen) {\n return \"underline decoration-comment/60 decoration-1 underline-offset-4\";\n }\n return \"underline decoration-comment/40 decoration-1 underline-offset-4\";\n case \"all\":\n if (state.hasActive) {\n return \"bg-comment-strong\";\n }\n if (state.hasOpen) {\n return \"bg-comment-soft\";\n }\n return \"bg-comment-soft opacity-60\";\n }\n}\n\nexport function rangesOverlap(\n leftFrom: number,\n leftTo: number,\n rightFrom: number,\n rightTo: number,\n): boolean {\n const leftEnd = Math.max(leftFrom, leftTo);\n const rightEnd = Math.max(rightFrom, rightTo);\n return leftFrom < rightEnd && rightFrom < leftEnd;\n}\n","import type { TrackedChangesSnapshot, TrackedChangeEntrySnapshot } from \"../../api/public-types\";\nimport { rangesOverlap, type MarkupDisplay } from \"./comment-decoration-model\";\n\nexport interface RevisionDecorationModel {\n revisions: RevisionDecorationEntry[];\n}\n\nexport interface RevisionDecorationEntry {\n revisionId: string;\n from: number;\n to: number;\n kind: TrackedChangeEntrySnapshot[\"kind\"];\n status: TrackedChangeEntrySnapshot[\"status\"];\n actionability: TrackedChangeEntrySnapshot[\"actionability\"];\n isActive: boolean;\n}\n\nexport interface RevisionRangeState {\n hasChanges: boolean;\n hasInsertions: boolean;\n hasDeletions: boolean;\n hasActive: boolean;\n count: number;\n overlapping: RevisionDecorationEntry[];\n}\n\nexport function createRevisionDecorationModel(\n snapshot?: TrackedChangesSnapshot,\n activeRevisionId?: string,\n): RevisionDecorationModel | undefined {\n if (!snapshot) {\n return undefined;\n }\n\n return {\n revisions: snapshot.revisions\n .filter((rev) => rev.anchor.kind !== \"detached\" && rev.status === \"active\")\n .map((rev) => {\n const anchor = rev.anchor;\n const from = anchor.kind === \"range\" ? anchor.from : anchor.kind === \"node\" ? anchor.at : 0;\n const to = anchor.kind === \"range\" ? anchor.to : anchor.kind === \"node\" ? anchor.at : 0;\n return {\n revisionId: rev.revisionId,\n from,\n to,\n kind: rev.kind,\n status: rev.status,\n actionability: rev.actionability,\n isActive: rev.revisionId === activeRevisionId,\n };\n }),\n };\n}\n\nexport function getRevisionRangeState(\n model: RevisionDecorationModel | undefined,\n from: number,\n to: number,\n): RevisionRangeState {\n if (!model) {\n return {\n hasChanges: false,\n hasInsertions: false,\n hasDeletions: false,\n hasActive: false,\n count: 0,\n overlapping: [],\n };\n }\n\n const overlapping = model.revisions.filter((rev) =>\n rangesOverlap(rev.from, rev.to, from, to),\n );\n return {\n hasChanges: overlapping.length > 0,\n hasInsertions: overlapping.some((rev) => rev.kind === \"insertion\"),\n hasDeletions: overlapping.some((rev) => rev.kind === \"deletion\"),\n hasActive: overlapping.some((rev) => rev.isActive),\n count: overlapping.length,\n overlapping,\n };\n}\n\nexport function getRevisionHighlightClass(\n model: RevisionDecorationModel | undefined,\n from: number,\n to: number,\n markupDisplay: MarkupDisplay = \"all\",\n): string {\n const state = getRevisionRangeState(model, from, to);\n if (!state.hasChanges) {\n return \"\";\n }\n\n const activeRing = state.hasActive ? \" ring-1 ring-accent/30\" : \"\";\n\n switch (markupDisplay) {\n case \"clean\":\n // In clean mode, deletions are hidden entirely (caller should not render).\n // Insertions render as normal text with no decoration.\n return \"\";\n case \"simple\":\n if (state.hasInsertions) {\n return `underline decoration-insert/60 decoration-1 underline-offset-2 text-primary${activeRing}`;\n }\n if (state.hasDeletions) {\n return `text-secondary line-through decoration-danger/70 decoration-1${activeRing}`;\n }\n return activeRing;\n case \"all\":\n if (state.hasInsertions) {\n return `text-primary bg-insert-soft/80 ring-1 ring-insert/20${activeRing}`;\n }\n if (state.hasDeletions) {\n return `text-danger line-through decoration-danger/80 decoration-1 bg-delete-soft/70${activeRing}`;\n }\n return activeRing;\n }\n}\n\nexport function shouldHideInCleanMode(\n model: RevisionDecorationModel | undefined,\n from: number,\n to: number,\n): boolean {\n const state = getRevisionRangeState(model, from, to);\n return state.hasDeletions;\n}\n","import type { SelectionSnapshot } from \"../../api/public-types\";\n\nexport function createSelectionSnapshot(anchor: number, head = anchor): SelectionSnapshot {\n const from = Math.min(anchor, head);\n const to = Math.max(anchor, head);\n return {\n anchor,\n head,\n isCollapsed: anchor === head,\n activeRange: {\n kind: \"range\",\n from,\n to,\n assoc: {\n start: -1,\n end: 1,\n },\n },\n };\n}\n\nexport function createNodeSelectionSnapshot(at: number, assoc: -1 | 1 = 1): SelectionSnapshot {\n return {\n anchor: at,\n head: at,\n isCollapsed: true,\n activeRange: {\n kind: \"node\",\n at,\n assoc,\n },\n };\n}\n\nexport function isCollapsedAtBlockStart(\n selection: SelectionSnapshot,\n blockFrom: number,\n): boolean {\n return selection.isCollapsed && selection.head === blockFrom;\n}\n\nexport function selectionTouchesRange(\n selection: SelectionSnapshot,\n from: number,\n to: number,\n): boolean {\n if (selection.isCollapsed) {\n return false;\n }\n\n const selectionFrom = Math.min(selection.anchor, selection.head);\n const selectionTo = Math.max(selection.anchor, selection.head);\n return selectionFrom < to && from < selectionTo;\n}\n"],"mappings":"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","names":["jsx","jsxs","TwSelectionToolbar","Fragment","jsx","jsxs","focusRingClass","Check","Fragment","jsx","jsxs","focusRingClass","Check","jsx","jsxs","focusRingClass","jsx","jsxs","AlertTriangle","Fragment","jsx","jsxs","Tooltip","jsx","jsxs","focusRingClass","React","Tooltip","Baseline","Bold","Highlighter","Italic","MessageSquare","ShieldAlert","ShieldCheck","Underline","Fragment","jsx","jsxs","focusRingClass","Bold","Italic","Underline","Baseline","Highlighter","MessageSquare","ShieldAlert","ShieldCheck","React","useCallback","useEffect","useMemo","useRef","useState","Tooltip","List","Fragment","jsx","jsxs","jsx","jsxs","ToolbarButton","jsx","jsxs","useEffect","useRef","useState","Fragment","jsx","jsxs","Tooltip","Check","MessageSquare","X","jsx","jsxs","focusRingClass","Check","X","MessageSquare","jsx","jsxs","ToolbarButton","Fragment","jsx","jsxs","useRef","useState","useMemo","useEffect","useCallback","List"]}