@bettercms-ai/kit 2.0.0 → 2.0.2

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 (120) hide show
  1. package/dist/adapters/lossy.d.ts +14 -6
  2. package/dist/adapters/lossy.js +23 -11
  3. package/dist/adapters/lossy.js.map +1 -1
  4. package/dist/adapters/prod-types.d.ts +46 -14
  5. package/dist/adapters/prod-types.js +37 -35
  6. package/dist/adapters/prod-types.js.map +1 -1
  7. package/dist/adapters/schema.d.ts +39 -0
  8. package/dist/adapters/schema.js +281 -82
  9. package/dist/adapters/schema.js.map +1 -1
  10. package/dist/context.d.ts +39 -0
  11. package/dist/context.js +40 -1
  12. package/dist/context.js.map +1 -1
  13. package/dist/controls/form-picker-register.d.ts +7 -1
  14. package/dist/controls/form-picker-register.js +1 -5
  15. package/dist/controls/form-picker-register.js.map +1 -1
  16. package/dist/controls/icon.d.ts +1 -1
  17. package/dist/controls/icon.js +1 -1
  18. package/dist/controls/icon.js.map +1 -1
  19. package/dist/controls/link.d.ts +11 -4
  20. package/dist/controls/link.js +120 -202
  21. package/dist/controls/link.js.map +1 -1
  22. package/dist/controls/location.js +3 -8
  23. package/dist/controls/location.js.map +1 -1
  24. package/dist/controls/media.d.ts +0 -14
  25. package/dist/controls/media.js +52 -95
  26. package/dist/controls/media.js.map +1 -1
  27. package/dist/controls/reference-services.d.ts +23 -2
  28. package/dist/controls/reference.d.ts +2 -2
  29. package/dist/controls/reference.js +79 -28
  30. package/dist/controls/reference.js.map +1 -1
  31. package/dist/controls/rich-text/article-shell.d.ts +145 -0
  32. package/dist/controls/rich-text/article-shell.js +514 -0
  33. package/dist/controls/rich-text/article-shell.js.map +1 -0
  34. package/dist/controls/rich-text/author.d.ts +25 -0
  35. package/dist/controls/rich-text/author.js +107 -0
  36. package/dist/controls/rich-text/author.js.map +1 -0
  37. package/dist/controls/rich-text/blocks.d.ts +19 -2
  38. package/dist/controls/rich-text/blocks.js +275 -638
  39. package/dist/controls/rich-text/blocks.js.map +1 -1
  40. package/dist/controls/rich-text/button.d.ts +23 -0
  41. package/dist/controls/rich-text/button.js +81 -0
  42. package/dist/controls/rich-text/button.js.map +1 -0
  43. package/dist/controls/rich-text/catalog.d.ts +2 -5
  44. package/dist/controls/rich-text/catalog.js +121 -7
  45. package/dist/controls/rich-text/catalog.js.map +1 -1
  46. package/dist/controls/rich-text/checklist.d.ts +24 -0
  47. package/dist/controls/rich-text/checklist.js +115 -0
  48. package/dist/controls/rich-text/checklist.js.map +1 -0
  49. package/dist/controls/rich-text/codec.d.ts +15 -1
  50. package/dist/controls/rich-text/codec.js +11 -1
  51. package/dist/controls/rich-text/codec.js.map +1 -1
  52. package/dist/controls/rich-text/columns.d.ts +41 -0
  53. package/dist/controls/rich-text/columns.js +181 -0
  54. package/dist/controls/rich-text/columns.js.map +1 -0
  55. package/dist/controls/rich-text/control.js +1 -0
  56. package/dist/controls/rich-text/control.js.map +1 -1
  57. package/dist/controls/rich-text/dom.d.ts +84 -4
  58. package/dist/controls/rich-text/dom.js +171 -10
  59. package/dist/controls/rich-text/dom.js.map +1 -1
  60. package/dist/controls/rich-text/editor.d.ts +4 -2
  61. package/dist/controls/rich-text/editor.js +199 -26
  62. package/dist/controls/rich-text/editor.js.map +1 -1
  63. package/dist/controls/rich-text/embed.d.ts +28 -0
  64. package/dist/controls/rich-text/embed.js +210 -0
  65. package/dist/controls/rich-text/embed.js.map +1 -0
  66. package/dist/controls/rich-text/footnote.d.ts +41 -0
  67. package/dist/controls/rich-text/footnote.js +185 -0
  68. package/dist/controls/rich-text/footnote.js.map +1 -0
  69. package/dist/controls/rich-text/gallery.d.ts +28 -0
  70. package/dist/controls/rich-text/gallery.js +167 -0
  71. package/dist/controls/rich-text/gallery.js.map +1 -0
  72. package/dist/controls/rich-text/link-form.d.ts +13 -1
  73. package/dist/controls/rich-text/link-form.js +41 -7
  74. package/dist/controls/rich-text/link-form.js.map +1 -1
  75. package/dist/controls/rich-text/ops.js +6 -0
  76. package/dist/controls/rich-text/ops.js.map +1 -1
  77. package/dist/controls/rich-text/related.d.ts +49 -0
  78. package/dist/controls/rich-text/related.js +233 -0
  79. package/dist/controls/rich-text/related.js.map +1 -0
  80. package/dist/controls/rich-text/toc.d.ts +47 -0
  81. package/dist/controls/rich-text/toc.js +160 -0
  82. package/dist/controls/rich-text/toc.js.map +1 -0
  83. package/dist/controls/slot-register.d.ts +6 -1
  84. package/dist/controls/slot-register.js +1 -4
  85. package/dist/controls/slot-register.js.map +1 -1
  86. package/dist/core/core.d.ts +11 -3
  87. package/dist/core/core.js +24 -6
  88. package/dist/core/core.js.map +1 -1
  89. package/dist/core/facets.d.ts +16 -0
  90. package/dist/core/facets.js +17 -1
  91. package/dist/core/facets.js.map +1 -1
  92. package/dist/core/index.js +2 -2
  93. package/dist/index.js +16 -5
  94. package/dist/index.js.map +1 -1
  95. package/dist/ledgers/exclusions.v1.js +141 -0
  96. package/dist/ledgers/exclusions.v1.js.map +1 -0
  97. package/dist/library/coverage.d.ts +13 -1
  98. package/dist/library/coverage.js +12 -1
  99. package/dist/library/coverage.js.map +1 -1
  100. package/dist/library/kit-catalog.json +158 -154
  101. package/dist/schema/types.d.ts +17 -0
  102. package/dist/schema/types.js.map +1 -1
  103. package/dist/styles.css +1 -1
  104. package/dist/testing/coverage-extras.d.ts +8 -0
  105. package/dist/testing/coverage-extras.js +44 -0
  106. package/dist/testing/coverage-extras.js.map +1 -0
  107. package/dist/testing/exclusions.d.ts +30 -0
  108. package/dist/testing/exclusions.js +13 -0
  109. package/dist/testing/exclusions.js.map +1 -0
  110. package/dist/ui/autocomplete.d.ts +29 -1
  111. package/dist/ui/autocomplete.js +102 -47
  112. package/dist/ui/autocomplete.js.map +1 -1
  113. package/dist/ui/button.js +3 -5
  114. package/dist/ui/button.js.map +1 -1
  115. package/dist/ui/index.js +2 -2
  116. package/dist/ui/overlay.d.ts +4 -1
  117. package/dist/ui/overlay.js +2 -1
  118. package/dist/ui/overlay.js.map +1 -1
  119. package/dist/ui/toast.js +1 -1
  120. package/package.json +8 -2
