@formicoidea/labre-core 0.32.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/dist/_pkgs/affine-block-attachment/attachment-block.js +1 -1
  2. package/dist/_pkgs/affine-block-callout/callout-block.js +1 -1
  3. package/dist/_pkgs/affine-block-code/code-block-inline.js +1 -1
  4. package/dist/_pkgs/affine-block-code/code-toolbar/config.js +3 -1
  5. package/dist/_pkgs/affine-block-code/code-toolbar/index.js +1 -1
  6. package/dist/_pkgs/affine-block-database/data-source.js +1 -2
  7. package/dist/_pkgs/affine-block-database/external-data-source.js +1 -1
  8. package/dist/_pkgs/affine-block-edgeless-text/edgeless-text-block.js +1 -1
  9. package/dist/_pkgs/affine-block-edgeless-text/edgeless-toolbar/config.js +1 -1
  10. package/dist/_pkgs/affine-block-embed/embed-figma-block/embed-figma-service.js +1 -1
  11. package/dist/_pkgs/affine-block-embed/embed-iframe-block/configs/toolbar.js +2 -2
  12. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/configs/toolbar.js +1 -1
  13. package/dist/_pkgs/affine-block-embed-doc/embed-linked-doc-block/utils.js +1 -1
  14. package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/configs/toolbar.js +1 -1
  15. package/dist/_pkgs/affine-block-embed-doc/embed-synced-doc-block/embed-synced-doc-block.js +1 -1
  16. package/dist/_pkgs/affine-block-frame/frame-manager.js +3 -1
  17. package/dist/_pkgs/affine-block-frame/frame-tool.js +1 -1
  18. package/dist/_pkgs/affine-block-image/components/page-image-block.js +1 -1
  19. package/dist/_pkgs/affine-block-image/image-edgeless-block.js +1 -1
  20. package/dist/_pkgs/affine-block-list/utils/forward-delete.js +1 -1
  21. package/dist/_pkgs/affine-block-note/commands/select-block.js +1 -1
  22. package/dist/_pkgs/affine-block-note/commands/select-blocks-between.js +1 -1
  23. package/dist/_pkgs/affine-block-note/move-block.js +1 -1
  24. package/dist/_pkgs/affine-block-paragraph/utils/forward-delete.js +2 -2
  25. package/dist/_pkgs/affine-block-paragraph/utils/merge-with-prev.js +1 -1
  26. package/dist/_pkgs/affine-block-root/edgeless/configs/toolbar/more.js +1 -1
  27. package/dist/_pkgs/affine-block-root/edgeless/edgeless-keyboard.js +1 -1
  28. package/dist/_pkgs/affine-block-root/edgeless/utils/clipboard-utils.js +1 -1
  29. package/dist/_pkgs/affine-block-surface/adapters/markdown/element-adapter/type.js +1 -1
  30. package/dist/_pkgs/affine-block-surface/adapters/plain-text/element-adapter/type.js +1 -1
  31. package/dist/_pkgs/affine-block-surface/element-model/index.d.ts +18 -3
  32. package/dist/_pkgs/affine-block-surface/element-model/index.js +12 -2
  33. package/dist/_pkgs/affine-block-surface/extensions/audit.js +23 -6
  34. package/dist/_pkgs/affine-block-surface/extensions/crud-extension.js +10 -5
  35. package/dist/_pkgs/affine-block-surface/extensions/editor-anchored-panel.js +2 -1
  36. package/dist/_pkgs/affine-block-surface/extensions/element-renderer.js +1 -1
  37. package/dist/_pkgs/affine-block-surface/extensions/export-manager/export-manager.js +1 -1
  38. package/dist/_pkgs/affine-block-surface/extensions/index.d.ts +4 -0
  39. package/dist/_pkgs/affine-block-surface/extensions/index.js +4 -0
  40. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.d.ts +172 -0
  41. package/dist/_pkgs/affine-block-surface/extensions/interchange-import.js +393 -0
  42. package/dist/_pkgs/affine-block-surface/extensions/interchange.d.ts +306 -0
  43. package/dist/_pkgs/affine-block-surface/extensions/interchange.js +64 -0
  44. package/dist/_pkgs/affine-block-surface/extensions/map-quality-widget.js +61 -61
  45. package/dist/_pkgs/affine-block-surface/extensions/morph-toolbar.d.ts +248 -0
  46. package/dist/_pkgs/affine-block-surface/extensions/morph-toolbar.js +248 -0
  47. package/dist/_pkgs/affine-block-surface/extensions/reading-widget.js +78 -80
  48. package/dist/_pkgs/affine-block-surface/extensions/reading.js +2 -2
  49. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.d.ts +107 -0
  50. package/dist/_pkgs/affine-block-surface/extensions/svg-sketch.js +958 -0
  51. package/dist/_pkgs/affine-block-surface/extensions/validation.d.ts +809 -20
  52. package/dist/_pkgs/affine-block-surface/extensions/validation.js +1661 -50
  53. package/dist/_pkgs/affine-block-surface/extensions/violation-detail-widget.d.ts +50 -6
  54. package/dist/_pkgs/affine-block-surface/extensions/violation-detail-widget.js +129 -32
  55. package/dist/_pkgs/affine-block-surface/framework-background/def.d.ts +289 -0
  56. package/dist/_pkgs/affine-block-surface/framework-background/def.js +126 -1
  57. package/dist/_pkgs/affine-block-surface/framework-background/labels.d.ts +42 -2
  58. package/dist/_pkgs/affine-block-surface/framework-background/labels.js +80 -4
  59. package/dist/_pkgs/affine-block-surface/framework-background/renderer.js +172 -11
  60. package/dist/_pkgs/affine-block-surface/renderer/overlay.js +1 -1
  61. package/dist/_pkgs/affine-block-surface-ref/portal/note.js +2 -2
  62. package/dist/_pkgs/affine-block-table/commands.js +1 -1
  63. package/dist/_pkgs/affine-components/edgeless-shape-color-picker/color-picker.js +1 -1
  64. package/dist/_pkgs/affine-components/embed-card-modal/embed-card-edit-modal.js +1 -1
  65. package/dist/_pkgs/affine-components/filterable-list/styles.js +1 -1
  66. package/dist/_pkgs/affine-components/peek/peekable.js +1 -1
  67. package/dist/_pkgs/affine-components/toolbar/index.d.ts +1 -0
  68. package/dist/_pkgs/affine-components/toolbar/index.js +1 -0
  69. package/dist/_pkgs/affine-components/toolbar/menu-button.js +1 -1
  70. package/dist/_pkgs/affine-components/toolbar/picker-menu.d.ts +55 -0
  71. package/dist/_pkgs/affine-components/toolbar/picker-menu.js +47 -0
  72. package/dist/_pkgs/affine-fragment-frame-panel/body/frame-panel-body.js +2 -2
  73. package/dist/_pkgs/affine-fragment-frame-panel/header/frame-panel-header.js +2 -2
  74. package/dist/_pkgs/affine-fragment-frame-panel/header/frames-setting-menu.js +1 -1
  75. package/dist/_pkgs/affine-fragment-outline/mobile-outline-panel.js +1 -1
  76. package/dist/_pkgs/affine-gfx-brush/toolbar/components/pen/pen-tool-button.js +1 -1
  77. package/dist/_pkgs/affine-gfx-connector/connector-manager.js +7 -10
  78. package/dist/_pkgs/affine-gfx-connector/connector-tool.d.ts +19 -1
  79. package/dist/_pkgs/affine-gfx-connector/connector-tool.js +10 -2
  80. package/dist/_pkgs/affine-gfx-connector/connector-watcher.js +1 -4
  81. package/dist/_pkgs/affine-gfx-connector/direction/direction-reveal.js +2 -1
  82. package/dist/_pkgs/affine-gfx-connector/direction/invert-direction.js +1 -3
  83. package/dist/_pkgs/affine-gfx-connector/element-renderer/index.js +1 -1
  84. package/dist/_pkgs/affine-gfx-connector/element-renderer/utils.js +1 -1
  85. package/dist/_pkgs/affine-gfx-connector/toolbar/config.js +1 -1
  86. package/dist/_pkgs/affine-gfx-mindmap/adapter/markdown/index.js +1 -1
  87. package/dist/_pkgs/affine-gfx-mindmap/adapter/utils.js +1 -1
  88. package/dist/_pkgs/affine-gfx-mindmap/templates/index.js +583 -4
  89. package/dist/_pkgs/affine-gfx-mindmap/toolbar/mindmap-menu.js +23 -23
  90. package/dist/_pkgs/affine-gfx-mindmap/toolbar/mindmap-tool-button.js +5 -1
  91. package/dist/_pkgs/affine-gfx-mindmap/view/utils.js +1 -1
  92. package/dist/_pkgs/affine-gfx-note/overlay/overlay.js +1 -1
  93. package/dist/_pkgs/affine-gfx-note/toolbar/note-senior-button.js +1 -1
  94. package/dist/_pkgs/affine-gfx-shape/consts.js +1 -1
  95. package/dist/_pkgs/affine-gfx-shape/draggable/shape-draggable.js +1 -1
  96. package/dist/_pkgs/affine-gfx-shape/element-renderer/shape/polygon.js +17 -9
  97. package/dist/_pkgs/affine-gfx-shape/element-renderer/shape/utils.js +8 -3
  98. package/dist/_pkgs/affine-gfx-shape/element-view.js +19 -12
  99. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-drawing-overlay.js +1 -1
  100. package/dist/_pkgs/affine-gfx-shape/overlay/polygon-vertex-editing-overlay.js +12 -7
  101. package/dist/_pkgs/affine-gfx-shape/overlay/shape-overlay.js +1 -1
  102. package/dist/_pkgs/affine-gfx-shape/polygon-tool.js +4 -2
  103. package/dist/_pkgs/affine-gfx-shape/shape-tool.js +1 -1
  104. package/dist/_pkgs/affine-gfx-shape/text/edgeless-shape-text-editor.js +1 -3
  105. package/dist/_pkgs/affine-gfx-template/builtin/other.js +66 -17
  106. package/dist/_pkgs/affine-gfx-template/toolbar/overlay-scrollbar.js +1 -1
  107. package/dist/_pkgs/affine-gfx-template/toolbar/template-panel.js +1 -1
  108. package/dist/_pkgs/affine-gfx-text/toolbar/actions.js +1 -1
  109. package/dist/_pkgs/affine-inline-link/command.js +1 -1
  110. package/dist/_pkgs/affine-inline-preset/command/format-block.js +1 -1
  111. package/dist/_pkgs/affine-inline-preset/command/format-native.js +2 -2
  112. package/dist/_pkgs/affine-inline-preset/command/format-text.js +1 -1
  113. package/dist/_pkgs/affine-inline-preset/inline-spec.js +1 -1
  114. package/dist/_pkgs/affine-inline-reference/reference-node/reference-node.js +1 -1
  115. package/dist/_pkgs/affine-model/elements/bpmn/node.d.ts +40 -7
  116. package/dist/_pkgs/affine-model/elements/bpmn/node.js +4 -2
  117. package/dist/_pkgs/affine-model/elements/bpmn/pool.d.ts +74 -17
  118. package/dist/_pkgs/affine-model/elements/bpmn/pool.js +55 -26
  119. package/dist/_pkgs/affine-model/elements/c4/board.d.ts +88 -0
  120. package/dist/_pkgs/affine-model/elements/c4/board.js +128 -0
  121. package/dist/_pkgs/affine-model/elements/c4/boundary.d.ts +63 -0
  122. package/dist/_pkgs/affine-model/elements/c4/boundary.js +134 -0
  123. package/dist/_pkgs/affine-model/elements/c4/index.d.ts +3 -0
  124. package/dist/_pkgs/affine-model/elements/c4/index.js +3 -0
  125. package/dist/_pkgs/affine-model/elements/c4/node.d.ts +97 -0
  126. package/dist/_pkgs/affine-model/elements/c4/node.js +130 -0
  127. package/dist/_pkgs/affine-model/elements/connector/connector.js +1 -1
  128. package/dist/_pkgs/affine-model/elements/context-map/context-map.d.ts +27 -0
  129. package/dist/_pkgs/affine-model/elements/context-map/context-map.js +94 -0
  130. package/dist/_pkgs/affine-model/elements/context-map/index.d.ts +1 -0
  131. package/dist/_pkgs/affine-model/elements/context-map/index.js +1 -0
  132. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.d.ts +34 -17
  133. package/dist/_pkgs/affine-model/elements/core-domain/core-domain.js +28 -26
  134. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.d.ts +36 -0
  135. package/dist/_pkgs/affine-model/elements/event-storming/event-storming.js +103 -0
  136. package/dist/_pkgs/affine-model/elements/event-storming/index.d.ts +1 -0
  137. package/dist/_pkgs/affine-model/elements/event-storming/index.js +1 -0
  138. package/dist/_pkgs/affine-model/elements/index.d.ts +11 -0
  139. package/dist/_pkgs/affine-model/elements/index.js +3 -0
  140. package/dist/_pkgs/affine-model/elements/shape/api/polygon.js +2 -8
  141. package/dist/_pkgs/affine-shared/adapters/html/block-adapter.js +1 -1
  142. package/dist/_pkgs/affine-shared/adapters/markdown/block-adapter.js +1 -1
  143. package/dist/_pkgs/affine-shared/adapters/markdown/delta-converter.js +1 -1
  144. package/dist/_pkgs/affine-shared/adapters/notion-html/block-adapter.js +1 -1
  145. package/dist/_pkgs/affine-shared/adapters/notion-html/delta-converter.js +1 -1
  146. package/dist/_pkgs/affine-shared/adapters/plain-text/block-adapter.js +1 -1
  147. package/dist/_pkgs/affine-shared/adapters/plain-text/delta-converter.js +1 -1
  148. package/dist/_pkgs/affine-shared/adapters/utils/color.js +5 -2
  149. package/dist/_pkgs/affine-shared/commands/model-crud/draft-selected-models.js +1 -1
  150. package/dist/_pkgs/affine-shared/commands/selection/focus-block-end.js +1 -1
  151. package/dist/_pkgs/affine-shared/commands/selection/focus-block-start.js +1 -1
  152. package/dist/_pkgs/affine-shared/consts/index.d.ts +10 -0
  153. package/dist/_pkgs/affine-shared/consts/index.js +10 -0
  154. package/dist/_pkgs/affine-shared/services/artefact-catalogue-service.d.ts +55 -0
  155. package/dist/_pkgs/affine-shared/services/artefact-catalogue-service.js +35 -0
  156. package/dist/_pkgs/affine-shared/services/audit-service.d.ts +11 -0
  157. package/dist/_pkgs/affine-shared/services/command-usage-service.d.ts +31 -0
  158. package/dist/_pkgs/affine-shared/services/command-usage-service.js +109 -0
  159. package/dist/_pkgs/affine-shared/services/comment-service/block-comment-manager.js +1 -1
  160. package/dist/_pkgs/affine-shared/services/doc-display-meta-service.js +1 -1
  161. package/dist/_pkgs/affine-shared/services/embed-iframe/embed-iframe-config.js +1 -1
  162. package/dist/_pkgs/affine-shared/services/index.d.ts +2 -0
  163. package/dist/_pkgs/affine-shared/services/index.js +2 -0
  164. package/dist/_pkgs/affine-shared/services/pivot-materiality-publisher.js +2 -1
  165. package/dist/_pkgs/affine-shared/services/telemetry-service/lifecycle.d.ts +73 -1
  166. package/dist/_pkgs/affine-shared/services/toolbar-service/registry.d.ts +44 -0
  167. package/dist/_pkgs/affine-shared/services/toolbar-service/registry.js +161 -3
  168. package/dist/_pkgs/affine-shared/services/universe-tag-defs-service.js +5 -3
  169. package/dist/_pkgs/affine-shared/test-utils/affine-template.js +1 -1
  170. package/dist/_pkgs/affine-shared/utils/edgeless.js +1 -1
  171. package/dist/_pkgs/affine-shared/utils/file/filesys.d.ts +34 -0
  172. package/dist/_pkgs/affine-shared/utils/file/filesys.js +48 -7
  173. package/dist/_pkgs/affine-shared/utils/zod-schema.js +1 -3
  174. package/dist/_pkgs/affine-widget-drag-handle/utils.js +1 -1
  175. package/dist/_pkgs/affine-widget-edgeless-auto-connect/index.js +1 -1
  176. package/dist/_pkgs/affine-widget-edgeless-dragging-area/edgeless-dragging-area-rect.js +1 -1
  177. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-default.d.ts +14 -0
  178. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-default.js +40 -0
  179. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.d.ts +158 -0
  180. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/artefact-catalogue-widget.js +572 -0
  181. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/catalogue-groups.d.ts +46 -0
  182. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/catalogue-groups.js +66 -0
  183. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/chord-format.d.ts +13 -0
  184. package/dist/_pkgs/affine-widget-edgeless-toolbar/catalogue/chord-format.js +50 -0
  185. package/dist/_pkgs/affine-widget-edgeless-toolbar/edgeless-toolbar.d.ts +6 -0
  186. package/dist/_pkgs/affine-widget-edgeless-toolbar/edgeless-toolbar.js +15 -5
  187. package/dist/_pkgs/affine-widget-edgeless-toolbar/effects.d.ts +2 -0
  188. package/dist/_pkgs/affine-widget-edgeless-toolbar/effects.js +2 -0
  189. package/dist/_pkgs/affine-widget-edgeless-toolbar/extension/index.d.ts +7 -0
  190. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.d.ts +4 -0
  191. package/dist/_pkgs/affine-widget-edgeless-toolbar/index.js +4 -0
  192. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.d.ts +19 -0
  193. package/dist/_pkgs/affine-widget-edgeless-toolbar/menu/command-menu.js +51 -10
  194. package/dist/_pkgs/affine-widget-edgeless-toolbar/view.js +9 -0
  195. package/dist/_pkgs/affine-widget-keyboard-toolbar/keyboard-tool-panel.js +1 -1
  196. package/dist/_pkgs/affine-widget-linked-doc/import-doc/import-doc.js +1 -1
  197. package/dist/_pkgs/affine-widget-linked-doc/linked-doc-popover.js +1 -1
  198. package/dist/_pkgs/affine-widget-page-dragging-area/index.js +1 -1
  199. package/dist/_pkgs/affine-widget-remote-selection/doc/doc-remote-selection.js +1 -1
  200. package/dist/_pkgs/affine-widget-toolbar/toolbar.js +6 -2
  201. package/dist/_pkgs/affine-widget-toolbar/utils.js +6 -2
  202. package/dist/_pkgs/data-view/view-presets/calendar/pc/actions.js +8 -12
  203. package/dist/_pkgs/data-view/view-presets/calendar/pc/view.js +52 -40
  204. package/dist/_pkgs/data-view/view-presets/table/mobile/group.js +3 -1
  205. package/dist/_pkgs/data-view/view-presets/table/pc/group.js +3 -1
  206. package/dist/_pkgs/std/clipboard/utils.js +4 -1
  207. package/dist/_pkgs/std/extension/command-registry.d.ts +159 -5
  208. package/dist/_pkgs/std/extension/command-registry.js +202 -4
  209. package/dist/_pkgs/std/extension/shortcut.js +2 -1
  210. package/dist/_pkgs/std/gfx/grid.js +1 -1
  211. package/dist/_pkgs/std/gfx/index.d.ts +1 -1
  212. package/dist/_pkgs/std/gfx/model/surface/element-model.d.ts +160 -0
  213. package/dist/_pkgs/std/gfx/model/surface/element-model.js +75 -1
  214. package/dist/_pkgs/std/gfx/model/surface/role.js +5 -3
  215. package/dist/_pkgs/std/gfx/model/surface/surface-model.js +2 -1
  216. package/dist/_pkgs/std/gfx/selection.js +1 -1
  217. package/dist/_pkgs/std/gfx/viewport.js +1 -1
  218. package/dist/_pkgs/std/inline/extensions/inline-manager.js +1 -1
  219. package/dist/_pkgs/std/inline/extensions/markdown-matcher.js +1 -1
  220. package/dist/_pkgs/store/model/store/crud.js +4 -1
  221. package/dist/commands.js +1 -1
  222. package/dist/extensions/command-usage.d.ts +23 -0
  223. package/dist/extensions/command-usage.js +37 -0
  224. package/dist/extensions/view.js +12 -0
  225. package/dist/frameworks.js +32 -0
  226. package/dist/translations.js +90 -2
  227. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import type { RootBlockModel } from '../../affine-model/index.js';
