@bpmnkit/editor 0.0.11 → 0.0.12

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.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <div align="center">
2
- <img src="https://raw.githubusercontent.com/bpmnkit/monorepo/main/doc/logos/logo-2-gateway.svg" width="72" height="72" alt="BPMN Kit logo">
2
+ <a href="https://bpmnkit.com"><img src="https://bpmnkit.com/favicon.svg" width="72" height="72" alt="BPMN Kit logo"></a>
3
3
  <h1>@bpmnkit/editor</h1>
4
4
  <p>Full-featured interactive BPMN editor with undo/redo, HUD, and side-dock UI</p>
5
5
 
@@ -123,3 +123,7 @@ interface SideDock {
123
123
  ## License
124
124
 
125
125
  [MIT](https://github.com/bpmnkit/monorepo/blob/main/LICENSE) © BPMN Kit — made by [u11g](https://u11g.com)
126
+
127
+ <div align="center">
128
+ <a href="https://bpmnkit.com"><img src="https://bpmnkit.com/favicon.svg" width="32" height="32" alt="BPMN Kit"></a>
129
+ </div>
package/dist/css.d.ts CHANGED
@@ -9,7 +9,7 @@ export declare function injectEditorStyles(): void;
9
9
  /** CSS for the editor HUD — panels, buttons, dropdowns, group picker.
10
10
  * Dark theme is the default. Light theme is activated by setting
11
11
  * `data-bpmnkit-hud-theme="light"` on `document.body`. */
12
- export declare const HUD_CSS = "\n/* \u2500\u2500 HUD base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.hud { position: absolute; z-index: 100; }\n\n/* \u2500\u2500 Dark theme (default) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.panel {\n display: flex; align-items: center; gap: 2px; padding: 4px;\n background: var(--bpmnkit-panel-bg, rgba(13, 13, 22, 0.92));\n backdrop-filter: blur(10px);\n border: 1px solid var(--bpmnkit-panel-border, rgba(255, 255, 255, 0.08));\n border-radius: 10px;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);\n}\n\n/* \u2500\u2500 HUD positions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#hud-top-center { top: 0; left: 50%; transform: translateX(-50%); height: 36px; }\n#hud-bottom-left { bottom: 10px; left: 10px; }\n#hud-bottom-center { bottom: 10px; left: 50%; transform: translateX(-50%); }\n#ctx-toolbar { display: none; transform: translateX(-50%); }\n#cfg-toolbar { display: none; transform: translate(-50%, -100%); }\n\n/* \u2500\u2500 Top center: strip floating card, merge into tab bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#hud-top-center.panel {\n background: transparent;\n backdrop-filter: none;\n border: none;\n border-radius: 0;\n box-shadow: none;\n padding: 0 2px;\n /* Pass clicks through the transparent background to the tab bar center slot. */\n pointer-events: none;\n}\n#hud-top-center.panel > * {\n pointer-events: auto;\n}\n\n/* \u2500\u2500 Icon buttons \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.hud-btn {\n display: flex; align-items: center; justify-content: center;\n width: 32px; height: 32px;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 6px;\n color: var(--bpmnkit-fg-muted, rgba(255,255,255,0.6));\n cursor: pointer;\n transition: background 0.1s, color 0.1s, border-color 0.1s;\n padding: 0; flex-shrink: 0;\n}\n.hud-btn:hover { background: rgba(255,255,255,0.08); color: var(--bpmnkit-fg, #cdd6f4); }\n.hud-btn.active { background: rgba(255,255,255,0.12); color: #fff; border-color: rgba(255,255,255,0.2); }\n.hud-btn:disabled { opacity: 0.28; cursor: default; }\n.hud-btn:disabled:hover { background: transparent; color: rgba(255,255,255,0.6); }\n.hud-btn svg { width: 16px; height: 16px; pointer-events: none; }\n\n/* \u2500\u2500 Group button: small chevron at bottom-right corner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.hud-btn[data-group] { position: relative; }\n.hud-btn[data-group]::after {\n content: '';\n position: absolute; bottom: 3px; right: 3px;\n width: 0; height: 0;\n border-left: 3px solid transparent;\n border-top: 3px solid currentColor;\n opacity: 0.55;\n}\n\n/* \u2500\u2500 Tool groups container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#tool-groups { display: flex; align-items: center; gap: 2px; }\n\n/* \u2500\u2500 Separator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.hud-sep { width: 1px; height: 20px; background: var(--bpmnkit-panel-border, rgba(255, 255, 255, 0.08)); margin: 0 2px; flex-shrink: 0; }\n\n/* \u2500\u2500 Zoom widget \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#btn-zoom-current {\n padding: 0 10px; height: 32px;\n background: transparent; border: 1px solid transparent; border-radius: 7px;\n color: rgba(255,255,255,0.6); cursor: pointer;\n font-size: 12px; font-weight: 600;\n transition: background 0.1s, color 0.1s;\n white-space: nowrap;\n}\n#btn-zoom-current:hover { background: rgba(255,255,255,0.08); color: #fff; }\n\n#zoom-expanded { display: none; align-items: center; gap: 2px; }\n#zoom-expanded.open { display: flex; }\n\n#btn-zoom-pct {\n padding: 0 8px; height: 30px;\n background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1); border-radius: 6px;\n color: rgba(255,255,255,0.75); cursor: pointer;\n font-size: 12px; font-weight: 600;\n transition: background 0.1s, color 0.1s;\n white-space: nowrap; min-width: 60px; text-align: center;\n}\n#btn-zoom-pct:hover { background: rgba(255,255,255,0.12); color: #fff; }\n\n/* \u2500\u2500 Dropdown menus \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.dropdown {\n position: absolute; display: none; flex-direction: column;\n gap: 1px; padding: 4px;\n background: var(--bpmnkit-panel-bg, rgba(13, 13, 22, 0.92));\n backdrop-filter: blur(12px);\n border: 1px solid var(--bpmnkit-panel-border, rgba(255, 255, 255, 0.08));\n border-radius: 9px;\n box-shadow: 0 6px 24px rgba(0,0,0,0.5);\n z-index: 200; min-width: 150px;\n}\n.dropdown.open { display: flex; }\n\n.drop-item {\n display: flex; align-items: center; gap: 8px;\n padding: 7px 10px;\n border: none; background: transparent;\n color: rgba(255,255,255,0.75); cursor: pointer;\n border-radius: 6px; font-size: 12px; text-align: left; width: 100%;\n transition: background 0.1s;\n}\n.drop-item:hover { background: rgba(255,255,255,0.08); color: #fff; }\n.drop-item .di-check { width: 14px; height: 14px; flex-shrink: 0; color: var(--bpmnkit-accent, #6b9df7); }\n.drop-item .di-icon { width: 14px; height: 14px; flex-shrink: 0; opacity: 0.7; }\n.drop-item svg { width: 14px; height: 14px; }\n.drop-sep { height: 1px; background: rgba(255,255,255,0.08); margin: 3px 0; }\n.drop-label {\n padding: 4px 10px 2px;\n font-size: 10px; font-weight: 600; letter-spacing: 0.06em;\n color: rgba(255,255,255,0.3); text-transform: uppercase;\n}\n\n/* \u2500\u2500 Group element picker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.group-picker {\n position: absolute;\n display: flex; flex-direction: row;\n gap: 2px; padding: 4px;\n background: var(--bpmnkit-panel-bg, rgba(13, 13, 22, 0.92));\n backdrop-filter: blur(12px);\n border: 1px solid var(--bpmnkit-panel-border, rgba(255, 255, 255, 0.08));\n border-radius: 9px;\n box-shadow: 0 6px 24px rgba(0,0,0,0.5);\n z-index: 300;\n}\n.group-picker-label {\n padding: 2px 6px 4px;\n font-size: 10px; font-weight: 600; letter-spacing: 0.05em;\n color: rgba(255,255,255,0.3); text-transform: uppercase;\n white-space: nowrap; align-self: center;\n border-right: 1px solid rgba(255,255,255,0.08);\n margin-right: 2px;\n}\n\n/* \u2500\u2500 Light theme overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n[data-bpmnkit-hud-theme=\"light\"] .panel {\n background: var(--bpmnkit-panel-bg, rgba(255,255,255,0.92));\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n}\n[data-bpmnkit-hud-theme=\"light\"] #hud-top-center.panel {\n background: transparent;\n backdrop-filter: none;\n border: none;\n box-shadow: none;\n}\n[data-bpmnkit-hud-theme=\"light\"] .hud-btn { color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] .hud-btn:hover { background: rgba(0,0,0,0.06); color: var(--bpmnkit-fg, #1a1a2e); }\n[data-bpmnkit-hud-theme=\"light\"] .hud-btn.active { background: rgba(0,0,0,0.08); color: var(--bpmnkit-fg, #1a1a2e); border-color: rgba(0,0,0,0.15); }\n[data-bpmnkit-hud-theme=\"light\"] .hud-btn:disabled:hover { background: transparent; color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] .hud-sep { background: var(--bpmnkit-panel-border, rgba(0,0,0,0.08)); }\n[data-bpmnkit-hud-theme=\"light\"] #btn-zoom-current { color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] #btn-zoom-current:hover { background: rgba(0,0,0,0.06); color: var(--bpmnkit-fg, #1a1a2e); }\n[data-bpmnkit-hud-theme=\"light\"] #btn-zoom-pct {\n background: rgba(0,0,0,0.04); border-color: rgba(0,0,0,0.1); color: var(--bpmnkit-fg-muted, #6666a0);\n}\n[data-bpmnkit-hud-theme=\"light\"] #btn-zoom-pct:hover { background: rgba(0,0,0,0.08); color: var(--bpmnkit-fg, #1a1a2e); }\n[data-bpmnkit-hud-theme=\"light\"] .dropdown {\n background: var(--bpmnkit-panel-bg, rgba(255,255,255,0.92));\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 6px 24px rgba(0,0,0,0.15);\n}\n[data-bpmnkit-hud-theme=\"light\"] .drop-item { color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] .drop-item:hover { background: rgba(0,0,0,0.05); color: var(--bpmnkit-fg, #1a1a2e); }\n[data-bpmnkit-hud-theme=\"light\"] .drop-sep { background: var(--bpmnkit-border, #d0d0e8); }\n[data-bpmnkit-hud-theme=\"light\"] .drop-label { color: rgba(0,0,0,0.35); }\n[data-bpmnkit-hud-theme=\"light\"] .group-picker {\n background: var(--bpmnkit-panel-bg, rgba(255,255,255,0.92));\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 6px 24px rgba(0,0,0,0.15);\n}\n[data-bpmnkit-hud-theme=\"light\"] .group-picker-label {\n color: rgba(0,0,0,0.35);\n border-right-color: rgba(0,0,0,0.08);\n}\n\n/* \u2500\u2500 Reference link button (wider text variant of hud-btn) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.ref-link-btn {\n height: 32px; padding: 0 8px;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 6px;\n color: rgba(255, 255, 255, 0.6);\n cursor: pointer;\n font-size: 12px;\n max-width: 160px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex-shrink: 0;\n transition: background 0.1s, color 0.1s;\n align-self: center;\n}\n.ref-link-btn:hover { background: rgba(255,255,255,0.08); color: #fff; }\n[data-bpmnkit-hud-theme=\"light\"] .ref-link-btn { color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] .ref-link-btn:hover { background: rgba(0,0,0,0.06); color: var(--bpmnkit-fg, #1a1a2e); }\n\n/* \u2500\u2500 Color swatches \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-color-swatches { display: flex; gap: 4px; padding: 2px 4px; align-items: center; }\n.bpmnkit-color-swatch {\n width: 16px; height: 16px; border-radius: 50%; cursor: pointer;\n border: 2px solid transparent; flex-shrink: 0;\n transition: transform 0.1s;\n padding: 0;\n}\n.bpmnkit-color-swatch:hover { transform: scale(1.2); }\n.bpmnkit-color-swatch.active { border-color: rgba(255,255,255,0.8); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-color-swatch.active { border-color: rgba(0,0,0,0.5); }\n.bpmnkit-color-swatch--default {\n background: transparent; border-color: rgba(255,255,255,0.25);\n position: relative; overflow: hidden;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-color-swatch--default { border-color: rgba(0,0,0,0.2); }\n.bpmnkit-color-swatch--default::after {\n content: ''; position: absolute;\n top: 1px; left: 50%; transform: translateX(-50%) rotate(-45deg);\n width: 1.5px; height: calc(100% - 2px);\n background: rgba(200,50,50,0.65); border-radius: 1px;\n}\n\n/* \u2500\u2500 Contextual Ask-AI button (tinted blue) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.ctx-ask-ai-btn { color: var(--bpmnkit-accent-bright, #89b4fa); opacity: 0.8; }\n.ctx-ask-ai-btn:hover { background: rgba(76, 142, 247, 0.15); color: #a8c8ff; opacity: 1; }\n[data-bpmnkit-hud-theme=\"light\"] .ctx-ask-ai-btn { color: var(--bpmnkit-accent, #1a56db); opacity: 0.7; }\n[data-bpmnkit-hud-theme=\"light\"] .ctx-ask-ai-btn:hover { background: var(--bpmnkit-accent-subtle, rgba(26,86,219,0.12)); color: var(--bpmnkit-accent, #1a56db); opacity: 1; }\n\n/* \u2500\u2500 New-diagram onboarding overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-empty-state {\n position: absolute; z-index: 50;\n top: 36px; left: 0; bottom: 0; right: 0;\n display: flex; align-items: center; justify-content: center;\n background: var(--bpmnkit-bg, #0d0d16);\n}\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-empty-state { background: var(--bpmnkit-bg, #f4f4f8); }\n\n.bpmnkit-onboard-inner {\n display: flex; flex-direction: column; align-items: center;\n gap: 28px; padding: 24px; max-width: 580px; width: 100%;\n}\n.bpmnkit-onboard-header { text-align: center; }\n.bpmnkit-onboard-title {\n color: rgba(255,255,255,0.82); font-size: 16px; font-weight: 600; margin: 0 0 7px;\n}\n.bpmnkit-onboard-sub {\n color: rgba(255,255,255,0.36); font-size: 13px; margin: 0;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-title { color: rgba(0,0,0,0.72); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-sub { color: rgba(0,0,0,0.38); }\n\n.bpmnkit-onboard-actions { display: flex; gap: 10px; width: 100%; }\n\n.bpmnkit-onboard-btn {\n flex: 1; display: flex; flex-direction: column; align-items: flex-start;\n gap: 10px; padding: 16px 14px;\n background: rgba(255,255,255,0.04);\n border: 1px solid rgba(255,255,255,0.07);\n border-radius: 10px; cursor: pointer; text-align: left;\n color: inherit; transition: background 0.15s, border-color 0.15s;\n}\n.bpmnkit-onboard-btn:hover {\n background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.14);\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn {\n background: rgba(0,0,0,0.03); border-color: rgba(0,0,0,0.08);\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn:hover {\n background: rgba(0,0,0,0.06); border-color: rgba(0,0,0,0.14);\n}\n\n.bpmnkit-onboard-btn-icon {\n display: flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; border-radius: 8px;\n background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.65); flex-shrink: 0;\n}\n.bpmnkit-onboard-btn-icon svg { width: 16px; height: 16px; pointer-events: none; }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn-icon {\n background: rgba(0,0,0,0.07); color: rgba(0,0,0,0.55);\n}\n\n.bpmnkit-onboard-btn--ai .bpmnkit-onboard-btn-icon {\n background: rgba(76,142,247,0.18); color: #8ab8ff;\n}\n.bpmnkit-onboard-btn--ai:hover { border-color: rgba(76,142,247,0.3); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn--ai .bpmnkit-onboard-btn-icon {\n background: rgba(26,86,219,0.1); color: #1a56db;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn--ai:hover { border-color: rgba(26,86,219,0.28); }\n\n.bpmnkit-onboard-btn-label { display: flex; flex-direction: column; gap: 3px; }\n.bpmnkit-onboard-btn-title {\n font-size: 13px; font-weight: 600; color: rgba(255,255,255,0.8); margin: 0;\n}\n.bpmnkit-onboard-btn-desc {\n font-size: 11px; color: rgba(255,255,255,0.32); margin: 0; line-height: 1.4;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn-title { color: rgba(0,0,0,0.72); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn-desc { color: rgba(0,0,0,0.36); }\n\n.bpmnkit-onboard-links { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }\n.bpmnkit-onboard-links a {\n color: rgba(255,255,255,0.22); font-size: 11px; text-decoration: none; transition: color 0.1s;\n}\n.bpmnkit-onboard-links a:hover { color: rgba(255,255,255,0.55); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-links a { color: rgba(0,0,0,0.25); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-links a:hover { color: rgba(0,0,0,0.6); }\n\n@media (max-width: 520px) {\n .bpmnkit-onboard-actions { flex-direction: column; }\n .bpmnkit-onboard-btn { flex-direction: row; align-items: center; gap: 12px; }\n .bpmnkit-onboard-btn-label { flex-direction: column; }\n}\n\n/* \u2500\u2500 Top-center overflow guard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#hud-top-center {\n max-width: calc(100% - 24px);\n overflow-x: auto; overflow-y: visible;\n scrollbar-width: none;\n}\n#hud-top-center::-webkit-scrollbar { display: none; }\n\n/* \u2500\u2500 Push HUD toolbar down when simulation banner is visible \u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sim-active #hud-top-center { top: 36px; }\n\n/* \u2500\u2500 Simulation active banner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-sim-banner {\n position: absolute;\n top: 0; left: 0; right: 0;\n z-index: 150;\n display: flex; align-items: center; justify-content: center; gap: 12px;\n padding: 7px 16px;\n background: rgba(217, 119, 6, 0.18);\n border-bottom: 1px solid rgba(217, 119, 6, 0.35);\n backdrop-filter: blur(6px);\n font-size: 12px; font-weight: 500;\n color: rgba(255, 193, 87, 0.95);\n pointer-events: auto;\n}\n#bpmnkit-sim-banner.hidden { display: none; }\n#bpmnkit-sim-banner-exit {\n padding: 3px 10px; border-radius: 5px;\n background: rgba(217, 119, 6, 0.22);\n border: 1px solid rgba(217, 119, 6, 0.4);\n color: inherit; cursor: pointer; font-size: 11px; font-weight: 600;\n transition: background 0.1s;\n}\n#bpmnkit-sim-banner-exit:hover { background: rgba(217, 119, 6, 0.35); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-sim-banner {\n background: rgba(254, 243, 199, 0.95);\n border-bottom-color: rgba(217, 119, 6, 0.25);\n color: #92400e;\n}\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-sim-banner-exit {\n background: rgba(217, 119, 6, 0.1); border-color: rgba(217, 119, 6, 0.3);\n}\n\n/* \u2500\u2500 Context menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-ctx-menu { min-width: 160px; }\n\n/* \u2500\u2500 Element search bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-search-bar {\n position: absolute;\n top: 44px; left: 50%; transform: translateX(-50%);\n z-index: 120;\n display: flex; align-items: center; gap: 6px;\n padding: 5px 10px;\n background: rgba(22, 22, 30, 0.92);\n backdrop-filter: blur(10px);\n border: 1px solid rgba(255,255,255,0.15);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0,0,0,0.4);\n}\n#bpmnkit-search-bar.hidden { display: none; }\n#bpmnkit-search-input {\n width: 220px; padding: 3px 6px;\n background: transparent; border: none;\n color: #fff; font-size: 13px; outline: none;\n}\n#bpmnkit-search-input::placeholder { color: rgba(255,255,255,0.35); }\n#bpmnkit-search-count {\n font-size: 11px; color: rgba(255,255,255,0.45); white-space: nowrap; min-width: 40px;\n}\n#bpmnkit-search-close {\n background: transparent; border: none; color: rgba(255,255,255,0.4);\n cursor: pointer; font-size: 16px; line-height: 1; padding: 0 2px;\n}\n#bpmnkit-search-close:hover { color: #fff; }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-bar {\n background: rgba(252, 252, 254, 0.96);\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 4px 16px rgba(0,0,0,0.12);\n}\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-input { color: rgba(0,0,0,0.9); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-input::placeholder { color: rgba(0,0,0,0.3); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-count { color: rgba(0,0,0,0.4); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-close { color: rgba(0,0,0,0.35); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-close:hover { color: rgba(0,0,0,0.8); }\n\n/* \u2500\u2500 Keyboard shortcuts modal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-shortcuts-modal {\n position: absolute; inset: 0; z-index: 200;\n display: flex; align-items: center; justify-content: center;\n background: rgba(0,0,0,0.55);\n backdrop-filter: blur(4px);\n}\n#bpmnkit-shortcuts-modal.hidden { display: none; }\n#bpmnkit-shortcuts-inner {\n background: var(--bpmnkit-surface-2, #1e1e2e);\n border: 1px solid var(--bpmnkit-panel-border, rgba(255,255,255,0.08));\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.5);\n padding: 20px 24px;\n min-width: 320px; max-width: 480px;\n color: rgba(255,255,255,0.85);\n}\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-shortcuts-inner {\n background: var(--bpmnkit-surface, #fff);\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 8px 32px rgba(0,0,0,0.15);\n color: rgba(0,0,0,0.8);\n}\n#bpmnkit-shortcuts-inner h3 { margin: 0 0 14px; font-size: 14px; font-weight: 700; }\n.bpmnkit-sc-row {\n display: flex; justify-content: space-between; align-items: center;\n padding: 5px 0; border-bottom: 1px solid rgba(255,255,255,0.06); font-size: 12px;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-sc-row { border-bottom-color: rgba(0,0,0,0.06); }\n.bpmnkit-sc-row:last-child { border-bottom: none; }\n.bpmnkit-sc-key {\n font-family: var(--font-mono, monospace);\n background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.12);\n border-radius: 4px; padding: 1px 6px; font-size: 11px;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-sc-key {\n background: rgba(0,0,0,0.06); border-color: rgba(0,0,0,0.12); color: rgba(0,0,0,0.7);\n}\n#bpmnkit-shortcuts-close {\n display: block; margin: 14px auto 0; padding: 6px 20px;\n background: var(--bpmnkit-surface-2, rgba(255,255,255,0.08)); border: 1px solid var(--bpmnkit-panel-border, rgba(255,255,255,0.08));\n border-radius: 6px; color: rgba(255,255,255,0.7); cursor: pointer; font-size: 12px;\n transition: background 0.1s;\n}\n#bpmnkit-shortcuts-close:hover { background: rgba(255,255,255,0.14); color: #fff; }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-shortcuts-close {\n background: var(--bpmnkit-surface-2, rgba(0,0,0,0.05)); border-color: var(--bpmnkit-border, #d0d0e8); color: rgba(0,0,0,0.6);\n}\n\n/* \u2500\u2500 Mobile: collapsible center toolbars \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#btn-bc-toggle, #btn-tc-toggle { display: none; }\n\n@media (max-width: 600px) {\n #btn-bc-toggle, #btn-tc-toggle { display: flex; }\n\n /* Collapsed: hide all children except the toggle button */\n #hud-bottom-center:not(.expanded) > *:not(#btn-bc-toggle) { display: none; }\n #hud-top-center:not(.expanded) > *:not(#btn-tc-toggle) { display: none; }\n\n /* Expanded: highlight the toggle button as a close affordance */\n #hud-bottom-center.expanded #btn-bc-toggle,\n #hud-top-center.expanded #btn-tc-toggle {\n background: rgba(255,255,255,0.08); color: #fff;\n }\n [data-bpmnkit-hud-theme=\"light\"] #hud-bottom-center.expanded #btn-bc-toggle,\n [data-bpmnkit-hud-theme=\"light\"] #hud-top-center.expanded #btn-tc-toggle {\n background: rgba(0,0,0,0.06); color: rgba(0,0,0,0.9);\n }\n}\n\n/* Hide bottom toolbar on welcome screen */\n.bpmnkit-welcome-active #hud-bottom-center { display: none !important; }\n";
12
+ export declare const HUD_CSS = "\n/* \u2500\u2500 HUD base \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.hud { position: absolute; z-index: 100; }\n\n/* \u2500\u2500 Dark theme (default) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.panel {\n display: flex; align-items: center; gap: 2px; padding: 4px;\n background: var(--bpmnkit-panel-bg, rgba(13, 13, 22, 0.92));\n backdrop-filter: blur(10px);\n border: 1px solid var(--bpmnkit-panel-border, rgba(255, 255, 255, 0.08));\n border-radius: 10px;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);\n}\n\n/* \u2500\u2500 HUD positions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#hud-top-center { top: 0; left: 50%; transform: translateX(-50%); height: 36px; }\n#hud-bottom-left { bottom: 10px; left: 10px; }\n#hud-bottom-center { bottom: 10px; left: 50%; transform: translateX(-50%); }\n#ctx-toolbar { display: none; transform: translateX(-50%); }\n#cfg-toolbar { display: none; transform: translate(-50%, -100%); }\n\n/* \u2500\u2500 Top center: strip floating card, merge into tab bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#hud-top-center.panel {\n background: transparent;\n backdrop-filter: none;\n border: none;\n border-radius: 0;\n box-shadow: none;\n padding: 0 2px;\n /* Pass clicks through the transparent background to the tab bar center slot. */\n pointer-events: none;\n}\n#hud-top-center.panel > * {\n pointer-events: auto;\n}\n\n/* \u2500\u2500 Icon buttons \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.hud-btn {\n display: flex; align-items: center; justify-content: center;\n width: 32px; height: 32px;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 6px;\n color: var(--bpmnkit-fg-muted, rgba(255,255,255,0.6));\n cursor: pointer;\n transition: background 0.1s, color 0.1s, border-color 0.1s;\n padding: 0; flex-shrink: 0;\n}\n.hud-btn:hover { background: rgba(255,255,255,0.08); color: var(--bpmnkit-fg, #cdd6f4); }\n.hud-btn.active { background: rgba(255,255,255,0.12); color: #fff; border-color: rgba(255,255,255,0.2); }\n.hud-btn:disabled { opacity: 0.28; cursor: default; }\n.hud-btn:disabled:hover { background: transparent; color: rgba(255,255,255,0.6); }\n.hud-btn svg { width: 16px; height: 16px; pointer-events: none; }\n\n/* \u2500\u2500 Group button: small chevron at bottom-right corner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.hud-btn[data-group] { position: relative; }\n.hud-btn[data-group]::after {\n content: '';\n position: absolute; bottom: 3px; right: 3px;\n width: 0; height: 0;\n border-left: 3px solid transparent;\n border-top: 3px solid currentColor;\n opacity: 0.55;\n}\n\n/* \u2500\u2500 Tool groups container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#tool-groups { display: flex; align-items: center; gap: 2px; }\n\n/* \u2500\u2500 Separator \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.hud-sep { width: 1px; height: 20px; background: var(--bpmnkit-panel-border, rgba(255, 255, 255, 0.08)); margin: 0 2px; flex-shrink: 0; }\n\n/* \u2500\u2500 Zoom widget \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#btn-zoom-current {\n padding: 0 10px; height: 32px;\n background: transparent; border: 1px solid transparent; border-radius: 7px;\n color: rgba(255,255,255,0.6); cursor: pointer;\n font-size: 12px; font-weight: 600;\n transition: background 0.1s, color 0.1s;\n white-space: nowrap;\n}\n#btn-zoom-current:hover { background: rgba(255,255,255,0.08); color: #fff; }\n\n#zoom-expanded { display: none; align-items: center; gap: 2px; }\n#zoom-expanded.open { display: flex; }\n\n#btn-zoom-pct {\n padding: 0 8px; height: 30px;\n background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.1); border-radius: 6px;\n color: rgba(255,255,255,0.75); cursor: pointer;\n font-size: 12px; font-weight: 600;\n transition: background 0.1s, color 0.1s;\n white-space: nowrap; min-width: 60px; text-align: center;\n}\n#btn-zoom-pct:hover { background: rgba(255,255,255,0.12); color: #fff; }\n\n/* \u2500\u2500 Dropdown menus \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.dropdown {\n position: absolute; display: none; flex-direction: column;\n gap: 1px; padding: 4px;\n background: var(--bpmnkit-panel-bg, rgba(13, 13, 22, 0.92));\n backdrop-filter: blur(12px);\n border: 1px solid var(--bpmnkit-panel-border, rgba(255, 255, 255, 0.08));\n border-radius: 9px;\n box-shadow: 0 6px 24px rgba(0,0,0,0.5);\n z-index: 200; min-width: 150px;\n}\n.dropdown.open { display: flex; }\n\n.drop-item {\n display: flex; align-items: center; gap: 8px;\n padding: 7px 10px;\n border: none; background: transparent;\n color: rgba(255,255,255,0.75); cursor: pointer;\n border-radius: 6px; font-size: 12px; text-align: left; width: 100%;\n transition: background 0.1s;\n}\n.drop-item:hover { background: rgba(255,255,255,0.08); color: #fff; }\n.drop-item .di-check { width: 14px; height: 14px; flex-shrink: 0; color: var(--bpmnkit-accent, #6b9df7); }\n.drop-item .di-icon { width: 14px; height: 14px; flex-shrink: 0; opacity: 0.7; }\n.drop-item svg { width: 14px; height: 14px; }\n.drop-sep { height: 1px; background: rgba(255,255,255,0.08); margin: 3px 0; }\n.drop-label {\n padding: 4px 10px 2px;\n font-size: 10px; font-weight: 600; letter-spacing: 0.06em;\n color: rgba(255,255,255,0.3); text-transform: uppercase;\n}\n\n/* \u2500\u2500 Group element picker \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.group-picker {\n position: absolute;\n display: flex; flex-direction: row;\n gap: 2px; padding: 4px;\n background: var(--bpmnkit-panel-bg, rgba(13, 13, 22, 0.92));\n backdrop-filter: blur(12px);\n border: 1px solid var(--bpmnkit-panel-border, rgba(255, 255, 255, 0.08));\n border-radius: 9px;\n box-shadow: 0 6px 24px rgba(0,0,0,0.5);\n z-index: 300;\n}\n.group-picker-label {\n padding: 2px 6px 4px;\n font-size: 10px; font-weight: 600; letter-spacing: 0.05em;\n color: rgba(255,255,255,0.3); text-transform: uppercase;\n white-space: nowrap; align-self: center;\n border-right: 1px solid rgba(255,255,255,0.08);\n margin-right: 2px;\n}\n\n/* \u2500\u2500 Light theme overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n[data-bpmnkit-hud-theme=\"light\"] .panel {\n background: var(--bpmnkit-panel-bg, rgba(255,255,255,0.92));\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n}\n[data-bpmnkit-hud-theme=\"light\"] #hud-top-center.panel {\n background: transparent;\n backdrop-filter: none;\n border: none;\n box-shadow: none;\n}\n[data-bpmnkit-hud-theme=\"light\"] .hud-btn { color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] .hud-btn:hover { background: rgba(0,0,0,0.06); color: var(--bpmnkit-fg, #1a1a2e); }\n[data-bpmnkit-hud-theme=\"light\"] .hud-btn.active { background: rgba(0,0,0,0.08); color: var(--bpmnkit-fg, #1a1a2e); border-color: rgba(0,0,0,0.15); }\n[data-bpmnkit-hud-theme=\"light\"] .hud-btn:disabled:hover { background: transparent; color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] .hud-sep { background: var(--bpmnkit-panel-border, rgba(0,0,0,0.08)); }\n[data-bpmnkit-hud-theme=\"light\"] #btn-zoom-current { color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] #btn-zoom-current:hover { background: rgba(0,0,0,0.06); color: var(--bpmnkit-fg, #1a1a2e); }\n[data-bpmnkit-hud-theme=\"light\"] #btn-zoom-pct {\n background: rgba(0,0,0,0.04); border-color: rgba(0,0,0,0.1); color: var(--bpmnkit-fg-muted, #6666a0);\n}\n[data-bpmnkit-hud-theme=\"light\"] #btn-zoom-pct:hover { background: rgba(0,0,0,0.08); color: var(--bpmnkit-fg, #1a1a2e); }\n[data-bpmnkit-hud-theme=\"light\"] .dropdown {\n background: var(--bpmnkit-panel-bg, rgba(255,255,255,0.92));\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 6px 24px rgba(0,0,0,0.15);\n}\n[data-bpmnkit-hud-theme=\"light\"] .drop-item { color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] .drop-item:hover { background: rgba(0,0,0,0.05); color: var(--bpmnkit-fg, #1a1a2e); }\n[data-bpmnkit-hud-theme=\"light\"] .drop-sep { background: var(--bpmnkit-border, #d0d0e8); }\n[data-bpmnkit-hud-theme=\"light\"] .drop-label { color: rgba(0,0,0,0.35); }\n[data-bpmnkit-hud-theme=\"light\"] .group-picker {\n background: var(--bpmnkit-panel-bg, rgba(255,255,255,0.92));\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 6px 24px rgba(0,0,0,0.15);\n}\n[data-bpmnkit-hud-theme=\"light\"] .group-picker-label {\n color: rgba(0,0,0,0.35);\n border-right-color: rgba(0,0,0,0.08);\n}\n\n/* \u2500\u2500 Neon theme overrides \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n[data-bpmnkit-hud-theme=\"neon\"] .panel {\n background: oklch(8% 0.03 270 / 0.96);\n border-color: oklch(65% 0.28 280 / 0.2);\n box-shadow: 0 2px 16px oklch(65% 0.28 280 / 0.12), 0 0 0 1px oklch(65% 0.28 280 / 0.1);\n}\n[data-bpmnkit-hud-theme=\"neon\"] #hud-top-center.panel {\n background: transparent; backdrop-filter: none; border: none; box-shadow: none;\n}\n[data-bpmnkit-hud-theme=\"neon\"] .hud-btn { color: oklch(65% 0.1 280); }\n[data-bpmnkit-hud-theme=\"neon\"] .hud-btn:hover { background: oklch(65% 0.28 280 / 0.12); color: oklch(88% 0.02 270); }\n[data-bpmnkit-hud-theme=\"neon\"] .hud-btn.active { background: oklch(65% 0.28 280 / 0.18); color: oklch(73% 0.16 280); border-color: oklch(65% 0.28 280 / 0.35); }\n[data-bpmnkit-hud-theme=\"neon\"] .hud-sep { background: oklch(65% 0.28 280 / 0.15); }\n[data-bpmnkit-hud-theme=\"neon\"] .dropdown {\n background: oklch(8% 0.03 270 / 0.97);\n border-color: oklch(65% 0.28 280 / 0.2);\n box-shadow: 0 6px 24px oklch(0% 0 0 / 0.6), 0 0 0 1px oklch(65% 0.28 280 / 0.1);\n}\n[data-bpmnkit-hud-theme=\"neon\"] .drop-item { color: oklch(65% 0.1 280); }\n[data-bpmnkit-hud-theme=\"neon\"] .drop-item:hover { background: oklch(65% 0.28 280 / 0.1); color: oklch(88% 0.02 270); }\n[data-bpmnkit-hud-theme=\"neon\"] .drop-sep { background: oklch(65% 0.28 280 / 0.15); }\n[data-bpmnkit-hud-theme=\"neon\"] .drop-label { color: oklch(50% 0.06 280); }\n[data-bpmnkit-hud-theme=\"neon\"] .group-picker {\n background: oklch(8% 0.03 270 / 0.97);\n border-color: oklch(65% 0.28 280 / 0.2);\n box-shadow: 0 6px 24px oklch(0% 0 0 / 0.6);\n}\n[data-bpmnkit-hud-theme=\"neon\"] .group-picker-label { color: oklch(50% 0.06 280); border-right-color: oklch(65% 0.28 280 / 0.15); }\n\n/* \u2500\u2500 Reference link button (wider text variant of hud-btn) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.ref-link-btn {\n height: 32px; padding: 0 8px;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 6px;\n color: rgba(255, 255, 255, 0.6);\n cursor: pointer;\n font-size: 12px;\n max-width: 160px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex-shrink: 0;\n transition: background 0.1s, color 0.1s;\n align-self: center;\n}\n.ref-link-btn:hover { background: rgba(255,255,255,0.08); color: #fff; }\n[data-bpmnkit-hud-theme=\"light\"] .ref-link-btn { color: var(--bpmnkit-fg-muted, #6666a0); }\n[data-bpmnkit-hud-theme=\"light\"] .ref-link-btn:hover { background: rgba(0,0,0,0.06); color: var(--bpmnkit-fg, #1a1a2e); }\n\n/* \u2500\u2500 Color swatches \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-color-swatches { display: flex; gap: 4px; padding: 2px 4px; align-items: center; }\n.bpmnkit-color-swatch {\n width: 16px; height: 16px; border-radius: 50%; cursor: pointer;\n border: 2px solid transparent; flex-shrink: 0;\n transition: transform 0.1s;\n padding: 0;\n}\n.bpmnkit-color-swatch:hover { transform: scale(1.2); }\n.bpmnkit-color-swatch.active { border-color: rgba(255,255,255,0.8); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-color-swatch.active { border-color: rgba(0,0,0,0.5); }\n.bpmnkit-color-swatch--default {\n background: transparent; border-color: rgba(255,255,255,0.25);\n position: relative; overflow: hidden;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-color-swatch--default { border-color: rgba(0,0,0,0.2); }\n.bpmnkit-color-swatch--default::after {\n content: ''; position: absolute;\n top: 1px; left: 50%; transform: translateX(-50%) rotate(-45deg);\n width: 1.5px; height: calc(100% - 2px);\n background: rgba(200,50,50,0.65); border-radius: 1px;\n}\n\n/* \u2500\u2500 Contextual Ask-AI button (tinted blue) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.ctx-ask-ai-btn { color: var(--bpmnkit-accent-bright, #89b4fa); opacity: 0.8; }\n.ctx-ask-ai-btn:hover { background: rgba(76, 142, 247, 0.15); color: #a8c8ff; opacity: 1; }\n[data-bpmnkit-hud-theme=\"light\"] .ctx-ask-ai-btn { color: var(--bpmnkit-accent, #1a56db); opacity: 0.7; }\n[data-bpmnkit-hud-theme=\"light\"] .ctx-ask-ai-btn:hover { background: var(--bpmnkit-accent-subtle, rgba(26,86,219,0.12)); color: var(--bpmnkit-accent, #1a56db); opacity: 1; }\n\n/* \u2500\u2500 New-diagram onboarding overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-empty-state {\n position: absolute; z-index: 50;\n top: 36px; left: 0; bottom: 0; right: 0;\n display: flex; align-items: center; justify-content: center;\n background: var(--bpmnkit-bg, #0d0d16);\n}\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-empty-state { background: var(--bpmnkit-bg, #f4f4f8); }\n\n.bpmnkit-onboard-inner {\n display: flex; flex-direction: column; align-items: center;\n gap: 28px; padding: 24px; max-width: 580px; width: 100%;\n}\n.bpmnkit-onboard-header { text-align: center; }\n.bpmnkit-onboard-title {\n color: rgba(255,255,255,0.82); font-size: 16px; font-weight: 600; margin: 0 0 7px;\n}\n.bpmnkit-onboard-sub {\n color: rgba(255,255,255,0.36); font-size: 13px; margin: 0;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-title { color: rgba(0,0,0,0.72); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-sub { color: rgba(0,0,0,0.38); }\n\n.bpmnkit-onboard-actions { display: flex; gap: 10px; width: 100%; }\n\n.bpmnkit-onboard-btn {\n flex: 1; display: flex; flex-direction: column; align-items: flex-start;\n gap: 10px; padding: 16px 14px;\n background: rgba(255,255,255,0.04);\n border: 1px solid rgba(255,255,255,0.07);\n border-radius: 10px; cursor: pointer; text-align: left;\n color: inherit; transition: background 0.15s, border-color 0.15s;\n}\n.bpmnkit-onboard-btn:hover {\n background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.14);\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn {\n background: rgba(0,0,0,0.03); border-color: rgba(0,0,0,0.08);\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn:hover {\n background: rgba(0,0,0,0.06); border-color: rgba(0,0,0,0.14);\n}\n\n.bpmnkit-onboard-btn-icon {\n display: flex; align-items: center; justify-content: center;\n width: 32px; height: 32px; border-radius: 8px;\n background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.65); flex-shrink: 0;\n}\n.bpmnkit-onboard-btn-icon svg { width: 16px; height: 16px; pointer-events: none; }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn-icon {\n background: rgba(0,0,0,0.07); color: rgba(0,0,0,0.55);\n}\n\n.bpmnkit-onboard-btn--ai .bpmnkit-onboard-btn-icon {\n background: rgba(76,142,247,0.18); color: #8ab8ff;\n}\n.bpmnkit-onboard-btn--ai:hover { border-color: rgba(76,142,247,0.3); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn--ai .bpmnkit-onboard-btn-icon {\n background: rgba(26,86,219,0.1); color: #1a56db;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn--ai:hover { border-color: rgba(26,86,219,0.28); }\n\n.bpmnkit-onboard-btn-label { display: flex; flex-direction: column; gap: 3px; }\n.bpmnkit-onboard-btn-title {\n font-size: 13px; font-weight: 600; color: rgba(255,255,255,0.8); margin: 0;\n}\n.bpmnkit-onboard-btn-desc {\n font-size: 11px; color: rgba(255,255,255,0.32); margin: 0; line-height: 1.4;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn-title { color: rgba(0,0,0,0.72); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-btn-desc { color: rgba(0,0,0,0.36); }\n\n.bpmnkit-onboard-links { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }\n.bpmnkit-onboard-links a {\n color: rgba(255,255,255,0.22); font-size: 11px; text-decoration: none; transition: color 0.1s;\n}\n.bpmnkit-onboard-links a:hover { color: rgba(255,255,255,0.55); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-links a { color: rgba(0,0,0,0.25); }\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-onboard-links a:hover { color: rgba(0,0,0,0.6); }\n\n@media (max-width: 520px) {\n .bpmnkit-onboard-actions { flex-direction: column; }\n .bpmnkit-onboard-btn { flex-direction: row; align-items: center; gap: 12px; }\n .bpmnkit-onboard-btn-label { flex-direction: column; }\n}\n\n/* \u2500\u2500 Top-center overflow guard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#hud-top-center {\n max-width: calc(100% - 24px);\n overflow-x: auto; overflow-y: visible;\n scrollbar-width: none;\n}\n#hud-top-center::-webkit-scrollbar { display: none; }\n\n/* \u2500\u2500 Push HUD toolbar down when simulation banner is visible \u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.bpmnkit-sim-active #hud-top-center { top: 36px; }\n\n/* \u2500\u2500 Simulation active banner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-sim-banner {\n position: absolute;\n top: 0; left: 0; right: 0;\n z-index: 150;\n display: flex; align-items: center; justify-content: center; gap: 12px;\n padding: 7px 16px;\n background: rgba(217, 119, 6, 0.18);\n border-bottom: 1px solid rgba(217, 119, 6, 0.35);\n backdrop-filter: blur(6px);\n font-size: 12px; font-weight: 500;\n color: rgba(255, 193, 87, 0.95);\n pointer-events: auto;\n}\n#bpmnkit-sim-banner.hidden { display: none; }\n#bpmnkit-sim-banner-exit {\n padding: 3px 10px; border-radius: 5px;\n background: rgba(217, 119, 6, 0.22);\n border: 1px solid rgba(217, 119, 6, 0.4);\n color: inherit; cursor: pointer; font-size: 11px; font-weight: 600;\n transition: background 0.1s;\n}\n#bpmnkit-sim-banner-exit:hover { background: rgba(217, 119, 6, 0.35); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-sim-banner {\n background: rgba(254, 243, 199, 0.95);\n border-bottom-color: rgba(217, 119, 6, 0.25);\n color: #92400e;\n}\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-sim-banner-exit {\n background: rgba(217, 119, 6, 0.1); border-color: rgba(217, 119, 6, 0.3);\n}\n\n/* \u2500\u2500 Context menu \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-ctx-menu { min-width: 160px; }\n\n/* \u2500\u2500 Element search bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-search-bar {\n position: absolute;\n top: 44px; left: 50%; transform: translateX(-50%);\n z-index: 120;\n display: flex; align-items: center; gap: 6px;\n padding: 5px 10px;\n background: rgba(22, 22, 30, 0.92);\n backdrop-filter: blur(10px);\n border: 1px solid rgba(255,255,255,0.15);\n border-radius: 8px;\n box-shadow: 0 4px 16px rgba(0,0,0,0.4);\n}\n#bpmnkit-search-bar.hidden { display: none; }\n#bpmnkit-search-input {\n width: 220px; padding: 3px 6px;\n background: transparent; border: none;\n color: #fff; font-size: 13px; outline: none;\n}\n#bpmnkit-search-input::placeholder { color: rgba(255,255,255,0.35); }\n#bpmnkit-search-count {\n font-size: 11px; color: rgba(255,255,255,0.45); white-space: nowrap; min-width: 40px;\n}\n#bpmnkit-search-close {\n background: transparent; border: none; color: rgba(255,255,255,0.4);\n cursor: pointer; font-size: 16px; line-height: 1; padding: 0 2px;\n}\n#bpmnkit-search-close:hover { color: #fff; }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-bar {\n background: rgba(252, 252, 254, 0.96);\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 4px 16px rgba(0,0,0,0.12);\n}\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-input { color: rgba(0,0,0,0.9); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-input::placeholder { color: rgba(0,0,0,0.3); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-count { color: rgba(0,0,0,0.4); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-close { color: rgba(0,0,0,0.35); }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-search-close:hover { color: rgba(0,0,0,0.8); }\n\n/* \u2500\u2500 Keyboard shortcuts modal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#bpmnkit-shortcuts-modal {\n position: absolute; inset: 0; z-index: 200;\n display: flex; align-items: center; justify-content: center;\n background: rgba(0,0,0,0.55);\n backdrop-filter: blur(4px);\n}\n#bpmnkit-shortcuts-modal.hidden { display: none; }\n#bpmnkit-shortcuts-inner {\n background: var(--bpmnkit-surface-2, #1e1e2e);\n border: 1px solid var(--bpmnkit-panel-border, rgba(255,255,255,0.08));\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.5);\n padding: 20px 24px;\n min-width: 320px; max-width: 480px;\n color: rgba(255,255,255,0.85);\n}\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-shortcuts-inner {\n background: var(--bpmnkit-surface, #fff);\n border-color: var(--bpmnkit-panel-border, rgba(0,0,0,0.08));\n box-shadow: 0 8px 32px rgba(0,0,0,0.15);\n color: rgba(0,0,0,0.8);\n}\n#bpmnkit-shortcuts-inner h3 { margin: 0 0 14px; font-size: 14px; font-weight: 700; }\n.bpmnkit-sc-row {\n display: flex; justify-content: space-between; align-items: center;\n padding: 5px 0; border-bottom: 1px solid rgba(255,255,255,0.06); font-size: 12px;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-sc-row { border-bottom-color: rgba(0,0,0,0.06); }\n.bpmnkit-sc-row:last-child { border-bottom: none; }\n.bpmnkit-sc-key {\n font-family: var(--font-mono, monospace);\n background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.12);\n border-radius: 4px; padding: 1px 6px; font-size: 11px;\n}\n[data-bpmnkit-hud-theme=\"light\"] .bpmnkit-sc-key {\n background: rgba(0,0,0,0.06); border-color: rgba(0,0,0,0.12); color: rgba(0,0,0,0.7);\n}\n#bpmnkit-shortcuts-close {\n display: block; margin: 14px auto 0; padding: 6px 20px;\n background: var(--bpmnkit-surface-2, rgba(255,255,255,0.08)); border: 1px solid var(--bpmnkit-panel-border, rgba(255,255,255,0.08));\n border-radius: 6px; color: rgba(255,255,255,0.7); cursor: pointer; font-size: 12px;\n transition: background 0.1s;\n}\n#bpmnkit-shortcuts-close:hover { background: rgba(255,255,255,0.14); color: #fff; }\n[data-bpmnkit-hud-theme=\"light\"] #bpmnkit-shortcuts-close {\n background: var(--bpmnkit-surface-2, rgba(0,0,0,0.05)); border-color: var(--bpmnkit-border, #d0d0e8); color: rgba(0,0,0,0.6);\n}\n\n/* \u2500\u2500 Mobile: collapsible center toolbars \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n#btn-bc-toggle, #btn-tc-toggle { display: none; }\n\n@media (max-width: 600px) {\n #btn-bc-toggle, #btn-tc-toggle { display: flex; }\n\n /* Collapsed: hide all children except the toggle button */\n #hud-bottom-center:not(.expanded) > *:not(#btn-bc-toggle) { display: none; }\n #hud-top-center:not(.expanded) > *:not(#btn-tc-toggle) { display: none; }\n\n /* Expanded: highlight the toggle button as a close affordance */\n #hud-bottom-center.expanded #btn-bc-toggle,\n #hud-top-center.expanded #btn-tc-toggle {\n background: rgba(255,255,255,0.08); color: #fff;\n }\n [data-bpmnkit-hud-theme=\"light\"] #hud-bottom-center.expanded #btn-bc-toggle,\n [data-bpmnkit-hud-theme=\"light\"] #hud-top-center.expanded #btn-tc-toggle {\n background: rgba(0,0,0,0.06); color: rgba(0,0,0,0.9);\n }\n}\n\n/* Hide bottom toolbar on welcome screen */\n.bpmnkit-welcome-active #hud-bottom-center { display: none !important; }\n";
13
13
  /** Injects the HUD stylesheet into `<head>` if not already present. */
14
14
  export declare function injectHudStyles(): void;
15
15
  //# sourceMappingURL=css.d.ts.map
package/dist/css.js CHANGED
@@ -414,6 +414,35 @@ export const HUD_CSS = `
414
414
  border-right-color: rgba(0,0,0,0.08);
415
415
  }
416
416
 
417
+ /* ── Neon theme overrides ────────────────────────────────────────── */
418
+ [data-bpmnkit-hud-theme="neon"] .panel {
419
+ background: oklch(8% 0.03 270 / 0.96);
420
+ border-color: oklch(65% 0.28 280 / 0.2);
421
+ box-shadow: 0 2px 16px oklch(65% 0.28 280 / 0.12), 0 0 0 1px oklch(65% 0.28 280 / 0.1);
422
+ }
423
+ [data-bpmnkit-hud-theme="neon"] #hud-top-center.panel {
424
+ background: transparent; backdrop-filter: none; border: none; box-shadow: none;
425
+ }
426
+ [data-bpmnkit-hud-theme="neon"] .hud-btn { color: oklch(65% 0.1 280); }
427
+ [data-bpmnkit-hud-theme="neon"] .hud-btn:hover { background: oklch(65% 0.28 280 / 0.12); color: oklch(88% 0.02 270); }
428
+ [data-bpmnkit-hud-theme="neon"] .hud-btn.active { background: oklch(65% 0.28 280 / 0.18); color: oklch(73% 0.16 280); border-color: oklch(65% 0.28 280 / 0.35); }
429
+ [data-bpmnkit-hud-theme="neon"] .hud-sep { background: oklch(65% 0.28 280 / 0.15); }
430
+ [data-bpmnkit-hud-theme="neon"] .dropdown {
431
+ background: oklch(8% 0.03 270 / 0.97);
432
+ border-color: oklch(65% 0.28 280 / 0.2);
433
+ box-shadow: 0 6px 24px oklch(0% 0 0 / 0.6), 0 0 0 1px oklch(65% 0.28 280 / 0.1);
434
+ }
435
+ [data-bpmnkit-hud-theme="neon"] .drop-item { color: oklch(65% 0.1 280); }
436
+ [data-bpmnkit-hud-theme="neon"] .drop-item:hover { background: oklch(65% 0.28 280 / 0.1); color: oklch(88% 0.02 270); }
437
+ [data-bpmnkit-hud-theme="neon"] .drop-sep { background: oklch(65% 0.28 280 / 0.15); }
438
+ [data-bpmnkit-hud-theme="neon"] .drop-label { color: oklch(50% 0.06 280); }
439
+ [data-bpmnkit-hud-theme="neon"] .group-picker {
440
+ background: oklch(8% 0.03 270 / 0.97);
441
+ border-color: oklch(65% 0.28 280 / 0.2);
442
+ box-shadow: 0 6px 24px oklch(0% 0 0 / 0.6);
443
+ }
444
+ [data-bpmnkit-hud-theme="neon"] .group-picker-label { color: oklch(50% 0.06 280); border-right-color: oklch(65% 0.28 280 / 0.15); }
445
+
417
446
  /* ── Reference link button (wider text variant of hud-btn) ──────── */
418
447
  .ref-link-btn {
419
448
  height: 32px; padding: 0 8px;
package/dist/dock.js CHANGED
@@ -100,6 +100,30 @@ const DOCK_CSS = `
100
100
  [data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__info-value { color: rgba(0,0,0,0.75); }
101
101
  [data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__info-row { border-bottom-color: rgba(0,0,0,0.06); }
102
102
  [data-bpmnkit-hud-theme="light"] .bpmnkit-side-dock__empty-hint { color: rgba(0,0,0,0.25); }
103
+ /* Neon theme */
104
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock {
105
+ background: oklch(6% 0.04 280);
106
+ border-left: 1px solid oklch(65% 0.28 280 / 0.35);
107
+ box-shadow: -8px 0 40px oklch(0% 0 0 / 0.8), -1px 0 20px oklch(65% 0.28 280 / 0.12);
108
+ }
109
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__collapse-handle {
110
+ background: oklch(6% 0.04 280);
111
+ border-color: oklch(65% 0.28 280 / 0.35);
112
+ color: oklch(65% 0.28 280 / 0.6);
113
+ }
114
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__collapse-handle:hover {
115
+ background: oklch(12% 0.04 270 / 0.99);
116
+ color: oklch(73% 0.16 280);
117
+ }
118
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__tab-strip { border-bottom-color: oklch(65% 0.28 280 / 0.25); }
119
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__tab { color: oklch(50% 0.1 280); }
120
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__tab:hover { color: oklch(73% 0.16 280); }
121
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__tab.active { color: oklch(72% 0.18 185); border-bottom-color: oklch(72% 0.18 185); }
122
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__resize-handle:hover { background: oklch(65% 0.28 280 / 0.25); }
123
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__info-label { color: oklch(50% 0.06 280); }
124
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__info-value { color: oklch(73% 0.16 280); }
125
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__info-row { border-bottom-color: oklch(65% 0.28 280 / 0.1); }
126
+ [data-bpmnkit-hud-theme="neon"] .bpmnkit-side-dock__empty-hint { color: oklch(45% 0.08 280); }
103
127
  `;
104
128
  function injectDockStyles() {
105
129
  if (document.getElementById(DOCK_STYLE_ID))
package/dist/editor.d.ts CHANGED
@@ -69,7 +69,7 @@ export declare class BpmnEditor {
69
69
  fitView(padding?: number): void;
70
70
  /** The host element that receives the `data-theme` attribute. */
71
71
  get container(): HTMLElement;
72
- getTheme(): "light" | "dark";
72
+ getTheme(): "light" | "dark" | "neon";
73
73
  setTheme(theme: Theme): void;
74
74
  zoomIn(): void;
75
75
  zoomOut(): void;
@@ -111,7 +111,7 @@ export declare class BpmnEditor {
111
111
  * using smart placement (right → bottom → top, avoids overlaps).
112
112
  * Returns the new element's id.
113
113
  */
114
- addConnectedElement(sourceId: string, type: CreateShapeType): string | null;
114
+ addConnectedElement(sourceId: string, type: CreateShapeType, name?: string): string | null;
115
115
  private _smartPlaceBounds;
116
116
  private _overlapsAny;
117
117
  /**
package/dist/editor.js CHANGED
@@ -244,11 +244,11 @@ export class BpmnEditor {
244
244
  injectEditorStyles();
245
245
  this._id = String(_instanceCounter++);
246
246
  // Resolve initial theme — localStorage overrides the options.theme when persistTheme is on
247
- let initialTheme = options.theme ?? "auto";
247
+ let initialTheme = options.theme ?? "neon";
248
248
  if (options.persistTheme) {
249
249
  try {
250
250
  const stored = localStorage.getItem("bpmnkit-theme");
251
- if (stored === "dark" || stored === "light" || stored === "auto") {
251
+ if (stored === "dark" || stored === "light" || stored === "auto" || stored === "neon") {
252
252
  initialTheme = stored;
253
253
  }
254
254
  }
@@ -500,7 +500,7 @@ export class BpmnEditor {
500
500
  this._stateMachine.setMode({ mode: "pan" });
501
501
  }
502
502
  else {
503
- this.setTool("select");
503
+ this.setTool("default");
504
504
  }
505
505
  }
506
506
  setTool(tool) {
@@ -512,7 +512,10 @@ export class BpmnEditor {
512
512
  this._overlay.setAlignmentGuides([]);
513
513
  this._setCreateEdgeDropHighlight(null);
514
514
  this._ghostSnapCenter = null;
515
- if (tool === "select") {
515
+ if (tool === "default") {
516
+ this._stateMachine.setMode({ mode: "default", sub: { name: "idle", hoveredId: null } });
517
+ }
518
+ else if (tool === "select") {
516
519
  this._stateMachine.setMode({ mode: "select", sub: { name: "idle", hoveredId: null } });
517
520
  }
518
521
  else if (tool === "pan") {
@@ -594,7 +597,10 @@ export class BpmnEditor {
594
597
  return this._host;
595
598
  }
596
599
  getTheme() {
597
- return this._host.getAttribute("data-theme") === "dark" ? "dark" : "light";
600
+ const t = this._host.getAttribute("data-theme");
601
+ if (t === "dark" || t === "neon")
602
+ return t;
603
+ return "light";
598
604
  }
599
605
  setTheme(theme) {
600
606
  this._theme = theme;
@@ -1066,7 +1072,7 @@ export class BpmnEditor {
1066
1072
  * using smart placement (right → bottom → top, avoids overlaps).
1067
1073
  * Returns the new element's id.
1068
1074
  */
1069
- addConnectedElement(sourceId, type) {
1075
+ addConnectedElement(sourceId, type, name) {
1070
1076
  if (!this._defs)
1071
1077
  return null;
1072
1078
  const srcShape = this._shapes.find((s) => s.id === sourceId);
@@ -1088,7 +1094,7 @@ export class BpmnEditor {
1088
1094
  }
1089
1095
  const newBounds = this._smartPlaceBounds(srcBounds, sourceId, w, h);
1090
1096
  const obstacles = this._shapes.filter((s) => s.id !== sourceId).map((s) => s.shape.bounds);
1091
- const r1 = createShape(this._defs, type, newBounds);
1097
+ const r1 = createShape(this._defs, type, newBounds, name);
1092
1098
  const waypoints = computeWaypointsAvoiding(srcBounds, newBounds, obstacles);
1093
1099
  const r2 = createConnection(r1.defs, sourceId, r1.id, waypoints);
1094
1100
  this._selectedIds = [r1.id];
@@ -1935,11 +1941,11 @@ export class BpmnEditor {
1935
1941
  ? "dark"
1936
1942
  : "light"
1937
1943
  : theme;
1938
- if (resolved === "dark") {
1939
- this._host.setAttribute("data-theme", "dark");
1944
+ if (resolved === "light") {
1945
+ this._host.removeAttribute("data-theme");
1940
1946
  }
1941
1947
  else {
1942
- this._host.removeAttribute("data-theme");
1948
+ this._host.setAttribute("data-theme", resolved);
1943
1949
  }
1944
1950
  }
1945
1951
  _installPlugin(plugin) {
package/dist/hud.d.ts CHANGED
@@ -75,6 +75,11 @@ export interface HudOptions {
75
75
  * Called when the user clicks "Exit" in the simulation active banner.
76
76
  */
77
77
  onExitSimulation?: () => void;
78
+ /**
79
+ * Called when the user presses the sidebar toggle shortcut (Ctrl+\).
80
+ * Typically toggles the side dock open/closed.
81
+ */
82
+ onToggleSidebar?: () => void;
78
83
  }
79
84
  export declare function initEditorHud(editor: BpmnEditor, options?: HudOptions): {
80
85
  setActive(active: boolean): void;
package/dist/hud.js CHANGED
@@ -61,6 +61,7 @@ const SHORTCUTS = [
61
61
  ["Ctrl+F", "Find element"],
62
62
  ["Ctrl+K", "Command palette"],
63
63
  ["Ctrl+E", "File switcher"],
64
+ ["Ctrl+\\", "Toggle sidebar"],
64
65
  ["H", "Hand tool"],
65
66
  ["V", "Select tool"],
66
67
  ["Escape", "Deselect / cancel"],
@@ -138,7 +139,6 @@ export function initEditorHud(editor, options = {}) {
138
139
  }
139
140
  // Tool selector — bottom center
140
141
  const btnSelect = hudBtn("btn-select", "Select (V)");
141
- btnSelect.classList.add("active");
142
142
  const btnPan = hudBtn("btn-pan", "Hand (H)");
143
143
  const btnSpace = hudBtn("btn-space", "Space tool");
144
144
  const toolGroupsEl = document.createElement("div");
@@ -235,7 +235,7 @@ export function initEditorHud(editor, options = {}) {
235
235
  editor.container.append(hudTopCenter, hudBottomLeft, hudBottomCenter, cfgToolbar, ctxToolbar, zoomMenuEl, moreMenuEl, labelPosMenuEl, refMenuEl, ctxMenuEl, simBannerEl, searchBarEl, shortcutsModal);
236
236
  // ── Theme ──────────────────────────────────────────────────────────────────
237
237
  const syncHudTheme = () => {
238
- document.body.dataset.bpmnHudTheme = editor.getTheme();
238
+ document.body.dataset.bpmnkitHudTheme = editor.getTheme();
239
239
  };
240
240
  syncHudTheme();
241
241
  const themeObs = new MutationObserver(syncHudTheme);
@@ -514,12 +514,16 @@ export function initEditorHud(editor, options = {}) {
514
514
  }
515
515
  }
516
516
  }
517
+ let _currentTool = "default";
518
+ editor.on("editor:tool", (tool) => {
519
+ _currentTool = tool;
520
+ });
517
521
  btnSelect.addEventListener("click", () => {
518
- editor.setTool("select");
522
+ editor.setTool(_currentTool === "select" ? "default" : "select");
519
523
  collapseOnMobile(hudBottomCenter);
520
524
  });
521
525
  btnPan.addEventListener("click", () => {
522
- editor.setTool("pan");
526
+ editor.setTool(_currentTool === "pan" ? "default" : "pan");
523
527
  collapseOnMobile(hudBottomCenter);
524
528
  });
525
529
  btnSpace.addEventListener("click", () => {
@@ -1619,6 +1623,10 @@ export function initEditorHud(editor, options = {}) {
1619
1623
  e.preventDefault();
1620
1624
  shortcutsModal.classList.remove("hidden");
1621
1625
  }
1626
+ if ((e.ctrlKey || e.metaKey) && e.key === "\\") {
1627
+ e.preventDefault();
1628
+ options.onToggleSidebar?.();
1629
+ }
1622
1630
  });
1623
1631
  // ── Close zoom widget on outside click ─────────────────────────────────────
1624
1632
  document.addEventListener("pointerdown", (e) => {
@@ -98,6 +98,9 @@ type SpaceSub = {
98
98
  axis: "h" | "v" | null;
99
99
  };
100
100
  export type EditorMode = {
101
+ mode: "default";
102
+ sub: SelectSub;
103
+ } | {
101
104
  mode: "select";
102
105
  sub: SelectSub;
103
106
  } | {
@@ -162,6 +165,13 @@ export declare class EditorStateMachine {
162
165
  private readonly _cb;
163
166
  private _mode;
164
167
  constructor(_cb: Callbacks);
168
+ /** Creates an idle state preserving the current base mode ("default" or "select"). */
169
+ private _idle;
170
+ /**
171
+ * Wraps a sub-state with the current base mode so that "default" and "select"
172
+ * mode operations return to the same mode when they complete.
173
+ */
174
+ private _withSub;
165
175
  get mode(): EditorMode;
166
176
  setMode(mode: EditorMode): void;
167
177
  onPointerDown(e: PointerEvent, diag: DiagPoint, hit: HitResult): void;
@@ -11,10 +11,21 @@ function screenDist(ax, ay, bx, by) {
11
11
  */
12
12
  export class EditorStateMachine {
13
13
  _cb;
14
- _mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
14
+ _mode = { mode: "default", sub: { name: "idle", hoveredId: null } };
15
15
  constructor(_cb) {
16
16
  this._cb = _cb;
17
17
  }
18
+ /** Creates an idle state preserving the current base mode ("default" or "select"). */
19
+ _idle() {
20
+ return this._withSub({ name: "idle", hoveredId: null });
21
+ }
22
+ /**
23
+ * Wraps a sub-state with the current base mode so that "default" and "select"
24
+ * mode operations return to the same mode when they complete.
25
+ */
26
+ _withSub(sub) {
27
+ return this._mode.mode === "default" ? { mode: "default", sub } : { mode: "select", sub };
28
+ }
18
29
  get mode() {
19
30
  return this._mode;
20
31
  }
@@ -24,11 +35,11 @@ export class EditorStateMachine {
24
35
  // ── Pointer down ─────────────────────────────────────────────────
25
36
  onPointerDown(e, diag, hit) {
26
37
  const mode = this._mode;
27
- // Create mode: place shape and revert to select
38
+ // Create mode: place shape and revert to default
28
39
  if (mode.mode === "create") {
29
40
  this._cb.commitCreate(mode.elementType, diag);
30
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
31
- this._cb.setTool("select");
41
+ this._mode = { mode: "default", sub: { name: "idle", hoveredId: null } };
42
+ this._cb.setTool("default");
32
43
  return;
33
44
  }
34
45
  // Space mode: lock viewport and begin drag
@@ -43,6 +54,17 @@ export class EditorStateMachine {
43
54
  // Pan mode: viewport handles this
44
55
  if (mode.mode === "pan")
45
56
  return;
57
+ // Default mode: canvas click without Shift → track for selection clear on pointer-up, but don't lock
58
+ // viewport so panning still works naturally. Shift falls through to rubber-band.
59
+ if (mode.mode === "default" && hit.type === "canvas" && !e.shiftKey) {
60
+ this._mode = this._withSub({
61
+ name: "pointing-canvas",
62
+ origin: diag,
63
+ screenX: e.clientX,
64
+ screenY: e.clientY,
65
+ });
66
+ return;
67
+ }
46
68
  // If already in connecting mode (entered from contextual toolbar), a click commits or cancels
47
69
  if (mode.sub.name === "connecting") {
48
70
  this._cb.lockViewport(false);
@@ -52,7 +74,7 @@ export class EditorStateMachine {
52
74
  else {
53
75
  this._cb.cancelConnect();
54
76
  }
55
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
77
+ this._mode = this._idle();
56
78
  return;
57
79
  }
58
80
  // In label-editing mode: clicking elsewhere commits label (via blur) — do nothing here
@@ -67,32 +89,26 @@ export class EditorStateMachine {
67
89
  if (!shape)
68
90
  return;
69
91
  this._cb.lockViewport(true);
70
- this._mode = {
71
- mode: "select",
72
- sub: {
73
- name: "pointing-handle",
74
- origin: diag,
75
- id: hit.shapeId,
76
- handle: hit.handle,
77
- screenX: e.clientX,
78
- screenY: e.clientY,
79
- },
80
- };
92
+ this._mode = this._withSub({
93
+ name: "pointing-handle",
94
+ origin: diag,
95
+ id: hit.shapeId,
96
+ handle: hit.handle,
97
+ screenX: e.clientX,
98
+ screenY: e.clientY,
99
+ });
81
100
  break;
82
101
  }
83
102
  case "port": {
84
103
  this._cb.lockViewport(true);
85
- this._mode = {
86
- mode: "select",
87
- sub: {
88
- name: "pointing-port",
89
- origin: diag,
90
- sourceId: hit.shapeId,
91
- port: hit.port,
92
- screenX: e.clientX,
93
- screenY: e.clientY,
94
- },
95
- };
104
+ this._mode = this._withSub({
105
+ name: "pointing-port",
106
+ origin: diag,
107
+ sourceId: hit.shapeId,
108
+ port: hit.port,
109
+ screenX: e.clientX,
110
+ screenY: e.clientY,
111
+ });
96
112
  break;
97
113
  }
98
114
  case "shape": {
@@ -102,95 +118,78 @@ export class EditorStateMachine {
102
118
  ? selectedIds.filter((id) => id !== hit.id)
103
119
  : [...selectedIds, hit.id];
104
120
  this._cb.setSelection(newIds);
105
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: hit.id } };
121
+ this._mode = this._withSub({ name: "idle", hoveredId: hit.id });
106
122
  }
107
123
  else {
108
124
  if (!selectedIds.includes(hit.id)) {
109
125
  this._cb.setSelection([hit.id]);
110
126
  }
111
- this._mode = {
112
- mode: "select",
113
- sub: {
114
- name: "pointing-shape",
115
- origin: diag,
116
- id: hit.id,
117
- screenX: e.clientX,
118
- screenY: e.clientY,
119
- },
120
- };
127
+ this._mode = this._withSub({
128
+ name: "pointing-shape",
129
+ origin: diag,
130
+ id: hit.id,
131
+ screenX: e.clientX,
132
+ screenY: e.clientY,
133
+ });
121
134
  }
122
135
  break;
123
136
  }
124
137
  case "edge": {
125
138
  this._cb.setEdgeSelected(hit.id);
126
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
139
+ this._mode = this._idle();
127
140
  break;
128
141
  }
129
142
  case "edge-segment": {
130
143
  this._cb.lockViewport(true);
131
- this._mode = {
132
- mode: "select",
133
- sub: {
134
- name: "pointing-edge-segment",
135
- edgeId: hit.id,
136
- segIdx: hit.segIdx,
137
- isHoriz: hit.isHoriz,
138
- projPt: hit.projPt,
139
- origin: diag,
140
- screenX: e.clientX,
141
- screenY: e.clientY,
142
- },
143
- };
144
+ this._mode = this._withSub({
145
+ name: "pointing-edge-segment",
146
+ edgeId: hit.id,
147
+ segIdx: hit.segIdx,
148
+ isHoriz: hit.isHoriz,
149
+ projPt: hit.projPt,
150
+ origin: diag,
151
+ screenX: e.clientX,
152
+ screenY: e.clientY,
153
+ });
144
154
  break;
145
155
  }
146
156
  case "edge-waypoint": {
147
157
  this._cb.lockViewport(true);
148
- this._mode = {
149
- mode: "select",
150
- sub: {
151
- name: "pointing-edge-waypoint",
152
- edgeId: hit.id,
153
- wpIdx: hit.wpIdx,
154
- pt: hit.pt,
155
- screenX: e.clientX,
156
- screenY: e.clientY,
157
- },
158
- };
158
+ this._mode = this._withSub({
159
+ name: "pointing-edge-waypoint",
160
+ edgeId: hit.id,
161
+ wpIdx: hit.wpIdx,
162
+ pt: hit.pt,
163
+ screenX: e.clientX,
164
+ screenY: e.clientY,
165
+ });
159
166
  break;
160
167
  }
161
168
  case "edge-endpoint": {
162
169
  this._cb.lockViewport(true);
163
- this._mode = {
164
- mode: "select",
165
- sub: {
166
- name: "pointing-edge-endpoint",
167
- edgeId: hit.edgeId,
168
- isStart: hit.isStart,
169
- origin: diag,
170
- screenX: e.clientX,
171
- screenY: e.clientY,
172
- },
173
- };
170
+ this._mode = this._withSub({
171
+ name: "pointing-edge-endpoint",
172
+ edgeId: hit.edgeId,
173
+ isStart: hit.isStart,
174
+ origin: diag,
175
+ screenX: e.clientX,
176
+ screenY: e.clientY,
177
+ });
174
178
  break;
175
179
  }
176
180
  case "canvas": {
177
181
  if (e.shiftKey) {
178
182
  this._cb.lockViewport(true);
179
- this._mode = {
180
- mode: "select",
181
- sub: { name: "rubber-band", origin: diag, current: diag },
182
- };
183
+ this._mode = this._withSub({ name: "rubber-band", origin: diag, current: diag });
183
184
  }
184
185
  else {
185
- this._mode = {
186
- mode: "select",
187
- sub: {
188
- name: "pointing-canvas",
189
- origin: diag,
190
- screenX: e.clientX,
191
- screenY: e.clientY,
192
- },
193
- };
186
+ // Only reachable in explicit "select" mode (default mode canvas+no-shift returned early)
187
+ this._mode = this._withSub({
188
+ name: "pointing-canvas",
189
+ origin: diag,
190
+ screenX: e.clientX,
191
+ screenY: e.clientY,
192
+ });
194
193
  }
195
194
  break;
196
195
  }
@@ -212,7 +211,7 @@ export class EditorStateMachine {
212
211
  this._cb.previewSpace(sub.origin, diag, axis);
213
212
  return;
214
213
  }
215
- if (mode.mode !== "select") {
214
+ if (mode.mode !== "select" && mode.mode !== "default") {
216
215
  if (mode.mode === "create") {
217
216
  // Ghost create: update overlay (editor reads state.mode to update ghost)
218
217
  }
@@ -224,7 +223,7 @@ export class EditorStateMachine {
224
223
  const hoveredId = hit.type === "shape" ? hit.id : null;
225
224
  if (hoveredId !== sub.hoveredId) {
226
225
  this._cb.setHovered(hoveredId);
227
- this._mode = { mode: "select", sub: { name: "idle", hoveredId } };
226
+ this._mode = this._withSub({ name: "idle", hoveredId });
228
227
  }
229
228
  if (hit.type === "edge-segment") {
230
229
  this._cb.showEdgeHoverDot(hit.projPt);
@@ -244,10 +243,7 @@ export class EditorStateMachine {
244
243
  const dist = screenDist(e.clientX, e.clientY, sub.screenX, sub.screenY);
245
244
  if (dist > DRAG_THRESHOLD) {
246
245
  this._cb.lockViewport(true);
247
- this._mode = {
248
- mode: "select",
249
- sub: { name: "translating", origin: sub.origin, last: diag },
250
- };
246
+ this._mode = this._withSub({ name: "translating", origin: sub.origin, last: diag });
251
247
  const dx = diag.x - sub.origin.x;
252
248
  const dy = diag.y - sub.origin.y;
253
249
  this._cb.previewTranslate(dx, dy);
@@ -257,7 +253,7 @@ export class EditorStateMachine {
257
253
  case "translating": {
258
254
  const dx = diag.x - sub.origin.x;
259
255
  const dy = diag.y - sub.origin.y;
260
- this._mode = { mode: "select", sub: { ...sub, last: diag } };
256
+ this._mode = this._withSub({ ...sub, last: diag });
261
257
  this._cb.previewTranslate(dx, dy);
262
258
  break;
263
259
  }
@@ -269,54 +265,49 @@ export class EditorStateMachine {
269
265
  if (!shape)
270
266
  break;
271
267
  const newBounds = applyResize(shape.shape.bounds, sub.handle, diag.x, diag.y);
272
- this._mode = {
273
- mode: "select",
274
- sub: {
275
- name: "resizing",
276
- id: sub.id,
277
- handle: sub.handle,
278
- original: shape.shape.bounds,
279
- current: diag,
280
- },
281
- };
268
+ this._mode = this._withSub({
269
+ name: "resizing",
270
+ id: sub.id,
271
+ handle: sub.handle,
272
+ original: shape.shape.bounds,
273
+ current: diag,
274
+ });
282
275
  this._cb.previewResize(newBounds);
283
276
  }
284
277
  break;
285
278
  }
286
279
  case "resizing": {
287
280
  const newBounds = applyResize(sub.original, sub.handle, diag.x, diag.y);
288
- this._mode = { mode: "select", sub: { ...sub, current: diag } };
281
+ this._mode = this._withSub({ ...sub, current: diag });
289
282
  this._cb.previewResize(newBounds);
290
283
  break;
291
284
  }
292
285
  case "pointing-port": {
293
286
  const dist = screenDist(e.clientX, e.clientY, sub.screenX, sub.screenY);
294
287
  if (dist > DRAG_THRESHOLD) {
295
- this._mode = {
296
- mode: "select",
297
- sub: { name: "connecting", sourceId: sub.sourceId, ghostEnd: diag },
298
- };
288
+ this._mode = this._withSub({
289
+ name: "connecting",
290
+ sourceId: sub.sourceId,
291
+ ghostEnd: diag,
292
+ });
299
293
  this._cb.previewConnect(diag);
300
294
  }
301
295
  break;
302
296
  }
303
297
  case "connecting": {
304
- this._mode = { mode: "select", sub: { ...sub, ghostEnd: diag } };
298
+ this._mode = this._withSub({ ...sub, ghostEnd: diag });
305
299
  this._cb.previewConnect(diag);
306
300
  break;
307
301
  }
308
302
  case "pointing-edge-endpoint": {
309
303
  const dist = screenDist(e.clientX, e.clientY, sub.screenX, sub.screenY);
310
304
  if (dist > DRAG_THRESHOLD) {
311
- this._mode = {
312
- mode: "select",
313
- sub: {
314
- name: "dragging-edge-endpoint",
315
- edgeId: sub.edgeId,
316
- isStart: sub.isStart,
317
- origin: sub.origin,
318
- },
319
- };
305
+ this._mode = this._withSub({
306
+ name: "dragging-edge-endpoint",
307
+ edgeId: sub.edgeId,
308
+ isStart: sub.isStart,
309
+ origin: sub.origin,
310
+ });
320
311
  this._cb.previewEndpointMove(sub.edgeId, sub.isStart, diag);
321
312
  }
322
313
  break;
@@ -328,15 +319,12 @@ export class EditorStateMachine {
328
319
  case "pointing-edge-segment": {
329
320
  const dist = screenDist(e.clientX, e.clientY, sub.screenX, sub.screenY);
330
321
  if (dist > DRAG_THRESHOLD) {
331
- this._mode = {
332
- mode: "select",
333
- sub: {
334
- name: "dragging-edge-waypoint-new",
335
- edgeId: sub.edgeId,
336
- segIdx: sub.segIdx,
337
- origin: sub.origin,
338
- },
339
- };
322
+ this._mode = this._withSub({
323
+ name: "dragging-edge-waypoint-new",
324
+ edgeId: sub.edgeId,
325
+ segIdx: sub.segIdx,
326
+ origin: sub.origin,
327
+ });
340
328
  this._cb.previewWaypointInsert(sub.edgeId, sub.segIdx, diag);
341
329
  }
342
330
  break;
@@ -348,15 +336,12 @@ export class EditorStateMachine {
348
336
  case "pointing-edge-waypoint": {
349
337
  const dist = screenDist(e.clientX, e.clientY, sub.screenX, sub.screenY);
350
338
  if (dist > DRAG_THRESHOLD) {
351
- this._mode = {
352
- mode: "select",
353
- sub: {
354
- name: "dragging-edge-waypoint",
355
- edgeId: sub.edgeId,
356
- wpIdx: sub.wpIdx,
357
- origin: sub.pt,
358
- },
359
- };
339
+ this._mode = this._withSub({
340
+ name: "dragging-edge-waypoint",
341
+ edgeId: sub.edgeId,
342
+ wpIdx: sub.wpIdx,
343
+ origin: sub.pt,
344
+ });
360
345
  this._cb.previewWaypointMove(sub.edgeId, sub.wpIdx, diag);
361
346
  }
362
347
  break;
@@ -366,20 +351,23 @@ export class EditorStateMachine {
366
351
  break;
367
352
  }
368
353
  case "rubber-band": {
369
- this._mode = { mode: "select", sub: { ...sub, current: diag } };
354
+ this._mode = this._withSub({ ...sub, current: diag });
370
355
  this._cb.previewRubberBand(sub.origin, diag);
371
356
  break;
372
357
  }
373
358
  case "pointing-canvas": {
374
- // Transition to rubber-band when drag threshold exceeded (no Shift required)
375
359
  const dist = screenDist(e.clientX, e.clientY, sub.screenX, sub.screenY);
376
360
  if (dist > DRAG_THRESHOLD) {
377
- this._cb.lockViewport(true);
378
- this._mode = {
379
- mode: "select",
380
- sub: { name: "rubber-band", origin: sub.origin, current: diag },
381
- };
382
- this._cb.previewRubberBand(sub.origin, diag);
361
+ if (this._mode.mode === "default") {
362
+ // Default mode canvas drag → pan. Return to idle so pointer-up doesn't clear selection.
363
+ this._mode = this._idle();
364
+ }
365
+ else {
366
+ // Select mode canvas drag → rubber-band
367
+ this._cb.lockViewport(true);
368
+ this._mode = this._withSub({ name: "rubber-band", origin: sub.origin, current: diag });
369
+ this._cb.previewRubberBand(sub.origin, diag);
370
+ }
383
371
  }
384
372
  break;
385
373
  }
@@ -399,13 +387,21 @@ export class EditorStateMachine {
399
387
  }
400
388
  return;
401
389
  }
402
- if (mode.mode !== "select")
390
+ // Pan mode: deselect tool on short click (no actual pan)
391
+ if (mode.mode === "pan") {
392
+ if (!this._cb.viewportDidPan()) {
393
+ this._mode = { mode: "default", sub: { name: "idle", hoveredId: null } };
394
+ this._cb.setTool("default");
395
+ }
396
+ return;
397
+ }
398
+ if (mode.mode !== "select" && mode.mode !== "default")
403
399
  return;
404
400
  const sub = mode.sub;
405
401
  switch (sub.name) {
406
402
  case "pointing-shape": {
407
403
  this._cb.setSelection([sub.id]);
408
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: sub.id } };
404
+ this._mode = this._withSub({ name: "idle", hoveredId: sub.id });
409
405
  break;
410
406
  }
411
407
  case "translating": {
@@ -413,24 +409,24 @@ export class EditorStateMachine {
413
409
  const dy = diag.y - sub.origin.y;
414
410
  this._cb.lockViewport(false);
415
411
  this._cb.commitTranslate(dx, dy);
416
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
412
+ this._mode = this._idle();
417
413
  break;
418
414
  }
419
415
  case "pointing-handle": {
420
416
  this._cb.lockViewport(false);
421
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
417
+ this._mode = this._idle();
422
418
  break;
423
419
  }
424
420
  case "resizing": {
425
421
  const newBounds = applyResize(sub.original, sub.handle, diag.x, diag.y);
426
422
  this._cb.lockViewport(false);
427
423
  this._cb.commitResize(sub.id, newBounds);
428
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
424
+ this._mode = this._idle();
429
425
  break;
430
426
  }
431
427
  case "pointing-port": {
432
428
  this._cb.lockViewport(false);
433
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
429
+ this._mode = this._idle();
434
430
  break;
435
431
  }
436
432
  case "connecting": {
@@ -441,7 +437,7 @@ export class EditorStateMachine {
441
437
  else {
442
438
  this._cb.cancelConnect();
443
439
  }
444
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
440
+ this._mode = this._idle();
445
441
  break;
446
442
  }
447
443
  case "rubber-band": {
@@ -459,50 +455,52 @@ export class EditorStateMachine {
459
455
  })
460
456
  .map((s) => s.id);
461
457
  this._cb.setSelection(ids);
462
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
458
+ this._mode = this._idle();
463
459
  break;
464
460
  }
465
461
  case "pointing-edge-endpoint": {
466
462
  this._cb.lockViewport(false);
467
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
463
+ this._mode = this._idle();
468
464
  break;
469
465
  }
470
466
  case "dragging-edge-endpoint": {
471
467
  this._cb.lockViewport(false);
472
468
  this._cb.commitEndpointMove(sub.edgeId, sub.isStart, diag);
473
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
469
+ this._mode = this._idle();
474
470
  break;
475
471
  }
476
472
  case "pointing-edge-segment": {
477
473
  this._cb.lockViewport(false);
478
474
  // Tap without drag: select the edge
479
475
  this._cb.setEdgeSelected(sub.edgeId);
480
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
476
+ this._mode = this._idle();
481
477
  break;
482
478
  }
483
479
  case "dragging-edge-waypoint-new": {
484
480
  this._cb.lockViewport(false);
485
481
  this._cb.commitWaypointInsert(sub.edgeId, sub.segIdx, diag);
486
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
482
+ this._mode = this._idle();
487
483
  break;
488
484
  }
489
485
  case "pointing-edge-waypoint": {
490
486
  this._cb.lockViewport(false);
491
487
  this._cb.setEdgeSelected(sub.edgeId);
492
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
488
+ this._mode = this._idle();
493
489
  break;
494
490
  }
495
491
  case "dragging-edge-waypoint": {
496
492
  this._cb.lockViewport(false);
497
493
  this._cb.commitWaypointMove(sub.edgeId, sub.wpIdx, diag);
498
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
494
+ this._mode = this._idle();
499
495
  break;
500
496
  }
501
497
  case "pointing-canvas": {
502
498
  if (!this._cb.viewportDidPan()) {
503
499
  this._cb.setSelection([]);
504
500
  }
505
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
501
+ // Return to default mode after canvas click
502
+ this._mode = { mode: "default", sub: { name: "idle", hoveredId: null } };
503
+ this._cb.setTool("default");
506
504
  break;
507
505
  }
508
506
  default:
@@ -521,8 +519,8 @@ export class EditorStateMachine {
521
519
  const mode = this._mode;
522
520
  if (mode.mode === "create" && e.key === "Escape") {
523
521
  e.preventDefault();
524
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
525
- this._cb.setTool("select");
522
+ this._mode = { mode: "default", sub: { name: "idle", hoveredId: null } };
523
+ this._cb.setTool("default");
526
524
  return;
527
525
  }
528
526
  if (mode.mode === "space" && e.key === "Escape") {
@@ -534,7 +532,7 @@ export class EditorStateMachine {
534
532
  this._mode = { mode: "space", sub: { name: "idle" } };
535
533
  return;
536
534
  }
537
- if (mode.mode !== "select")
535
+ if (mode.mode !== "select" && mode.mode !== "default")
538
536
  return;
539
537
  const sub = mode.sub;
540
538
  if (e.key === "Escape") {
@@ -567,7 +565,7 @@ export class EditorStateMachine {
567
565
  this._cb.cancelWaypointMove();
568
566
  }
569
567
  this._cb.setSelection([]);
570
- this._mode = { mode: "select", sub: { name: "idle", hoveredId: null } };
568
+ this._mode = this._idle();
571
569
  return;
572
570
  }
573
571
  if (e.key === "Delete" || e.key === "Backspace") {
package/dist/types.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { BpmnDefinitions } from "@bpmnkit/core";
3
3
  export type CreateShapeType = "startEvent" | "messageStartEvent" | "timerStartEvent" | "conditionalStartEvent" | "signalStartEvent" | "endEvent" | "messageEndEvent" | "escalationEndEvent" | "errorEndEvent" | "compensationEndEvent" | "signalEndEvent" | "terminateEndEvent" | "intermediateThrowEvent" | "intermediateCatchEvent" | "messageCatchEvent" | "messageThrowEvent" | "timerCatchEvent" | "escalationThrowEvent" | "conditionalCatchEvent" | "linkCatchEvent" | "linkThrowEvent" | "compensationThrowEvent" | "signalCatchEvent" | "signalThrowEvent" | "task" | "serviceTask" | "userTask" | "scriptTask" | "sendTask" | "receiveTask" | "businessRuleTask" | "manualTask" | "callActivity" | "subProcess" | "adHocSubProcess" | "transaction" | "exclusiveGateway" | "parallelGateway" | "inclusiveGateway" | "eventBasedGateway" | "complexGateway" | "textAnnotation";
4
4
  /** Element types that support resize handles. */
5
5
  export declare const RESIZABLE_TYPES: ReadonlySet<string>;
6
- export type Tool = "select" | "pan" | "space" | `create:${CreateShapeType}`;
6
+ export type Tool = "default" | "select" | "pan" | "space" | `create:${CreateShapeType}`;
7
7
  export type HandleDir = "nw" | "n" | "ne" | "e" | "se" | "s" | "sw" | "w";
8
8
  export type PortDir = "top" | "right" | "bottom" | "left";
9
9
  export type EditorOptions = CanvasOptions & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bpmnkit/editor",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -17,8 +17,8 @@
17
17
  "dist/**/*.d.ts"
18
18
  ],
19
19
  "dependencies": {
20
- "@bpmnkit/canvas": "0.0.11",
21
- "@bpmnkit/core": "0.0.11"
20
+ "@bpmnkit/canvas": "0.0.12",
21
+ "@bpmnkit/core": "0.0.12"
22
22
  },
23
23
  "description": "Full-featured interactive BPMN editor with undo/redo, HUD, and side-dock UI",
24
24
  "keywords": [