@@ -1 +1 @@
1
- {"version":3,"file":"editor.js","names":[],"sources":["../../../src/controls/rich-text/editor.tsx"],"sourcesContent":["/**\n * RICH TEXT — the boxed rich-text editor (V2 HEAD controls/rich-text-editor.tsx, Figma 60995-5431, CPO D49 / D54 / D55).\n *\n * contentEditable + execCommand keeps it dependency-free; the value is clean HTML, which the field's control turns into\n * the stored value through the host's codec (./codec.ts). Rich blocks (an image) are React \"islands\" rendered into\n * contenteditable=false nodes and written back as static HTML, so a re-mount restores them (./dom.ts).\n *\n * ./toolbar.tsx the field toolbar (no room at rest, folds into the chevron by width)\n * ./catalog.tsx Insert menu, slash menu and the shared block catalogue\n * ./blocks.tsx the rich blocks (an image)\n * ./markdown.ts HTML ⇄ Markdown for the Markdown toggle and pasting\n * ./ops.ts pure DOM block operations (insert, turn into, move, duplicate, live Markdown, field rules)\n * ./floating.tsx the selection bubble\n * ./dom.ts hydrate / serialize / sanitize and selection helpers\n *\n * Everything the editor offers is limited to what the field accepts (`features`): a toolbar button, a slash command, a\n * Markdown shortcut or pasted markup the field cannot hold is not offered, or is turned into what it can hold and said so.\n */\nimport * as React from \"react\";\nimport { createPortal, flushSync } from \"react-dom\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport { IconArrowBarToDown, IconArrowBarToUp, IconCopy, IconGripVertical, IconPlus, IconTransform, IconTrash } from \"@tabler/icons-react\";\nimport { cn } from \"../../lib/cn\";\nimport { eventKey } from \"../../lib/key-event\";\nimport { useKitEnv, useKitServices, type AiPreset } from \"../../context\";\nimport { Button } from \"../../ui/button\";\nimport { Textarea } from \"../../ui/input\";\nimport { ExpandedEditorModal } from \"../../ui/expanded-editor-modal\";\nimport { Menu, MenuContent, MenuItem, MenuSeparator, MenuSub, MenuSubContent, MenuSubTrigger, MenuTrigger, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Tooltip } from \"../../ui/overlay\";\nimport { shortcutHintsOn } from \"../../ui/shortcut-hint\";\nimport { ALL_FEATURES, type RichTextFeature } from \"./codec\";\nimport { COMPONENT_INSERT_TOAST, type KitHistoryStep } from \"../component-services\";\nimport { Island, type IslandCtx } from \"./blocks\";\nimport { openComponentPanel } from \"./component-panel\";\nimport { CatalogComponentsProvider, InsertMenuContent, SlashMenuPanel, blockAllowed, catalogKey, noteRecent, useCatalog, type CatalogComponents, type CatalogItem } from \"./catalog\";\nimport {\n closestBlock, createIsland, defaultModel, editingHost, esc, hydrate, isEmptyHtml, placeCaret, rangeRect, rid, sanitize,\n serialize, textBeforeCaret, topBlock, type IslandEl, type IslandModels, type IslandKind,\n} from \"./dom\";\nimport { htmlToMarkdown, looksLikeMarkdown, markdownToHtml } from \"./markdown\";\nimport * as ops from \"./ops\";\nimport { SelectionBubble } from \"./floating\";\nimport { LinkForm, type TextLink } from \"./link-form\";\nimport { EMPTY_FMT, FormatToolbar, MARK_FEATURE, stylesFor, type Fmt, type MarkCmd } from \"./toolbar\";\n\n/* ── Prose styles for the editable surface (kit tokens only) ──\n * Every descendant rule skips `[data-rt-isolate]` subtrees, as V2's (rich-text-editor.tsx:46-58): a block's own UI inside\n * the writing surface (a table island's column headers, a component card's form) is app UI, not prose. */\nexport const RT_PROSE =\n \"text-kit-base leading-[1.6] text-kit-fg [&>*+*]:mt-3 \" +\n // BUG-7: a styled run keeps the SITE's class (the stored design), but the site's stylesheet is not here. Only the\n // utilities the dashboard happens to build apply: `text-transparent` without its `bg-clip-text` gradient drew the\n // words invisible. The run's text is drawn as text; the class itself is kept, so a save writes it back unchanged.\n \"[&_span[class]:not([data-rt-isolate]_*)]:!text-inherit [&_span[class]:not([data-rt-isolate]_*)]:![-webkit-text-fill-color:currentColor] [&_span[class]:not([data-rt-isolate]_*)]:!bg-none [&_span[class]:not([data-rt-isolate]_*)]:!opacity-100 [&_span[class]:not([data-rt-isolate]_*)]:!visible \" +\n \"[&_h1:not([data-rt-isolate]_*)]:text-[28px] [&_h1:not([data-rt-isolate]_*)]:font-semibold [&_h1:not([data-rt-isolate]_*)]:leading-9 [&_h1:not([data-rt-isolate]_*)]:tracking-[-0.01em] [&_h2:not([data-rt-isolate]_*)]:text-[22px] [&_h2:not([data-rt-isolate]_*)]:font-semibold [&_h2:not([data-rt-isolate]_*)]:leading-8 [&_h2:not([data-rt-isolate]_*)]:tracking-[-0.01em] \" +\n \"[&_h3:not([data-rt-isolate]_*)]:text-kit-lg [&_h3:not([data-rt-isolate]_*)]:font-semibold [&_h4:not([data-rt-isolate]_*)]:text-kit-md [&_h4:not([data-rt-isolate]_*)]:font-semibold [&_h5:not([data-rt-isolate]_*)]:text-kit-base [&_h5:not([data-rt-isolate]_*)]:font-semibold [&_h6:not([data-rt-isolate]_*)]:text-kit-sm [&_h6:not([data-rt-isolate]_*)]:font-semibold [&_h6:not([data-rt-isolate]_*)]:uppercase [&_h6:not([data-rt-isolate]_*)]:tracking-wide [&_h6:not([data-rt-isolate]_*)]:text-kit-fg-2 [&>h1]:mt-6 [&>h2]:mt-6 [&>h3]:mt-5 [&>*:first-child]:mt-0 \" +\n // a block's own list (key takeaways, V2 data-rt-isolate) is app UI, not body prose: V2 rich-text-editor.tsx skips it\n \"[&_ul:not([data-rt-isolate]_*)]:list-disc [&_ul:not([data-rt-isolate]_*)]:pl-5 [&_ol:not([data-rt-isolate]_*)]:list-decimal [&_ol:not([data-rt-isolate]_*)]:pl-5 [&_li:not([data-rt-isolate]_*)]:pl-1 [&_li+li:not([data-rt-isolate]_*)]:mt-1 [&_li:not([data-rt-isolate]_*)]:marker:text-kit-fg-3 \" +\n \"[&_ul[data-task]:not([data-rt-isolate]_*)]:list-none [&_ul[data-task]:not([data-rt-isolate]_*)]:pl-0 [&_ul[data-task]>li:not([data-rt-isolate]_*)]:relative [&_ul[data-task]>li:not([data-rt-isolate]_*)]:pl-7 [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:absolute [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:left-0 [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:top-[0.2em] [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:flex [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:size-4 [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:items-center [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:justify-center [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:rounded-kit-md [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:border [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:border-kit-line-strong [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:bg-kit-surface [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:text-[11px] [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:font-semibold [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:leading-none [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:content-[''] \" +\n \"[&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:text-kit-fg-3 [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:line-through [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:before:border-kit-inverse [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:before:bg-kit-inverse [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:before:text-kit-fg-inverse [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:before:content-['✓'] \" +\n \"[&_blockquote:not([data-rt-isolate]_*)]:border-l-2 [&_blockquote:not([data-rt-isolate]_*)]:border-kit-line-strong [&_blockquote:not([data-rt-isolate]_*)]:pl-4 [&_blockquote:not([data-rt-isolate]_*)]:text-kit-fg-2 [&_blockquote:not([data-rt-isolate]_*)]:italic \" +\n \"[&_a:not([data-rt-isolate]_*)]:text-kit-accent-fg [&_a:not([data-rt-isolate]_*)]:underline [&_a:not([data-rt-isolate]_*)]:decoration-kit-accent-line [&_a:not([data-rt-isolate]_*)]:underline-offset-2 \" +\n \"[&_a[data-button]:not([data-rt-isolate]_*)]:inline-flex [&_a[data-button]:not([data-rt-isolate]_*)]:h-9 [&_a[data-button]:not([data-rt-isolate]_*)]:items-center [&_a[data-button]:not([data-rt-isolate]_*)]:rounded-kit-md [&_a[data-button]:not([data-rt-isolate]_*)]:bg-kit-inverse [&_a[data-button]:not([data-rt-isolate]_*)]:px-3.5 [&_a[data-button]:not([data-rt-isolate]_*)]:text-kit-sm [&_a[data-button]:not([data-rt-isolate]_*)]:font-medium [&_a[data-button]:not([data-rt-isolate]_*)]:text-kit-fg-inverse [&_a[data-button]:not([data-rt-isolate]_*)]:no-underline \" +\n // a glossary term (`<abbr data-term title>`) reads as a dotted underline; a footnote marker as a small superscript\n \"[&_abbr:not([data-rt-isolate]_*)]:cursor-help [&_abbr:not([data-rt-isolate]_*)]:underline [&_abbr:not([data-rt-isolate]_*)]:decoration-dotted [&_abbr:not([data-rt-isolate]_*)]:underline-offset-2 [&_sup:not([data-rt-isolate]_*)]:text-[0.7em] [&_sup:not([data-rt-isolate]_*)]:leading-none \" +\n \"[&_code:not([data-rt-isolate]_*)]:rounded-kit-md [&_code:not([data-rt-isolate]_*)]:bg-kit-muted [&_code:not([data-rt-isolate]_*)]:px-1 [&_code:not([data-rt-isolate]_*)]:py-px [&_code:not([data-rt-isolate]_*)]:font-kit-mono [&_code:not([data-rt-isolate]_*)]:text-[0.9em] \" +\n \"[&_pre:not([data-rt-isolate]_*)]:overflow-x-auto [&_pre:not([data-rt-isolate]_*)]:whitespace-pre-wrap [&_pre:not([data-rt-isolate]_*)]:rounded-kit-lg [&_pre:not([data-rt-isolate]_*)]:bg-kit-code [&_pre:not([data-rt-isolate]_*)]:text-kit-code-fg [&_pre:not([data-rt-isolate]_*)]:p-3 [&_pre:not([data-rt-isolate]_*)]:font-kit-mono [&_pre:not([data-rt-isolate]_*)]:text-kit-sm [&_pre:not([data-rt-isolate]_*)]:border [&_pre:not([data-rt-isolate]_*)]:border-kit-line \" +\n \"[&_pre_code:not([data-rt-isolate]_*)]:rounded-none [&_pre_code:not([data-rt-isolate]_*)]:bg-transparent [&_pre_code:not([data-rt-isolate]_*)]:p-0 [&_pre_code:not([data-rt-isolate]_*)]:text-[1em] \" +\n \"[&_hr:not([data-rt-isolate]_*)]:my-6 [&_hr:not([data-rt-isolate]_*)]:border-kit-line \" +\n // V2 rich-text-editor.tsx 64-65: an image's figure sits 16px off its neighbours (my-4), the picture framed\n \"[&_figure:not([data-rt-isolate]_*)]:my-4 [&_img:not([data-rt-isolate]_*)]:rounded-kit-lg [&_img:not([data-rt-isolate]_*)]:border [&_img:not([data-rt-isolate]_*)]:border-kit-line [&_figcaption:not([data-rt-isolate]_*)]:mt-1.5 [&_figcaption:not([data-rt-isolate]_*)]:text-center [&_figcaption:not([data-rt-isolate]_*)]:text-kit-sm [&_figcaption:not([data-rt-isolate]_*)]:text-kit-fg-3 \" +\n \"[&_figure_img:not([data-rt-isolate]_*)]:block [&_figure[data-size=s]_img:not([data-rt-isolate]_*)]:w-1/3 [&_figure[data-size=m]_img:not([data-rt-isolate]_*)]:w-1/2 [&_figure[data-size=l]_img:not([data-rt-isolate]_*)]:w-3/4 [&_figure[data-align=center]_img:not([data-rt-isolate]_*)]:mx-auto [&_figure[data-align=right]_img:not([data-rt-isolate]_*)]:ml-auto [&_figure[data-align=full]_img:not([data-rt-isolate]_*)]:w-full \" +\n \"[&_div[data-callout]:not([data-rt-isolate]_*)]:rounded-kit-lg [&_div[data-callout]:not([data-rt-isolate]_*)]:border [&_div[data-callout]:not([data-rt-isolate]_*)]:border-kit-info-line [&_div[data-callout]:not([data-rt-isolate]_*)]:bg-kit-info-soft [&_div[data-callout]:not([data-rt-isolate]_*)]:px-4 [&_div[data-callout]:not([data-rt-isolate]_*)]:py-3 [&_div[data-callout]:not([data-rt-isolate]_*)]:text-kit-fg \" +\n \"[&_div[data-callout=tip]:not([data-rt-isolate]_*)]:border-kit-success-line [&_div[data-callout=tip]:not([data-rt-isolate]_*)]:bg-kit-success-soft [&_div[data-callout=warning]:not([data-rt-isolate]_*)]:border-kit-warning-line [&_div[data-callout=warning]:not([data-rt-isolate]_*)]:bg-kit-warning-soft [&_div[data-callout]>p[data-title]:not([data-rt-isolate]_*)]:font-medium \" +\n \"[&_details:not([data-rt-isolate]_*)]:rounded-kit-md [&_summary:not([data-rt-isolate]_*)]:cursor-pointer [&_summary:not([data-rt-isolate]_*)]:font-medium [&_details>div:not([data-rt-isolate]_*)]:mt-1 [&_details>div:not([data-rt-isolate]_*)]:border-l [&_details>div:not([data-rt-isolate]_*)]:border-kit-line [&_details>div:not([data-rt-isolate]_*)]:pl-4 [&_details>div:not([data-rt-isolate]_*)]:ml-1 \" +\n \"[&_div[data-rt=columns]:not([data-rt-isolate]_*)]:grid [&_div[data-rt=columns]:not([data-rt-isolate]_*)]:gap-4 [&_div[data-cols='2']:not([data-rt-isolate]_*)]:grid-cols-2 [&_div[data-cols='3']:not([data-rt-isolate]_*)]:grid-cols-3 [&_div[data-cols='4']:not([data-rt-isolate]_*)]:grid-cols-4 [&_div[data-gap=s]:not([data-rt-isolate]_*)]:gap-2 [&_div[data-gap=l]:not([data-rt-isolate]_*)]:gap-7 \" +\n \"[&_div[data-rt=file]:not([data-rt-isolate]_*)]:rounded-kit-lg [&_div[data-rt=file]:not([data-rt-isolate]_*)]:border [&_div[data-rt=file]:not([data-rt-isolate]_*)]:border-kit-line [&_div[data-rt=file]:not([data-rt-isolate]_*)]:px-3 [&_div[data-rt=file]:not([data-rt-isolate]_*)]:py-2.5 [&_div[data-rt=file]:not([data-rt-isolate]_*)]:text-kit-sm \" +\n \"[&_div[data-embed]:not([data-rt-isolate]_*)]:flex [&_div[data-embed]:not([data-rt-isolate]_*)]:aspect-video [&_div[data-embed]:not([data-rt-isolate]_*)]:items-center [&_div[data-embed]:not([data-rt-isolate]_*)]:justify-center [&_div[data-embed]:not([data-rt-isolate]_*)]:rounded-kit-lg [&_div[data-embed]:not([data-rt-isolate]_*)]:border [&_div[data-embed]:not([data-rt-isolate]_*)]:border-kit-line [&_div[data-embed]:not([data-rt-isolate]_*)]:bg-kit-subtle [&_div[data-embed]:not([data-rt-isolate]_*)]:text-kit-sm [&_div[data-embed]:not([data-rt-isolate]_*)]:text-kit-fg-3 \" +\n \"[&_div[data-block]:not([data-rt-isolate]_*)]:flex [&_div[data-block]:not([data-rt-isolate]_*)]:items-center [&_div[data-block]:not([data-rt-isolate]_*)]:gap-2 [&_div[data-block]:not([data-rt-isolate]_*)]:rounded-kit-lg [&_div[data-block]:not([data-rt-isolate]_*)]:border [&_div[data-block]:not([data-rt-isolate]_*)]:border-dashed [&_div[data-block]:not([data-rt-isolate]_*)]:border-kit-accent-line [&_div[data-block]:not([data-rt-isolate]_*)]:bg-kit-accent-softer [&_div[data-block]:not([data-rt-isolate]_*)]:px-3 [&_div[data-block]:not([data-rt-isolate]_*)]:py-3 [&_div[data-block]:not([data-rt-isolate]_*)]:text-kit-sm [&_div[data-block]:not([data-rt-isolate]_*)]:text-kit-accent-fg \" +\n \"[&_table:not([data-rt-isolate]_*)]:w-full [&_table:not([data-rt-isolate]_*)]:border-collapse [&_table:not([data-rt-isolate]_*)]:text-kit-sm [&_td:not([data-rt-isolate]_*)]:border [&_td:not([data-rt-isolate]_*)]:border-kit-line [&_td:not([data-rt-isolate]_*)]:px-2.5 [&_td:not([data-rt-isolate]_*)]:py-1.5 [&_td:not([data-rt-isolate]_*)]:align-top [&_th:not([data-rt-isolate]_*)]:border [&_th:not([data-rt-isolate]_*)]:border-kit-line [&_th:not([data-rt-isolate]_*)]:bg-kit-subtle [&_th:not([data-rt-isolate]_*)]:px-2.5 [&_th:not([data-rt-isolate]_*)]:py-1.5 [&_th:not([data-rt-isolate]_*)]:text-left [&_th:not([data-rt-isolate]_*)]:align-top [&_th:not([data-rt-isolate]_*)]:font-medium\";\n\n/** Panel density (≈340px inspector): 13px text, smaller headings. */\nexport const RT_PANEL = \"text-kit-sm leading-[1.6] [&_h1:not([data-rt-isolate]_*)]:text-kit-xl [&_h1:not([data-rt-isolate]_*)]:leading-7 [&_h2:not([data-rt-isolate]_*)]:text-kit-lg [&_h2:not([data-rt-isolate]_*)]:leading-7 [&_h3:not([data-rt-isolate]_*)]:text-kit-md [&_h4:not([data-rt-isolate]_*)]:text-kit-base [&_h5:not([data-rt-isolate]_*)]:text-kit-sm [&_h6:not([data-rt-isolate]_*)]:text-kit-xs\";\n\n/** execCommand, where the engine has it (it returns false where it does not). */\nconst exec = (cmd: string, arg?: string): boolean => {\n try {\n return typeof document.execCommand === \"function\" && document.execCommand(cmd, false, arg);\n } catch {\n return false;\n }\n};\n/** A footnote marker (`<sup data-footnote>`, or the table's `<sup><a href=\"#…-fn-n\">`): never an x² mark. */\nconst FOOTNOTE_SUP = \"sup[data-footnote], sup:has(> a[href*='-fn-'])\";\n/** x² / x₂ (V2): on inside the same mark takes it off (unwrap, keeping the words selected); inside the other one swaps;\n * otherwise the browser wraps the selection. Footnote markers are never touched. */\nfunction toggleScript(root: HTMLElement, tag: \"sup\" | \"sub\") {\n const s = window.getSelection();\n if (!s || !s.rangeCount) return;\n const at = (n: Node | null) => (n?.nodeType === 1 ? (n as HTMLElement) : (n?.parentElement ?? null));\n const find = (t: \"sup\" | \"sub\") => {\n const el = at(s.anchorNode)?.closest<HTMLElement>(t === \"sup\" ? `sup:not(${FOOTNOTE_SUP})` : \"sub\");\n return el && root.contains(el) ? el : null;\n };\n const unwrap = (el: HTMLElement) => {\n const first = el.firstChild;\n const last = el.lastChild;\n el.replaceWith(...Array.from(el.childNodes));\n if (first && last) {\n const r = document.createRange();\n r.setStartBefore(first);\n r.setEndAfter(last);\n s.removeAllRanges();\n s.addRange(r);\n }\n };\n const same = find(tag);\n if (same) return unwrap(same);\n const other = find(tag === \"sup\" ? \"sub\" : \"sup\");\n if (other) unwrap(other);\n exec(tag === \"sup\" ? \"superscript\" : \"subscript\");\n}\n\n/** Focus is in another text field (the comment composer, a link input) while the page's selection stays in this editor. */\nconst typingElsewhere = (el: HTMLElement | null) => {\n const ae = document.activeElement;\n return !!el && !!ae && ae !== el && !el.contains(ae) && ae.matches(\"input, textarea, [contenteditable='true']\");\n};\nconst queryState = (c: string) => {\n try {\n return typeof document.queryCommandState === \"function\" && document.queryCommandState(c);\n } catch {\n return false;\n }\n};\n/** Insert HTML at the caret: the browser's own insert (undoable), else by hand. */\nfunction insertHtmlAtCaret(html: string) {\n if (exec(\"insertHTML\", html)) return;\n const s = window.getSelection();\n if (!s || !s.rangeCount) return;\n const r = s.getRangeAt(0);\n r.deleteContents();\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = sanitize(html);\n const last = tpl.content.lastChild;\n r.insertNode(tpl.content);\n if (last) {\n r.setStartAfter(last);\n r.collapse(true);\n s.removeAllRanges();\n s.addRange(r);\n }\n}\n/* ── Word count (V2 rich-text-editor.tsx:115-128 + article.ts countWords, CPO D54 / D55) ──\n * Words = what the writer wrote once, in the flow a reader follows: text, headings, lists, quotes, callouts, toggles,\n * table cells and image captions. Not counted: components (counted apart), a pull quote (it repeats a line of the\n * story), key takeaways (they restate it), embeds, video and file links. */\nconst NOT_COUNTED = \"[data-rt=component],[data-rt=pullquote],[data-rt=takeaways],[data-rt=embed],[data-rt=video],[data-rt=file]\";\nconst WORDS = (s: string) => s.replace(/\\u200b/g, \"\").trim().split(/\\s+/).filter(Boolean).length;\nexport function countWords(html: string): number {\n if (!html) return 0;\n if (!/data-rt=\"(?:component|pullquote|takeaways|embed|video|file)\"/.test(html) || typeof DOMParser === \"undefined\")\n // A block's end and a line break part words; any other tag is a mark inside one (\"<strong>Screw</strong>Fast,\").\n return WORDS(html.replace(/<\\/(p|li|h[1-6]|blockquote|pre|figcaption|td|th|summary|div)>|<br\\s*\\/?>/g, \" \").replace(/<[^>]+>/g, \"\").replace(/&nbsp;|&[a-z]+;/g, \" \"));\n const doc = new DOMParser().parseFromString(`<body>${html}</body>`, \"text/html\");\n doc.body.querySelectorAll(NOT_COUNTED).forEach((n) => n.remove());\n doc.body.querySelectorAll(\"p,li,h1,h2,h3,h4,h5,h6,td,th,figcaption,summary,pre,blockquote,div\").forEach((n) => n.append(\" \"));\n return WORDS(doc.body.textContent ?? \"\");\n}\n/** Linked component instances in the body. */\nexport const countComponents = (html: string) => (html.match(/data-rt=\"component\"/g) ?? []).length;\n/** \"1,840 words · 3 components\" */\nexport const bodyCountLabel = (html: string) => {\n const w = countWords(html);\n const c = countComponents(html);\n return `${w.toLocaleString(\"en-US\")} ${w === 1 ? \"word\" : \"words\"}${c ? ` · ${c} ${c === 1 ? \"block\" : \"blocks\"}` : \"\"}`;\n};\n\nfunction insertTextAtCaret(text: string) {\n if (exec(\"insertText\", text)) return;\n const s = window.getSelection();\n if (!s || !s.rangeCount) return;\n const r = s.getRangeAt(0);\n r.deleteContents();\n const t = document.createTextNode(text);\n r.insertNode(t);\n r.setStartAfter(t);\n r.collapse(true);\n s.removeAllRanges();\n s.addRange(r);\n}\n\n/** The slash menu at full height (header 32, list 300, footer 28, borders), the least it shrinks to, and the gap it keeps from the window's edge. */\nconst SLASH_MENU_H = 362;\nconst SLASH_MIN_H = 160;\nconst SLASH_EDGE = 8;\n\n/**\n * Where the slash menu goes, collision-aware: below the caret when the whole menu fits there, else on the side with\n * more room, and never taller than that room (its list scrolls), so the last row (More components) stays reachable in\n * a short window.\n */\nexport function slashPlacement(caret: { top: number; bottom: number }, viewportH: number): { flipUp: boolean; maxHeight: number } {\n const below = viewportH - caret.bottom - 6 - SLASH_EDGE;\n const above = caret.top - 6 - SLASH_EDGE;\n const flipUp = below < SLASH_MENU_H && above > below;\n return { flipUp, maxHeight: Math.max(SLASH_MIN_H, Math.min(SLASH_MENU_H, flipUp ? above : below)) };\n}\n\ntype IslandStep = { el: IslandEl; before: IslandModels[IslandKind]; label: string; at: number };\n/** A step the host's history holds (KitServices.historyStep); its undo and redo are the host's, while it is next. */\ntype HostStep = { label: string; step: KitHistoryStep };\ntype GutterState = { el: HTMLElement; top: number; height: number };\ntype SlashState = { rect: DOMRect; node: Text; offset: number; query: string; folder: boolean; active: number };\ntype LinkState = { rect: DOMRect; initial: TextLink; existing: HTMLAnchorElement | null };\ntype Notice = { message: string; description?: string; action?: { label: string; onClick: () => void } };\n\nexport interface RichTextEditorProps {\n value: string;\n onChange: (html: string) => void;\n readOnly?: boolean;\n placeholder?: string;\n docKey: string;\n /** what the field accepts; the editor offers nothing else (default: everything) */\n features?: readonly RichTextFeature[];\n /** a one-paragraph field: Enter starts no new block */\n single?: boolean;\n /** links may open in a new tab */\n allowNewTab?: boolean;\n /** the writing surface's id (the field label's `for`; its label is `${id}-label`) */\n id?: string;\n invalid?: boolean;\n /** panel = narrow (~340px) inspector, document = the full editor column. */\n variant?: \"panel\" | \"document\";\n /** CPO D49: the expanded editor's breadcrumb, root → this field (\"Alternating feature rows\", \"Thin walls\", \"Body\"). */\n expandCrumbs?: string[];\n /** Controlled expanded modal (a host's label-row action opens it too). */\n expandedOpen?: boolean;\n onExpandedOpenChange?: (open: boolean) => void;\n /** This editor IS the body of the expanded modal: toolbar always shown, tall writing surface. */\n inModal?: boolean;\n /** Already the full editor: no Expand button. */\n hideFullscreen?: boolean;\n /** Scroll the writing surface beyond this height (px). */\n maxHeight?: number;\n autoFocus?: boolean;\n /** Shows the toolbar Comment button. */\n onComment?: (quote: string) => void;\n /** the components this field may embed (the insert menus' More components); absent → none offered */\n components?: CatalogComponents;\n}\n\n/* ── Editor ────────────────────────────────────────────────────────── */\nexport function RichTextEditor({\n value,\n onChange,\n readOnly,\n placeholder,\n docKey,\n features = ALL_FEATURES,\n single,\n allowNewTab = true,\n id,\n invalid,\n variant = \"document\",\n expandCrumbs,\n expandedOpen,\n onExpandedOpenChange,\n inModal,\n hideFullscreen,\n maxHeight,\n autoFocus,\n onComment,\n components,\n}: RichTextEditorProps) {\n const hints = shortcutHintsOn();\n const ph = placeholder ?? (hints ? \"Type '/' for commands\" : \"Write something…\");\n const dense = variant === \"panel\";\n const ref = React.useRef<HTMLDivElement>(null);\n const wrap = React.useRef<HTMLDivElement>(null);\n const scroller = React.useRef<HTMLDivElement>(null);\n const saved = React.useRef<Range | null>(null);\n const known = React.useRef<string | null>(null);\n const pending = React.useRef<string | null>(null);\n /** a host undo just ran: its value is loaded even while the editor has focus (⌘Z here) */\n const forceLoad = React.useRef(false);\n const prevDoc = React.useRef<string | null>(null);\n const onChangeRef = React.useRef(onChange);\n onChangeRef.current = onChange;\n const valueRef = React.useRef(value);\n valueRef.current = value;\n const services = useKitServices();\n const env = useKitEnv();\n const featureKey = features.join(\",\");\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const allows = React.useCallback((f: RichTextFeature) => features.includes(f), [featureKey]);\n\n const [empty, setEmpty] = React.useState(isEmptyHtml(value));\n const [words, setWords] = React.useState(() => countWords(value));\n const [comps, setComps] = React.useState(() => countComponents(value));\n const [fmt, setFmt] = React.useState<Fmt>(EMPTY_FMT);\n const [modalOwn, setModalOwn] = React.useState(false);\n const modalOpen = expandedOpen ?? modalOwn;\n const setModalOpen = (o: boolean) => (onExpandedOpenChange ? onExpandedOpenChange(o) : setModalOwn(o));\n const [md, setMd] = React.useState<{ text: string; original: string } | null>(null);\n const [mdConfirm, setMdConfirm] = React.useState(false);\n // Reduced motion: the Markdown confirm fades only (no slide).\n const reduceMotion = useReducedMotion();\n const [bubble, setBubble] = React.useState<DOMRect | null>(null);\n /** Comment was picked: the toolbar stays away until the next click or key inside this editor */\n const [quiet, setQuiet] = React.useState(false);\n React.useEffect(() => {\n const el = ref.current;\n if (!quiet || !el) return;\n const wake = () => setQuiet(false);\n el.addEventListener(\"mousedown\", wake);\n el.addEventListener(\"keydown\", wake);\n return () => {\n el.removeEventListener(\"mousedown\", wake);\n el.removeEventListener(\"keydown\", wake);\n };\n }, [quiet]);\n const [slash, setSlash] = React.useState<SlashState | null>(null);\n const [gutter, setGutter] = React.useState<GutterState | null>(null);\n const [blockMenu, setBlockMenu] = React.useState(false);\n const [gutterInsert, setGutterInsert] = React.useState(false);\n const gutterTarget = React.useRef<HTMLElement | null>(null);\n // D58: AI writing help follows ai.use and needs the host's AI service; without both no AI entry point is drawn.\n const canAI = env.can(\"ai.use\") && !!services.aiRewrite;\n const aiAttempt = React.useRef(0);\n const [link, setLink] = React.useState<LinkState | null>(null);\n const [drag, setDrag] = React.useState<{ from: HTMLElement; line: number | null; target: Element | null } | null>(null);\n const [focused, setFocused] = React.useState(false);\n const [menus, setMenus] = React.useState({ style: false, more: false });\n const [insertOpen, setInsertOpen] = React.useState(false);\n const inserted = React.useRef(false);\n const [islands, setIslands] = React.useState<{ id: string; el: IslandEl }[]>([]);\n const hist = React.useRef<{ past: IslandStep[]; future: IslandStep[]; textAt: number; hosts: HostStep[] }>({ past: [], future: [], textAt: 0, hosts: [] });\n const [width, setWidth] = React.useState(720);\n /* The block gutter (+ / grip) never reserves room inside the field: it floats in the space LEFT of the box when the\n host leaves ≥ 48px there (document columns), and sits in the box's padding otherwise. */\n const [gutterRoom, setGutterRoom] = React.useState(false);\n const blurTimer = React.useRef<number | undefined>(undefined);\n const [notice, setNotice] = React.useState<Notice | null>(null);\n\n const expanded = !!inModal;\n const toolbarOpen = !readOnly && (focused || menus.style || menus.more || insertOpen || expanded || !!md || !!link);\n const scrollable = !!maxHeight && !expanded;\n\n /** A refusal or a result the author must see: the host's toaster, else a line under the editor. Never silent. */\n const notify = React.useCallback(\n (message: string, opts: { description?: string; action?: Notice[\"action\"] } = {}) => {\n if (services.toast) services.toast(message, opts);\n else setNotice({ message, ...opts });\n },\n [services],\n );\n React.useEffect(() => {\n if (!notice) return;\n const t = window.setTimeout(() => setNotice(null), 8000);\n return () => window.clearTimeout(t);\n }, [notice]);\n\n /* ── islands ─────────────────────────────────────────────────────── */\n const syncIslands = React.useCallback(() => {\n const el = ref.current;\n if (!el) return setIslands((p) => (p.length ? [] : p));\n const list = Array.from(el.querySelectorAll<IslandEl>(\":scope > [data-rt-island]\"));\n const seen = new Set<string>();\n for (const x of list) {\n if (!x.__rt) {\n // a copy the browser made (drag/drop, native undo of a clone): start it fresh\n x.innerHTML = \"\";\n x.__rt = defaultModel(x.getAttribute(\"data-rt-island\") as IslandKind);\n delete x.dataset.rtId;\n }\n if (!x.dataset.rtId || seen.has(x.dataset.rtId)) x.dataset.rtId = rid(\"i\");\n seen.add(x.dataset.rtId);\n }\n setIslands((prev) => (prev.length === list.length && prev.every((p, i) => p.el === list[i]) ? prev : list.map((x) => ({ id: x.dataset.rtId!, el: x }))));\n }, []);\n\n /* ── value in / out ──────────────────────────────────────────────── */\n const load = React.useCallback(\n (html: string) => {\n const el = ref.current;\n if (!el) return;\n el.innerHTML = sanitize(html || \"\") || \"<p><br></p>\";\n hydrate(el);\n known.current = html;\n setEmpty(isEmptyHtml(html));\n setWords(countWords(html));\n setComps(countComponents(html));\n syncIslands();\n },\n [syncIslands],\n );\n\n const emit = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n syncIslands();\n const html = serialize(el);\n setEmpty(isEmptyHtml(html) && !el.querySelector(\":scope > [data-rt-island], :scope > hr\"));\n setWords(countWords(html));\n setComps(countComponents(html));\n if (html === known.current) return;\n forceLoad.current = false;\n known.current = html;\n onChangeRef.current(html);\n }, [syncIslands]);\n\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const docChanged = prevDoc.current !== null && prevDoc.current !== docKey;\n prevDoc.current = docKey;\n if (pending.current !== null) {\n const h = pending.current;\n pending.current = null;\n load(h);\n return;\n }\n if (forceLoad.current && value !== known.current) {\n forceLoad.current = false;\n load(value);\n return;\n }\n if (docChanged || !el.firstChild || (value !== known.current && !wrap.current?.contains(document.activeElement))) load(value);\n }, [value, docKey, md, load]);\n\n React.useEffect(() => {\n setMd(null);\n setMdConfirm(false);\n setSlash(null);\n setLink(null);\n setGutter(null);\n }, [docKey]);\n\n React.useEffect(() => {\n exec(\"defaultParagraphSeparator\", \"p\");\n if (autoFocus && ref.current && !readOnly) {\n ref.current.focus({ preventScroll: true });\n placeCaret(ref.current.lastElementChild ?? ref.current);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n React.useEffect(() => {\n const w = wrap.current;\n if (!w || typeof ResizeObserver === \"undefined\") return;\n const measureRoom = () => {\n let a = w.parentElement;\n while (a && a !== document.body) {\n const cs = getComputedStyle(a);\n if (cs.overflowX !== \"visible\" || cs.overflowY !== \"visible\") break;\n a = a.parentElement;\n }\n const left = w.getBoundingClientRect().left - (a ? a.getBoundingClientRect().left : 0);\n setGutterRoom(left >= 48);\n };\n const ro = new ResizeObserver(([e]) => {\n setWidth(Math.round(e.contentRect.width));\n measureRoom();\n });\n ro.observe(w);\n return () => ro.disconnect();\n }, []);\n\n /* the toolbar sticks below any sticky header (e.g. field tabs) in the same scroll area */\n const [stickyTop, setStickyTop] = React.useState(0);\n React.useEffect(() => {\n const w = wrap.current;\n if (!toolbarOpen || dense || !w) return;\n let sp = w.parentElement;\n while (sp && !/(auto|scroll)/.test(getComputedStyle(sp).overflowY)) sp = sp.parentElement;\n if (!sp) return setStickyTop(0);\n let top = 0;\n sp.querySelectorAll<HTMLElement>(\".sticky\").forEach((h) => {\n if (h.contains(w) || w.contains(h) || !(h.compareDocumentPosition(w) & Node.DOCUMENT_POSITION_FOLLOWING)) return;\n const cs = getComputedStyle(h);\n if (cs.position !== \"sticky\") return;\n top = Math.max(top, (parseFloat(cs.top) || 0) + h.offsetHeight);\n });\n setStickyTop(top);\n }, [toolbarOpen, dense]);\n\n // the slash menu follows the caret when anything scrolls; it closes only when the caret has left the \"/\" it was opened for\n const hasSlash = !!slash;\n React.useEffect(() => {\n if (!hasSlash) return;\n let raf = 0;\n const on = (e: Event) => {\n if (e.target instanceof Element && e.target.closest(\"[role=listbox]\")) return;\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() =>\n setSlash((sl) => {\n const s = window.getSelection();\n if (!sl || !s || !s.rangeCount || s.getRangeAt(0).startContainer !== sl.node) return null;\n const rect = rangeRect(s.getRangeAt(0), sl.node.parentElement ?? ref.current);\n return rect.top === sl.rect.top && rect.left === sl.rect.left ? sl : { ...sl, rect };\n }),\n );\n };\n window.addEventListener(\"scroll\", on, true);\n return () => {\n cancelAnimationFrame(raf);\n window.removeEventListener(\"scroll\", on, true);\n };\n }, [hasSlash]);\n\n // keep the bubble on the selection while anything scrolls (incl. the toolbar sliding open)\n const hasBubble = !!bubble;\n React.useEffect(() => {\n if (!hasBubble) return;\n let raf = 0;\n const on = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const s = window.getSelection();\n const ok = s && s.rangeCount && !s.isCollapsed && ref.current?.contains(s.anchorNode) && !typingElsewhere(ref.current);\n setBubble(ok ? rangeRect(s!.getRangeAt(0), ref.current) : null);\n });\n };\n window.addEventListener(\"scroll\", on, true);\n window.addEventListener(\"resize\", on);\n // The toolbar sliding open moves the words without a scroll: the bubble sat on the selected word.\n const box = new ResizeObserver(on);\n if (wrap.current) box.observe(wrap.current);\n return () => {\n cancelAnimationFrame(raf);\n box.disconnect();\n window.removeEventListener(\"scroll\", on, true);\n window.removeEventListener(\"resize\", on);\n };\n }, [hasBubble]);\n\n /* ── selection ───────────────────────────────────────────────────── */\n const saveSel = () => {\n const s = window.getSelection();\n if (s && s.rangeCount && ref.current?.contains(s.anchorNode)) saved.current = s.getRangeAt(0).cloneRange();\n };\n const restoreSel = () => {\n const el = ref.current;\n if (!el) return;\n const r = saved.current;\n const s = window.getSelection();\n if (r && el.contains(r.startContainer) && s) {\n (editingHost(r.startContainer) ?? el).focus({ preventScroll: true });\n s.removeAllRanges();\n s.addRange(r);\n } else {\n el.focus({ preventScroll: true });\n placeCaret(el.lastElementChild ?? el);\n }\n };\n\n const refresh = React.useCallback(() => {\n const el = ref.current;\n const s = window.getSelection();\n if (!el || !s || !s.rangeCount || !el.contains(s.anchorNode)) return;\n // typing somewhere else (the comment composer, a link field) keeps the page's selection here: no toolbar over it\n if (typingElsewhere(el)) {\n setBubble(null);\n return;\n }\n saved.current = s.getRangeAt(0).cloneRange();\n const anchorEl = s.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode?.parentElement;\n const inIsland = !!anchorEl?.closest(\"[data-rt-island]\");\n const tb = topBlock(el, s.anchorNode);\n const r = s.getRangeAt(0);\n const hasSel = !s.isCollapsed && !!r.toString().trim();\n const next: Fmt = {\n bold: queryState(\"bold\") && !/^H[1-6]$/.test(tb?.tagName ?? \"\"),\n italic: queryState(\"italic\"),\n underline: queryState(\"underline\"),\n strike: queryState(\"strikeThrough\"),\n // our own check: the base CSS resets sup/sub alignment, so the browser's own state for them always reads false\n sup: !!anchorEl?.closest(`sup:not(${FOOTNOTE_SUP})`),\n sub: !!anchorEl?.closest(\"sub\"),\n ul: !inIsland && tb?.tagName === \"UL\",\n ol: !inIsland && tb?.tagName === \"OL\",\n block: inIsland ? \"island\" : (tb?.tagName.toLowerCase() ?? \"p\"),\n hasSel,\n onLink: !!anchorEl?.closest(\"a\"),\n };\n setFmt((p) => (JSON.stringify(p) === JSON.stringify(next) ? p : next));\n setBubble(hasSel ? rangeRect(r, el) : null);\n el.querySelectorAll(\":scope > [data-hint]\").forEach((n) => (n !== tb || n.textContent) && n.removeAttribute(\"data-hint\"));\n if (tb && tb.tagName === \"P\" && s.isCollapsed && !tb.textContent && !tb.querySelector(\"img\") && document.activeElement === el && shortcutHintsOn()) tb.setAttribute(\"data-hint\", \"Type '/' for commands\");\n }, []);\n\n React.useEffect(() => {\n const on = () => refresh();\n // focus moving into another text field (the comment composer opening) fires no selectionchange: hide on focusin too\n const away = () => typingElsewhere(ref.current) && setBubble(null);\n document.addEventListener(\"selectionchange\", on);\n document.addEventListener(\"focusin\", away);\n return () => {\n document.removeEventListener(\"selectionchange\", on);\n document.removeEventListener(\"focusin\", away);\n };\n }, [refresh]);\n\n const run = (fn: () => void) => {\n restoreSel();\n fn();\n emit();\n refresh();\n };\n\n /* ── gutter ──────────────────────────────────────────────────────── */\n const placeGutter = (b: HTMLElement | null) => {\n const sc = scroller.current;\n if (!b || !sc) return setGutter(null);\n const sr = sc.getBoundingClientRect();\n const br = b.getBoundingClientRect();\n setGutter((g) => {\n const top = br.top - sr.top + sc.scrollTop;\n return g && g.el === b && g.top === top ? g : { el: b, top, height: br.height };\n });\n };\n const currentBlock = (): HTMLElement | null => {\n const el = ref.current;\n if (!el) return null;\n const s = window.getSelection();\n return topBlock(el, s && s.rangeCount && el.contains(s.anchorNode) ? s.anchorNode : document.activeElement);\n };\n\n /* ── block operations (DOM work lives in ./ops) ─────────── */\n const deleteBlock = (b: HTMLElement) => {\n const el = ref.current;\n if (!el || !el.contains(b)) return;\n const next = b.nextSibling;\n b.remove();\n let filler: HTMLElement | null = null;\n if (!el.firstElementChild) {\n filler = document.createElement(\"p\");\n filler.innerHTML = \"<br>\";\n el.append(filler);\n }\n setGutter(null);\n setBlockMenu(false);\n emit();\n notify(\"Block deleted\", {\n action: {\n label: \"Undo\",\n onClick: () => {\n const root = ref.current;\n if (!root) return;\n if (filler?.isConnected && !filler.textContent) filler.remove();\n if (next && next.parentNode === root) root.insertBefore(b, next);\n else root.append(b);\n emit();\n },\n },\n });\n };\n\n const duplicateBlock = (b: HTMLElement) => {\n const c = ops.duplicateBlock(b);\n emit();\n if (gutter) placeGutter(c);\n };\n\n const moveBlock = (b: HTMLElement, dir: -1 | 1) => {\n if (!ops.moveBlock(b, dir)) return;\n emit();\n if (gutter) requestAnimationFrame(() => placeGutter(b));\n };\n\n const turnInto = (b: HTMLElement | null, tag: string) => {\n const el = ref.current;\n if (el && ops.turnInto(el, b, tag)) emit();\n };\n\n const exitIsland = (x: HTMLElement) => {\n const el = ref.current;\n if (!el || !el.contains(x)) return;\n const next = ops.ensureLineAfter(x);\n el.focus({ preventScroll: true });\n placeCaret(next, false);\n emit();\n };\n\n const insertBlock = (it: CatalogItem) => {\n const el = ref.current;\n if (!el || readOnly) return;\n if (it.kind === \"component\" && it.component) {\n // V2 insert: a fresh linked instance, ONE undo step\n const c = it.component;\n noteRecent(it);\n const made: { el: IslandEl | null } = { el: null };\n oneStep(`Insert ${c.name}`, () => {\n const isl = (made.el = ops.insertIsland(el, \"component\", { ...defaultModel(\"component\"), ref: c.id, name: c.name }));\n emit();\n return isl;\n });\n refresh();\n // V2 insert: its properties open beside it, and the toast says what a shared component is\n if (made.el && services.useComponentInfo) openComponentPanel(made.el);\n services.toast?.(`${c.name} added`, { description: COMPONENT_INSERT_TOAST });\n return;\n }\n if (!it.id || !blockAllowed(it.id, allows)) return;\n noteRecent(it);\n ops.insertBasic(el, it.id);\n emit();\n refresh();\n };\n\n /* ── slash menu ──────────────────────────────────────────────────── */\n const slashCat = useCatalog(slash?.query ?? \"\", allows, slash?.folder ?? false, components ?? null);\n const caretRect = () => {\n const s = window.getSelection();\n if (!s || !s.rangeCount) return null;\n return rangeRect(s.getRangeAt(0), topBlock(ref.current, s.anchorNode) ?? ref.current);\n };\n const pickSlash = (it: CatalogItem) => {\n if (it.kind === \"folder\") return setSlash((s) => s && { ...s, folder: true, active: 1 });\n if (it.kind === \"back\") return setSlash((s) => s && { ...s, folder: false, active: 0 });\n const sl = slash;\n setSlash(null);\n if (sl) {\n try {\n const r = document.createRange();\n r.setStart(sl.node, sl.offset);\n r.setEnd(sl.node, Math.min(sl.node.length, sl.offset + 1 + sl.query.length));\n r.deleteContents();\n const c = document.createRange();\n c.setStart(sl.node, Math.min(sl.offset, sl.node.length));\n c.collapse(true);\n const s = window.getSelection();\n s?.removeAllRanges();\n s?.addRange(c);\n } catch {\n /* the text moved */\n }\n // A component is ONE step of the host's history, recorded from the body as it stands when the step starts: the\n // typed \"/query\" goes first, flushed, so an undo of the insert never brings it back as a paragraph.\n if (it.kind === \"component\") flushSync(() => emit());\n }\n insertBlock(it);\n };\n\n const toggleInlineCode = () => {\n const el = ref.current;\n const s = window.getSelection();\n if (!el || !s || !s.rangeCount || !allows(\"code\")) return;\n const anchorEl = s.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode?.parentElement;\n const code = anchorEl?.closest(\"code\");\n if (code && el.contains(code) && !code.closest(\"pre\")) {\n code.replaceWith(...Array.from(code.childNodes));\n emit();\n return;\n }\n const text = s.toString();\n if (!text) return void notify(\"Select some text first\", { description: \"Or wrap words in backticks to format them as code.\" });\n insertHtmlAtCaret(`<code>${esc(text)}</code>`);\n emit();\n };\n\n /* ── keyboard ────────────────────────────────────────────────────── */\n const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (slash) {\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setSlash(slash.folder ? { ...slash, folder: false, active: 0 } : null);\n return;\n }\n if (catalogKey(e, slashCat.flat, slash.active, (a) => setSlash((s) => s && { ...s, active: a }), pickSlash, false)) {\n e.preventDefault();\n return;\n }\n }\n const mod = e.metaKey || e.ctrlKey;\n const k = eventKey(e);\n if (mod && !e.altKey && k === \"k\") {\n e.preventDefault();\n saveSel();\n openLink();\n return;\n }\n if (mod && !e.altKey && !e.shiftKey && k === \"e\") {\n e.preventDefault();\n toggleInlineCode();\n return;\n }\n // the browser's own mark shortcuts, only for the marks the field keeps\n if (mod && !e.altKey && !e.shiftKey && ((k === \"b\" && !allows(\"bold\")) || (k === \"i\" && !allows(\"italic\")) || (k === \"u\" && !allows(\"underline\")))) {\n e.preventDefault();\n return;\n }\n if (mod && e.altKey && /^Digit[0-6]$/.test(e.code)) {\n e.preventDefault();\n const n = Number(e.code.slice(5));\n const tag = n === 0 ? \"p\" : `h${n}`;\n if (tag === \"p\" || allows(tag as RichTextFeature)) turnInto(currentBlock(), tag);\n return;\n }\n if (e.key === \"Enter\" && !mod && !e.shiftKey) {\n // a one-paragraph field has no second block to start\n if (single) {\n e.preventDefault();\n return;\n }\n // Enter on an empty quote or heading line leaves it for a paragraph\n const cb = currentBlock();\n if (cb && /^(BLOCKQUOTE|H[1-6])$/.test(cb.tagName) && !cb.textContent?.replace(/​/g, \"\").trim()) {\n e.preventDefault();\n turnInto(cb, \"p\");\n return;\n }\n // Enter at the end of a quote starts a paragraph (not another quote)\n const sel = window.getSelection();\n if (cb?.tagName === \"BLOCKQUOTE\" && sel?.isCollapsed && sel.rangeCount && !cb.querySelector(\"p\")) {\n const rest = document.createRange();\n rest.selectNodeContents(cb);\n rest.setStart(sel.anchorNode!, sel.anchorOffset);\n if (!rest.toString().trim()) {\n e.preventDefault();\n const p = document.createElement(\"p\");\n p.innerHTML = \"<br>\";\n cb.after(p);\n placeCaret(p);\n emit();\n return;\n }\n }\n const s = window.getSelection();\n const pre = s?.anchorNode && (s.anchorNode.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode.parentElement)?.closest(\"pre\");\n if (pre && ref.current?.contains(pre)) {\n e.preventDefault();\n exec(\"insertLineBreak\");\n return;\n }\n }\n if (e.key === \"ArrowDown\" && !mod && !e.shiftKey && !single) {\n // leave a trailing heading / quote / code block / list\n const b = currentBlock();\n const s = window.getSelection();\n if (b && !b.nextElementSibling && b.tagName !== \"P\" && !b.hasAttribute(\"data-rt-island\") && s?.isCollapsed && s.rangeCount) {\n const rest = document.createRange();\n rest.selectNodeContents(b);\n rest.setStart(s.anchorNode!, s.anchorOffset);\n if (!rest.toString().trim()) {\n e.preventDefault();\n const p = ops.ensureLineAfter(b);\n placeCaret(p, false);\n emit();\n }\n }\n }\n };\n\n /** Block-level shortcuts; runs for the surface and for text inside rich blocks. */\n const onWrapKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.defaultPrevented) return;\n const mod = e.metaKey || e.ctrlKey;\n if (mod && e.key === \"Enter\" && !hideFullscreen) {\n e.preventDefault();\n setModalOpen(true);\n return;\n }\n if (md || readOnly) return;\n const t = e.target as HTMLElement;\n if (!ref.current?.contains(t) || t.tagName === \"INPUT\" || t.tagName === \"TEXTAREA\") return;\n if (undoKey(e)) return;\n if (single) return;\n if (mod && !e.shiftKey && !e.altKey && eventKey(e) === \"d\") {\n e.preventDefault();\n const b = currentBlock();\n if (b) duplicateBlock(b);\n return;\n }\n if (mod && e.shiftKey && (e.key === \"ArrowUp\" || e.key === \"ArrowDown\")) {\n e.preventDefault();\n const b = currentBlock();\n if (b) moveBlock(b, e.key === \"ArrowUp\" ? -1 : 1);\n }\n };\n\n const onInput = (e: React.FormEvent<HTMLDivElement>) => {\n if (e.target !== ref.current) return;\n const ne = e.nativeEvent as InputEvent;\n if (ne.inputType !== \"historyUndo\" && ne.inputType !== \"historyRedo\") {\n hist.current.textAt = Date.now();\n hist.current.future = [];\n }\n if (!single && ne.inputType === \"insertText\" && (ne.data === \" \" || ne.data === \"-\") && ops.liveMarkdown(ref.current!, ne.data, allows)) {\n setSlash(null);\n emit();\n return;\n }\n if (ne.inputType === \"insertText\" && ne.data === \"`\" && allows(\"code\")) ops.liveInlineCode();\n emit();\n const s = window.getSelection();\n if (!s || !s.rangeCount) return setSlash(null);\n const r = s.getRangeAt(0);\n if (!slash) {\n // \"/\" opens the menu only at the very start of a block, and only in a field that takes more than one block\n if (single || ne.inputType !== \"insertText\" || ne.data !== \"/\" || r.startContainer.nodeType !== 3) return;\n const blk = closestBlock(ref.current!, r.startContainer);\n if (!blk || textBeforeCaret(blk) !== \"/\") return;\n const rect = caretRect();\n if (rect) setSlash({ rect, node: r.startContainer as Text, offset: r.startOffset - 1, query: \"\", folder: false, active: 0 });\n return;\n }\n if (r.startContainer !== slash.node || r.startOffset <= slash.offset || slash.node.data[slash.offset] !== \"/\") return setSlash(null);\n const q = slash.node.data.slice(slash.offset + 1, r.startOffset);\n if (/\\s/.test(q) || q.length > 24) return setSlash(null);\n setSlash({ ...slash, query: q, active: slash.folder ? 1 : 0 });\n };\n\n /* ── links ───────────────────────────────────────────────────────── */\n const openLink = () => {\n if (!allows(\"link\")) return;\n restoreSel();\n const s = window.getSelection();\n const anchorEl = s?.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s?.anchorNode?.parentElement;\n const anchor = (anchorEl?.closest(\"a\") as HTMLAnchorElement | null) ?? null;\n if (!anchor && (!s || s.isCollapsed || !s.toString().trim())) {\n notify(\"Select some text first\", { description: hints ? \"Then press ⌘K to link it.\" : \"Then link it.\" });\n return;\n }\n const rect = s && s.rangeCount ? rangeRect(s.getRangeAt(0), ref.current) : ref.current!.getBoundingClientRect();\n setBubble(null);\n setLink({ rect, existing: anchor, initial: anchor ? { href: anchor.getAttribute(\"href\") ?? \"\", newTab: anchor.getAttribute(\"target\") === \"_blank\" } : { href: \"\" } });\n };\n const saveLink = (v: TextLink) => {\n const l = link;\n setLink(null);\n if (!l) return;\n if (l.existing) {\n l.existing.setAttribute(\"href\", v.href);\n if (v.newTab) l.existing.setAttribute(\"target\", \"_blank\");\n else l.existing.removeAttribute(\"target\");\n emit();\n return;\n }\n run(() => {\n const text = window.getSelection()?.toString() || v.href;\n insertHtmlAtCaret(`<a href=\"${esc(v.href).replace(/\"/g, \"&quot;\")}\"${v.newTab ? ` target=\"_blank\"` : \"\"}>${esc(text)}</a>`);\n });\n };\n\n /* ── AI rewrite of the selection (the host's service) ────────────── */\n const aiRewrite = (preset: AiPreset) => {\n const rewrite = services.aiRewrite;\n restoreSel();\n const range = saved.current?.cloneRange();\n const text = range?.toString() ?? \"\";\n if (!rewrite || !range || !text.trim()) return;\n setBubble(null);\n Promise.resolve()\n .then(() => rewrite(text, preset, aiAttempt.current++))\n .then(\n (out) => {\n const el = ref.current;\n if (!el || !el.contains(range.startContainer) || range.toString() !== text) {\n notify(\"The text changed before the rewrite came back\", { description: \"Nothing was replaced. Select it again to retry.\" });\n return;\n }\n el.focus({ preventScroll: true });\n const s = window.getSelection();\n s?.removeAllRanges();\n s?.addRange(range);\n insertTextAtCaret(out);\n emit();\n notify(\"Rewritten with AI\", { description: hints ? \"Press ⌘Z to undo\" : undefined });\n },\n (err: unknown) => notify(\"Could not rewrite the selection\", { description: err instanceof Error ? err.message : String(err) }),\n );\n };\n\n /* ── drag to reorder via the grip ────────────────────────────────── */\n const onGripDown = (e: React.PointerEvent) => {\n if (!gutter) return;\n startDrag(gutter.el, e, () => setBlockMenu(true));\n };\n /** Drag a top-level block (the gutter grip) to a new position; a tap calls `onTap`. */\n const startDrag = (from: HTMLElement, e: React.PointerEvent, onTap?: () => void) => {\n if (readOnly || e.button !== 0) return;\n e.preventDefault();\n const start = e.clientY;\n let moved = false;\n const kids = () => Array.from(ref.current?.children ?? []);\n const move = (ev: PointerEvent) => {\n if (!moved && Math.abs(ev.clientY - start) < 4) return;\n moved = true;\n const sc = scroller.current!;\n const sr = sc.getBoundingClientRect();\n let target: Element | null = null;\n let line = 0;\n for (const k of kids()) {\n const r = k.getBoundingClientRect();\n if (ev.clientY < r.top + r.height / 2) {\n target = k;\n line = r.top - sr.top + sc.scrollTop - 4;\n break;\n }\n line = r.bottom - sr.top + sc.scrollTop + 4;\n }\n setDrag({ from, line, target });\n };\n const up = () => {\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", up);\n if (!moved) {\n onTap?.();\n return;\n }\n setDrag((d) => {\n if (d && d.target !== d.from) {\n if (d.target) d.target.before(d.from);\n else ref.current?.append(d.from);\n setTimeout(emit, 0);\n }\n return null;\n });\n };\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", up);\n };\n\n /* ── pasted and converted markup keeps to the field's rules ──────── */\n const conform = (html: string): string => {\n const r = ops.restrictHtml(html, allows);\n if (r.dropped.length) notify(`This field keeps no ${r.dropped.join(\" or \")}`, { description: \"They were left out; the text around them was kept.\" });\n return r.html;\n };\n\n /* ── Markdown mode ───────────────────────────────────────────────── */\n const toggleMarkdown = () => {\n if (!md) {\n const html = ref.current ? serialize(ref.current) : value;\n const text = htmlToMarkdown(html);\n setMd({ text, original: text });\n setSlash(null);\n setGutter(null);\n setBubble(null);\n setLink(null);\n return;\n }\n if (md.text === md.original) {\n setMd(null);\n setMdConfirm(false);\n return;\n }\n setMdConfirm(true);\n };\n const convertMarkdown = () => {\n if (!md) return;\n let html: string;\n try {\n html = conform(markdownToHtml(md.text));\n } catch (err) {\n notify(\"Could not convert this Markdown\", { description: `${err instanceof Error ? err.message : String(err)}. Your rich text is unchanged.` });\n return;\n }\n pending.current = html;\n known.current = html;\n onChangeRef.current(html);\n setMd(null);\n setMdConfirm(false);\n };\n\n /* ── One undo history (CPO D54): typing is the browser's own undo; an island write (an image's address or alt text)\n is a step on this stack. ⌘Z takes whichever happened last. ── */\n /** A host step's undo or redo; its value then loads even here, with the caret in the editor. */\n const runHost = (run: () => true | string): true | string => {\n forceLoad.current = true;\n const r = run();\n if (r !== true) forceLoad.current = false;\n return r;\n };\n /**\n * This body's host step that is the host's next undo (or redo) NOW. The host's toolbar moves these steps too: after\n * its Undo then Redo, the step is the latest change again, so ⌘Z here undoes it. Any later change in this body is a\n * host step of its own (the body's value is the host's), so a host step that is next is the latest change here.\n */\n const hostNext = (way: \"undo\" | \"redo\"): HostStep | null => {\n const hs = hist.current.hosts;\n for (let i = hs.length - 1; i >= 0; i--) if (hs[i].step.next() === way) return hs[i];\n return null;\n };\n const islandUndo = (): boolean => {\n const host = hostNext(\"undo\");\n if (host) {\n const r = runHost(host.step.undo);\n if (r !== true) notify(\"Nothing was undone\", { description: r });\n return true;\n }\n const h = hist.current;\n // a step whose island is gone has nothing to undo\n while (h.past.length && !h.past[h.past.length - 1].el.isConnected) h.past.pop();\n const step = h.past[h.past.length - 1];\n if (!step || step.at < h.textAt) return false;\n if (!step.el.__rtSet) return false;\n h.past.pop();\n h.future.push({ ...step, before: step.el.__rt!, at: Date.now() });\n step.el.__rtSet(step.before);\n return true;\n };\n const islandRedo = (): boolean => {\n const host = hostNext(\"redo\");\n if (host) {\n const r = runHost(host.step.redo);\n if (r !== true) notify(\"Nothing was redone\", { description: r });\n return true;\n }\n const h = hist.current;\n const step = h.future.pop();\n if (!step || !step.el.isConnected || !step.el.__rtSet) return false;\n h.past.push({ ...step, before: step.el.__rt!, at: Date.now() });\n step.el.__rtSet(step.before);\n return true;\n };\n /**\n * One action as ONE undo step (a separate copy, \"use shared version again\", a component inserted): in the host's\n * history when it keeps one (KitServices.historyStep: its toolbar Undo, an Undo toast and ⌘Z here are the same\n * undo), else in this editor's own (`before`: the model the island had; an insert has none, and stays as undoable\n * as any block inserted here). `write` makes the change and answers the island it changed. Answers its undo.\n */\n const oneStep = (label: string, write: () => IslandEl | null, before?: IslandModels[IslandKind]): (() => true | string) => {\n const h = hist.current;\n const made: { el: IslandEl | null } = { el: null };\n const historyStep = services.historyStep;\n const step = historyStep\n ? historyStep(() => {\n made.el = write();\n })\n : ((made.el = write()), null);\n const el = made.el;\n if (step) {\n h.hosts = [...h.hosts, { label, step }].slice(-100);\n return () => runHost(step.undo);\n }\n if (!el || !before) return () => \"This change has no undo step here.\";\n const s: IslandStep = { el, before, label, at: Date.now() };\n h.past = [...h.past, s].slice(-100);\n h.future = [];\n return () => {\n if (!h.past.includes(s)) return \"It was undone already.\";\n if (h.past[h.past.length - 1] !== s || s.at < h.textAt) return \"Changes made after it come first. Press ⌘Z to undo them.\";\n return islandUndo() ? true : \"The block was removed, so there is nothing to undo.\";\n };\n };\n const record = (el: IslandEl, before: IslandModels[IslandKind], label: string, coalesce?: boolean) => {\n const h = hist.current;\n const now = Date.now();\n const top = h.past[h.past.length - 1];\n // typing in one field coalesces (~500ms), unless the text was edited in between\n if (coalesce && top && top.el === el && top.label === label && now - top.at < 500 && top.at > h.textAt) top.at = now;\n else h.past = [...h.past, { el, before, label, at: now }].slice(-100);\n h.future = [];\n };\n const undoKey = (e: React.KeyboardEvent): boolean => {\n const mod = e.metaKey || e.ctrlKey;\n if (!mod || e.altKey || eventKey(e) !== \"z\") return false;\n if (e.shiftKey) {\n if (!islandRedo()) return false;\n e.preventDefault();\n return true;\n }\n if (islandUndo()) {\n e.preventDefault();\n return true;\n }\n if (!hist.current.past.length || !ref.current) return false;\n e.preventDefault();\n const before = ref.current.innerHTML;\n exec(\"undo\");\n if (ref.current.innerHTML === before) {\n hist.current.textAt = 0;\n islandUndo();\n }\n return true;\n };\n\n /* ── API for islands (stable) ────────────────────────────────────── */\n const api = React.useRef({ emit, deleteBlock, exitIsland, record, oneStep, notify, duplicateBlock, moveBlock, islandUndo, islandRedo, startDrag });\n api.current = { emit, deleteBlock, exitIsland, record, oneStep, notify, duplicateBlock, moveBlock, islandUndo, islandRedo, startDrag };\n const islandCtx = React.useMemo<IslandCtx>(\n () => ({\n readOnly,\n dense,\n emit: () => api.current.emit(),\n remove: (x) => api.current.deleteBlock(x),\n exit: (x) => api.current.exitIsland(x),\n record: (x, before, label, coalesce) => api.current.record(x, before, label, coalesce),\n step: (label, write, before) => api.current.oneStep(label, write, before),\n notify: (message, description) => api.current.notify(message, { description }),\n duplicate: (x) => api.current.duplicateBlock(x),\n move: (x, dir) => api.current.moveBlock(x, dir),\n undo: () => api.current.islandUndo(),\n redo: () => api.current.islandRedo(),\n drag: (x, e) => api.current.startDrag(x, e),\n }),\n [readOnly, dense],\n );\n\n const commentSel = onComment\n ? () => {\n restoreSel();\n const q = window.getSelection()?.toString().trim();\n // the comment popover takes over: the selection toolbar steps away so it never sits on the composer\n setBubble(null);\n setQuiet(true);\n if (q) onComment(q);\n }\n : undefined;\n const onMark = (cmd: MarkCmd) =>\n allows(MARK_FEATURE[cmd]) &&\n run(() =>\n cmd === \"superscript\" || cmd === \"subscript\" ? ref.current && toggleScript(ref.current, cmd === \"superscript\" ? \"sup\" : \"sub\") : exec(cmd),\n );\n const onStyle = (tag: string) => {\n restoreSel();\n turnInto(currentBlock(), tag);\n refresh();\n };\n\n /* ── render ──────────────────────────────────────────────────────── */\n const { flipUp, maxHeight: slashMaxH } = slash ? slashPlacement(slash.rect, window.innerHeight) : { flipUp: false, maxHeight: SLASH_MENU_H };\n const gBlock = gutter?.el;\n const gIsText = !!gBlock && !gBlock.hasAttribute(\"data-rt-island\") && gBlock.tagName !== \"HR\";\n const btn = dense ? \"size-5 [&_svg:not([data-rt-isolate]_*)]:size-3.5\" : \"size-[22px] [&_svg:not([data-rt-isolate]_*)]:size-3.5\";\n /* outside: + and grip float left of the box · inset: a slim grip sits in the 16px padding (insert via / or the\n toolbar) · none: compact inspector fields and one-paragraph fields */\n const gutterMode: \"outside\" | \"inset\" | \"none\" = readOnly || dense || single ? \"none\" : gutterRoom ? \"outside\" : \"inset\";\n const showGutter = gutterMode !== \"none\";\n const minH = expanded ? \"min-h-[60vh]\" : single ? \"min-h-9\" : dense ? \"min-h-[120px]\" : \"min-h-[190px]\";\n const turnStyles = stylesFor(allows).filter((s) => [\"p\", \"h1\", \"h2\", \"h3\", \"blockquote\"].includes(s.tag));\n\n return (\n <CatalogComponentsProvider value={components ?? null}>\n <div\n ref={wrap}\n data-rt-editor=\"\"\n className={cn(\n \"relative [--rt-toolbar-h:2rem] pointer-coarse:[--rt-toolbar-h:2.75rem]\",\n \"rounded-kit-lg border transition-colors duration-150\",\n /* the expanded modal is raised: the editor sits level with it, never below (D56) */\n expanded ? \"bg-[var(--kit-surface-raised)]\" : \"bg-kit-surface\",\n /* V2 rich-text-editor.tsx:1152: line at rest, line-strong while the toolbar is open; an invalid value (dash) keeps its edge */\n invalid ? \"border-[var(--kit-field-invalid)]\" : toolbarOpen ? \"border-kit-line-strong\" : \"border-kit-line\",\n )}\n /* what the sticky toolbar covers at the top of the scroll area */\n style={{ \"--rt-sticky-top\": toolbarOpen && !dense ? `calc(${stickyTop}px + var(--rt-toolbar-h))` : \"var(--kit-sticky-top, 0px)\" } as React.CSSProperties}\n onMouseLeave={() => !blockMenu && !gutterInsert && !drag && setGutter(null)}\n onKeyDown={onWrapKeyDown}\n onFocus={() => {\n window.clearTimeout(blurTimer.current);\n setFocused(true);\n }}\n onBlur={() => {\n window.clearTimeout(blurTimer.current);\n blurTimer.current = window.setTimeout(() => {\n const a = document.activeElement;\n if (wrap.current?.contains(a) || a?.closest(\"[role=menu],[role=dialog],[role=listbox],[data-floating-layer]\")) return;\n setFocused(false);\n setBubble(null);\n ref.current?.querySelectorAll(\"[data-hint]\").forEach((n) => n.removeAttribute(\"data-hint\"));\n if (valueRef.current !== known.current && !md) load(valueRef.current);\n }, 400);\n }}\n >\n {readOnly ? null : (\n <FormatToolbar\n open={toolbarOpen}\n sticky={!dense}\n stickyTop={stickyTop}\n width={width}\n dense={dense}\n fmt={fmt}\n md={!!md}\n allows={allows}\n hideFullscreen={hideFullscreen}\n insertOpen={insertOpen}\n setInsertOpen={(o) => {\n if (o) inserted.current = false;\n setInsertOpen(o);\n }}\n onMenuOpen={(name, o) => setMenus((m) => ({ ...m, [name]: o }))}\n onStyle={onStyle}\n onMark={onMark}\n onList={(kind) =>\n allows(kind) &&\n run(() => {\n // Chrome nests the list inside a heading/quote (<h2><ul>…) — turn the line into a paragraph first.\n const b = currentBlock();\n if (b && /^(H[1-6]|BLOCKQUOTE)$/.test(b.tagName)) turnInto(b, \"p\");\n exec(kind === \"ul\" ? \"insertUnorderedList\" : \"insertOrderedList\");\n // …and it can still leave <p><ul>…</ul></p>; lift the list out of any text block.\n ref.current?.querySelectorAll(\":is(p,h1,h2,h3,h4,h5,h6,blockquote) > :is(ul,ol)\").forEach((list) => {\n const host = list.parentElement!;\n host.replaceWith(...Array.from(host.childNodes).filter((n) => n.nodeType === 1 || n.textContent?.trim()));\n });\n })\n }\n onLink={openLink}\n onClear={() =>\n run(() => {\n exec(\"removeFormat\");\n exec(\"unlink\");\n })\n }\n onComment={commentSel}\n onInlineCode={() => {\n restoreSel();\n toggleInlineCode();\n }}\n onCodeBlock={() => {\n restoreSel();\n if (allows(\"pre\")) turnInto(currentBlock(), \"pre\");\n }}\n onInsert={(it) => {\n inserted.current = true;\n restoreSel();\n insertBlock(it);\n setInsertOpen(false);\n }}\n keepFocusOnInsertClose={() => inserted.current}\n onFullscreen={() => setModalOpen(true)}\n onMarkdown={toggleMarkdown}\n saveSel={saveSel}\n />\n )}\n\n {md ? (\n <div className=\"px-3 pb-2.5 pt-2.5\">\n <Textarea\n aria-label=\"Field content as Markdown\"\n spellCheck={false}\n value={md.text}\n readOnly={readOnly}\n onChange={(e) => {\n setMd({ ...md, text: e.target.value });\n setMdConfirm(false);\n }}\n className={cn(\"font-kit-mono text-kit-xs leading-5\", expanded ? \"min-h-[60vh]\" : dense ? \"min-h-[120px]\" : \"min-h-[190px]\")}\n style={scrollable ? { maxHeight } : undefined}\n />\n <p className=\"mt-1.5 text-kit-2xs text-kit-fg-3\">Markdown. Switching back converts it to blocks.</p>\n <AnimatePresence initial={false}>\n {mdConfirm ? (\n <motion.div\n key=\"confirm\"\n initial={{ opacity: 0, y: reduceMotion ? 0 : 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: reduceMotion ? 0 : 4 }}\n transition={{ duration: 0.15 }}\n role=\"alertdialog\"\n aria-label=\"Convert edited Markdown?\"\n className=\"mt-2 flex flex-wrap items-center gap-2 rounded-kit-lg border border-kit-line bg-kit-subtle px-3 py-2\"\n >\n <span className=\"flex-1 text-kit-sm font-medium text-kit-fg\">Convert edited Markdown?</span>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => setMdConfirm(false)}>\n Keep editing Markdown\n </Button>\n <Button size=\"xs\" variant=\"primary\" autoFocus onClick={convertMarkdown}>\n Convert to rich text\n </Button>\n </motion.div>\n ) : null}\n </AnimatePresence>\n </div>\n ) : (\n <div\n ref={scroller}\n className={cn(\"relative\", scrollable && \"overflow-y-auto\")}\n style={scrollable ? { maxHeight } : undefined}\n onMouseMove={(e) => {\n if (drag || blockMenu || gutterInsert || !showGutter) return;\n const t = e.target as HTMLElement;\n if (t.closest(\"[data-rt-gutter]\")) return;\n const b = topBlock(ref.current, t);\n // a component card carries its own handle and ⋯ menu (V2 rich-text-editor.tsx:1297-1298): no second grip beside it\n placeGutter(b?.getAttribute(\"data-rt-island\") === \"component\" ? null : b);\n }}\n >\n <div\n ref={ref}\n id={inModal ? undefined : id}\n role=\"textbox\"\n aria-multiline={!single}\n aria-labelledby={!inModal && id ? `${id}-label` : undefined}\n aria-label=\"Rich text\"\n aria-placeholder={ph}\n aria-readonly={readOnly || undefined}\n aria-invalid={invalid || undefined}\n contentEditable={!readOnly}\n suppressContentEditableWarning\n spellCheck\n tabIndex={readOnly ? 0 : undefined}\n onInput={onInput}\n onKeyDown={onKeyDown}\n onKeyUp={refresh}\n onMouseUp={refresh}\n onPaste={(e) => {\n if (readOnly) return;\n const files = Array.from(e.clipboardData.files).filter((f) => f.type.startsWith(\"image/\"));\n if (files.length) {\n e.preventDefault();\n notify(allows(\"image\") ? \"Add images from the media library\" : \"This field keeps no images\", {\n description: allows(\"image\") ? \"A pasted file has no address the page can show it from. Use Insert › Image.\" : undefined,\n });\n return;\n }\n const text = e.clipboardData.getData(\"text/plain\");\n e.preventDefault();\n if (!text) return;\n if (single || (!/\\n/.test(text.trim()) && !looksLikeMarkdown(text))) {\n insertTextAtCaret(single ? text.replace(/\\s*\\n\\s*/g, \" \") : text);\n emit();\n return;\n }\n let html: string;\n try {\n html = markdownToHtml(text);\n } catch {\n html = text.split(/\\n{2,}/).map((p) => `<p>${esc(p.trim()).replace(/\\n/g, \"<br>\")}</p>`).join(\"\");\n }\n insertHtmlAtCaret(conform(html));\n if (ref.current) hydrate(ref.current);\n emit();\n }}\n onDragOver={(e) => {\n if (e.dataTransfer.types.includes(\"application/x-bcms-asset\") && allows(\"image\")) e.preventDefault();\n }}\n onDrop={(e) => {\n const asset = e.dataTransfer.getData(\"application/x-bcms-asset\");\n if (!asset || readOnly || !allows(\"image\")) return;\n e.preventDefault();\n try {\n const a = JSON.parse(asset) as { url: string; alt?: string; name: string };\n const b = topBlock(ref.current, e.target as Node);\n const isl = createIsland(\"image\", defaultModel(\"image\", { src: a.url, alt: a.alt ?? \"\" }));\n if (b) b.after(isl);\n else ref.current?.append(isl);\n ops.ensureLineAfter(isl);\n emit();\n } catch {\n notify(\"That drop is not an image from the media library\");\n }\n }}\n className={cn(\n RT_PROSE,\n dense && RT_PANEL,\n \"peer relative outline-none focus-visible:shadow-none [&_*:not([data-rt-isolate]_*)]:outline-none\",\n \"[&>p[data-hint]]:before:pointer-events-none [&>p[data-hint]]:before:float-left [&>p[data-hint]]:before:h-0 [&>p[data-hint]]:before:text-kit-fg-4 [&>p[data-hint]]:before:content-[attr(data-hint)]\",\n \"[&_a[data-button]:not([data-rt-isolate]_*)]:cursor-pointer [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:cursor-pointer\",\n \"[&_sup[data-rt=fn]]:mx-px [&_sup[data-rt=fn]]:cursor-pointer [&_sup[data-rt=fn]]:rounded-kit-sm [&_sup[data-rt=fn]]:px-0.5 [&_sup[data-rt=fn]]:text-[0.72em] [&_sup[data-rt=fn]]:font-semibold [&_sup[data-rt=fn]]:text-kit-accent-fg [&_sup[data-rt=fn]:hover]:bg-kit-accent-soft\",\n dense ? \"px-2.5 py-2\" : \"px-4 py-3.5\",\n minH,\n )}\n />\n {empty ? (\n <div aria-hidden className={cn(\"pointer-events-none absolute text-kit-fg-4 peer-focus:hidden\", dense ? \"text-kit-sm\" : \"text-kit-base\", dense ? \"left-2.5 top-2\" : \"left-4 top-3.5\")}>\n {ph}\n </div>\n ) : null}\n\n {/* Block gutter (+ / grip) */}\n {gutter && showGutter ? (\n <div\n data-rt-gutter=\"\"\n /* z-3: under the sticky toolbar (z-4), so a tall block's grip never paints over it */\n className={cn(\"absolute z-[3] flex items-start\", gutterMode === \"outside\" ? \"-left-12 pr-1\" : \"left-0\")}\n style={{ top: gutter.top + Math.max(-2, Math.min(4, gutter.height / 2 - 12)) }}\n >\n {gutterMode === \"outside\" ? (\n <Popover\n open={gutterInsert}\n onOpenChange={(o) => {\n if (o) {\n gutterTarget.current = gutter.el;\n inserted.current = false;\n }\n setGutterInsert(o);\n }}\n >\n <Tooltip content=\"Add a block below\" disabled={gutterInsert}>\n <PopoverTrigger\n aria-label=\"Add a block below\"\n className={cn(\"flex items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg data-[popup-open]:bg-kit-hover data-[popup-open]:text-kit-fg\", btn)}\n >\n <IconPlus stroke={1.5} aria-hidden />\n </PopoverTrigger>\n </Tooltip>\n {gutterInsert ? (\n <InsertMenuContent\n side=\"bottom\"\n align=\"start\"\n allows={allows}\n keepFocusOnClose={() => inserted.current}\n onInsert={(it) => {\n const b = gutterTarget.current;\n const el = ref.current;\n inserted.current = true;\n setGutterInsert(false);\n if (!b || !el || !el.contains(b)) return;\n const p = document.createElement(\"p\");\n p.innerHTML = \"<br>\";\n b.after(p);\n el.focus({ preventScroll: true });\n placeCaret(p);\n insertBlock(it);\n }}\n />\n ) : null}\n </Popover>\n ) : null}\n <Menu open={blockMenu} onOpenChange={setBlockMenu}>\n <Tooltip content=\"Drag to move, click for options\" disabled={blockMenu || !!drag}>\n <MenuTrigger\n aria-label=\"Block options\"\n onPointerDown={onGripDown}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setBlockMenu(true);\n }\n }}\n className={cn(\n \"flex cursor-grab items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg active:cursor-grabbing\",\n gutterMode === \"inset\" ? \"h-[22px] w-4 rounded-kit-sm [&_svg:not([data-rt-isolate]_*)]:size-3.5\" : btn,\n (blockMenu || drag) && \"bg-kit-hover text-kit-fg\",\n )}\n >\n <IconGripVertical stroke={1.5} aria-hidden />\n </MenuTrigger>\n </Tooltip>\n <MenuContent className=\"w-56\" align=\"start\" finalFocus={false}>\n {turnStyles.length > 1 ? (\n <MenuSub>\n <MenuSubTrigger icon={<IconTransform stroke={1.5} />} disabled={!gIsText}>\n Turn into\n </MenuSubTrigger>\n <MenuSubContent className=\"w-48\">\n {turnStyles.map((t) => (\n <MenuItem key={t.tag} icon={t.icon} onClick={() => turnInto(gBlock ?? null, t.tag)}>\n {t.label}\n </MenuItem>\n ))}\n </MenuSubContent>\n </MenuSub>\n ) : null}\n <MenuItem icon={<IconCopy stroke={1.5} />} shortcut=\"⌘D\" onClick={() => gBlock && duplicateBlock(gBlock)}>\n Duplicate\n </MenuItem>\n <MenuItem icon={<IconArrowBarToUp stroke={1.5} />} shortcut=\"⌘⇧↑\" disabled={!gBlock?.previousElementSibling} onClick={() => gBlock && moveBlock(gBlock, -1)}>\n Move up\n </MenuItem>\n <MenuItem icon={<IconArrowBarToDown stroke={1.5} />} shortcut=\"⌘⇧↓\" disabled={!gBlock?.nextElementSibling} onClick={() => gBlock && moveBlock(gBlock, 1)}>\n Move down\n </MenuItem>\n <MenuSeparator />\n <MenuItem danger icon={<IconTrash stroke={1.5} />} onClick={() => gBlock && deleteBlock(gBlock)}>\n Delete\n </MenuItem>\n </MenuContent>\n </Menu>\n </div>\n ) : null}\n {drag?.line != null ? <div className=\"pointer-events-none absolute inset-x-3 z-[6] h-0.5 rounded-full bg-kit-info\" style={{ top: drag.line }} /> : null}\n\n {/* Rich blocks render into their contenteditable=false hosts */}\n {islands.map(({ id: key, el }) => createPortal(<Island el={el} ctx={islandCtx} />, el, key))}\n </div>\n )}\n\n {/* Footer meta (V2 rich-text-editor.tsx:1563-1571), and any refusal said in place when the host has no toaster */}\n <div className=\"flex h-7 items-center justify-end gap-3 rounded-b-kit-lg border-t border-kit-line-subtle px-3 text-kit-2xs text-kit-fg-3\">\n {notice ? (\n <span role=\"status\" aria-live=\"polite\" className=\"mr-auto min-w-0 truncate text-kit-fg-2\">\n {notice.message}\n {notice.description ? ` ${notice.description}` : \"\"}\n {notice.action ? (\n <button\n type=\"button\"\n className=\"ml-1.5 font-medium text-kit-fg underline underline-offset-2\"\n onClick={() => {\n notice.action!.onClick();\n setNotice(null);\n }}\n >\n {notice.action.label}\n </button>\n ) : null}\n </span>\n ) : null}\n <span className=\"tabular-nums\">\n {words.toLocaleString(\"en-US\")} {words === 1 ? \"word\" : \"words\"}\n {comps ? ` · ${comps} ${comps === 1 ? \"block\" : \"blocks\"}` : \"\"} · {Math.max(1, Math.round(words / 220))} min read\n </span>\n </div>\n\n {/* Bubble toolbar on selection: a toolbar menu owns the moment, so the bubble steps aside while one is open */}\n {bubble && !quiet && !readOnly && !slash && !link && !md && !menus.style && !menus.more && !insertOpen ? (\n <SelectionBubble\n rect={bubble}\n avoid={toolbarOpen ? wrap.current?.querySelector<HTMLElement>('[role=\"toolbar\"][aria-label=\"Text formatting\"]')?.getBoundingClientRect() : null}\n fmt={fmt}\n allows={allows}\n saveSel={saveSel}\n onAi={canAI ? aiRewrite : undefined}\n onStyle={onStyle}\n onMark={onMark}\n onInlineCode={() => {\n restoreSel();\n toggleInlineCode();\n }}\n onLink={openLink}\n onComment={commentSel}\n />\n ) : null}\n\n {/* Slash menu (opens only at the start of a block; never takes focus) */}\n {slash && !md\n ? createPortal(\n <>\n <div data-floating-layer=\"\" className=\"pointer-events-auto fixed inset-0 z-[var(--kit-z-popover,84)]\" onMouseDown={() => setSlash(null)} />\n <motion.div\n initial={{ opacity: 0, y: flipUp ? -4 : 4 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.14 }}\n style={{\n left: Math.min(window.innerWidth - 330, Math.max(8, slash.rect.left)),\n ...(flipUp ? { bottom: window.innerHeight - slash.rect.top + 6 } : { top: slash.rect.bottom + 6 }),\n }}\n data-floating-layer=\"\"\n className=\"pointer-events-auto fixed z-[calc(var(--kit-z-popover,84)_+_1)]\"\n >\n <SlashMenuPanel query={slash.query} folder={slash.folder} active={slash.active} allows={allows} setActive={(a) => setSlash((s) => s && { ...s, active: a })} onPick={pickSlash} maxHeight={slashMaxH} />\n </motion.div>\n </>,\n document.body,\n )\n : null}\n\n {/* Link popover anchored to the selection */}\n <Popover open={!!link} onOpenChange={(o) => !o && setLink(null)}>\n <PopoverAnchor\n render={<span className=\"pointer-events-none fixed\" style={link ? { top: link.rect.bottom, left: link.rect.left, width: Math.max(1, link.rect.width), height: 1 } : { top: 0, left: 0 }} />}\n />\n <PopoverContent className=\"w-[340px] rounded-kit-lg p-3\" finalFocus={false}>\n {link ? (\n <div className=\"flex flex-col gap-2\">\n <LinkForm\n initial={link.initial}\n allowNewTab={allowNewTab}\n onSave={saveLink}\n onCancel={() => setLink(null)}\n onDetach={\n link.existing\n ? () => {\n const a = link.existing!;\n a.replaceWith(...Array.from(a.childNodes));\n setLink(null);\n emit();\n }\n : undefined\n }\n />\n </div>\n ) : null}\n </PopoverContent>\n </Popover>\n {!hideFullscreen ? (\n <ExpandedEditorModal open={modalOpen} onOpenChange={setModalOpen} crumbs={expandCrumbs?.length ? expandCrumbs : [\"Text\"]} returnFocus={() => ref.current} meta={bodyCountLabel(value)}>\n {modalOpen ? (\n <RichTextEditor\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n placeholder={placeholder}\n docKey={`${docKey}:expanded`}\n features={features}\n single={single}\n allowNewTab={allowNewTab}\n expandCrumbs={expandCrumbs}\n variant=\"document\"\n hideFullscreen\n inModal\n autoFocus\n onComment={onComment}\n components={components}\n />\n ) : null}\n </ExpandedEditorModal>\n ) : null}\n </div>\n </CatalogComponentsProvider>\n );\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"editor.js","names":[],"sources":["../../../src/controls/rich-text/editor.tsx"],"sourcesContent":["/**\n * RICH TEXT — the boxed rich-text editor (V2 HEAD controls/rich-text-editor.tsx, Figma 60995-5431, CPO D49 / D54 / D55).\n *\n * contentEditable + execCommand keeps it dependency-free; the value is clean HTML, which the field's control turns into\n * the stored value through the host's codec (./codec.ts). Rich blocks (an image) are React \"islands\" rendered into\n * contenteditable=false nodes and written back as static HTML, so a re-mount restores them (./dom.ts).\n *\n * ./toolbar.tsx the field toolbar (no room at rest, folds into the chevron by width)\n * ./catalog.tsx Insert menu, slash menu and the shared block catalogue\n * ./blocks.tsx the rich blocks (an image)\n * ./markdown.ts HTML ⇄ Markdown for the Markdown toggle and pasting\n * ./ops.ts pure DOM block operations (insert, turn into, move, duplicate, live Markdown, field rules)\n * ./floating.tsx the selection bubble\n * ./dom.ts hydrate / serialize / sanitize and selection helpers\n *\n * Everything the editor offers is limited to what the field accepts (`features`): a toolbar button, a slash command, a\n * Markdown shortcut or pasted markup the field cannot hold is not offered, or is turned into what it can hold and said so.\n */\nimport * as React from \"react\";\nimport { createPortal, flushSync } from \"react-dom\";\nimport { AnimatePresence, motion, useReducedMotion } from \"framer-motion\";\nimport { IconArrowBarToDown, IconArrowBarToUp, IconCopy, IconGripVertical, IconPlus, IconTransform, IconTrash } from \"@tabler/icons-react\";\nimport { cn } from \"../../lib/cn\";\nimport { eventKey } from \"../../lib/key-event\";\nimport { useKitEnv, useKitServices, type AiPreset } from \"../../context\";\nimport { Button } from \"../../ui/button\";\nimport { Textarea } from \"../../ui/input\";\nimport { ExpandedEditorModal } from \"../../ui/expanded-editor-modal\";\nimport { Menu, MenuContent, MenuItem, MenuSeparator, MenuSub, MenuSubContent, MenuSubTrigger, MenuTrigger, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Tooltip } from \"../../ui/overlay\";\nimport { shortcutHintsOn } from \"../../ui/shortcut-hint\";\nimport { ALL_FEATURES, type RichTextFeature, type RichTextRead } from \"./codec\";\nimport { COMPONENT_INSERT_TOAST, type KitHistoryStep } from \"../component-services\";\nimport { Island, type IslandCtx } from \"./blocks\";\nimport { openComponentPanel } from \"./component-panel\";\nimport { CatalogComponentsProvider, InsertMenuContent, SlashMenuPanel, blockAllowed, catalogKey, noteRecent, useCatalog, type CatalogComponents, type CatalogItem } from \"./catalog\";\nimport {\n closestBlock, createIsland, defaultModel, editingHost, esc, hydrate, isEmptyHtml, placeCaret, rangeRect, rid, sanitize,\n serialize, textBeforeCaret, topBlock, type IslandEl, type IslandModels, type IslandKind,\n} from \"./dom\";\nimport { htmlToMarkdown, looksLikeMarkdown, markdownToHtml } from \"./markdown\";\nimport * as ops from \"./ops\";\nimport { SelectionBubble } from \"./floating\";\nimport { LinkPopoverBody } from \"../link\";\nimport { applyTextLink, fromLinkValue, textLinkOf, toLinkValue, type TextLink } from \"./link-form\";\nimport { checklistShortcut, insertChecklist, syncTaskA11y, toggleTaskAtPointer, toggleTaskFromKey } from \"./checklist\";\nimport { createOutlineStore, outlineOf } from \"./toc\";\nimport { backToMarker, caretAfterMarker, FN_MARK, FOOTNOTE_POPOVER_CLASS, FOOTNOTE_REFUSED, FootnoteEditor, FootnotesList, insertFootnote, renumberFootnotes } from \"./footnote\";\nimport { applyButton, ButtonLinkPanel, buttonAt, buttonInitial, insertButton, removeButton } from \"./button\";\nimport { EMPTY_FMT, FormatToolbar, MARK_FEATURE, stylesFor, type Fmt, type MarkCmd } from \"./toolbar\";\n\n/* ── Prose styles for the editable surface (kit tokens only) ──\n * Every descendant rule skips `[data-rt-isolate]` subtrees, as V2's (rich-text-editor.tsx:46-58): a block's own UI inside\n * the writing surface (a table island's column headers, a component card's form) is app UI, not prose. */\nexport const RT_PROSE =\n \"text-kit-base leading-[1.6] text-kit-fg [&>*+*]:mt-3 \" +\n // BUG-7: a styled run keeps the SITE's class (the stored design), but the site's stylesheet is not here. Only the\n // utilities the dashboard happens to build apply: `text-transparent` without its `bg-clip-text` gradient drew the\n // words invisible. The run's text is drawn as text; the class itself is kept, so a save writes it back unchanged.\n \"[&_span[class]:not([data-rt-isolate]_*)]:!text-inherit [&_span[class]:not([data-rt-isolate]_*)]:![-webkit-text-fill-color:currentColor] [&_span[class]:not([data-rt-isolate]_*)]:!bg-none [&_span[class]:not([data-rt-isolate]_*)]:!opacity-100 [&_span[class]:not([data-rt-isolate]_*)]:!visible \" +\n \"[&_h1:not([data-rt-isolate]_*)]:text-[28px] [&_h1:not([data-rt-isolate]_*)]:font-semibold [&_h1:not([data-rt-isolate]_*)]:leading-9 [&_h1:not([data-rt-isolate]_*)]:tracking-[-0.01em] [&_h2:not([data-rt-isolate]_*)]:text-[22px] [&_h2:not([data-rt-isolate]_*)]:font-semibold [&_h2:not([data-rt-isolate]_*)]:leading-8 [&_h2:not([data-rt-isolate]_*)]:tracking-[-0.01em] \" +\n \"[&_h3:not([data-rt-isolate]_*)]:text-kit-lg [&_h3:not([data-rt-isolate]_*)]:font-semibold [&_h4:not([data-rt-isolate]_*)]:text-kit-md [&_h4:not([data-rt-isolate]_*)]:font-semibold [&_h5:not([data-rt-isolate]_*)]:text-kit-base [&_h5:not([data-rt-isolate]_*)]:font-semibold [&_h6:not([data-rt-isolate]_*)]:text-kit-sm [&_h6:not([data-rt-isolate]_*)]:font-semibold [&_h6:not([data-rt-isolate]_*)]:uppercase [&_h6:not([data-rt-isolate]_*)]:tracking-wide [&_h6:not([data-rt-isolate]_*)]:text-kit-fg-2 [&>h1]:mt-6 [&>h2]:mt-6 [&>h3]:mt-5 [&>*:first-child]:mt-0 \" +\n // a block's own list (key takeaways, V2 data-rt-isolate) is app UI, not body prose: V2 rich-text-editor.tsx skips it\n \"[&_ul:not([data-rt-isolate]_*)]:list-disc [&_ul:not([data-rt-isolate]_*)]:pl-5 [&_ol:not([data-rt-isolate]_*)]:list-decimal [&_ol:not([data-rt-isolate]_*)]:pl-5 [&_li:not([data-rt-isolate]_*)]:pl-1 [&_li+li:not([data-rt-isolate]_*)]:mt-1 [&_li:not([data-rt-isolate]_*)]:marker:text-kit-fg-3 \" +\n \"[&_ul[data-task]:not([data-rt-isolate]_*)]:list-none [&_ul[data-task]:not([data-rt-isolate]_*)]:pl-0 [&_ul[data-task]>li:not([data-rt-isolate]_*)]:relative [&_ul[data-task]>li:not([data-rt-isolate]_*)]:pl-7 [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:absolute [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:left-0 [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:top-[0.2em] [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:flex [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:size-4 [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:items-center [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:justify-center [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:rounded-kit-md [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:border [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:border-kit-line-strong [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:bg-kit-surface [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:text-[11px] [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:font-semibold [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:leading-none [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:content-[''] \" +\n \"[&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:text-kit-fg-3 [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:line-through [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:before:border-kit-inverse [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:before:bg-kit-inverse [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:before:text-kit-fg-inverse [&_ul[data-task]>li[data-checked=true]:not([data-rt-isolate]_*)]:before:content-['✓'] \" +\n \"[&_blockquote:not([data-rt-isolate]_*)]:border-l-2 [&_blockquote:not([data-rt-isolate]_*)]:border-kit-line-strong [&_blockquote:not([data-rt-isolate]_*)]:pl-4 [&_blockquote:not([data-rt-isolate]_*)]:text-kit-fg-2 [&_blockquote:not([data-rt-isolate]_*)]:italic \" +\n \"[&_a:not([data-rt-isolate]_*)]:text-kit-accent-fg [&_a:not([data-rt-isolate]_*)]:underline [&_a:not([data-rt-isolate]_*)]:decoration-kit-accent-line [&_a:not([data-rt-isolate]_*)]:underline-offset-2 \" +\n \"[&_a[data-button]:not([data-rt-isolate]_*)]:inline-flex [&_a[data-button]:not([data-rt-isolate]_*)]:h-9 [&_a[data-button]:not([data-rt-isolate]_*)]:items-center [&_a[data-button]:not([data-rt-isolate]_*)]:rounded-kit-md [&_a[data-button]:not([data-rt-isolate]_*)]:bg-kit-inverse [&_a[data-button]:not([data-rt-isolate]_*)]:px-3.5 [&_a[data-button]:not([data-rt-isolate]_*)]:text-kit-sm [&_a[data-button]:not([data-rt-isolate]_*)]:font-medium [&_a[data-button]:not([data-rt-isolate]_*)]:text-kit-fg-inverse [&_a[data-button]:not([data-rt-isolate]_*)]:no-underline \" +\n // a glossary term (`<abbr data-term title>`) reads as a dotted underline; a footnote marker as a small superscript\n \"[&_abbr:not([data-rt-isolate]_*)]:cursor-help [&_abbr:not([data-rt-isolate]_*)]:underline [&_abbr:not([data-rt-isolate]_*)]:decoration-dotted [&_abbr:not([data-rt-isolate]_*)]:underline-offset-2 [&_sup:not([data-rt-isolate]_*)]:text-[0.7em] [&_sup:not([data-rt-isolate]_*)]:leading-none \" +\n \"[&_code:not([data-rt-isolate]_*)]:rounded-kit-md [&_code:not([data-rt-isolate]_*)]:bg-kit-muted [&_code:not([data-rt-isolate]_*)]:px-1 [&_code:not([data-rt-isolate]_*)]:py-px [&_code:not([data-rt-isolate]_*)]:font-kit-mono [&_code:not([data-rt-isolate]_*)]:text-[0.9em] \" +\n \"[&_pre:not([data-rt-isolate]_*)]:overflow-x-auto [&_pre:not([data-rt-isolate]_*)]:whitespace-pre-wrap [&_pre:not([data-rt-isolate]_*)]:rounded-kit-lg [&_pre:not([data-rt-isolate]_*)]:bg-kit-code [&_pre:not([data-rt-isolate]_*)]:text-kit-code-fg [&_pre:not([data-rt-isolate]_*)]:p-3 [&_pre:not([data-rt-isolate]_*)]:font-kit-mono [&_pre:not([data-rt-isolate]_*)]:text-kit-sm [&_pre:not([data-rt-isolate]_*)]:border [&_pre:not([data-rt-isolate]_*)]:border-kit-line \" +\n \"[&_pre_code:not([data-rt-isolate]_*)]:rounded-none [&_pre_code:not([data-rt-isolate]_*)]:bg-transparent [&_pre_code:not([data-rt-isolate]_*)]:p-0 [&_pre_code:not([data-rt-isolate]_*)]:text-[1em] \" +\n \"[&_hr:not([data-rt-isolate]_*)]:my-6 [&_hr:not([data-rt-isolate]_*)]:border-kit-line \" +\n // V2 rich-text-editor.tsx 64-65: an image's figure sits 16px off its neighbours (my-4), the picture framed\n \"[&_figure:not([data-rt-isolate]_*)]:my-4 [&_img:not([data-rt-isolate]_*)]:rounded-kit-lg [&_img:not([data-rt-isolate]_*)]:border [&_img:not([data-rt-isolate]_*)]:border-kit-line [&_figcaption:not([data-rt-isolate]_*)]:mt-1.5 [&_figcaption:not([data-rt-isolate]_*)]:text-center [&_figcaption:not([data-rt-isolate]_*)]:text-kit-sm [&_figcaption:not([data-rt-isolate]_*)]:text-kit-fg-3 \" +\n \"[&_figure_img:not([data-rt-isolate]_*)]:block [&_figure[data-size=s]_img:not([data-rt-isolate]_*)]:w-1/3 [&_figure[data-size=m]_img:not([data-rt-isolate]_*)]:w-1/2 [&_figure[data-size=l]_img:not([data-rt-isolate]_*)]:w-3/4 [&_figure[data-align=center]_img:not([data-rt-isolate]_*)]:mx-auto [&_figure[data-align=right]_img:not([data-rt-isolate]_*)]:ml-auto [&_figure[data-align=full]_img:not([data-rt-isolate]_*)]:w-full \" +\n \"[&_div[data-callout]:not([data-rt-isolate]_*)]:rounded-kit-lg [&_div[data-callout]:not([data-rt-isolate]_*)]:border [&_div[data-callout]:not([data-rt-isolate]_*)]:border-kit-info-line [&_div[data-callout]:not([data-rt-isolate]_*)]:bg-kit-info-soft [&_div[data-callout]:not([data-rt-isolate]_*)]:px-4 [&_div[data-callout]:not([data-rt-isolate]_*)]:py-3 [&_div[data-callout]:not([data-rt-isolate]_*)]:text-kit-fg \" +\n \"[&_div[data-callout=tip]:not([data-rt-isolate]_*)]:border-kit-success-line [&_div[data-callout=tip]:not([data-rt-isolate]_*)]:bg-kit-success-soft [&_div[data-callout=warning]:not([data-rt-isolate]_*)]:border-kit-warning-line [&_div[data-callout=warning]:not([data-rt-isolate]_*)]:bg-kit-warning-soft [&_div[data-callout]>p[data-title]:not([data-rt-isolate]_*)]:font-medium \" +\n \"[&_details:not([data-rt-isolate]_*)]:rounded-kit-md [&_summary:not([data-rt-isolate]_*)]:cursor-pointer [&_summary:not([data-rt-isolate]_*)]:font-medium [&_details>div:not([data-rt-isolate]_*)]:mt-1 [&_details>div:not([data-rt-isolate]_*)]:border-l [&_details>div:not([data-rt-isolate]_*)]:border-kit-line [&_details>div:not([data-rt-isolate]_*)]:pl-4 [&_details>div:not([data-rt-isolate]_*)]:ml-1 \" +\n \"[&_div[data-rt=columns]:not([data-rt-isolate]_*)]:grid [&_div[data-rt=columns]:not([data-rt-isolate]_*)]:gap-4 [&_div[data-cols='2']:not([data-rt-isolate]_*)]:grid-cols-2 [&_div[data-cols='3']:not([data-rt-isolate]_*)]:grid-cols-3 [&_div[data-cols='4']:not([data-rt-isolate]_*)]:grid-cols-4 [&_div[data-gap=s]:not([data-rt-isolate]_*)]:gap-2 [&_div[data-gap=l]:not([data-rt-isolate]_*)]:gap-7 \" +\n \"[&_div[data-rt=file]:not([data-rt-isolate]_*)]:rounded-kit-lg [&_div[data-rt=file]:not([data-rt-isolate]_*)]:border [&_div[data-rt=file]:not([data-rt-isolate]_*)]:border-kit-line [&_div[data-rt=file]:not([data-rt-isolate]_*)]:px-3 [&_div[data-rt=file]:not([data-rt-isolate]_*)]:py-2.5 [&_div[data-rt=file]:not([data-rt-isolate]_*)]:text-kit-sm \" +\n \"[&_div[data-embed]:not([data-rt-isolate]_*)]:flex [&_div[data-embed]:not([data-rt-isolate]_*)]:aspect-video [&_div[data-embed]:not([data-rt-isolate]_*)]:items-center [&_div[data-embed]:not([data-rt-isolate]_*)]:justify-center [&_div[data-embed]:not([data-rt-isolate]_*)]:rounded-kit-lg [&_div[data-embed]:not([data-rt-isolate]_*)]:border [&_div[data-embed]:not([data-rt-isolate]_*)]:border-kit-line [&_div[data-embed]:not([data-rt-isolate]_*)]:bg-kit-subtle [&_div[data-embed]:not([data-rt-isolate]_*)]:text-kit-sm [&_div[data-embed]:not([data-rt-isolate]_*)]:text-kit-fg-3 \" +\n \"[&_div[data-block]:not([data-rt-isolate]_*)]:flex [&_div[data-block]:not([data-rt-isolate]_*)]:items-center [&_div[data-block]:not([data-rt-isolate]_*)]:gap-2 [&_div[data-block]:not([data-rt-isolate]_*)]:rounded-kit-lg [&_div[data-block]:not([data-rt-isolate]_*)]:border [&_div[data-block]:not([data-rt-isolate]_*)]:border-dashed [&_div[data-block]:not([data-rt-isolate]_*)]:border-kit-accent-line [&_div[data-block]:not([data-rt-isolate]_*)]:bg-kit-accent-softer [&_div[data-block]:not([data-rt-isolate]_*)]:px-3 [&_div[data-block]:not([data-rt-isolate]_*)]:py-3 [&_div[data-block]:not([data-rt-isolate]_*)]:text-kit-sm [&_div[data-block]:not([data-rt-isolate]_*)]:text-kit-accent-fg \" +\n \"[&_table:not([data-rt-isolate]_*)]:w-full [&_table:not([data-rt-isolate]_*)]:border-collapse [&_table:not([data-rt-isolate]_*)]:text-kit-sm [&_td:not([data-rt-isolate]_*)]:border [&_td:not([data-rt-isolate]_*)]:border-kit-line [&_td:not([data-rt-isolate]_*)]:px-2.5 [&_td:not([data-rt-isolate]_*)]:py-1.5 [&_td:not([data-rt-isolate]_*)]:align-top [&_th:not([data-rt-isolate]_*)]:border [&_th:not([data-rt-isolate]_*)]:border-kit-line [&_th:not([data-rt-isolate]_*)]:bg-kit-subtle [&_th:not([data-rt-isolate]_*)]:px-2.5 [&_th:not([data-rt-isolate]_*)]:py-1.5 [&_th:not([data-rt-isolate]_*)]:text-left [&_th:not([data-rt-isolate]_*)]:align-top [&_th:not([data-rt-isolate]_*)]:font-medium\";\n\n/** Panel density (≈340px inspector): 13px text, smaller headings. */\nexport const RT_PANEL = \"text-kit-sm leading-[1.6] [&_h1:not([data-rt-isolate]_*)]:text-kit-xl [&_h1:not([data-rt-isolate]_*)]:leading-7 [&_h2:not([data-rt-isolate]_*)]:text-kit-lg [&_h2:not([data-rt-isolate]_*)]:leading-7 [&_h3:not([data-rt-isolate]_*)]:text-kit-md [&_h4:not([data-rt-isolate]_*)]:text-kit-base [&_h5:not([data-rt-isolate]_*)]:text-kit-sm [&_h6:not([data-rt-isolate]_*)]:text-kit-xs\";\n\n/** execCommand, where the engine has it (it returns false where it does not). */\nconst exec = (cmd: string, arg?: string): boolean => {\n try {\n return typeof document.execCommand === \"function\" && document.execCommand(cmd, false, arg);\n } catch {\n return false;\n }\n};\n/** A footnote marker (`<sup data-footnote>`, or the table's `<sup><a href=\"#…-fn-n\">`): never an x² mark. */\nconst FOOTNOTE_SUP = \"sup[data-footnote], sup:has(> a[href*='-fn-'])\";\n/** x² / x₂ (V2): on inside the same mark takes it off (unwrap, keeping the words selected); inside the other one swaps;\n * otherwise the browser wraps the selection. Footnote markers are never touched. */\nfunction toggleScript(root: HTMLElement, tag: \"sup\" | \"sub\") {\n const s = window.getSelection();\n if (!s || !s.rangeCount) return;\n const at = (n: Node | null) => (n?.nodeType === 1 ? (n as HTMLElement) : (n?.parentElement ?? null));\n const find = (t: \"sup\" | \"sub\") => {\n const el = at(s.anchorNode)?.closest<HTMLElement>(t === \"sup\" ? `sup:not(${FOOTNOTE_SUP})` : \"sub\");\n return el && root.contains(el) ? el : null;\n };\n const unwrap = (el: HTMLElement) => {\n const first = el.firstChild;\n const last = el.lastChild;\n el.replaceWith(...Array.from(el.childNodes));\n if (first && last) {\n const r = document.createRange();\n r.setStartBefore(first);\n r.setEndAfter(last);\n s.removeAllRanges();\n s.addRange(r);\n }\n };\n const same = find(tag);\n if (same) return unwrap(same);\n const other = find(tag === \"sup\" ? \"sub\" : \"sup\");\n if (other) unwrap(other);\n exec(tag === \"sup\" ? \"superscript\" : \"subscript\");\n}\n\n/** Focus is in another text field (the comment composer, a link input) while the page's selection stays in this editor. */\nconst typingElsewhere = (el: HTMLElement | null) => {\n const ae = document.activeElement;\n return !!el && !!ae && ae !== el && !el.contains(ae) && ae.matches(\"input, textarea, [contenteditable='true']\");\n};\nconst queryState = (c: string) => {\n try {\n return typeof document.queryCommandState === \"function\" && document.queryCommandState(c);\n } catch {\n return false;\n }\n};\n/** Insert HTML at the caret: the browser's own insert (undoable), else by hand. */\nfunction insertHtmlAtCaret(html: string) {\n if (exec(\"insertHTML\", html)) return;\n const s = window.getSelection();\n if (!s || !s.rangeCount) return;\n const r = s.getRangeAt(0);\n r.deleteContents();\n const tpl = document.createElement(\"template\");\n tpl.innerHTML = sanitize(html);\n const last = tpl.content.lastChild;\n r.insertNode(tpl.content);\n if (last) {\n r.setStartAfter(last);\n r.collapse(true);\n s.removeAllRanges();\n s.addRange(r);\n }\n}\n/* ── Word count (V2 rich-text-editor.tsx:115-128 + article.ts countWords, CPO D54 / D55) ──\n * Words = what the writer wrote once, in the flow a reader follows: text, headings, lists, quotes, callouts, toggles,\n * table cells and image captions. Not counted: components (counted apart), a pull quote (it repeats a line of the\n * story), key takeaways (they restate it), a table of contents, related reading, the author card, embeds, video and\n * file links, the footnotes list and a footnote mark (V2 article.ts NOT_COUNTED, verbatim: D2, 278 → 262 words on\n * rich-blog-post). */\nconst NOT_COUNTED = [\n \"[data-rt=component]\", \"[data-rt=pullquote]\", \"[data-rt=takeaways]\", \"[data-rt=toc]\", \"[data-rt=related]\", \"[data-rt=author]\",\n \"[data-rt=embed]\", \"[data-rt=video]\", \"[data-rt=file]\", \"[data-rt=footnotes]\", \"sup[data-rt=fn]\",\n].join(\",\");\nconst WORDS = (s: string) => s.replace(/\\u200b/g, \"\").trim().split(/\\s+/).filter(Boolean).length;\nexport function countWords(html: string): number {\n if (!html) return 0;\n if (!/data-rt=\"(?:component|pullquote|takeaways|toc|related|author|embed|video|file|footnotes|fn)\"/.test(html) || typeof DOMParser === \"undefined\")\n // V2 article.ts, verbatim (owner rule: V2 exact): every tag parts words, so a mark inside a word counts it twice\n return WORDS(html.replace(/<[^>]+>/g, \" \").replace(/&nbsp;|&[a-z]+;/g, \" \"));\n const doc = new DOMParser().parseFromString(`<body>${html}</body>`, \"text/html\");\n doc.body.querySelectorAll(NOT_COUNTED).forEach((n) => n.remove());\n doc.body.querySelectorAll(\"p,li,h1,h2,h3,h4,h5,h6,td,th,figcaption,summary,pre,blockquote,div\").forEach((n) => n.append(\" \"));\n return WORDS(doc.body.textContent ?? \"\");\n}\n/** Linked component instances in the body. */\nexport const countComponents = (html: string) => (html.match(/data-rt=\"component\"/g) ?? []).length;\n/** \"1,840 words · 3 components\" */\nexport const bodyCountLabel = (html: string) => {\n const w = countWords(html);\n const c = countComponents(html);\n return `${w.toLocaleString(\"en-US\")} ${w === 1 ? \"word\" : \"words\"}${c ? ` · ${c} ${c === 1 ? \"component\" : \"components\"}` : \"\"}`;\n};\n\nfunction insertTextAtCaret(text: string) {\n if (exec(\"insertText\", text)) return;\n const s = window.getSelection();\n if (!s || !s.rangeCount) return;\n const r = s.getRangeAt(0);\n r.deleteContents();\n const t = document.createTextNode(text);\n r.insertNode(t);\n r.setStartAfter(t);\n r.collapse(true);\n s.removeAllRanges();\n s.addRange(r);\n}\n\n/** The slash menu at full height (header 32, list 300, footer 28, borders), the least it shrinks to, and the gap it keeps from the window's edge. */\nconst SLASH_MENU_H = 362;\nconst SLASH_MIN_H = 160;\nconst SLASH_EDGE = 8;\n\n/**\n * Where the slash menu goes, collision-aware: below the caret when the whole menu fits there, else on the side with\n * more room, and never taller than that room (its list scrolls), so the last row (More components) stays reachable in\n * a short window.\n */\nexport function slashPlacement(caret: { top: number; bottom: number }, viewportH: number): { flipUp: boolean; maxHeight: number } {\n const below = viewportH - caret.bottom - 6 - SLASH_EDGE;\n const above = caret.top - 6 - SLASH_EDGE;\n const flipUp = below < SLASH_MENU_H && above > below;\n return { flipUp, maxHeight: Math.max(SLASH_MIN_H, Math.min(SLASH_MENU_H, flipUp ? above : below)) };\n}\n\ntype IslandStep = { el: IslandEl; before: IslandModels[IslandKind]; label: string; at: number };\n/** A step the host's history holds (KitServices.historyStep); its undo and redo are the host's, while it is next. */\ntype HostStep = { label: string; step: KitHistoryStep };\ntype GutterState = { el: HTMLElement; top: number; height: number };\ntype SlashState = { rect: DOMRect; node: Text; offset: number; query: string; folder: boolean; active: number };\ntype LinkState = { rect: DOMRect; initial: TextLink; existing: HTMLAnchorElement | null; button?: { a: HTMLAnchorElement; label: string } };\ntype Notice = { message: string; description?: string; action?: { label: string; onClick: () => void } };\n\nexport interface RichTextEditorProps {\n value: string;\n onChange: (html: string) => void;\n readOnly?: boolean;\n placeholder?: string;\n docKey: string;\n /** what the field accepts; the editor offers nothing else (default: everything) */\n features?: readonly RichTextFeature[];\n /** where an author bio and related posts point (the host codec's RichTextRead.references) */\n references?: RichTextRead[\"references\"];\n /** a one-paragraph field: Enter starts no new block */\n single?: boolean;\n /** links may open in a new tab */\n allowNewTab?: boolean;\n /** the writing surface's id (the field label's `for`; its label is `${id}-label`) */\n id?: string;\n invalid?: boolean;\n /** panel = narrow (~340px) inspector, document = the full editor column. */\n variant?: \"panel\" | \"document\";\n /** CPO D49: the expanded editor's breadcrumb, root → this field (\"Alternating feature rows\", \"Thin walls\", \"Body\"). */\n expandCrumbs?: string[];\n /** Controlled expanded modal (a host's label-row action opens it too). */\n expandedOpen?: boolean;\n onExpandedOpenChange?: (open: boolean) => void;\n /** This editor IS the body of the expanded modal: toolbar always shown, tall writing surface. */\n inModal?: boolean;\n /** Already the full editor: no Expand button. */\n hideFullscreen?: boolean;\n /** Scroll the writing surface beyond this height (px). */\n maxHeight?: number;\n autoFocus?: boolean;\n /** Shows the toolbar Comment button. */\n onComment?: (quote: string) => void;\n /** the components this field may embed (the insert menus' More components); absent → none offered */\n components?: CatalogComponents;\n}\n\n/* ── Editor ────────────────────────────────────────────────────────── */\nexport function RichTextEditor({\n value,\n onChange,\n readOnly,\n placeholder,\n docKey,\n features = ALL_FEATURES,\n references,\n single,\n allowNewTab = true,\n id,\n invalid,\n variant = \"document\",\n expandCrumbs,\n expandedOpen,\n onExpandedOpenChange,\n inModal,\n hideFullscreen,\n maxHeight,\n autoFocus,\n onComment,\n components,\n}: RichTextEditorProps) {\n const hints = shortcutHintsOn();\n const ph = placeholder ?? (hints ? \"Type '/' for commands\" : \"Write something…\");\n const dense = variant === \"panel\";\n const ref = React.useRef<HTMLDivElement>(null);\n const wrap = React.useRef<HTMLDivElement>(null);\n const scroller = React.useRef<HTMLDivElement>(null);\n const saved = React.useRef<Range | null>(null);\n const known = React.useRef<string | null>(null);\n const pending = React.useRef<string | null>(null);\n /** a host undo just ran: its value is loaded even while the editor has focus (⌘Z here) */\n const forceLoad = React.useRef(false);\n const prevDoc = React.useRef<string | null>(null);\n const onChangeRef = React.useRef(onChange);\n onChangeRef.current = onChange;\n const valueRef = React.useRef(value);\n valueRef.current = value;\n const services = useKitServices();\n const env = useKitEnv();\n const featureKey = features.join(\",\");\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const allows = React.useCallback((f: RichTextFeature) => features.includes(f), [featureKey]);\n\n const [empty, setEmpty] = React.useState(isEmptyHtml(value));\n const [words, setWords] = React.useState(() => countWords(value));\n const [comps, setComps] = React.useState(() => countComponents(value));\n const [fmt, setFmt] = React.useState<Fmt>(EMPTY_FMT);\n const [modalOwn, setModalOwn] = React.useState(false);\n const modalOpen = expandedOpen ?? modalOwn;\n const setModalOpen = (o: boolean) => (onExpandedOpenChange ? onExpandedOpenChange(o) : setModalOwn(o));\n const [md, setMd] = React.useState<{ text: string; original: string } | null>(null);\n const [mdConfirm, setMdConfirm] = React.useState(false);\n // Reduced motion: the Markdown confirm fades only (no slide).\n const reduceMotion = useReducedMotion();\n const [bubble, setBubble] = React.useState<DOMRect | null>(null);\n /** Comment was picked: the toolbar stays away until the next click or key inside this editor */\n const [quiet, setQuiet] = React.useState(false);\n React.useEffect(() => {\n const el = ref.current;\n if (!quiet || !el) return;\n const wake = () => setQuiet(false);\n el.addEventListener(\"mousedown\", wake);\n el.addEventListener(\"keydown\", wake);\n return () => {\n el.removeEventListener(\"mousedown\", wake);\n el.removeEventListener(\"keydown\", wake);\n };\n }, [quiet]);\n const [slash, setSlash] = React.useState<SlashState | null>(null);\n const [gutter, setGutter] = React.useState<GutterState | null>(null);\n const [blockMenu, setBlockMenu] = React.useState(false);\n const [gutterInsert, setGutterInsert] = React.useState(false);\n const gutterTarget = React.useRef<HTMLElement | null>(null);\n // D58: AI writing help follows ai.use and needs the host's AI service; without both no AI entry point is drawn.\n const canAI = env.can(\"ai.use\") && !!services.aiRewrite;\n const aiAttempt = React.useRef(0);\n const [link, setLink] = React.useState<LinkState | null>(null);\n const [drag, setDrag] = React.useState<{ from: HTMLElement; line: number | null; target: Element | null } | null>(null);\n const [focused, setFocused] = React.useState(false);\n const [menus, setMenus] = React.useState({ style: false, more: false });\n const [insertOpen, setInsertOpen] = React.useState(false);\n const inserted = React.useRef(false);\n const [islands, setIslands] = React.useState<{ id: string; el: IslandEl }[]>([]);\n const hist = React.useRef<{ past: IslandStep[]; future: IslandStep[]; textAt: number; hosts: HostStep[] }>({ past: [], future: [], textAt: 0, hosts: [] });\n const [width, setWidth] = React.useState(720);\n /* The block gutter (+ / grip) never reserves room inside the field: it floats in the space LEFT of the box when the\n host leaves ≥ 48px there (document columns), and sits in the box's padding otherwise. */\n const [gutterRoom, setGutterRoom] = React.useState(false);\n const blurTimer = React.useRef<number | undefined>(undefined);\n const [notice, setNotice] = React.useState<Notice | null>(null);\n\n const expanded = !!inModal;\n const toolbarOpen = !readOnly && (focused || menus.style || menus.more || insertOpen || expanded || !!md || !!link);\n const scrollable = !!maxHeight && !expanded;\n\n /** A refusal or a result the author must see: the host's toaster, else a line under the editor. Never silent. */\n const notify = React.useCallback(\n (message: string, opts: { description?: string; action?: Notice[\"action\"] } = {}) => {\n if (services.toast) services.toast(message, opts);\n else setNotice({ message, ...opts });\n },\n [services],\n );\n React.useEffect(() => {\n if (!notice) return;\n const t = window.setTimeout(() => setNotice(null), 8000);\n return () => window.clearTimeout(t);\n }, [notice]);\n\n /* ── islands ─────────────────────────────────────────────────────── */\n /** V2 article-blocks.tsx:45-66: one live outline per editor, so every table of contents follows the headings */\n const outline = React.useRef(createOutlineStore());\n /** V2 rich-text-editor.tsx:271-276: the body's markers in text order, and the one whose note is open */\n const [footnotes, setFootnotes] = React.useState<{ el: HTMLElement; note: string }[]>([]);\n const [fnEdit, setFnEdit] = React.useState<{ el: HTMLElement; rect: DOMRect; fresh: boolean } | null>(null);\n const syncIslands = React.useCallback(() => {\n const el = ref.current;\n if (!el) return setIslands((p) => (p.length ? [] : p));\n const list = Array.from(el.querySelectorAll<IslandEl>(\":scope > [data-rt-island]\"));\n const seen = new Set<string>();\n for (const x of list) {\n if (!x.__rt) {\n // a copy the browser made (drag/drop, native undo of a clone): start it fresh\n x.innerHTML = \"\";\n x.__rt = defaultModel(x.getAttribute(\"data-rt-island\") as IslandKind);\n delete x.dataset.rtId;\n }\n if (!x.dataset.rtId || seen.has(x.dataset.rtId)) x.dataset.rtId = rid(\"i\");\n seen.add(x.dataset.rtId);\n }\n setIslands((prev) => (prev.length === list.length && prev.every((p, i) => p.el === list[i]) ? prev : list.map((x) => ({ id: x.dataset.rtId!, el: x }))));\n }, []);\n\n /* ── value in / out ──────────────────────────────────────────────── */\n const load = React.useCallback(\n (html: string) => {\n const el = ref.current;\n if (!el) return;\n el.innerHTML = sanitize(html || \"\") || \"<p><br></p>\";\n // the notes list is derived from the markers (V2: dropped on load, written on render); a marker is not text\n el.querySelectorAll(':scope > ol[data-rt=\"footnotes\"]').forEach((n) => n.remove());\n el.querySelectorAll<HTMLElement>(FN_MARK).forEach((m) => m.setAttribute(\"contenteditable\", \"false\"));\n hydrate(el);\n syncTaskA11y(el);\n setFootnotes(renumberFootnotes(el));\n outline.current.set(outlineOf(el));\n known.current = html;\n setEmpty(isEmptyHtml(html));\n setWords(countWords(html));\n setComps(countComponents(html));\n syncIslands();\n },\n [syncIslands],\n );\n\n const emit = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n syncIslands();\n syncTaskA11y(el);\n outline.current.set(outlineOf(el));\n setFootnotes(renumberFootnotes(el));\n const html = serialize(el);\n setEmpty(isEmptyHtml(html) && !el.querySelector(\":scope > [data-rt-island], :scope > hr\"));\n setWords(countWords(html));\n setComps(countComponents(html));\n if (html === known.current) return;\n forceLoad.current = false;\n known.current = html;\n onChangeRef.current(html);\n }, [syncIslands]);\n\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const docChanged = prevDoc.current !== null && prevDoc.current !== docKey;\n prevDoc.current = docKey;\n if (pending.current !== null) {\n const h = pending.current;\n pending.current = null;\n load(h);\n return;\n }\n if (forceLoad.current && value !== known.current) {\n forceLoad.current = false;\n load(value);\n return;\n }\n if (docChanged || !el.firstChild || (value !== known.current && !wrap.current?.contains(document.activeElement))) load(value);\n }, [value, docKey, md, load]);\n\n React.useEffect(() => {\n setMd(null);\n setMdConfirm(false);\n setSlash(null);\n setLink(null);\n setGutter(null);\n }, [docKey]);\n\n React.useEffect(() => {\n exec(\"defaultParagraphSeparator\", \"p\");\n if (autoFocus && ref.current && !readOnly) {\n ref.current.focus({ preventScroll: true });\n placeCaret(ref.current.lastElementChild ?? ref.current);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n React.useEffect(() => {\n const w = wrap.current;\n if (!w || typeof ResizeObserver === \"undefined\") return;\n const measureRoom = () => {\n let a = w.parentElement;\n while (a && a !== document.body) {\n const cs = getComputedStyle(a);\n if (cs.overflowX !== \"visible\" || cs.overflowY !== \"visible\") break;\n a = a.parentElement;\n }\n const left = w.getBoundingClientRect().left - (a ? a.getBoundingClientRect().left : 0);\n setGutterRoom(left >= 48);\n };\n const ro = new ResizeObserver(([e]) => {\n setWidth(Math.round(e.contentRect.width));\n measureRoom();\n });\n ro.observe(w);\n return () => ro.disconnect();\n }, []);\n\n /* the toolbar sticks below any sticky header (e.g. field tabs) in the same scroll area */\n const [stickyTop, setStickyTop] = React.useState(0);\n React.useEffect(() => {\n const w = wrap.current;\n if (!toolbarOpen || dense || !w) return;\n let sp = w.parentElement;\n while (sp && !/(auto|scroll)/.test(getComputedStyle(sp).overflowY)) sp = sp.parentElement;\n if (!sp) return setStickyTop(0);\n let top = 0;\n sp.querySelectorAll<HTMLElement>(\".sticky\").forEach((h) => {\n if (h.contains(w) || w.contains(h) || !(h.compareDocumentPosition(w) & Node.DOCUMENT_POSITION_FOLLOWING)) return;\n const cs = getComputedStyle(h);\n if (cs.position !== \"sticky\") return;\n top = Math.max(top, (parseFloat(cs.top) || 0) + h.offsetHeight);\n });\n setStickyTop(top);\n }, [toolbarOpen, dense]);\n\n // the slash menu follows the caret when anything scrolls; it closes only when the caret has left the \"/\" it was opened for\n const hasSlash = !!slash;\n React.useEffect(() => {\n if (!hasSlash) return;\n let raf = 0;\n const on = (e: Event) => {\n if (e.target instanceof Element && e.target.closest(\"[role=listbox]\")) return;\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() =>\n setSlash((sl) => {\n const s = window.getSelection();\n if (!sl || !s || !s.rangeCount || s.getRangeAt(0).startContainer !== sl.node) return null;\n const rect = rangeRect(s.getRangeAt(0), sl.node.parentElement ?? ref.current);\n return rect.top === sl.rect.top && rect.left === sl.rect.left ? sl : { ...sl, rect };\n }),\n );\n };\n window.addEventListener(\"scroll\", on, true);\n return () => {\n cancelAnimationFrame(raf);\n window.removeEventListener(\"scroll\", on, true);\n };\n }, [hasSlash]);\n\n // keep the bubble on the selection while anything scrolls (incl. the toolbar sliding open)\n const hasBubble = !!bubble;\n React.useEffect(() => {\n if (!hasBubble) return;\n let raf = 0;\n const on = () => {\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const s = window.getSelection();\n const ok = s && s.rangeCount && !s.isCollapsed && ref.current?.contains(s.anchorNode) && !typingElsewhere(ref.current);\n setBubble(ok ? rangeRect(s!.getRangeAt(0), ref.current) : null);\n });\n };\n window.addEventListener(\"scroll\", on, true);\n window.addEventListener(\"resize\", on);\n // The toolbar sliding open moves the words without a scroll: the bubble sat on the selected word.\n const box = new ResizeObserver(on);\n if (wrap.current) box.observe(wrap.current);\n return () => {\n cancelAnimationFrame(raf);\n box.disconnect();\n window.removeEventListener(\"scroll\", on, true);\n window.removeEventListener(\"resize\", on);\n };\n }, [hasBubble]);\n\n /* ── selection ───────────────────────────────────────────────────── */\n const saveSel = () => {\n const s = window.getSelection();\n if (s && s.rangeCount && ref.current?.contains(s.anchorNode)) saved.current = s.getRangeAt(0).cloneRange();\n };\n const restoreSel = () => {\n const el = ref.current;\n if (!el) return;\n const r = saved.current;\n const s = window.getSelection();\n if (r && el.contains(r.startContainer) && s) {\n (editingHost(r.startContainer) ?? el).focus({ preventScroll: true });\n s.removeAllRanges();\n s.addRange(r);\n } else {\n el.focus({ preventScroll: true });\n placeCaret(el.lastElementChild ?? el);\n }\n };\n\n const refresh = React.useCallback(() => {\n const el = ref.current;\n const s = window.getSelection();\n if (!el || !s || !s.rangeCount || !el.contains(s.anchorNode)) return;\n // typing somewhere else (the comment composer, a link field) keeps the page's selection here: no toolbar over it\n if (typingElsewhere(el)) {\n setBubble(null);\n return;\n }\n saved.current = s.getRangeAt(0).cloneRange();\n const anchorEl = s.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode?.parentElement;\n const inIsland = !!anchorEl?.closest(\"[data-rt-island]\");\n const tb = topBlock(el, s.anchorNode);\n const r = s.getRangeAt(0);\n const hasSel = !s.isCollapsed && !!r.toString().trim();\n const next: Fmt = {\n bold: queryState(\"bold\") && !/^H[1-6]$/.test(tb?.tagName ?? \"\"),\n italic: queryState(\"italic\"),\n underline: queryState(\"underline\"),\n strike: queryState(\"strikeThrough\"),\n // our own check: the base CSS resets sup/sub alignment, so the browser's own state for them always reads false\n sup: !!anchorEl?.closest(`sup:not(${FOOTNOTE_SUP})`),\n sub: !!anchorEl?.closest(\"sub\"),\n ul: !inIsland && tb?.tagName === \"UL\",\n ol: !inIsland && tb?.tagName === \"OL\",\n block: inIsland ? \"island\" : (tb?.tagName.toLowerCase() ?? \"p\"),\n hasSel,\n onLink: !!anchorEl?.closest(\"a\"),\n };\n setFmt((p) => (JSON.stringify(p) === JSON.stringify(next) ? p : next));\n setBubble(hasSel ? rangeRect(r, el) : null);\n el.querySelectorAll(\":scope > [data-hint]\").forEach((n) => (n !== tb || n.textContent) && n.removeAttribute(\"data-hint\"));\n if (tb && tb.tagName === \"P\" && s.isCollapsed && !tb.textContent && !tb.querySelector(\"img\") && document.activeElement === el && shortcutHintsOn()) tb.setAttribute(\"data-hint\", \"Type '/' for commands\");\n }, []);\n\n React.useEffect(() => {\n const on = () => refresh();\n // focus moving into another text field (the comment composer opening) fires no selectionchange: hide on focusin too\n const away = () => typingElsewhere(ref.current) && setBubble(null);\n document.addEventListener(\"selectionchange\", on);\n document.addEventListener(\"focusin\", away);\n return () => {\n document.removeEventListener(\"selectionchange\", on);\n document.removeEventListener(\"focusin\", away);\n };\n }, [refresh]);\n\n const run = (fn: () => void) => {\n restoreSel();\n fn();\n emit();\n refresh();\n };\n\n /* ── gutter ──────────────────────────────────────────────────────── */\n const placeGutter = (b: HTMLElement | null) => {\n const sc = scroller.current;\n if (!b || !sc) return setGutter(null);\n const sr = sc.getBoundingClientRect();\n const br = b.getBoundingClientRect();\n setGutter((g) => {\n const top = br.top - sr.top + sc.scrollTop;\n return g && g.el === b && g.top === top ? g : { el: b, top, height: br.height };\n });\n };\n const currentBlock = (): HTMLElement | null => {\n const el = ref.current;\n if (!el) return null;\n const s = window.getSelection();\n return topBlock(el, s && s.rangeCount && el.contains(s.anchorNode) ? s.anchorNode : document.activeElement);\n };\n\n /* ── block operations (DOM work lives in ./ops) ─────────── */\n const deleteBlock = (b: HTMLElement) => {\n const el = ref.current;\n if (!el || !el.contains(b)) return;\n const next = b.nextSibling;\n b.remove();\n let filler: HTMLElement | null = null;\n if (!el.firstElementChild) {\n filler = document.createElement(\"p\");\n filler.innerHTML = \"<br>\";\n el.append(filler);\n }\n setGutter(null);\n setBlockMenu(false);\n emit();\n notify(\"Block deleted\", {\n action: {\n label: \"Undo\",\n onClick: () => {\n const root = ref.current;\n if (!root) return;\n if (filler?.isConnected && !filler.textContent) filler.remove();\n if (next && next.parentNode === root) root.insertBefore(b, next);\n else root.append(b);\n emit();\n },\n },\n });\n };\n\n const duplicateBlock = (b: HTMLElement) => {\n const c = ops.duplicateBlock(b);\n emit();\n if (gutter) placeGutter(c);\n };\n\n const moveBlock = (b: HTMLElement, dir: -1 | 1) => {\n if (!ops.moveBlock(b, dir)) return;\n emit();\n if (gutter) requestAnimationFrame(() => placeGutter(b));\n };\n\n const turnInto = (b: HTMLElement | null, tag: string) => {\n const el = ref.current;\n if (el && ops.turnInto(el, b, tag)) emit();\n };\n\n const exitIsland = (x: HTMLElement) => {\n const el = ref.current;\n if (!el || !el.contains(x)) return;\n const next = ops.ensureLineAfter(x);\n el.focus({ preventScroll: true });\n placeCaret(next, false);\n emit();\n };\n\n const insertBlock = (it: CatalogItem) => {\n const el = ref.current;\n if (!el || readOnly) return;\n if (it.kind === \"component\" && it.component) {\n // V2 insert: a fresh linked instance, ONE undo step\n const c = it.component;\n noteRecent(it);\n const made: { el: IslandEl | null } = { el: null };\n oneStep(`Insert ${c.name}`, () => {\n const isl = (made.el = ops.insertIsland(el, \"component\", { ...defaultModel(\"component\"), ref: c.id, name: c.name }));\n emit();\n return isl;\n });\n refresh();\n // V2 insert: its properties open beside it, and the toast says what a shared component is\n if (made.el && services.useComponentInfo) openComponentPanel(made.el);\n services.toast?.(`${c.name} added`, { description: COMPONENT_INSERT_TOAST });\n return;\n }\n if (!it.id || !blockAllowed(it.id, allows)) return;\n noteRecent(it);\n if (it.id === \"footnote\") {\n // V2 rich-text-editor.tsx:610-615: at the caret in the text, else said why\n const m = insertFootnote(el);\n if (!m) return void notify(FOOTNOTE_REFUSED.title, { description: FOOTNOTE_REFUSED.description });\n emit();\n openFootnote(m, true);\n return;\n }\n if (it.id === \"task\") insertChecklist(el);\n else if (it.id === \"button\") {\n // V2 rich-text-editor.tsx:627: a new button opens its popover\n const a = insertButton(el);\n emit();\n refresh();\n openButton(a);\n return;\n } else if (it.id === \"related\" && references?.topic === false) {\n // no topic field to rank by: a new block is Newest (Same topic would be refused on save, no_topic_field)\n ops.insertIsland(el, \"related\", { ...defaultModel(\"related\"), mode: \"newest\" });\n } else ops.insertBasic(el, it.id);\n emit();\n refresh();\n };\n\n /* ── slash menu ──────────────────────────────────────────────────── */\n const slashCat = useCatalog(slash?.query ?? \"\", allows, slash?.folder ?? false, components ?? null);\n const caretRect = () => {\n const s = window.getSelection();\n if (!s || !s.rangeCount) return null;\n return rangeRect(s.getRangeAt(0), topBlock(ref.current, s.anchorNode) ?? ref.current);\n };\n const pickSlash = (it: CatalogItem) => {\n if (it.kind === \"folder\") return setSlash((s) => s && { ...s, folder: true, active: 1 });\n if (it.kind === \"back\") return setSlash((s) => s && { ...s, folder: false, active: 0 });\n const sl = slash;\n setSlash(null);\n if (sl) {\n try {\n const r = document.createRange();\n r.setStart(sl.node, sl.offset);\n r.setEnd(sl.node, Math.min(sl.node.length, sl.offset + 1 + sl.query.length));\n r.deleteContents();\n const c = document.createRange();\n c.setStart(sl.node, Math.min(sl.offset, sl.node.length));\n c.collapse(true);\n const s = window.getSelection();\n s?.removeAllRanges();\n s?.addRange(c);\n } catch {\n /* the text moved */\n }\n // A component is ONE step of the host's history, recorded from the body as it stands when the step starts: the\n // typed \"/query\" goes first, flushed, so an undo of the insert never brings it back as a paragraph.\n if (it.kind === \"component\") flushSync(() => emit());\n }\n insertBlock(it);\n };\n\n const toggleInlineCode = () => {\n const el = ref.current;\n const s = window.getSelection();\n if (!el || !s || !s.rangeCount || !allows(\"code\")) return;\n const anchorEl = s.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode?.parentElement;\n const code = anchorEl?.closest(\"code\");\n if (code && el.contains(code) && !code.closest(\"pre\")) {\n code.replaceWith(...Array.from(code.childNodes));\n emit();\n return;\n }\n const text = s.toString();\n if (!text) return void notify(\"Select some text first\", { description: \"Or wrap words in backticks to format them as code.\" });\n insertHtmlAtCaret(`<code>${esc(text)}</code>`);\n emit();\n };\n\n /* ── keyboard ────────────────────────────────────────────────────── */\n const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (slash) {\n if (e.key === \"Escape\") {\n e.preventDefault();\n e.stopPropagation();\n setSlash(slash.folder ? { ...slash, folder: false, active: 0 } : null);\n return;\n }\n if (catalogKey(e, slashCat.flat, slash.active, (a) => setSlash((s) => s && { ...s, active: a }), pickSlash, false)) {\n e.preventDefault();\n return;\n }\n }\n const mod = e.metaKey || e.ctrlKey;\n const k = eventKey(e);\n if (!mod && !e.altKey && !readOnly && ref.current && toggleTaskFromKey(ref.current, e.key)) {\n e.preventDefault();\n emit();\n return;\n }\n if (mod && !e.altKey && k === \"k\") {\n e.preventDefault();\n saveSel();\n openLink();\n return;\n }\n if (mod && !e.altKey && !e.shiftKey && k === \"e\") {\n e.preventDefault();\n toggleInlineCode();\n return;\n }\n // the browser's own mark shortcuts, only for the marks the field keeps\n if (mod && !e.altKey && !e.shiftKey && ((k === \"b\" && !allows(\"bold\")) || (k === \"i\" && !allows(\"italic\")) || (k === \"u\" && !allows(\"underline\")))) {\n e.preventDefault();\n return;\n }\n if (mod && e.altKey && /^Digit[0-6]$/.test(e.code)) {\n e.preventDefault();\n const n = Number(e.code.slice(5));\n const tag = n === 0 ? \"p\" : `h${n}`;\n if (tag === \"p\" || allows(tag as RichTextFeature)) turnInto(currentBlock(), tag);\n return;\n }\n if (e.key === \"Enter\" && !mod && !e.shiftKey) {\n // a one-paragraph field has no second block to start\n if (single) {\n e.preventDefault();\n return;\n }\n // Enter on an empty quote or heading line leaves it for a paragraph\n const cb = currentBlock();\n if (cb && /^(BLOCKQUOTE|H[1-6])$/.test(cb.tagName) && !cb.textContent?.replace(/​/g, \"\").trim()) {\n e.preventDefault();\n turnInto(cb, \"p\");\n return;\n }\n // Enter at the end of a quote starts a paragraph (not another quote)\n const sel = window.getSelection();\n if (cb?.tagName === \"BLOCKQUOTE\" && sel?.isCollapsed && sel.rangeCount && !cb.querySelector(\"p\")) {\n const rest = document.createRange();\n rest.selectNodeContents(cb);\n rest.setStart(sel.anchorNode!, sel.anchorOffset);\n if (!rest.toString().trim()) {\n e.preventDefault();\n const p = document.createElement(\"p\");\n p.innerHTML = \"<br>\";\n cb.after(p);\n placeCaret(p);\n emit();\n return;\n }\n }\n const s = window.getSelection();\n const pre = s?.anchorNode && (s.anchorNode.nodeType === 1 ? (s.anchorNode as HTMLElement) : s.anchorNode.parentElement)?.closest(\"pre\");\n if (pre && ref.current?.contains(pre)) {\n e.preventDefault();\n exec(\"insertLineBreak\");\n return;\n }\n }\n if (e.key === \"ArrowDown\" && !mod && !e.shiftKey && !single) {\n // leave a trailing heading / quote / code block / list\n const b = currentBlock();\n const s = window.getSelection();\n if (b && !b.nextElementSibling && b.tagName !== \"P\" && !b.hasAttribute(\"data-rt-island\") && s?.isCollapsed && s.rangeCount) {\n const rest = document.createRange();\n rest.selectNodeContents(b);\n rest.setStart(s.anchorNode!, s.anchorOffset);\n if (!rest.toString().trim()) {\n e.preventDefault();\n const p = ops.ensureLineAfter(b);\n placeCaret(p, false);\n emit();\n }\n }\n }\n };\n\n /** Block-level shortcuts; runs for the surface and for text inside rich blocks. */\n const onWrapKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.defaultPrevented) return;\n const mod = e.metaKey || e.ctrlKey;\n if (mod && e.key === \"Enter\" && !hideFullscreen) {\n e.preventDefault();\n setModalOpen(true);\n return;\n }\n if (md || readOnly) return;\n const t = e.target as HTMLElement;\n if (!ref.current?.contains(t) || t.tagName === \"INPUT\" || t.tagName === \"TEXTAREA\") return;\n if (undoKey(e)) return;\n if (single) return;\n if (mod && !e.shiftKey && !e.altKey && eventKey(e) === \"d\") {\n e.preventDefault();\n const b = currentBlock();\n if (b) duplicateBlock(b);\n return;\n }\n if (mod && e.shiftKey && (e.key === \"ArrowUp\" || e.key === \"ArrowDown\")) {\n e.preventDefault();\n const b = currentBlock();\n if (b) moveBlock(b, e.key === \"ArrowUp\" ? -1 : 1);\n }\n };\n\n const onInput = (e: React.FormEvent<HTMLDivElement>) => {\n if (e.target !== ref.current) return;\n const ne = e.nativeEvent as InputEvent;\n if (ne.inputType !== \"historyUndo\" && ne.inputType !== \"historyRedo\") {\n hist.current.textAt = Date.now();\n hist.current.future = [];\n }\n if (!single && ne.inputType === \"insertText\" && allows(\"checklist\") && checklistShortcut(ref.current!, ne.data)) {\n setSlash(null);\n emit();\n return;\n }\n if (!single && ne.inputType === \"insertText\" && (ne.data === \" \" || ne.data === \"-\") && ops.liveMarkdown(ref.current!, ne.data, allows)) {\n setSlash(null);\n emit();\n return;\n }\n if (ne.inputType === \"insertText\" && ne.data === \"`\" && allows(\"code\")) ops.liveInlineCode();\n emit();\n const s = window.getSelection();\n if (!s || !s.rangeCount) return setSlash(null);\n const r = s.getRangeAt(0);\n if (!slash) {\n // \"/\" opens the menu only at the very start of a block, and only in a field that takes more than one block\n if (single || ne.inputType !== \"insertText\" || ne.data !== \"/\" || r.startContainer.nodeType !== 3) return;\n const blk = closestBlock(ref.current!, r.startContainer);\n if (!blk || textBeforeCaret(blk) !== \"/\") return;\n const rect = caretRect();\n if (rect) setSlash({ rect, node: r.startContainer as Text, offset: r.startOffset - 1, query: \"\", folder: false, active: 0 });\n return;\n }\n if (r.startContainer !== slash.node || r.startOffset <= slash.offset || slash.node.data[slash.offset] !== \"/\") return setSlash(null);\n const q = slash.node.data.slice(slash.offset + 1, r.startOffset);\n if (/\\s/.test(q) || q.length > 24) return setSlash(null);\n setSlash({ ...slash, query: q, active: slash.folder ? 1 : 0 });\n };\n\n /* ── links ───────────────────────────────────────────────────────── */\n const openLink = () => {\n if (!allows(\"link\")) return;\n restoreSel();\n const s = window.getSelection();\n const anchorEl = s?.anchorNode?.nodeType === 1 ? (s.anchorNode as HTMLElement) : s?.anchorNode?.parentElement;\n const anchor = (anchorEl?.closest(\"a\") as HTMLAnchorElement | null) ?? null;\n if (anchor && ref.current && buttonAt(ref.current, anchor)) return openButton(anchor);\n if (!anchor && (!s || s.isCollapsed || !s.toString().trim())) {\n notify(\"Select some text first\", { description: hints ? \"Then press ⌘K to link it.\" : \"Then link it.\" });\n return;\n }\n const rect = s && s.rangeCount ? rangeRect(s.getRangeAt(0), ref.current) : ref.current!.getBoundingClientRect();\n setBubble(null);\n setLink({ rect, existing: anchor, initial: anchor ? textLinkOf(anchor) : { href: \"\" } });\n };\n /* ── footnotes (V2 rich-text-editor.tsx:1081-1130) ───────────────── */\n const openFootnote = (m: HTMLElement, fresh = false) => {\n if (readOnly) return;\n setBubble(null);\n setFnEdit({ el: m, rect: m.getBoundingClientRect(), fresh });\n };\n const removeFootnote = (m: HTMLElement) => {\n setFnEdit(null);\n m.remove();\n emit();\n };\n /** closed: a new footnote with no note is taken back out (V2), else the caret goes back after its marker */\n const closeFootnote = () => {\n const f = fnEdit;\n setFnEdit(null);\n if (!f || !ref.current) return;\n if (f.fresh && !(f.el.getAttribute(\"data-note\") ?? \"\").trim()) return removeFootnote(f.el);\n caretAfterMarker(ref.current, f.el);\n };\n\n /** V2 rich-text-editor.tsx:865-873: a button's popover, its label above the link form */\n const openButton = (a: HTMLAnchorElement) => {\n if (readOnly) return;\n const { link: initial, label } = buttonInitial(a);\n setBubble(null);\n setLink({ rect: a.getBoundingClientRect(), existing: a, initial, button: { a, label } });\n };\n const saveButton = (v: TextLink, label: string) => {\n const b = link?.button;\n setLink(null);\n if (!b) return;\n applyButton(b.a, v, label);\n emit();\n };\n const saveLink = (v: TextLink) => {\n const l = link;\n setLink(null);\n if (!l) return;\n if (l.existing) {\n applyTextLink(l.existing, v);\n emit();\n return;\n }\n run(() => {\n const text = window.getSelection()?.toString() || v.href;\n const attr = (s: string) => esc(s).replace(/\"/g, \"&quot;\");\n insertHtmlAtCaret(`<a href=\"${attr(v.href)}\"${v.newTab ? ` target=\"_blank\"` : \"\"}${v.rel ? ` rel=\"${attr(v.rel)}\"` : \"\"}>${esc(text)}</a>`);\n });\n };\n\n /* ── AI rewrite of the selection (the host's service) ────────────── */\n const aiRewrite = (preset: AiPreset) => {\n const rewrite = services.aiRewrite;\n restoreSel();\n const range = saved.current?.cloneRange();\n const text = range?.toString() ?? \"\";\n if (!rewrite || !range || !text.trim()) return;\n setBubble(null);\n Promise.resolve()\n .then(() => rewrite(text, preset, aiAttempt.current++))\n .then(\n (out) => {\n const el = ref.current;\n if (!el || !el.contains(range.startContainer) || range.toString() !== text) {\n notify(\"The text changed before the rewrite came back\", { description: \"Nothing was replaced. Select it again to retry.\" });\n return;\n }\n el.focus({ preventScroll: true });\n const s = window.getSelection();\n s?.removeAllRanges();\n s?.addRange(range);\n insertTextAtCaret(out);\n emit();\n notify(\"Rewritten with AI\", { description: hints ? \"Press ⌘Z to undo\" : undefined });\n },\n (err: unknown) => notify(\"Could not rewrite the selection\", { description: err instanceof Error ? err.message : String(err) }),\n );\n };\n\n /* ── drag to reorder via the grip ────────────────────────────────── */\n const onGripDown = (e: React.PointerEvent) => {\n if (!gutter) return;\n startDrag(gutter.el, e, () => setBlockMenu(true));\n };\n /** Drag a top-level block (the gutter grip) to a new position; a tap calls `onTap`. */\n const startDrag = (from: HTMLElement, e: React.PointerEvent, onTap?: () => void) => {\n if (readOnly || e.button !== 0) return;\n e.preventDefault();\n const start = e.clientY;\n let moved = false;\n const kids = () => Array.from(ref.current?.children ?? []);\n const move = (ev: PointerEvent) => {\n if (!moved && Math.abs(ev.clientY - start) < 4) return;\n moved = true;\n const sc = scroller.current!;\n const sr = sc.getBoundingClientRect();\n let target: Element | null = null;\n let line = 0;\n for (const k of kids()) {\n const r = k.getBoundingClientRect();\n if (ev.clientY < r.top + r.height / 2) {\n target = k;\n line = r.top - sr.top + sc.scrollTop - 4;\n break;\n }\n line = r.bottom - sr.top + sc.scrollTop + 4;\n }\n setDrag({ from, line, target });\n };\n const up = () => {\n window.removeEventListener(\"pointermove\", move);\n window.removeEventListener(\"pointerup\", up);\n if (!moved) {\n onTap?.();\n return;\n }\n setDrag((d) => {\n if (d && d.target !== d.from) {\n if (d.target) d.target.before(d.from);\n else ref.current?.append(d.from);\n setTimeout(emit, 0);\n }\n return null;\n });\n };\n window.addEventListener(\"pointermove\", move);\n window.addEventListener(\"pointerup\", up);\n };\n\n /* ── pasted and converted markup keeps to the field's rules ──────── */\n const conform = (html: string): string => {\n const r = ops.restrictHtml(html, allows);\n if (r.dropped.length) notify(`This field keeps no ${r.dropped.join(\" or \")}`, { description: \"They were left out; the text around them was kept.\" });\n return r.html;\n };\n\n /* ── Markdown mode ───────────────────────────────────────────────── */\n const toggleMarkdown = () => {\n if (!md) {\n const html = ref.current ? serialize(ref.current) : value;\n const text = htmlToMarkdown(html);\n setMd({ text, original: text });\n setSlash(null);\n setGutter(null);\n setBubble(null);\n setLink(null);\n return;\n }\n if (md.text === md.original) {\n setMd(null);\n setMdConfirm(false);\n return;\n }\n setMdConfirm(true);\n };\n const convertMarkdown = () => {\n if (!md) return;\n let html: string;\n try {\n html = conform(markdownToHtml(md.text));\n } catch (err) {\n notify(\"Could not convert this Markdown\", { description: `${err instanceof Error ? err.message : String(err)}. Your rich text is unchanged.` });\n return;\n }\n pending.current = html;\n known.current = html;\n onChangeRef.current(html);\n setMd(null);\n setMdConfirm(false);\n };\n\n /* ── One undo history (CPO D54): typing is the browser's own undo; an island write (an image's address or alt text)\n is a step on this stack. ⌘Z takes whichever happened last. ── */\n /** A host step's undo or redo; its value then loads even here, with the caret in the editor. */\n const runHost = (run: () => true | string): true | string => {\n forceLoad.current = true;\n const r = run();\n if (r !== true) forceLoad.current = false;\n return r;\n };\n /**\n * This body's host step that is the host's next undo (or redo) NOW. The host's toolbar moves these steps too: after\n * its Undo then Redo, the step is the latest change again, so ⌘Z here undoes it. Any later change in this body is a\n * host step of its own (the body's value is the host's), so a host step that is next is the latest change here.\n */\n const hostNext = (way: \"undo\" | \"redo\"): HostStep | null => {\n const hs = hist.current.hosts;\n for (let i = hs.length - 1; i >= 0; i--) if (hs[i].step.next() === way) return hs[i];\n return null;\n };\n const islandUndo = (): boolean => {\n const host = hostNext(\"undo\");\n if (host) {\n const r = runHost(host.step.undo);\n if (r !== true) notify(\"Nothing was undone\", { description: r });\n return true;\n }\n const h = hist.current;\n // a step whose island is gone has nothing to undo\n while (h.past.length && !h.past[h.past.length - 1].el.isConnected) h.past.pop();\n const step = h.past[h.past.length - 1];\n if (!step || step.at < h.textAt) return false;\n if (!step.el.__rtSet) return false;\n h.past.pop();\n h.future.push({ ...step, before: step.el.__rt!, at: Date.now() });\n step.el.__rtSet(step.before);\n return true;\n };\n const islandRedo = (): boolean => {\n const host = hostNext(\"redo\");\n if (host) {\n const r = runHost(host.step.redo);\n if (r !== true) notify(\"Nothing was redone\", { description: r });\n return true;\n }\n const h = hist.current;\n const step = h.future.pop();\n if (!step || !step.el.isConnected || !step.el.__rtSet) return false;\n h.past.push({ ...step, before: step.el.__rt!, at: Date.now() });\n step.el.__rtSet(step.before);\n return true;\n };\n /**\n * One action as ONE undo step (a separate copy, \"use shared version again\", a component inserted): in the host's\n * history when it keeps one (KitServices.historyStep: its toolbar Undo, an Undo toast and ⌘Z here are the same\n * undo), else in this editor's own (`before`: the model the island had; an insert has none, and stays as undoable\n * as any block inserted here). `write` makes the change and answers the island it changed. Answers its undo.\n */\n const oneStep = (label: string, write: () => IslandEl | null, before?: IslandModels[IslandKind]): (() => true | string) => {\n const h = hist.current;\n const made: { el: IslandEl | null } = { el: null };\n const historyStep = services.historyStep;\n const step = historyStep\n ? historyStep(() => {\n made.el = write();\n })\n : ((made.el = write()), null);\n const el = made.el;\n if (step) {\n h.hosts = [...h.hosts, { label, step }].slice(-100);\n return () => runHost(step.undo);\n }\n if (!el || !before) return () => \"This change has no undo step here.\";\n const s: IslandStep = { el, before, label, at: Date.now() };\n h.past = [...h.past, s].slice(-100);\n h.future = [];\n return () => {\n if (!h.past.includes(s)) return \"It was undone already.\";\n if (h.past[h.past.length - 1] !== s || s.at < h.textAt) return \"Changes made after it come first. Press ⌘Z to undo them.\";\n return islandUndo() ? true : \"The block was removed, so there is nothing to undo.\";\n };\n };\n const record = (el: IslandEl, before: IslandModels[IslandKind], label: string, coalesce?: boolean) => {\n const h = hist.current;\n const now = Date.now();\n const top = h.past[h.past.length - 1];\n // typing in one field coalesces (~500ms), unless the text was edited in between\n if (coalesce && top && top.el === el && top.label === label && now - top.at < 500 && top.at > h.textAt) top.at = now;\n else h.past = [...h.past, { el, before, label, at: now }].slice(-100);\n h.future = [];\n };\n const undoKey = (e: React.KeyboardEvent): boolean => {\n const mod = e.metaKey || e.ctrlKey;\n if (!mod || e.altKey || eventKey(e) !== \"z\") return false;\n if (e.shiftKey) {\n if (!islandRedo()) return false;\n e.preventDefault();\n return true;\n }\n if (islandUndo()) {\n e.preventDefault();\n return true;\n }\n if (!hist.current.past.length || !ref.current) return false;\n e.preventDefault();\n const before = ref.current.innerHTML;\n exec(\"undo\");\n if (ref.current.innerHTML === before) {\n hist.current.textAt = 0;\n islandUndo();\n }\n return true;\n };\n\n /* ── API for islands (stable) ────────────────────────────────────── */\n const api = React.useRef({ emit, deleteBlock, exitIsland, record, oneStep, notify, duplicateBlock, moveBlock, islandUndo, islandRedo, startDrag, allows });\n api.current = { emit, deleteBlock, exitIsland, record, oneStep, notify, duplicateBlock, moveBlock, islandUndo, islandRedo, startDrag, allows };\n const islandCtx = React.useMemo<IslandCtx>(\n () => ({\n readOnly,\n dense,\n emit: () => api.current.emit(),\n remove: (x) => api.current.deleteBlock(x),\n exit: (x) => api.current.exitIsland(x),\n record: (x, before, label, coalesce) => api.current.record(x, before, label, coalesce),\n step: (label, write, before) => api.current.oneStep(label, write, before),\n notify: (message, description) => api.current.notify(message, { description }),\n duplicate: (x) => api.current.duplicateBlock(x),\n move: (x, dir) => api.current.moveBlock(x, dir),\n undo: () => api.current.islandUndo(),\n redo: () => api.current.islandRedo(),\n drag: (x, e) => api.current.startDrag(x, e),\n allows: (f) => api.current.allows(f),\n outline: outline.current,\n references,\n }),\n [readOnly, dense, references],\n );\n\n const commentSel = onComment\n ? () => {\n restoreSel();\n const q = window.getSelection()?.toString().trim();\n // the comment popover takes over: the selection toolbar steps away so it never sits on the composer\n setBubble(null);\n setQuiet(true);\n if (q) onComment(q);\n }\n : undefined;\n const onMark = (cmd: MarkCmd) =>\n allows(MARK_FEATURE[cmd]) &&\n run(() =>\n cmd === \"superscript\" || cmd === \"subscript\" ? ref.current && toggleScript(ref.current, cmd === \"superscript\" ? \"sup\" : \"sub\") : exec(cmd),\n );\n const onStyle = (tag: string) => {\n restoreSel();\n turnInto(currentBlock(), tag);\n refresh();\n };\n\n /* ── render ──────────────────────────────────────────────────────── */\n const { flipUp, maxHeight: slashMaxH } = slash ? slashPlacement(slash.rect, window.innerHeight) : { flipUp: false, maxHeight: SLASH_MENU_H };\n const gBlock = gutter?.el;\n const gIsText = !!gBlock && !gBlock.hasAttribute(\"data-rt-island\") && gBlock.tagName !== \"HR\";\n const btn = dense ? \"size-5 [&_svg:not([data-rt-isolate]_*)]:size-3.5\" : \"size-[22px] [&_svg:not([data-rt-isolate]_*)]:size-3.5\";\n /* outside: + and grip float left of the box · inset: a slim grip sits in the 16px padding (insert via / or the\n toolbar) · none: compact inspector fields and one-paragraph fields */\n const gutterMode: \"outside\" | \"inset\" | \"none\" = readOnly || dense || single ? \"none\" : gutterRoom ? \"outside\" : \"inset\";\n const showGutter = gutterMode !== \"none\";\n const minH = expanded ? \"min-h-[60vh]\" : single ? \"min-h-9\" : dense ? \"min-h-[120px]\" : \"min-h-[190px]\";\n const turnStyles = stylesFor(allows).filter((s) => [\"p\", \"h1\", \"h2\", \"h3\", \"blockquote\"].includes(s.tag));\n\n return (\n <CatalogComponentsProvider value={components ?? null}>\n <div\n ref={wrap}\n data-rt-editor=\"\"\n className={cn(\n \"relative [--rt-toolbar-h:2rem] pointer-coarse:[--rt-toolbar-h:2.75rem]\",\n \"rounded-kit-lg border transition-colors duration-150\",\n /* the expanded modal is raised: the editor sits level with it, never below (D56) */\n expanded ? \"bg-[var(--kit-surface-raised)]\" : \"bg-kit-surface\",\n /* V2 rich-text-editor.tsx:1152: line at rest, line-strong while the toolbar is open; an invalid value (dash) keeps its edge */\n invalid ? \"border-[var(--kit-field-invalid)]\" : toolbarOpen ? \"border-kit-line-strong\" : \"border-kit-line\",\n )}\n /* what the sticky toolbar covers at the top of the scroll area */\n style={{ \"--rt-sticky-top\": toolbarOpen && !dense ? `calc(${stickyTop}px + var(--rt-toolbar-h))` : \"var(--kit-sticky-top, 0px)\" } as React.CSSProperties}\n onMouseLeave={() => !blockMenu && !gutterInsert && !drag && setGutter(null)}\n onKeyDown={onWrapKeyDown}\n onFocus={() => {\n window.clearTimeout(blurTimer.current);\n setFocused(true);\n }}\n onBlur={() => {\n window.clearTimeout(blurTimer.current);\n blurTimer.current = window.setTimeout(() => {\n const a = document.activeElement;\n if (wrap.current?.contains(a) || a?.closest(\"[role=menu],[role=dialog],[role=listbox],[data-floating-layer]\")) return;\n setFocused(false);\n setBubble(null);\n ref.current?.querySelectorAll(\"[data-hint]\").forEach((n) => n.removeAttribute(\"data-hint\"));\n if (valueRef.current !== known.current && !md) load(valueRef.current);\n }, 400);\n }}\n >\n {readOnly ? null : (\n <FormatToolbar\n open={toolbarOpen}\n sticky={!dense}\n stickyTop={stickyTop}\n width={width}\n dense={dense}\n fmt={fmt}\n md={!!md}\n allows={allows}\n hideFullscreen={hideFullscreen}\n insertOpen={insertOpen}\n setInsertOpen={(o) => {\n if (o) inserted.current = false;\n setInsertOpen(o);\n }}\n onMenuOpen={(name, o) => setMenus((m) => ({ ...m, [name]: o }))}\n onStyle={onStyle}\n onMark={onMark}\n onList={(kind) =>\n allows(kind) &&\n run(() => {\n // Chrome nests the list inside a heading/quote (<h2><ul>…) — turn the line into a paragraph first.\n const b = currentBlock();\n if (b && /^(H[1-6]|BLOCKQUOTE)$/.test(b.tagName)) turnInto(b, \"p\");\n exec(kind === \"ul\" ? \"insertUnorderedList\" : \"insertOrderedList\");\n // …and it can still leave <p><ul>…</ul></p>; lift the list out of any text block.\n ref.current?.querySelectorAll(\":is(p,h1,h2,h3,h4,h5,h6,blockquote) > :is(ul,ol)\").forEach((list) => {\n const host = list.parentElement!;\n host.replaceWith(...Array.from(host.childNodes).filter((n) => n.nodeType === 1 || n.textContent?.trim()));\n });\n })\n }\n onLink={openLink}\n onClear={() =>\n run(() => {\n exec(\"removeFormat\");\n exec(\"unlink\");\n })\n }\n onComment={commentSel}\n onInlineCode={() => {\n restoreSel();\n toggleInlineCode();\n }}\n onCodeBlock={() => {\n restoreSel();\n if (allows(\"pre\")) turnInto(currentBlock(), \"pre\");\n }}\n onInsert={(it) => {\n inserted.current = true;\n restoreSel();\n insertBlock(it);\n setInsertOpen(false);\n }}\n keepFocusOnInsertClose={() => inserted.current}\n onFullscreen={() => setModalOpen(true)}\n onMarkdown={toggleMarkdown}\n saveSel={saveSel}\n />\n )}\n\n {md ? (\n <div className=\"px-3 pb-2.5 pt-2.5\">\n <Textarea\n aria-label=\"Field content as Markdown\"\n spellCheck={false}\n value={md.text}\n readOnly={readOnly}\n onChange={(e) => {\n setMd({ ...md, text: e.target.value });\n setMdConfirm(false);\n }}\n className={cn(\"font-kit-mono text-kit-xs leading-5\", expanded ? \"min-h-[60vh]\" : dense ? \"min-h-[120px]\" : \"min-h-[190px]\")}\n style={scrollable ? { maxHeight } : undefined}\n />\n <p className=\"mt-1.5 text-kit-2xs text-kit-fg-3\">Markdown. Switching back converts it to blocks.</p>\n <AnimatePresence initial={false}>\n {mdConfirm ? (\n <motion.div\n key=\"confirm\"\n initial={{ opacity: 0, y: reduceMotion ? 0 : 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: reduceMotion ? 0 : 4 }}\n transition={{ duration: 0.15 }}\n role=\"alertdialog\"\n aria-label=\"Convert edited Markdown?\"\n className=\"mt-2 flex flex-wrap items-center gap-2 rounded-kit-lg border border-kit-line bg-kit-subtle px-3 py-2\"\n >\n <span className=\"flex-1 text-kit-sm font-medium text-kit-fg\">Convert edited Markdown?</span>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => setMdConfirm(false)}>\n Keep editing Markdown\n </Button>\n <Button size=\"xs\" variant=\"primary\" autoFocus onClick={convertMarkdown}>\n Convert to rich text\n </Button>\n </motion.div>\n ) : null}\n </AnimatePresence>\n </div>\n ) : (\n <div\n ref={scroller}\n className={cn(\"relative\", scrollable && \"overflow-y-auto\")}\n style={scrollable ? { maxHeight } : undefined}\n onMouseMove={(e) => {\n if (drag || blockMenu || gutterInsert || !showGutter) return;\n const t = e.target as HTMLElement;\n if (t.closest(\"[data-rt-gutter]\")) return;\n const b = topBlock(ref.current, t);\n // a component card carries its own handle and ⋯ menu (V2 rich-text-editor.tsx:1297-1298): no second grip beside it\n placeGutter(b?.getAttribute(\"data-rt-island\") === \"component\" ? null : b);\n }}\n >\n <div\n ref={ref}\n id={inModal ? undefined : id}\n role=\"textbox\"\n aria-multiline={!single}\n aria-labelledby={!inModal && id ? `${id}-label` : undefined}\n aria-label=\"Rich text\"\n aria-placeholder={ph}\n aria-readonly={readOnly || undefined}\n aria-invalid={invalid || undefined}\n contentEditable={!readOnly}\n suppressContentEditableWarning\n spellCheck\n tabIndex={readOnly ? 0 : undefined}\n onInput={onInput}\n onKeyDown={onKeyDown}\n onKeyUp={refresh}\n onMouseUp={refresh}\n onMouseDown={(e) => {\n // V2 rich-text-editor.tsx:1314-1321: a press on a task's box ticks it (the caret stays where it was)\n if (readOnly || !ref.current || !toggleTaskAtPointer(ref.current, e.target, e.clientX)) return;\n e.preventDefault();\n emit();\n }}\n onClick={(e) => {\n const fn = (e.target as HTMLElement).closest?.<HTMLElement>(FN_MARK);\n if (fn && ref.current?.contains(fn) && !fn.closest(\"[data-rt-island]\") && !readOnly) {\n e.preventDefault();\n return openFootnote(fn);\n }\n const a = ref.current ? buttonAt(ref.current, e.target) : null;\n if (!a || readOnly) return;\n e.preventDefault();\n openButton(a);\n }}\n onPaste={(e) => {\n if (readOnly) return;\n const files = Array.from(e.clipboardData.files).filter((f) => f.type.startsWith(\"image/\"));\n if (files.length) {\n e.preventDefault();\n notify(allows(\"image\") ? \"Add images from the media library\" : \"This field keeps no images\", {\n description: allows(\"image\") ? \"A pasted file has no address the page can show it from. Use Insert › Image.\" : undefined,\n });\n return;\n }\n const text = e.clipboardData.getData(\"text/plain\");\n e.preventDefault();\n if (!text) return;\n if (single || (!/\\n/.test(text.trim()) && !looksLikeMarkdown(text))) {\n insertTextAtCaret(single ? text.replace(/\\s*\\n\\s*/g, \" \") : text);\n emit();\n return;\n }\n let html: string;\n try {\n html = markdownToHtml(text);\n } catch {\n html = text.split(/\\n{2,}/).map((p) => `<p>${esc(p.trim()).replace(/\\n/g, \"<br>\")}</p>`).join(\"\");\n }\n insertHtmlAtCaret(conform(html));\n if (ref.current) hydrate(ref.current);\n emit();\n }}\n onDragOver={(e) => {\n if (e.dataTransfer.types.includes(\"application/x-bcms-asset\") && allows(\"image\")) e.preventDefault();\n }}\n onDrop={(e) => {\n const asset = e.dataTransfer.getData(\"application/x-bcms-asset\");\n if (!asset || readOnly || !allows(\"image\")) return;\n e.preventDefault();\n try {\n const a = JSON.parse(asset) as { url: string; alt?: string; name: string };\n const b = topBlock(ref.current, e.target as Node);\n const isl = createIsland(\"image\", defaultModel(\"image\", { src: a.url, alt: a.alt ?? \"\" }));\n if (b) b.after(isl);\n else ref.current?.append(isl);\n ops.ensureLineAfter(isl);\n emit();\n } catch {\n notify(\"That drop is not an image from the media library\");\n }\n }}\n className={cn(\n RT_PROSE,\n dense && RT_PANEL,\n \"peer relative outline-none focus-visible:shadow-none [&_*:not([data-rt-isolate]_*)]:outline-none\",\n \"[&>p[data-hint]]:before:pointer-events-none [&>p[data-hint]]:before:float-left [&>p[data-hint]]:before:h-0 [&>p[data-hint]]:before:text-kit-fg-4 [&>p[data-hint]]:before:content-[attr(data-hint)]\",\n \"[&_a[data-button]:not([data-rt-isolate]_*)]:cursor-pointer [&_ul[data-task]>li:not([data-rt-isolate]_*)]:before:cursor-pointer\",\n // line-height 0 after the size (tailwind-merge drops a leading before a text size): V2 gets it from preflight (RTE:1387)\n \"[&_sup[data-rt=fn]]:mx-px [&_sup[data-rt=fn]]:cursor-pointer [&_sup[data-rt=fn]]:rounded-kit-sm [&_sup[data-rt=fn]]:px-0.5 [&_sup[data-rt=fn]]:text-[0.72em] [&_sup[data-rt=fn]]:leading-[0] [&_sup[data-rt=fn]]:font-semibold [&_sup[data-rt=fn]]:text-kit-accent-fg [&_sup[data-rt=fn]:hover]:bg-kit-accent-soft\",\n dense ? \"px-2.5 py-2\" : \"px-4 py-3.5\",\n minH,\n )}\n />\n {empty ? (\n <div aria-hidden className={cn(\"pointer-events-none absolute text-kit-fg-4 peer-focus:hidden\", dense ? \"text-kit-sm\" : \"text-kit-base\", dense ? \"left-2.5 top-2\" : \"left-4 top-3.5\")}>\n {ph}\n </div>\n ) : null}\n\n {/* Block gutter (+ / grip) */}\n {gutter && showGutter ? (\n <div\n data-rt-gutter=\"\"\n /* z-3: under the sticky toolbar (z-4), so a tall block's grip never paints over it */\n className={cn(\"absolute z-[3] flex items-start\", gutterMode === \"outside\" ? \"-left-12 pr-1\" : \"left-0\")}\n style={{ top: gutter.top + Math.max(-2, Math.min(4, gutter.height / 2 - 12)) }}\n >\n {gutterMode === \"outside\" ? (\n <Popover\n open={gutterInsert}\n onOpenChange={(o) => {\n if (o) {\n gutterTarget.current = gutter.el;\n inserted.current = false;\n }\n setGutterInsert(o);\n }}\n >\n <Tooltip content=\"Add a block below\" disabled={gutterInsert}>\n <PopoverTrigger\n aria-label=\"Add a block below\"\n className={cn(\"flex items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg data-[popup-open]:bg-kit-hover data-[popup-open]:text-kit-fg\", btn)}\n >\n <IconPlus stroke={1.5} aria-hidden />\n </PopoverTrigger>\n </Tooltip>\n {gutterInsert ? (\n <InsertMenuContent\n side=\"bottom\"\n align=\"start\"\n allows={allows}\n keepFocusOnClose={() => inserted.current}\n onInsert={(it) => {\n const b = gutterTarget.current;\n const el = ref.current;\n inserted.current = true;\n setGutterInsert(false);\n if (!b || !el || !el.contains(b)) return;\n const p = document.createElement(\"p\");\n p.innerHTML = \"<br>\";\n b.after(p);\n el.focus({ preventScroll: true });\n placeCaret(p);\n insertBlock(it);\n }}\n />\n ) : null}\n </Popover>\n ) : null}\n <Menu open={blockMenu} onOpenChange={setBlockMenu}>\n <Tooltip content=\"Drag to move, click for options\" disabled={blockMenu || !!drag}>\n <MenuTrigger\n aria-label=\"Block options\"\n onPointerDown={onGripDown}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setBlockMenu(true);\n }\n }}\n className={cn(\n \"flex cursor-grab items-center justify-center rounded-kit-md text-kit-fg-3 hover:bg-kit-hover hover:text-kit-fg active:cursor-grabbing\",\n gutterMode === \"inset\" ? \"h-[22px] w-4 rounded-kit-sm [&_svg:not([data-rt-isolate]_*)]:size-3.5\" : btn,\n (blockMenu || drag) && \"bg-kit-hover text-kit-fg\",\n )}\n >\n <IconGripVertical stroke={1.5} aria-hidden />\n </MenuTrigger>\n </Tooltip>\n <MenuContent className=\"w-56\" align=\"start\" finalFocus={false}>\n {turnStyles.length > 1 ? (\n <MenuSub>\n <MenuSubTrigger icon={<IconTransform stroke={1.5} />} disabled={!gIsText}>\n Turn into\n </MenuSubTrigger>\n <MenuSubContent className=\"w-48\">\n {turnStyles.map((t) => (\n <MenuItem key={t.tag} icon={t.icon} onClick={() => turnInto(gBlock ?? null, t.tag)}>\n {t.label}\n </MenuItem>\n ))}\n </MenuSubContent>\n </MenuSub>\n ) : null}\n <MenuItem icon={<IconCopy stroke={1.5} />} shortcut=\"⌘D\" onClick={() => gBlock && duplicateBlock(gBlock)}>\n Duplicate\n </MenuItem>\n <MenuItem icon={<IconArrowBarToUp stroke={1.5} />} shortcut=\"⌘⇧↑\" disabled={!gBlock?.previousElementSibling} onClick={() => gBlock && moveBlock(gBlock, -1)}>\n Move up\n </MenuItem>\n <MenuItem icon={<IconArrowBarToDown stroke={1.5} />} shortcut=\"⌘⇧↓\" disabled={!gBlock?.nextElementSibling} onClick={() => gBlock && moveBlock(gBlock, 1)}>\n Move down\n </MenuItem>\n <MenuSeparator />\n <MenuItem danger icon={<IconTrash stroke={1.5} />} onClick={() => gBlock && deleteBlock(gBlock)}>\n Delete\n </MenuItem>\n </MenuContent>\n </Menu>\n </div>\n ) : null}\n {drag?.line != null ? <div className=\"pointer-events-none absolute inset-x-3 z-[6] h-0.5 rounded-full bg-kit-info\" style={{ top: drag.line }} /> : null}\n\n {/* Rich blocks render into their contenteditable=false hosts */}\n {islands.map(({ id: key, el }) => createPortal(<Island el={el} ctx={islandCtx} />, el, key))}\n </div>\n )}\n\n {/* Footnotes (V2 rich-text-editor.tsx:1533-1560): the notes in text order, each a way to edit it and back to it */}\n <FootnotesList\n notes={footnotes}\n readOnly={readOnly}\n density={dense ? \"dense\" : \"default\"}\n onEdit={(m) => openFootnote(m)}\n onBack={(m) => ref.current && backToMarker(ref.current, m)}\n />\n\n {/* Footer meta (V2 rich-text-editor.tsx:1563-1571), and any refusal said in place when the host has no toaster */}\n <div className=\"flex h-7 items-center justify-end gap-3 rounded-b-kit-lg border-t border-kit-line-subtle px-3 text-kit-2xs text-kit-fg-3\">\n {notice ? (\n <span role=\"status\" aria-live=\"polite\" className=\"mr-auto min-w-0 truncate text-kit-fg-2\">\n {notice.message}\n {notice.description ? ` ${notice.description}` : \"\"}\n {notice.action ? (\n <button\n type=\"button\"\n className=\"ml-1.5 font-medium text-kit-fg underline underline-offset-2\"\n onClick={() => {\n notice.action!.onClick();\n setNotice(null);\n }}\n >\n {notice.action.label}\n </button>\n ) : null}\n </span>\n ) : null}\n <span className=\"tabular-nums\">\n {words.toLocaleString(\"en-US\")} {words === 1 ? \"word\" : \"words\"}\n {comps ? ` · ${comps} ${comps === 1 ? \"component\" : \"components\"}` : \"\"} · {Math.max(1, Math.round(words / 220))} min read\n </span>\n </div>\n\n {/* Bubble toolbar on selection: a toolbar menu owns the moment, so the bubble steps aside while one is open */}\n {bubble && !quiet && !readOnly && !slash && !link && !md && !menus.style && !menus.more && !insertOpen ? (\n <SelectionBubble\n rect={bubble}\n avoid={toolbarOpen ? wrap.current?.querySelector<HTMLElement>('[role=\"toolbar\"][aria-label=\"Text formatting\"]')?.getBoundingClientRect() : null}\n fmt={fmt}\n allows={allows}\n saveSel={saveSel}\n onAi={canAI ? aiRewrite : undefined}\n onStyle={onStyle}\n onMark={onMark}\n onInlineCode={() => {\n restoreSel();\n toggleInlineCode();\n }}\n onLink={openLink}\n onComment={commentSel}\n />\n ) : null}\n\n {/* Slash menu (opens only at the start of a block; never takes focus) */}\n {slash && !md\n ? createPortal(\n <>\n <div data-floating-layer=\"\" className=\"pointer-events-auto fixed inset-0 z-[var(--kit-z-popover,84)]\" onMouseDown={() => setSlash(null)} />\n <motion.div\n initial={{ opacity: 0, y: flipUp ? -4 : 4 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.14 }}\n style={{\n left: Math.min(window.innerWidth - 330, Math.max(8, slash.rect.left)),\n ...(flipUp ? { bottom: window.innerHeight - slash.rect.top + 6 } : { top: slash.rect.bottom + 6 }),\n }}\n data-floating-layer=\"\"\n className=\"pointer-events-auto fixed z-[calc(var(--kit-z-popover,84)_+_1)]\"\n >\n <SlashMenuPanel query={slash.query} folder={slash.folder} active={slash.active} allows={allows} setActive={(a) => setSlash((s) => s && { ...s, active: a })} onPick={pickSlash} maxHeight={slashMaxH} />\n </motion.div>\n </>,\n document.body,\n )\n : null}\n\n {/* Footnote note: a small popover at its marker (V2 rich-text-editor.tsx:1644-1680, one setting) */}\n <Popover open={!!fnEdit} onOpenChange={(o) => !o && closeFootnote()}>\n <PopoverAnchor\n render={<span className=\"pointer-events-none fixed\" style={fnEdit ? { top: fnEdit.rect.bottom, left: fnEdit.rect.left, width: Math.max(1, fnEdit.rect.width), height: 1 } : { top: 0, left: 0 }} />}\n />\n <PopoverContent className={FOOTNOTE_POPOVER_CLASS} finalFocus={false}>\n {fnEdit ? (\n <FootnoteEditor\n key={footnotes.findIndex((f) => f.el === fnEdit.el)}\n n={footnotes.findIndex((f) => f.el === fnEdit.el) + 1}\n note={fnEdit.el.getAttribute(\"data-note\") ?? \"\"}\n onChange={(v) => {\n fnEdit.el.setAttribute(\"data-note\", v);\n emit();\n }}\n onRemove={() => removeFootnote(fnEdit.el)}\n onDone={closeFootnote}\n />\n ) : null}\n </PopoverContent>\n </Popover>\n\n {/* Link popover anchored to the selection */}\n <Popover open={!!link} onOpenChange={(o) => !o && setLink(null)}>\n <PopoverAnchor\n render={<span className=\"pointer-events-none fixed\" style={link ? { top: link.rect.bottom, left: link.rect.left, width: Math.max(1, link.rect.width), height: 1 } : { top: 0, left: 0 }} />}\n />\n <PopoverContent className=\"w-[340px] rounded-kit-lg p-3\" finalFocus={false}>\n {link?.button ? (\n <ButtonLinkPanel\n initial={link.initial}\n label={link.button.label}\n allowNewTab={allowNewTab}\n onSave={saveButton}\n onCancel={() => setLink(null)}\n onDetach={() => {\n const a = link.button!.a;\n setLink(null);\n if (ref.current) removeButton(ref.current, a);\n emit();\n }}\n />\n ) : link ? (\n <div className=\"flex flex-col gap-2\">\n <LinkPopoverBody\n initial={toLinkValue(link.initial)}\n hideNewTab={!allowNewTab}\n onSave={(v) => saveLink(fromLinkValue(v, allowNewTab))}\n onCancel={() => setLink(null)}\n onDetach={\n link.existing\n ? () => {\n const a = link.existing!;\n a.replaceWith(...Array.from(a.childNodes));\n setLink(null);\n emit();\n }\n : undefined\n }\n />\n </div>\n ) : null}\n </PopoverContent>\n </Popover>\n {!hideFullscreen ? (\n <ExpandedEditorModal open={modalOpen} onOpenChange={setModalOpen} crumbs={expandCrumbs?.length ? expandCrumbs : [\"Text\"]} returnFocus={() => ref.current} meta={bodyCountLabel(value)}>\n {modalOpen ? (\n <RichTextEditor\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n placeholder={placeholder}\n docKey={`${docKey}:expanded`}\n features={features}\n references={references}\n single={single}\n allowNewTab={allowNewTab}\n expandCrumbs={expandCrumbs}\n variant=\"document\"\n hideFullscreen\n inModal\n autoFocus\n onComment={onComment}\n components={components}\n />\n ) : null}\n </ExpandedEditorModal>\n ) : null}\n </div>\n </CatalogComponentsProvider>\n );\n}\n\n"],"mappings":"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"}