2
2
  import { WidgetComponent } from '../../std/index.js';
3
3
  import { nothing } from 'lit';
4
- import { type ExemptionScope, type ViolationSeverity } from './validation.js';
4
+ import { type ExemptionScope, type ProvenanceSource, type ViolationSeverity } from './validation.js';
5
5
  export declare const VIOLATION_DETAIL_WIDGET = "affine-violation-detail-widget";
6
6
  /**
7
7
  * Chrome wording, and only chrome: an English default so a catalogue-less
@@ -17,6 +17,25 @@ export declare const VIOLATION_DETAIL_WIDGET = "affine-violation-detail-widget";
17
17
  export declare const SEVERITY_FALLBACK: Record<ViolationSeverity, string>;
18
18
  /** What the badge says of an excused violation, per scope of the exception. */
19
19
  export declare const EXEMPTION_FALLBACK: Record<ExemptionScope, string>;
20
+ /**
21
+ * What the bubble calls each kind of authority a rule can claim
22
+ * ({@link RuleProvenance}).
23
+ *
24
+ * The one wording in this file that changes what a finding MEANS rather than
25
+ * how it looks: "Standard" tells an architect the diagram breaks a published
26
+ * specification, "Labre convention" tells them it does not. An external review
27
+ * of the BPMN pack asked for exactly this line, because a house style shown
28
+ * without it reads as a norm violation — and a tool that cannot be trusted on
29
+ * that distinction is a tool an architect stops believing.
30
+ *
31
+ * The word only; the CITATION beside it is the rule's own `reference`, rendered
32
+ * verbatim and never translated (a page number is the same in every language).
33
+ *
34
+ * Exported for the same reason {@link SEVERITY_FALLBACK} is: the manifest walks
35
+ * this table under `com.labre.validation.provenance.` instead of restating four
36
+ * wordings a source scan could not check behind a template key.
37
+ */
38
+ export declare const PROVENANCE_FALLBACK: Record<ProvenanceSource, string>;
20
39
  /**
21
40
  * The PERSISTENT half of the PF7 affordance, and the restitution behind it.
22
41
  *
@@ -79,11 +98,20 @@ export declare const EXEMPTION_FALLBACK: Record<ExemptionScope, string>;
79
98
  *
80
99
  * ## What it knows
81
100
  *
82
- * Nothing about rules. It consumes normalised {@link Violation} objects off
83
- * `ValidationManager.violations$` and resolves their `messageKey` through the
84
- * host's catalogue ({@link translateKey}), falling back to the raw key. No rule
85
- * logic, no hard-coded rule wording — the library must not put words in a
86
- * framework's mouth.
101
+ * No rule LOGIC, and no hard-coded rule wording — the library must not put
102
+ * words in a framework's mouth. It consumes normalised {@link Violation}
103
+ * objects off `ValidationManager.violations$` and resolves their `messageKey`
104
+ * through the host's catalogue ({@link translateKey}), falling back to the raw
105
+ * key.
106
+ *
107
+ * The one thing it reads off the RULE rather than off the finding is
108
+ * {@link ValidationRule.provenance} — whether the sentence above it restates a
109
+ * published standard, a linter's recommendation, or a Labre house style. It is
110
+ * looked up by `ruleId` through {@link ValidationManager.ruleOf}, the same path
111
+ * this widget already walks to name a finding's framework when it reports an
112
+ * exception, and it is still declared data rather than logic: the widget
113
+ * chooses the LABEL for a source it is handed, and prints the citation
114
+ * verbatim.
87
115
  */
88
116
  export declare class ViolationDetailWidget extends WidgetComponent<RootBlockModel> {
89
117
  static styles: import("lit").CSSResult;
@@ -220,6 +248,22 @@ export declare class ViolationDetailWidget extends WidgetComponent<RootBlockMode
220
248
  */
221
249
  private _estimateBubbleHeight;
222
250
  private _severityLabel;
251
+ /**
252
+ * The one line saying where the rule behind a finding gets its authority.
253
+ *
254
+ * Resolved through {@link ValidationManager.ruleOf}, which is the path this
255
+ * widget already uses to name a finding's framework when it reports an
256
+ * exception — the bubble consumes normalised {@link Violation}s and knows
257
+ * nothing about rules, so the manager is the only place a rule can come from.
258
+ *
259
+ * Rendered ONLY when the rule declares one. A rule that says nothing about
260
+ * its provenance gets no line and no invented one: the library must not put
261
+ * an authority in a framework's mouth any more than it puts words there
262
+ * (see {@link translateKey}). That is also why the fallback is chrome-only —
263
+ * the LABEL is ours, the citation is the framework's, and the citation is
264
+ * printed exactly as declared rather than translated.
265
+ */
266
+ private _renderProvenance;
223
267
  /**
224
268
  * Grant or revoke, then report it.
225
269
  *
@@ -93,6 +93,30 @@ export const EXEMPTION_FALLBACK = {
93
93
  element: 'Exception',
94
94
  map: 'Exception (whole map)',
95
95
  };
96
+ /**
97
+ * What the bubble calls each kind of authority a rule can claim
98
+ * ({@link RuleProvenance}).
99
+ *
100
+ * The one wording in this file that changes what a finding MEANS rather than
101
+ * how it looks: "Standard" tells an architect the diagram breaks a published
102
+ * specification, "Labre convention" tells them it does not. An external review
103
+ * of the BPMN pack asked for exactly this line, because a house style shown
104
+ * without it reads as a norm violation — and a tool that cannot be trusted on
105
+ * that distinction is a tool an architect stops believing.
106
+ *
107
+ * The word only; the CITATION beside it is the rule's own `reference`, rendered
108
+ * verbatim and never translated (a page number is the same in every language).
109
+ *
110
+ * Exported for the same reason {@link SEVERITY_FALLBACK} is: the manifest walks
111
+ * this table under `com.labre.validation.provenance.` instead of restating four
112
+ * wordings a source scan could not check behind a template key.
113
+ */
114
+ export const PROVENANCE_FALLBACK = {
115
+ standard: 'Standard',
116
+ recommendation: 'Recommendation',
117
+ 'labre-convention': 'Labre convention',
118
+ organization: 'Organisation rule',
119
+ };
96
120
  /**
97
121
  * The PERSISTENT half of the PF7 affordance, and the restitution behind it.
98
122
  *
@@ -155,11 +179,20 @@ export const EXEMPTION_FALLBACK = {
155
179
  *
156
180
  * ## What it knows
157
181
  *
158
- * Nothing about rules. It consumes normalised {@link Violation} objects off
159
- * `ValidationManager.violations$` and resolves their `messageKey` through the
160
- * host's catalogue ({@link translateKey}), falling back to the raw key. No rule
161
- * logic, no hard-coded rule wording — the library must not put words in a
162
- * framework's mouth.
182
+ * No rule LOGIC, and no hard-coded rule wording — the library must not put
183
+ * words in a framework's mouth. It consumes normalised {@link Violation}
184
+ * objects off `ValidationManager.violations$` and resolves their `messageKey`
185
+ * through the host's catalogue ({@link translateKey}), falling back to the raw
186
+ * key.
187
+ *
188
+ * The one thing it reads off the RULE rather than off the finding is
189
+ * {@link ValidationRule.provenance} — whether the sentence above it restates a
190
+ * published standard, a linter's recommendation, or a Labre house style. It is
191
+ * looked up by `ruleId` through {@link ValidationManager.ruleOf}, the same path
192
+ * this widget already walks to name a finding's framework when it reports an
193
+ * exception, and it is still declared data rather than logic: the widget
194
+ * chooses the LABEL for a source it is handed, and prints the citation
195
+ * verbatim.
163
196
  */
164
197
  let ViolationDetailWidget = (() => {
165
198
  let _classSuper = WidgetComponent;
@@ -403,6 +436,22 @@ let ViolationDetailWidget = (() => {
403
436
  overflow-wrap: anywhere;
404
437
  }
405
438
 
439
+ /* Where the rule's authority comes from. Discreet on purpose: it is
440
+ context for the sentence above it, not a second finding — one line,
441
+ secondary colour, below the suggestion and above the way out. */
442
+ .violation-provenance {
443
+ margin-top: 6px;
444
+ color: var(--affine-text-secondary-color);
445
+ font-size: 12px;
446
+ overflow-wrap: anywhere;
447
+ }
448
+
449
+ /* The LABEL carries the weight, because it is the word that decides how
450
+ much an architect has to care. The citation beside it stays plain. */
451
+ .violation-provenance-source {
452
+ font-weight: 600;
453
+ }
454
+
406
455
  /* "No rule is a wall": the way out is on the message, one click away, and
407
456
  never behind a settings panel (PF8.1). */
408
457
  .violation-actions {
@@ -627,11 +676,50 @@ let ViolationDetailWidget = (() => {
627
676
  const padding = 24;
628
677
  // Message, optional hint, severity chip and the action row underneath it.
629
678
  const perEntry = 100;
630
- return Math.min(BUBBLE_MAX_HEIGHT, padding + Math.max(1, entries.length) * perEntry);
679
+ // ...plus one line for each entry that will actually SHOW a provenance,
680
+ // asked the same way the render asks it. A framework whose rules declare
681
+ // none must not have the bubble reserve room for a line it never draws.
682
+ const provenanceLine = 18;
683
+ const validation = this.std.getOptional(ValidationManager);
684
+ const cited = entries.filter(entry => validation?.ruleOf(entry.ruleId)?.provenance !== undefined).length;
685
+ return Math.min(BUBBLE_MAX_HEIGHT, padding + Math.max(1, entries.length) * perEntry + cited * provenanceLine);
631
686
  }
632
687
  _severityLabel(severity) {
633
688
  return translateKey(this.std, `com.labre.validation.severity.${severity}`, SEVERITY_FALLBACK[severity]);
634
689
  }
690
+ /**
691
+ * The one line saying where the rule behind a finding gets its authority.
692
+ *
693
+ * Resolved through {@link ValidationManager.ruleOf}, which is the path this
694
+ * widget already uses to name a finding's framework when it reports an
695
+ * exception — the bubble consumes normalised {@link Violation}s and knows
696
+ * nothing about rules, so the manager is the only place a rule can come from.
697
+ *
698
+ * Rendered ONLY when the rule declares one. A rule that says nothing about
699
+ * its provenance gets no line and no invented one: the library must not put
700
+ * an authority in a framework's mouth any more than it puts words there
701
+ * (see {@link translateKey}). That is also why the fallback is chrome-only —
702
+ * the LABEL is ours, the citation is the framework's, and the citation is
703
+ * printed exactly as declared rather than translated.
704
+ */
705
+ _renderProvenance(ruleId) {
706
+ const provenance = this.std
707
+ .getOptional(ValidationManager)
708
+ ?.ruleOf(ruleId)?.provenance;
709
+ if (provenance === undefined)
710
+ return nothing;
711
+ const { source, reference } = provenance;
712
+ const label = translateKey(this.std, `com.labre.validation.provenance.${source}`, PROVENANCE_FALLBACK[source]);
713
+ return html `<div
714
+ class="violation-provenance"
715
+ data-testid="violation-provenance"
716
+ data-provenance=${source}
717
+ >
718
+ <span class="violation-provenance-source">${label}</span>${reference
719
+ ? html ` — ${reference}`
720
+ : nothing}
721
+ </div>`;
722
+ }
635
723
  /**
636
724
  * Grant or revoke, then report it.
637
725
  *
@@ -696,15 +784,15 @@ let ViolationDetailWidget = (() => {
696
784
  _renderEntry(entry, violations) {
697
785
  const { exemption } = entry;
698
786
  const action = (key, fallback, testid, scope, granted) => html `<button
699
- class="violation-action"
700
- type="button"
701
- data-testid=${testid}
702
- @pointerdown=${this._swallow}
703
- @pointerup=${this._swallow}
704
- @click=${this._exception(violations, scope, granted)}
705
- >
706
- ${translateKey(this.std, key, fallback)}
707
- </button>`;
787
+ class="violation-action"
788
+ type="button"
789
+ data-testid=${testid}
790
+ @pointerdown=${this._swallow}
791
+ @pointerup=${this._swallow}
792
+ @click=${this._exception(violations, scope, granted)}
793
+ >
794
+ ${translateKey(this.std, key, fallback)}
795
+ </button>`;
708
796
  return html `<div class="violation-entry" data-exemption=${exemption ?? ''}>
709
797
  <div class="violation-severity" data-severity=${entry.severity}>
710
798
  ${this._severityLabel(entry.severity)}
@@ -726,6 +814,7 @@ let ViolationDetailWidget = (() => {
726
814
  ${translateKey(this.std, entry.suggestion, entry.suggestionFallback)}
727
815
  </div>`
728
816
  : nothing}
817
+ ${this._renderProvenance(entry.ruleId)}
729
818
  <div class="violation-actions">
730
819
  ${exemption
731
820
  ? action('com.labre.validation.action.revoke', 'Revoke', 'violation-revoke', exemption, false)
@@ -734,8 +823,7 @@ let ViolationDetailWidget = (() => {
734
823
  // A family that measures against no background records no
735
824
  // `backgroundId`, so there is no map to write the wider
736
825
  // arbitration on and the action simply does not exist.
737
- violations.some(violation => violation.backgroundId !== undefined) &&
738
- this._isRepeated(violations)
826
+ violations.some(violation => violation.backgroundId !== undefined) && this._isRepeated(violations)
739
827
  ? action('com.labre.validation.action.ignore-map', 'Ignore this rule on the whole map', 'violation-ignore-map', 'map', true)
740
828
  : nothing}`}
741
829
  </div>
@@ -763,7 +851,9 @@ let ViolationDetailWidget = (() => {
763
851
  data-flip-y=${flipY}
764
852
  aria-label=${translateKey(this.std, 'com.labre.validation.bubble.label', 'Validation details')}
765
853
  style=${styleMap({
766
- left: flipX ? `${x - BUBBLE_GAP - BUBBLE_WIDTH}px` : `${x + BUBBLE_GAP}px`,
854
+ left: flipX
855
+ ? `${x - BUBBLE_GAP - BUBBLE_WIDTH}px`
856
+ : `${x + BUBBLE_GAP}px`,
767
857
  top: flipY ? `${y - BUBBLE_GAP}px` : `${y + BUBBLE_GAP}px`,
768
858
  ...(flipY ? { transform: 'translateY(-100%)' } : {}),
769
859
  })}
@@ -838,29 +928,34 @@ let ViolationDetailWidget = (() => {
838
928
  const width = right - left;
839
929
  const height = bottom - top;
840
930
  const strips = [
841
- { left: left - band, top: top - band, width: width + band * 2, height: band },
931
+ {
932
+ left: left - band,
933
+ top: top - band,
934
+ width: width + band * 2,
935
+ height: band,
936
+ },
842
937
  { left: left - band, top: bottom, width: width + band * 2, height: band },
843
938
  { left: left - band, top, width: band, height },
844
939
  { left: right, top, width: band, height },
845
940
  ];
846
941
  return strips.map(strip => html `<button
847
- class="violation-bracket-hit"
848
- type="button"
849
- tabindex="-1"
850
- aria-hidden="true"
851
- data-anchor-id=${anchor.id}
852
- data-testid="violation-bracket-hit"
853
- title=${label}
854
- style=${styleMap({
942
+ class="violation-bracket-hit"
943
+ type="button"
944
+ tabindex="-1"
945
+ aria-hidden="true"
946
+ data-anchor-id=${anchor.id}
947
+ data-testid="violation-bracket-hit"
948
+ title=${label}
949
+ style=${styleMap({
855
950
  left: `${strip.left}px`,
856
951
  top: `${strip.top}px`,
857
952
  width: `${Math.max(0, strip.width)}px`,
858
953
  height: `${Math.max(0, strip.height)}px`,
859
954
  })}
860
- @pointerdown=${this._swallow}
861
- @pointerup=${this._swallow}
862
- @click=${this._open(anchor.id)}
863
- ></button>`);
955
+ @pointerdown=${this._swallow}
956
+ @pointerup=${this._swallow}
957
+ @click=${this._open(anchor.id)}
958
+ ></button>`);
864
959
  }
865
960
  render() {
866
961
  if (this._violations.length === 0)
@@ -891,7 +986,9 @@ let ViolationDetailWidget = (() => {
891
986
  }
892
987
  // Strictly one marker at a time: while the bracket is still drawn the
893
988
  // badge does not exist, and the bracket's own band takes the clicks.
894
- const fresh = timeline ? anchorEmphasis(anchor, timeline, now) > 0 : false;
989
+ const fresh = timeline
990
+ ? anchorEmphasis(anchor, timeline, now) > 0
991
+ : false;
895
992
  const [badgeX, badgeY] = this._badgeAt(anchor);
896
993
  return html `${fresh
897
994
  ? this._renderBracketHit(anchor, label)
@@ -59,6 +59,18 @@ export interface BackgroundTextStyle {
59
59
  weight?: number;
60
60
  /** Named consumer: Estuarine's `e` / `t` letters are `italic 700`. */
61
61
  italic?: boolean;
62
+ /**
63
+ * Where the anchor sits on the glyphs. `alphabetic` — the default, and what
64
+ * every text meant before this existed — puts it on the BASELINE, so the
65
+ * words hang above the anchor; `middle` centres them on it.
66
+ *
67
+ * Named consumer: the BPMN pool, whose participant name is centred ACROSS the
68
+ * band it is written in. A baseline anchor there would push the name against
69
+ * the frame instead of down the middle of the band — the one case where the
70
+ * two conventions are visibly different, because the room the text is given
71
+ * is the width of the glyphs and nothing more.
72
+ */
73
+ baseline?: 'alphabetic' | 'middle';
62
74
  }
63
75
  /** Where a piece of text sits: a plot ratio plus a fixed model-unit offset. */
64
76
  export interface BackgroundAnchor {
@@ -92,6 +104,18 @@ export interface BackgroundTextDef extends BackgroundLabelSource {
92
104
  id: string;
93
105
  anchor: BackgroundAnchor;
94
106
  style: BackgroundTextStyle;
107
+ /**
108
+ * Only drawn when {@link FrameworkBackgroundDef.variantProp} reads one of
109
+ * these — the same semantics a wash already has
110
+ * ({@link BackgroundWashDef.variants}), and the reason a variant is a
111
+ * DECLARATION and not a second background.
112
+ *
113
+ * Absent means every variant, which is what every text meant before this
114
+ * existed. Distinct from {@link visibleProp}, and the two compose: a variant
115
+ * says which chart this text belongs to, a visible prop says whether the user
116
+ * has switched it off in the chart it does belong to.
117
+ */
118
+ variants?: readonly string[];
95
119
  /** Defaults to `left` for horizontal text and `center` for vertical. */
96
120
  align?: 'left' | 'center' | 'right';
97
121
  /** Drawn rotated -90°, reading bottom-to-top. */
@@ -167,6 +191,19 @@ export interface BackgroundZoneDef {
167
191
  w: Ratio;
168
192
  h: Ratio;
169
193
  };
194
+ /**
195
+ * The variants this zone exists in, same semantics as
196
+ * {@link BackgroundWashDef.variants}: only drawn when
197
+ * {@link FrameworkBackgroundDef.variantProp} reads one of them, and absent
198
+ * means all of them.
199
+ *
200
+ * Unlike {@link fillVisibleProp}, which gates the TINT alone, this gates the
201
+ * zone as a whole — its {@link label} included, unless that label names its
202
+ * own variants. A quadrant that is not part of this reading of the chart has
203
+ * no name to be written on the canvas either, and the same precedent already
204
+ * holds one layer up: an axis' title shares the axis' visibility.
205
+ */
206
+ variants?: readonly string[];
170
207
  /** Tint painted under everything but the card. */
171
208
  fill?: BackgroundColor;
172
209
  /** Model prop gating the tint (not the label). */
@@ -174,6 +211,135 @@ export interface BackgroundZoneDef {
174
211
  /** The zone name. Anchored in plot ratios like any other text. */
175
212
  label?: BackgroundTextDef;
176
213
  }
214
+ /**
215
+ * One region of the plot an INSTANCE declares, read off a model prop.
216
+ *
217
+ * The counterpart of {@link BackgroundZoneDef}, which is part of the framework
218
+ * and identical on every element of it. This one is the user's own partition of
219
+ * their own frame: a BPMN pool's lanes (couloirs) are exactly this — how many
220
+ * there are, what they are called and how the height is shared between them is
221
+ * a property of THAT pool, not of BPMN.
222
+ */
223
+ export interface BackgroundInstanceZoneItem {
224
+ /** Stable id inside the instance; what a reported zone id is built from. */
225
+ id: string;
226
+ /** The zone name, drawn in the band. Absent means an unnamed band. */
227
+ name?: string;
228
+ /**
229
+ * A relative WEIGHT, not a length: the zones share the plot in proportion to
230
+ * their sizes. See {@link BackgroundInstanceZonesDef} for why.
231
+ */
232
+ size: number;
233
+ }
234
+ /**
235
+ * A label STRIP at the leading edge of every instance zone.
236
+ *
237
+ * The placement BPMN 2.0 draws a lane title in, and the one bpmn.io, Camunda
238
+ * and Visio all render: a fixed-width band along the lane's leading edge,
239
+ * immediately inside the pool's own participant band, with the lane name turned
240
+ * on its side. The first placement this file offered wrote the name across the
241
+ * zone's top-left corner instead; the PO's visual recette (2026-08-26) settled
242
+ * it against the corner, on notation rather than on taste — a reader who knows
243
+ * BPMN reads the strip as a lane title and a floating corner word as a note.
244
+ *
245
+ * ## The strip is CHROME, not a smaller zone
246
+ *
247
+ * {@link backgroundInstanceZones} keeps reporting the FULL plot slice, and the
248
+ * strip is painted inside it. That is the BPMN reading and not an
249
+ * implementation shortcut: the title band belongs TO the lane, so an element
250
+ * dropped on it is in that lane, and a lane's share of the pool does not shrink
251
+ * because it was given a name. Membership, the audit and every rule therefore
252
+ * see exactly what they saw before this existed.
253
+ *
254
+ * ## Which way the words run
255
+ *
256
+ * From the stack, not from a field: a `'y'` stack makes the strip tall and
257
+ * narrow, so the name is rotated to read bottom-to-top, exactly as the
258
+ * participant name is one level up ({@link BackgroundSideBandDef}); an `'x'`
259
+ * stack makes it short and wide, so the name stays upright. A declaration that
260
+ * could disagree with its own geometry would only ever be a way to get it
261
+ * wrong.
262
+ */
263
+ export interface BackgroundInstanceZoneBandDef {
264
+ /** Strip thickness in FIXED model units — across the stacking direction. */
265
+ width: number;
266
+ /** The line between the strip and the rest of the zone. Absent means none. */
267
+ divider?: BackgroundStroke;
268
+ }
269
+ /**
270
+ * A background whose plot its INSTANCES divide up.
271
+ *
272
+ * A framework declares here that its elements carry their own partition, which
273
+ * prop holds it and how the pieces stack; the primitive paints the dividers and
274
+ * the names, and the audit reports the pieces as zones like any other. Named
275
+ * consumer: the BPMN pool, whose lanes arrive in the tranche after this one.
276
+ *
277
+ * ## Why weights and not model units
278
+ *
279
+ * Every position in this file is a ratio of the plot precisely so that a
280
+ * background survives being stretched, and an instance partition has to survive
281
+ * it too. Sizes are therefore NORMALISED over their sum: a pool with lanes of
282
+ * `1, 2, 1` gives the middle one half the height at any size, and dragging the
283
+ * pool taller redistributes the extra space proportionally instead of leaving a
284
+ * gap under the last band or pushing it out of the frame. The numbers are also
285
+ * free of a unit the user would have to think in — `2` reads as "twice the
286
+ * other one", which is the only thing a lane's height ever means.
287
+ */
288
+ export interface BackgroundInstanceZonesDef {
289
+ /** Model prop holding the {@link BackgroundInstanceZoneItem}[]. */
290
+ prop: string;
291
+ /**
292
+ * Which way the zones stack. `'y'` lays them out as horizontal bands, full
293
+ * width, top to bottom in array order — the BPMN pool. `'x'` is the
294
+ * symmetric case: full-height columns, left to right.
295
+ */
296
+ stack: 'x' | 'y';
297
+ /** The line between two adjacent zones. Absent means none is drawn. */
298
+ divider?: BackgroundStroke;
299
+ /**
300
+ * How a zone's {@link BackgroundInstanceZoneItem.name} is written.
301
+ *
302
+ * Not a {@link BackgroundTextDef}: there is one style for every zone of the
303
+ * instance, and the anchor is the zone's own geometry rather than a declared
304
+ * ratio — the whole point is that the declaration does not know how many
305
+ * zones there are or where they sit.
306
+ *
307
+ * ## Two placements, selected by the PRESENCE of {@link band}
308
+ *
309
+ * - **corner** (no `band`) — horizontal, anchored at the top-left of the
310
+ * zone, inset by `dx` / `dy` in FIXED model units like every other offset
311
+ * here. The original placement, and still the default;
312
+ * - **band** — a fixed-width label STRIP at the zone's leading edge, with the
313
+ * name written along it: rotated for a `'y'` stack, upright for an `'x'`
314
+ * one. See {@link BackgroundInstanceZoneBandDef}.
315
+ *
316
+ * Presence as the selector rather than a discriminated union, deliberately.
317
+ * A union would need a tag on every declaration that already exists, which
318
+ * makes an additive change a breaking one for no reader; and presence is
319
+ * already how this file says "this feature is off" everywhere else — an
320
+ * absent `instanceZones` is no partition, an absent `divider` is no line, an
321
+ * absent `label` is no names at all. `dx` / `dy` belong to the corner
322
+ * placement and are ignored under a band, which has no corner to inset from.
323
+ */
324
+ label?: {
325
+ style: BackgroundTextStyle;
326
+ /** Corner placement only. */
327
+ dx?: number;
328
+ /** Corner placement only. */
329
+ dy?: number;
330
+ /** Present = band placement. */
331
+ band?: BackgroundInstanceZoneBandDef;
332
+ };
333
+ /**
334
+ * Prefix of the reported zone ids: `'lane'` reports `lane:sales`.
335
+ *
336
+ * A namespace, not decoration. The instance zones are concatenated with the
337
+ * declared ones ({@link FrameworkBackgroundDef.zones}) wherever zones are
338
+ * consumed, and a user free to name a lane `early` must not be able to shadow
339
+ * a framework zone by doing so.
340
+ */
341
+ idPrefix: string;
342
+ }
177
343
  /**
178
344
  * A flat colour wash over the plot, given as gradient stops.
179
345
  *
@@ -196,12 +362,56 @@ export interface BackgroundWashDef {
196
362
  }
197
363
  export interface BackgroundSurfaceDef {
198
364
  fill?: BackgroundColor;
365
+ /**
366
+ * The frame round the card. `dash` is a pattern in model units, exactly as
367
+ * {@link BackgroundStroke.dash} is; absent — which is what every declaration
368
+ * written before it existed says — draws the solid line it always drew.
369
+ *
370
+ * Named consumer: the C4 boundary, which the notation draws as a DASHED
371
+ * rectangle round a group of elements. A dash is what tells a boundary from a
372
+ * board on that canvas, so it belongs where the rest of the frame is declared
373
+ * rather than in a renderer wrapper only one framework would ever have.
374
+ */
199
375
  border?: {
200
376
  color: BackgroundColor;
201
377
  width: number;
202
378
  radius?: number;
379
+ dash?: readonly number[];
203
380
  };
204
381
  }
382
+ /**
383
+ * A filled strip of FIXED width, painted over one margin of the card.
384
+ *
385
+ * The width of a band IS the margin it covers
386
+ * ({@link BackgroundGeometry.margin}), never a second number: the margin is
387
+ * already the room the plot gives up to the furniture, and letting a
388
+ * declaration state a different width would be two numbers that must agree and
389
+ * one day will not. An element narrower than its own margin clamps the band to
390
+ * the element, which is the only case where the two can disagree.
391
+ *
392
+ * A band is part of the CARD, not a layer over it: it is painted over the
393
+ * card's fill and under its border, so the frame keeps outlining the whole
394
+ * element. Its {@link label} is a text like any other, drawn with the rest of
395
+ * them, and anchored in plot ratios — the plot edge is the band's inner edge,
396
+ * so `x: 0` with a negative `dx` walks back INTO the band.
397
+ *
398
+ * Named consumer: the BPMN pool, a lane whose participant name is written up a
399
+ * filled band along its left edge, with a {@link divider} between that band and
400
+ * the flow area.
401
+ *
402
+ * Only `'left'` for now — same philosophy as the wash direction
403
+ * ({@link BackgroundWashDef.stops}): the union grows the day a framework asks
404
+ * for a top or a right band, not in anticipation of one.
405
+ */
406
+ export interface BackgroundSideBandDef {
407
+ side: 'left';
408
+ /** Tint over the whole strip. Absent means the card shows through. */
409
+ fill?: BackgroundColor;
410
+ /** The line between the band and the plot. Absent means none. */
411
+ divider?: BackgroundStroke;
412
+ /** The words written in the band — the band's own label. */
413
+ label?: BackgroundTextDef;
414
+ }
205
415
  /** Everything that dresses the frame: the card, the fills, the colour code. */
206
416
  export interface BackgroundChromeDef {
207
417
  /** Font family every text inherits unless it names its own. */
@@ -211,6 +421,11 @@ export interface BackgroundChromeDef {
211
421
  * a plain white rectangle with no border.
212
422
  */
213
423
  surface?: BackgroundSurfaceDef;
424
+ /**
425
+ * Filled strips over the margins, painted WITH the card — over its fill, under
426
+ * its border — in declaration order.
427
+ */
428
+ sideBands?: readonly BackgroundSideBandDef[];
214
429
  /** Washes over the plot, painted in declaration order, under the zones. */
215
430
  washes?: readonly BackgroundWashDef[];
216
431
  /** The colour code: names a palette entry `@name` can resolve to. */
@@ -253,6 +468,12 @@ export interface FrameworkBackgroundDef {
253
468
  variantProp?: string;
254
469
  axes?: readonly BackgroundAxisDef[];
255
470
  zones?: readonly BackgroundZoneDef[];
471
+ /**
472
+ * The plot partition each INSTANCE carries, if this framework lets its
473
+ * elements declare one. Absent — the case for every framework so far — means
474
+ * a background whose zones are the same on every element of it.
475
+ */
476
+ instanceZones?: BackgroundInstanceZonesDef;
256
477
  /**
257
478
  * Width of the TOLERANCE BAND around each zone transition, as a ratio of the
258
479
  * plot span the transition is measured across. Centred on the transition, so
@@ -299,6 +520,74 @@ export declare function warnBrokenBackgroundColor(reason: string): void;
299
520
  * request for transparency: it warns and returns {@link BROKEN_BACKGROUND_COLOR}.
300
521
  */
301
522
  export declare function backgroundColor(color: BackgroundColor | undefined, palette: Readonly<Record<string, BackgroundColor>> | undefined): string;
523
+ /** One zone of one instance, resolved: a name and a rectangle in plot ratios. */
524
+ export interface BackgroundInstanceZone {
525
+ /** `${idPrefix}:${item.id}` — never collides with a declared zone id. */
526
+ id: string;
527
+ name?: string;
528
+ rect: {
529
+ x: Ratio;
530
+ y: Ratio;
531
+ w: Ratio;
532
+ h: Ratio;
533
+ };
534
+ }
535
+ /**
536
+ * The plot partition ONE instance carries, as rectangles in plot ratios.
537
+ *
538
+ * The semantic accessor onto {@link BackgroundInstanceZonesDef}: everything
539
+ * that has to know where a user's own zones sit — the renderer that draws their
540
+ * dividers and their names, the audit that reports them, the rules a later
541
+ * tranche will judge inside them — reads them here, so a lane is one shape and
542
+ * not four that must agree. Named consumer: the BPMN pool's lanes (couloirs).
543
+ *
544
+ * Pure: declaration plus the instance's bag of props in, plain data out. Ratios
545
+ * and not model units, for the reason every position in this file is a ratio —
546
+ * an instance stretched to twice its height keeps the same partition.
547
+ *
548
+ * ## What a malformed partition does
549
+ *
550
+ * A partition is data the user edits, so it gets typos and half-written rows,
551
+ * and none of them may take the frame down or paint a picture that lies:
552
+ *
553
+ * - a missing, empty or non-array prop yields `[]` — a background that simply
554
+ * has no partition yet, which is what every instance looks like the moment it
555
+ * is created;
556
+ * - an entry that is not an object, or carries no string id, is dropped;
557
+ * - a size that is not a finite number, or is `0` or less, is dropped with a
558
+ * warning: a zero-height band is a band nothing can be in, and a negative one
559
+ * would eat into its neighbours. Dropped rather than clamped, for the reason
560
+ * {@link FrameworkBackgroundDef.transitionBandWidth} drops its own degenerate
561
+ * case — silently inventing a size is worse than showing one band fewer;
562
+ * - once for each distinct problem, like every other diagnostic on the paint
563
+ * path (see {@link warnBrokenBackgroundColor}).
564
+ *
565
+ * The survivors keep their declaration ORDER, and their sizes are normalised
566
+ * over the sum of the survivors — so dropping a broken row redistributes its
567
+ * space rather than leaving a hole where it was.
568
+ */
569
+ export declare function backgroundInstanceZones(def: FrameworkBackgroundDef, model: Readonly<Record<string, unknown>>): readonly BackgroundInstanceZone[];
570
+ /** A rectangle in ELEMENT-LOCAL model units, i.e. what the renderer paints in. */
571
+ export interface BackgroundRect {
572
+ x: number;
573
+ y: number;
574
+ w: number;
575
+ h: number;
576
+ }
577
+ /**
578
+ * The label STRIP of one instance zone, in element-local model units.
579
+ *
580
+ * `null` when the declaration asks for no band, or when there is no room for
581
+ * one. THE one place that knows where a lane title sits: the renderer paints
582
+ * from it and the framework's view hit-tests a double-click against it, so the
583
+ * words a user aims at and the words they get are the same rectangle by
584
+ * construction rather than by two constants that must agree.
585
+ *
586
+ * Clamped to the plot, the way a side band clamps to an element narrower than
587
+ * its own margin ({@link BackgroundSideBandDef}) — the same degenerate case,
588
+ * and the same answer.
589
+ */
590
+ export declare function backgroundInstanceZoneBand(def: FrameworkBackgroundDef, zone: BackgroundInstanceZone, plot: ReturnType<typeof backgroundPlot>): BackgroundRect | null;
302
591
  /**
303
592
  * Whether the resize handles are offered for this element.
304
593
  *