@unofficialbox/box-open-elements 0.29.2 → 0.31.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.
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  Browse the full catalog on the **[live docs site](https://unofficialbox.github.io/box-open-elements)** — live previews, an events/properties inspector, per-framework code snippets (React / Angular / Vue / Svelte / HTML), and the foundations pages.
14
14
 
15
- The library is organized around three layers (see [taxonomy](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/taxonomy.md) for the canonical model):
15
+ The library is organized around three layers (see [taxonomy](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/taxonomy.md) for the canonical model):
16
16
 
17
17
  - **Foundations** — design decisions as data: tokens, color, typography, iconography, accessibility, theming
18
18
  - **Components** — accessible Web Components for single controls, organized by category
@@ -77,7 +77,7 @@ selection.toggleSelection("1");
77
77
  - optimized component entrypoints: `@unofficialbox/box-open-elements/<name>`
78
78
  - patterns: `@unofficialbox/box-open-elements/patterns/<area>` and `@unofficialbox/box-open-elements/patterns/<area>/<module>`
79
79
 
80
- See the versioned [API guidelines](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/api-guidelines.md).
80
+ See the versioned [API guidelines](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/api-guidelines.md).
81
81
 
82
82
  ## Developing
83
83
 
@@ -91,17 +91,17 @@ bun run docs # build + serve the docs site at http://localhost:4600
91
91
 
92
92
  ## Documentation
93
93
 
94
- The versioned docs index is at [docs/README.md](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/README.md). The most important entries:
95
-
96
- - [Taxonomy](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/taxonomy.md)
97
- - [Architecture](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/architecture.md)
98
- - [API Guidelines](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/api-guidelines.md)
99
- - [Components catalog](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/components/catalog.md) and [patterns catalog](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/patterns/catalog.md)
100
- - [Using with React, Angular, Vue, and Svelte](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/integration/frameworks.md)
101
- - [Design Tokens](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/foundations/tokens.md)
102
- - [Content Explorer](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/patterns/content-explorer.md)
103
- - [Box Server Integration](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/integration/box-server.md)
104
- - [Agent UI guidelines](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/patterns/agent-ui-guidelines.md), [building blocks](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/patterns/agent-ui.md), and [motion](https://github.com/unofficialbox/box-open-elements/blob/v0.29.2/docs/foundations/motion.md)
94
+ The versioned docs index is at [docs/README.md](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/README.md). The most important entries:
95
+
96
+ - [Taxonomy](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/taxonomy.md)
97
+ - [Architecture](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/architecture.md)
98
+ - [API Guidelines](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/api-guidelines.md)
99
+ - [Components catalog](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/components/catalog.md) and [patterns catalog](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/patterns/catalog.md)
100
+ - [Using with React, Angular, Vue, and Svelte](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/integration/frameworks.md)
101
+ - [Design Tokens](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/foundations/tokens.md)
102
+ - [Content Explorer](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/patterns/content-explorer.md)
103
+ - [Box Server Integration](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/integration/box-server.md)
104
+ - [Agent UI guidelines](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/patterns/agent-ui-guidelines.md), [building blocks](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/patterns/agent-ui.md), and [motion](https://github.com/unofficialbox/box-open-elements/blob/v0.31.0/docs/foundations/motion.md)
105
105
 
106
106
  ## Contributing
107
107
 
@@ -294,6 +294,7 @@ export class CodeEditor extends BaseElement {
294
294
  [part=editor]:focus-within{box-shadow:0 0 0 3px var(--boe-token-surface-surface-brand,#0061d5)}
295
295
  .cm-editor.cm-focused{outline:none}
296
296
  .cm-scroller{max-height:var(--boe-code-editor-height,420px);min-height:160px;overflow:auto;font-family:var(--boe-code-font-family,monospace);font-size:var(--boe-code-font-size,14px);line-height:var(--boe-code-line-height,1.6)}
297
+ .cm-editor .cm-scroller{line-height:var(--boe-code-line-height,1.4)!important}
297
298
  :host([fill-height]){height:100%}
298
299
  :host([fill-height]) [part=editor],:host([fill-height]) .cm-editor,:host([fill-height]) .cm-scroller{height:100%;max-height:none;min-height:0}
299
300
  .cm-gutters,.cm-panels{color:var(--boe-code-foreground,var(--boe-token-text-text,#222))!important;border-color:var(--boe-token-stroke-stroke,#ddd)!important}
@@ -302,7 +303,7 @@ export class CodeEditor extends BaseElement {
302
303
  .cm-tooltip{background:var(--boe-code-popup-background,var(--boe-token-surface-surface-secondary,#fbfbfb))!important;color:var(--boe-code-popup-foreground,var(--boe-code-foreground,var(--boe-token-text-text,#222)))!important;border-color:var(--boe-code-popup-border,var(--boe-token-stroke-stroke,#ddd))!important}
303
304
  .cm-tooltip .cm-diagnostic,.cm-tooltip-autocomplete ul li{color:var(--boe-code-popup-foreground,var(--boe-code-foreground,var(--boe-token-text-text,#222)))}
304
305
  .cm-cursor{border-left-color:var(--boe-code-caret,var(--boe-token-text-text,#222))}
305
- .cm-activeLine,.cm-activeLineGutter{background:color-mix(in srgb,var(--boe-token-surface-surface-brand,#0061d5) 12%,transparent)!important}
306
+ .cm-activeLine,.cm-activeLineGutter{background:var(--boe-code-active-line,color-mix(in srgb,var(--boe-token-surface-surface-brand,#0061d5) 12%,transparent))!important}
306
307
  :host([current-line-style=border]) .cm-activeLine{background:transparent!important;box-shadow:inset 0 1px var(--boe-code-current-line-border,var(--boe-token-stroke-stroke,#ddd)),inset 0 -1px var(--boe-code-current-line-border,var(--boe-token-stroke-stroke,#ddd))}
307
308
  :host([current-line-style=none]) .cm-activeLine{background:transparent!important}
308
309
  :host([current-line-style=border]) .cm-activeLineGutter,:host([current-line-style=none]) .cm-activeLineGutter{background:transparent!important}
@@ -122,7 +122,7 @@ export interface BoxElementPropertyKeys {
122
122
  "box-presence": "label" | "max" | "transport" | "users";
123
123
  "box-preview-element": "actions" | "adapterState" | "heading" | "itemLabel" | "message" | "provider" | "providerAdapter" | "providerLabel" | "status";
124
124
  "box-preview-header": "actions" | "breadcrumbs" | "heading" | "message" | "status";
125
- "box-process-modeler": "catalog" | "connections" | "detail" | "disableConnections" | "document" | "embedMode" | "fields" | "headingLevel" | "history" | "lastRun" | "layout" | "locked" | "model" | "outline" | "processSummary" | "processTitle" | "renderInspector" | "selectedPath" | "showLastRun" | "snapToGrid" | "variables";
125
+ "box-process-modeler": "catalog" | "connections" | "detail" | "disableConnections" | "document" | "embedMode" | "fields" | "headingLevel" | "history" | "lastRun" | "layout" | "locked" | "model" | "outline" | "processSummary" | "processTitle" | "renderInspector" | "selectedPath" | "showLastRun" | "snapToGrid" | "variables" | "variablesEditable";
126
126
  "box-progress-bar": "hideLabel" | "label" | "max" | "value";
127
127
  "box-progress-ring": "label" | "max" | "size" | "value";
128
128
  "box-progress-steps": "compact" | "items" | "label" | "value";
@@ -942,6 +942,20 @@ export interface BoxElementEventMap {
942
942
  name: string;
943
943
  value: string;
944
944
  }>;
945
+ "process-variable-edit-request": CustomEvent<{
946
+ type: "add";
947
+ } | {
948
+ type: "remove";
949
+ name: string;
950
+ } | {
951
+ type: "rename";
952
+ name: string;
953
+ value: string;
954
+ } | {
955
+ type: "scope";
956
+ name: string;
957
+ value: "iteration" | "process";
958
+ }>;
945
959
  "projection-changed": CustomEvent<{
946
960
  projection: import("./patterns/process-modeler/model.js").ProcessProjection<unknown>;
947
961
  version: string | number;
@@ -1,7 +1,14 @@
1
1
  /** Detach graph presentation data without cloning the host-owned node payload. */
2
2
  export function snapshotProcessProjection(projection) {
3
3
  return {
4
- boxes: projection.boxes.map(box => ({ ...box, ...(box.path ? { path: [...box.path] } : {}) })),
4
+ boxes: projection.boxes.map(box => ({
5
+ ...box,
6
+ ...(box.path ? { path: [...box.path] } : {}),
7
+ ...(box.technicalDetails ? { technicalDetails: box.technicalDetails.map(detail => ({
8
+ ...detail,
9
+ ...(detail.segments ? { segments: detail.segments.map(segment => ({ ...segment })) } : {}),
10
+ })) } : {}),
11
+ })),
5
12
  lines: projection.lines.map(line => ({
6
13
  ...line,
7
14
  ...(line.points ? { points: line.points.map(point => ({ ...point })) } : {}),
@@ -1,2 +1,2 @@
1
1
  /** Riptide Diagram anatomy expressed through public Box Open Elements tokens. */
2
- export declare const processModelerDesign = "\n :host([hidden]), [hidden] { display: none !important; }\n *, *::before, *::after { box-sizing: border-box; }\n button, input, textarea, select { font: inherit; color: inherit; }\n button { min-height: 36px; padding: 8px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); cursor: pointer; }\n button:disabled { opacity: .5; cursor: default; }\n :is(button,input,textarea,select,[part=canvas],[part=minimap],[part=box],[part=frame]):focus-visible { outline: 2px solid var(--boe-token-surface-surface-brand, #0061d5); outline-offset: 2px; }\n :host {\n display: block;\n position: relative;\n isolation: isolate;\n min-width: 0;\n --boe-process-box-edge: color-mix(in srgb, var(--boe-token-text-text, #141413) 55%, var(--boe-token-surface-surface, #fff));\n color: var(--boe-token-text-text, #141413);\n background: var(--boe-token-surface-surface, #fff);\n font: 14px/1.5 var(--boe-token-font-family-base, Inter, sans-serif);\n }\n [part=sr-only], [part=status], [part=urgent-status] { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }\n [part=toolbar] {\n min-height: 56px;\n margin: 0;\n padding: 8px 16px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n flex-wrap: wrap;\n border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8);\n background: var(--boe-token-surface-surface, #fff);\n }\n [part=toolbar] button, [part=controls] button, [part=selection-toolbar] button {\n min-height: 30px;\n padding: 4px 10px;\n border: 1px solid transparent;\n border-radius: 8px;\n background: transparent;\n font-size: 13px;\n font-weight: 600;\n }\n [part=toolbar] svg, [part=controls] svg { width: 16px; height: 16px; display: block; }\n [part=toolbar] [data-command=undo], [part=toolbar] [data-command=redo], [part=controls] button:not([data-command=reset]) { width: 30px; height: 30px; padding: 6px; display: grid; place-items: center; }\n [part=controls] [data-command=snap][aria-pressed=true], [part=controls] [data-command=lock][aria-pressed=true] { background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 10%, var(--boe-token-surface-surface, #fff)); color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=toolbar] button:hover, [part=controls] button:hover, [part=selection-toolbar] button:hover {\n background: var(--boe-token-surface-surface-hover, #f4f4f4);\n }\n [part=toolbar] [data-command=tidy] { border-color: var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 18px; }\n [part=view-switch] { display: flex; gap: 2px; padding: 3px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 20px; }\n [part=view-switch] button { border-radius: 16px; }\n [part=view-switch] button[aria-pressed=true] { border-color: var(--boe-token-stroke-stroke, #e8e8e8); background: var(--boe-token-surface-surface, #fff); }\n [part=run-toggle] { display: flex; align-items: center; gap: 8px; white-space: nowrap; font-size: 13px; font-weight: 600; cursor: pointer; }\n [part=run-toggle] input { appearance: none; position: relative; width: 32px; height: 18px; margin: 0; border: 0; border-radius: 9px; background: var(--boe-token-surface-surface-hover, #f4f4f4); cursor: pointer; transition: background var(--boe-profile-motion-interactive, 200ms) ease-out; }\n [part=run-toggle] input::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--boe-token-surface-surface, #fff); box-shadow: 0 1px 2px rgb(0 0 0 / .25); transition: transform var(--boe-profile-motion-interactive, 200ms) ease-out; }\n [part=run-toggle] input:checked { background: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=run-toggle] input:checked::after { transform: translateX(14px); }\n [part=run-toggle] input:focus-visible { outline: 2px solid var(--boe-token-surface-surface-brand, #0061d5); outline-offset: 2px; }\n [part=toolbar] [data-command=checks-status] { white-space: nowrap; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=toolbar] [data-command=checks-status][data-state=bad] { color: var(--boe-token-text-status-text-error, #b92340); }\n [part=view-menu] { display: none; position: relative; }\n [part=view-menu] summary { list-style: none; padding: 4px 14px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 18px; font-size: 13px; font-weight: 600; cursor: pointer; }\n [part=view-menu][open] { z-index: 20; }\n [part=view-menu-options] { position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; width: 192px; padding: 6px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 10px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=view-menu] button { display: block; width: 100%; text-align: start; background: transparent; }\n [part=layout] {\n display: grid;\n grid-template-columns: 248px minmax(0, 1fr) 320px;\n gap: 0;\n min-height: 0;\n height: var(--boe-process-height, 660px);\n overflow: hidden;\n }\n [part=pane-drawer] { display: contents; color: inherit; }\n [part=canvas-stack] { display: grid; grid-template-rows: auto minmax(0, 1fr); min-width: 0; min-height: 0; }\n /* The hidden hold leaves row 1 empty. Keep the canvas in the flexible row\n explicitly; auto-placement otherwise puts its absolute world in a 0px row. */\n [part=canvas-stack] > [part=hold] { grid-row: 1; }\n [part=canvas-stack] > [part=canvas] { grid-row: 2; }\n [part=insert-chooser]::backdrop { background: rgb(0 0 0 / .45); }\n [part=pane-scrim] { position: absolute; inset: 0; z-index: 30; background: rgb(0 0 0 / .45); }\n [part=pane-title], [part=pane-close], [data-command=palette], [data-command=details] { display: none; }\n [part=palette], [part=inspector] {\n min-width: 0;\n overflow: auto;\n padding: 12px;\n border: 0;\n border-radius: 0;\n background: var(--boe-token-surface-surface, #fff);\n }\n [part=palette] { display: flex; flex-direction: column; gap: 12px; border-right: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }\n [part=palette-heading] { margin: 0 4px; font-size: 14px; font-weight: 650; line-height: 20px; }\n [part=skip-link] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }\n [part=skip-link]:focus-visible { position: static; width: auto; height: auto; clip-path: none; }\n [part=inspector] { border-left: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); padding: 16px 0; }\n [part=palette] label { font-size: 0; position: relative; }\n [part=search-icon] { position: absolute; left: 12px; top: 9px; width: 18px; height: 18px; color: var(--boe-token-text-text-secondary, #6f6f6f); pointer-events: none; }\n [part=palette] input {\n width: 100%; min-width: 0;\n height: 36px;\n padding: 0 12px 0 36px;\n border: 1px solid transparent;\n border-radius: 24px;\n background: var(--boe-token-surface-surface-hover, #f4f4f4);\n font-size: 13px;\n }\n [part=palette] input:focus-visible { border-color: var(--boe-token-surface-surface-brand, #0061d5); background: var(--boe-token-surface-surface, #fff); }\n [part=choices] { display: grid; align-content: start; gap: 4px; max-height: none; overflow: visible; }\n [part=group] { margin: 4px 4px 6px; font-size: 12px; font-weight: 650; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=choice] {\n display: grid; grid-template-columns: 20px minmax(0,1fr); gap: 0 10px;\n min-height: 44px; padding: 8px 10px; border: 1px solid transparent; border-radius: 10px;\n text-align: start; background: transparent; cursor: grab;\n }\n [part=choice]:hover { border-color: var(--boe-token-stroke-stroke, #e8e8e8); background: var(--boe-token-surface-surface-hover, #f4f4f4); }\n [part=choice-icon] { grid-row: span 2; width: 20px; height: 20px; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=choice][data-tone=accent] [part=choice-icon] { color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=choice-icon] svg { width: 20px; height: 20px; }\n [part=choice-name] { font-size: 13px; font-weight: 600; line-height: 1.3; }\n [part=choice-description] { grid-column: 2; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.35; }\n [part=palette-hint] { margin: 4px; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.45; }\n [part=canvas] {\n position: relative; min-width: 0; height: 100%; overflow: hidden;\n border: 0; border-radius: 0;\n background-color: var(--boe-token-surface-surface-secondary, #fbfbfb);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--boe-token-text-text-secondary, #6f6f6f) 26%, transparent) 1px, transparent 1.2px);\n background-size: 12px 12px;\n touch-action: none; user-select: none; cursor: grab;\n }\n [part=canvas][data-panning] { cursor: grabbing; }\n [part=hold] { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 16px; border-bottom: 1px solid var(--boe-token-stroke-status-stroke-warning, #9a6b00); background: var(--boe-token-surface-status-surface-warning, #fff7df); color: var(--boe-token-text-status-text-warning, #6b4a00); font-size: 13px; }\n [part=hold-text] { flex: 1 1 280px; min-width: 0; }\n [part=hold] button { min-height: 28px; padding: 3px 8px; border: 1px solid currentColor; border-radius: 6px; background: transparent; font-size: 12px; font-weight: 650; white-space: nowrap; }\n [part=world] { position: absolute; inset: 0; transform-origin: 0 0; }\n [part=lines] { position: absolute; inset: 0; width: 1px; height: 1px; overflow: visible; pointer-events: none; z-index: 3; }\n [part=line] { stroke: var(--boe-token-text-text-secondary, #6f6f6f); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; fill: none; }\n [part=line][data-selected=true] { stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 2; }\n [part=line][data-drop=true] { stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 2.5; stroke-dasharray: 6 4; }\n [part=line-hit] { fill: none; stroke: transparent; stroke-width: 24; pointer-events: stroke; }\n [part=connection-preview] { fill: none; stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 2.5; stroke-dasharray: 6 4; }\n [part=pinned-end] { fill: var(--boe-token-surface-surface-brand, #0061d5); pointer-events: none; }\n [part=box], [part=frame] {\n position: absolute; touch-action: none; text-align: start; z-index: 4; display: grid; grid-template-columns: 20px minmax(0,1fr); align-content: center;\n gap: 2px 10px; min-width: 0; min-height: 64px; padding: 11px 12px;\n border: 1px solid var(--boe-process-box-edge, var(--boe-control-edge, #858585));\n border-radius: 8px; background: var(--boe-token-surface-surface, #fff);\n font-size: 13px; line-height: 1.3;\n transition: border-color var(--boe-profile-motion-interactive, 200ms) ease-out,\n background var(--boe-profile-motion-interactive, 200ms) ease-out;\n }\n [part=box]:hover, [part=frame]:hover { border-color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [data-connect-target=true] { border-color: var(--boe-token-surface-surface-brand, #0061d5) !important; }\n [part=box] strong, [part=frame] strong { overflow-wrap: anywhere; }\n [part=box] strong, [part=frame] strong { font-size: 13.5px; font-weight: 650; line-height: 1.3; }\n [part=box] small, [part=frame] small { grid-column: 2; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; line-height: 1.35; }\n [part=technical-description] { font: 12px/1.4 ui-monospace, 'SF Mono', Menlo, Consolas, monospace !important; overflow-wrap: anywhere; }\n [part=metrics] { grid-column: 2; font-size: 12px; font-variant-numeric: tabular-nums; }\n [part=metric-warning] { color: var(--boe-token-text-status-text-warning, #8a5800); }\n [part=icon] { grid-row: span 3; width: 20px; height: 20px; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=icon] svg { display: block; width: 20px; height: 20px; }\n [data-tone=accent] > [part=icon] { color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=box][aria-current=true], [part=frame][aria-current=true] {\n border: 1px solid var(--boe-token-surface-surface-brand, #0061d5);\n background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 7%, var(--boe-token-surface-surface, #fff));\n }\n [data-invalid=true] { border-color: var(--boe-token-text-status-text-error, #b92340) !important; }\n [part=problem] { grid-column: 1 / -1; color: var(--boe-token-text-status-text-error, #b92340); font-size: 12px; }\n [part=frame] { z-index: 1; align-content: start; border-radius: 12px; background: color-mix(in srgb, var(--boe-token-surface-surface, #fff) 78%, transparent); }\n [part=frame] small { grid-column: 2; }\n [part=loop-mark] { position: absolute; right: 12px; bottom: 8px; font-size: 20px; line-height: 1; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=frame-resize] { position: absolute; right: -12px; bottom: -12px; z-index: 8; width: 28px; height: 28px; min-height: 28px; padding: 0; border: 0; border-radius: 8px; background: var(--boe-token-surface-surface, #fff); box-shadow: 0 0 0 1px var(--boe-process-box-edge, #858585); cursor: nwse-resize; }\n [part=frame-resize]::before { content: ''; position: absolute; right: 7px; bottom: 7px; width: 11px; height: 11px; border-right: 2px solid var(--boe-token-text-text-secondary, #6f6f6f); border-bottom: 2px solid var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=frame]:not([aria-current=true]) [part=frame-resize] { visibility: hidden; }\n [data-shape=gateway], [data-shape=event] { width: 56px !important; height: 56px !important; min-height: 0; padding: 0; border: 0 !important; background: transparent !important; display: block; overflow: visible; }\n [data-shape=gateway]::before { content: ''; position: absolute; left: 8px; top: 8px; width: 40px; height: 40px; rotate: 45deg; border: 1.5px solid var(--boe-process-box-edge, var(--boe-control-edge, #858585)); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); }\n [data-shape=event]::before { content: ''; position: absolute; left: 8px; top: 8px; width: 40px; height: 40px; border: 1.5px solid var(--boe-process-box-edge, var(--boe-control-edge, #858585)); border-radius: 50%; background: var(--boe-token-surface-surface, #fff); }\n [data-shape=event][data-kind=finish]::before { border-width: 4px; }\n [data-shape=event][data-kind=scheduled-start]::after { content: ''; position: absolute; left: 13px; top: 13px; width: 30px; height: 30px; border: 1px solid currentColor; border-radius: 50%; }\n [data-shape=gateway] > [part=icon], [data-shape=event] > [part=icon] { position: absolute; left: 18px; top: 18px; z-index: 1; }\n [data-shape=gateway] > strong, [data-shape=event] > strong { position: absolute; top: 58px; left: 50%; width: 150px; translate: -50% 0; text-align: center; font-size: 12px; }\n [data-shape=gateway] > small { display: none; }\n [data-shape=event] > small { position: absolute; top: 75px; left: 50%; width: 172px; translate: -50% 0; text-align: center; font-size: 11px; line-height: 1.25; }\n [data-shape=gateway][aria-current=true]::before, [data-shape=event][aria-current=true]::before { border-color: var(--boe-token-surface-surface-brand, #0061d5); background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 7%, var(--boe-token-surface-surface, #fff)); }\n [part=port] { position: absolute; z-index: 5; width: 24px; height: 24px; min-height: 24px; padding: 0; border: 0; border-radius: 50%; background: transparent; opacity: 0; }\n [part=port][data-side=north] { left: calc(50% - 12px); top: -12px; }\n [part=port][data-side=south] { left: calc(50% - 12px); bottom: -12px; }\n [part=port][data-side=east] { right: -12px; top: calc(50% - 12px); }\n [part=port][data-side=west] { left: -12px; top: calc(50% - 12px); }\n [part=port]::before { content: ''; display: block; width: 10px; height: 10px; margin: 7px; border: 1.5px solid var(--boe-token-surface-surface-brand, #0061d5); border-radius: 50%; background: var(--boe-token-surface-surface, #fff); }\n [part=port]:hover::before, [part=port]:focus-visible::before { width: 22px; height: 22px; margin: 1px; background: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=port]::after { position: absolute; inset: 1px; display: none; place-items: center; color: #fff; font-size: 15px; font-weight: 700; line-height: 1; }\n [part=port][data-side=north]::after { content: '\u2191'; }\n [part=port][data-side=east]::after { content: '\u2192'; }\n [part=port][data-side=south]::after { content: '\u2193'; }\n [part=port][data-side=west]::after { content: '\u2190'; }\n [part=port]:hover::after, [part=port]:focus-visible::after, [part=port][data-hot=true]::after { display: grid; }\n [part=port][data-hot=true] { opacity: 1; }\n [part=port][data-hot=true]::before { width: 22px; height: 22px; margin: 1px; background: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=end-grip] { position: absolute; z-index: 8; width: 24px; height: 24px; min-height: 24px; padding: 0; border: 0; border-radius: 50%; background: transparent; }\n [part=end-grip]::before { content: ''; display: block; width: 10px; height: 10px; margin: 7px; border: 1.5px solid var(--boe-token-surface-surface-brand, #0061d5); border-radius: 50%; background: var(--boe-token-surface-surface, #fff); }\n [part=box]:hover [part=port], [part=box]:focus-within [part=port], [part=box][aria-current=true] [part=port], [part=frame]:hover [part=port] { opacity: 1; }\n [part=connection] { position: absolute; z-index: 5; display: flex; align-items: center; gap: 4px; transform: translate(-50%,-50%); min-width: 0; min-height: 0; padding: 2px 6px; border-radius: 6px; background: var(--boe-token-surface-surface-secondary, #fbfbfb); font-size: 12px; font-weight: 600; white-space: nowrap; }\n /* Unlabelled lines still need a reachable midpoint for pointer insert/selection. */\n [part=connection]:has(> span:empty):not(:has(> small)) { padding: 0; background: transparent; min-width: calc(24px * var(--boe-process-inverse-zoom, 1)); min-height: calc(24px * var(--boe-process-inverse-zoom, 1)); }\n [part=connection] > small { margin-left: 4px; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 11px; font-weight: 400; font-variant-numeric: tabular-nums; }\n [part=connection-actions] { position: absolute; top: 100%; left: 50%; transform: translateX(-50%); display: flex; gap: 4px; width: max-content; padding: 4px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); opacity: 0; pointer-events: none; }\n [part=connection]:hover [part=connection-actions], [part=connection]:focus-within [part=connection-actions] { opacity: 1; pointer-events: auto; }\n [part=connection-actions] button { min-height: 32px; padding: 4px; font-size: 12px; }\n [part=note] { width: 208px; border: 1px dashed var(--boe-process-box-edge, var(--boe-control-edge, #858585)); border-radius: 8px; }\n [part=section] { z-index: 0; border: 1px solid var(--boe-process-box-edge, var(--boe-control-edge, #858585)); border-radius: 16px; background: color-mix(in srgb, var(--boe-token-surface-surface, #fff) 45%, transparent); }\n [part=section] strong { display: block; font-size: 12.5px; font-weight: 650; line-height: 1.3; }\n [part=section] small { display: block; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 11.5px; line-height: 1.35; }\n [part=note], [part=section] { position: absolute; padding: 8px; pointer-events: none; }\n [part=marquee] { position: absolute; border: 2px solid var(--boe-token-surface-surface-brand, #0061d5); background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 12%, transparent); pointer-events: none; }\n [part=connect-tooltip] { position: absolute; z-index: 20; max-width: 240px; padding: 5px 8px; border-radius: 7px; background: var(--boe-token-text-text, #141413); color: var(--boe-token-surface-surface, #fff); font-size: 12px; pointer-events: none; box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=connect-tooltip][data-invalid=true] { background: var(--boe-token-text-status-text-error, #b92340); color: #fff; }\n [part=ghost-box], [part=palette-ghost] { position: absolute; z-index: 5; display: flex; align-items: center; padding: 11px 12px; border: 1.5px dashed var(--boe-token-surface-surface-brand, #0061d5); border-radius: 8px; background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 10%, var(--boe-token-surface-surface, #fff)); font-size: 13px; font-weight: 650; pointer-events: none; }\n [part=guide] { position: absolute; background: var(--boe-token-surface-surface-brand, #0061d5); pointer-events: none; }\n [part=measure] { position: absolute; padding: 4px; background: var(--boe-token-surface-surface, #fff); font-size: 12px; pointer-events: none; }\n [part=insert-chooser] { max-width: calc(100vw - 32px); max-height: 65vh; overflow: auto; padding: 12px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); }\n [part=keyboard-chooser] { position: fixed; inset: auto; width: min(320px, calc(100vw - 24px)); max-height: min(420px, calc(100dvh - 24px)); margin: 0; overflow: auto; padding: 12px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); color: var(--boe-token-text-text, #141413); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=chooser-title] { margin: 0 0 10px; font-size: 12px; font-weight: 650; line-height: 1.4; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=controls] { position: absolute; left: 16px; bottom: 16px; z-index: 10; display: flex; align-items: center; gap: 2px; padding: 4px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=controls] [data-command=reset] { min-width: 56px; font-variant-numeric: tabular-nums; }\n [part=minimap] { position: absolute; right: 16px; bottom: 16px; width: 208px; height: 136px; touch-action: none; background: var(--boe-token-surface-surface, #fff); border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=minimap] rect:not([data-viewport]) { fill: var(--boe-token-stroke-stroke-hover, #d3d3d3); }\n [part=minimap] [data-viewport] { fill: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 9%, transparent); stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 1; }\n [part=selection-toolbar] { position: absolute; bottom: auto; z-index: 11; display: flex; flex-wrap: nowrap; gap: 2px; padding: 4px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); white-space: nowrap; }\n [part=selection-toolbar] button { display: inline-flex; align-items: center; gap: 4px; }\n [part=selection-plus] { font-size: 18px; line-height: 12px; font-weight: 500; }\n [part=checks] { display: grid; gap: 6px; margin-top: 12px; }\n [part=checks] button { color: var(--boe-token-text-status-text-error, #b92340); }\n [part=process-heading] { display: grid; gap: 2px; padding: 0 16px 12px; }\n :host([embed-mode]) [part=view-switch], :host([embed-mode]) [part=run-toggle], :host([embed-mode]) [part=view-menu] { display: none; }\n [part=process-title] { font-size: 15px; line-height: 1.4; }\n [part=process-summary] { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; }\n [part=pane-tabs] { display: flex; flex-wrap: nowrap; gap: 4px; margin: 0; padding: 0 16px; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); overflow-x: auto; }\n [part=pane-tabs] button { flex: none; min-height: 40px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: transparent; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 13px; font-weight: 600; }\n [part=pane-tabs] button[aria-selected=true] { color: var(--boe-token-text-text, #141413); border-bottom-color: currentColor; }\n [part=editor], [part=pane-content] { padding: 8px 16px; }\n [part=editor] { display: grid; align-content: start; gap: 12px; }\n [part=inspector-kind] { display: none; }\n [part=inspector-purpose] { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; }\n [part=field] { display: grid; gap: 4px; }\n [part=field] label { display: grid; gap: 5px; font-size: 12.5px; font-weight: 650; }\n [part=field] :is(input:not([type=checkbox]),textarea,select) { width: 100%; min-height: 36px; padding: 7px 10px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); color: var(--boe-token-text-text, #141413); font-family: inherit; font-size: 13px; line-height: 1.4; }\n [part=field] textarea { min-height: 76px; resize: vertical; }\n [part=field]:has([part=action-options]) { position: relative; }\n [part=field]:has([part=action-options]) input { padding-right: 34px; }\n [part=action-caret] { position: absolute; z-index: 1; top: 25px; right: 2px; width: 32px; min-height: 32px; padding: 0; border: 0; background: transparent; font-size: 18px; }\n [part=action-options] { position: absolute; z-index: 30; top: calc(100% - 1px); left: 0; right: 0; max-height: 280px; overflow: auto; padding: 6px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 10px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=action-options][hidden] { display: none; }\n [part=action-options] button { display: block; width: 100%; min-height: 36px; padding: 7px 9px; border: 0; border-radius: 7px; text-align: start; background: transparent; font-size: 12.5px; }\n [part=action-options] button:hover, [part=action-options] [aria-selected=true] { background: var(--boe-token-surface-surface-hover, #f4f4f4); }\n [part=action-options] button strong { display: block; font-size: 13px; font-weight: 650; }\n [part=action-options] button small { display: block; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=action-options] [part=action-back] { color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=field] input[type=checkbox] { justify-self: start; width: 18px; height: 18px; accent-color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=field] small { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.4; }\n [part=field] [part=field-problem] { color: var(--boe-token-text-status-text-error, #b92340); }\n [part=variable-chips] { display: flex; flex-wrap: wrap; gap: 4px; }\n [part=variable-chips] button { min-height: 24px; padding: 2px 8px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface-secondary, #fbfbfb); font-size: 11.5px; }\n [part=leads-to] { display: grid; gap: 6px; padding-top: 10px; border-top: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }\n [part=leads-to] h3 { margin: 0; font-size: 12.5px; }\n [part=lead-row] { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12.5px; }\n [part=lead-row] button, [part=leads-to] > button, [part=inspector-actions] button { min-height: 28px; padding: 4px 8px; font-size: 12px; }\n [part=inspector-metrics] { margin: 0; padding-top: 10px; border-top: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); font-size: 12px; font-variant-numeric: tabular-nums; }\n [part=inspector-metrics] h3 { margin: 0 0 6px; font-size: 12.5px; }\n [part=inspector-metrics] p { margin: 0 0 8px; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=inspector-metrics] dl { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; margin: 0; }\n [part=inspector-metrics] dt { color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=inspector-metrics] dd { margin: 0; font-weight: 650; }\n [part=inspector-actions] { display: flex; gap: 8px; padding-top: 10px; border-top: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }\n [part=arrange-actions] { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 6px; }\n [part=arrange-actions] button { min-height: 32px; padding: 5px 7px; font-size: 12px; text-align: start; }\n [part=outline-intro] { margin: 4px 0 14px; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; line-height: 1.5; }\n [part=copy-outline] { justify-self: start; min-height: 28px; margin-bottom: 8px; padding: 4px 10px; border-radius: 16px; font-size: 12px; font-weight: 650; }\n [part=outline-list] { margin: 0; padding-left: 18px; display: grid; gap: 8px; }\n [part=outline-list] [part=outline-list] { margin: 6px 0 0; gap: 6px; }\n [part=outline-list] li { padding-left: 0; font-size: 12.5px; }\n [part=outline-list] li::marker { color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=outline-list] button, [part=outline-list] strong { border: 0; border-radius: 4px; background: transparent; padding: 0; min-height: 0; font-size: 12.5px; font-weight: 650; line-height: 1.45; text-align: start; }\n [part=outline-list] button:hover { color: var(--boe-token-surface-surface-brand, #0061d5); text-decoration: underline; }\n [part=outline-list] button[aria-current=true] { color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=outline-list] p { margin: 2px 0 0; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.45; }\n [part=inspector-heading] { margin: 0 0 2px; font-size: 15px; font-weight: 650; }\n [part=inspector-heading][data-single=true]:not(:focus-visible) { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }\n [part=checks] { margin: 0; padding: 0; }\n [part=checks] button { width: 100%; border: 0; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 0; text-align: start; background: transparent; }\n [part=variable-row], [part=connection-row] { display: grid; gap: 4px; padding: 10px 0; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); font-size: 12.5px; }\n [part=variable-row] p { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=variable-scope] { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 11.5px; }\n [part=variable-row] label { display: grid; gap: 4px; font-weight: 650; }\n [part=variable-row] input { min-height: 36px; padding: 7px 10px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); }\n [part=help] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }\n :host([data-narrow]) [part=layout] { grid-template-columns: minmax(0,1fr); }\n :host([data-narrow]) [part=layout] { overflow: visible; }\n :host([data-narrow]) [part=pane-drawer] { display: none; position: absolute; z-index: 40; margin: 0; max-width: none; max-height: none; padding: 0; overflow: auto; border: 0; border-radius: 0; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .24)); }\n :host([data-narrow]) [part=pane-drawer][open] { display: block; }\n :host([data-narrow]) [part=pane-title] { display: block; position: absolute; top: 18px; left: 16px; margin: 0; font-size: 14px; font-weight: 650; line-height: 20px; }\n :host([data-narrow]) [part=pane-close], :host([data-narrow]) [data-command=palette], :host([data-narrow]) [data-command=details] { display: inline-block; }\n :host([data-narrow]) [part=pane-close] { position: absolute; top: 12px; right: 12px; z-index: 1; width: 28px; height: 28px; padding: 0; border-radius: 50%; font-size: 16px; font-weight: 600; line-height: 1; }\n :host([data-narrow]) [part=pane-drawer][data-pane=palette] { left: 0; top: 0; bottom: auto; width: min(320px, 86%); height: 100%; max-height: 100%; }\n :host([data-narrow]) [part=pane-drawer][data-pane=inspector] { left: 0; right: 0; top: auto; bottom: 0; width: 100%; height: min(62%, 560px); border-radius: 24px 24px 0 0; }\n :host([data-narrow]) [part=pane-drawer][data-pane=inspector]::before { content: ''; display: block; width: 36px; height: 4px; margin: 6px auto; border-radius: 2px; background: var(--boe-token-text-text-secondary, #767676); opacity: .55; }\n :host([data-narrow]) [part=palette], :host([data-narrow]) [part=inspector] { height: 100%; }\n :host([data-narrow]) [part=palette] { padding-top: 54px; }\n :host([data-narrow]) [part=palette-heading] { display: none; }\n :host([data-narrow]) [part=minimap] { display: none; }\n :host([data-narrow]) [part=toolbar] { justify-content: flex-start; }\n :host([data-narrow]) [data-command=palette] { order: -2; }\n :host([data-narrow]) [part=view-menu] { order: -1; }\n :host([data-narrow]) [part=view-switch], :host([data-narrow]) [part=run-toggle] { display: none; }\n :host([data-narrow]) [data-command=checks-status] { display: none; }\n :host([data-narrow]:not([embed-mode])) [part=view-menu] { display: block; }\n :host([data-narrow]) [part=controls] { left: 12px; bottom: 12px; }\n :host([data-narrow]) [part=selection-toolbar] [part=selection-plus] + span { display: none; }\n :host([data-phone]) [data-command=tidy] { display: none; }\n :host([data-phone]) [data-command=undo], :host([data-phone]) [data-command=redo] { display: none; }\n @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0s !important; animation-duration: 0s !important; scroll-behavior: auto !important; } }\n";
2
+ export declare const processModelerDesign = "\n :host([hidden]), [hidden] { display: none !important; }\n *, *::before, *::after { box-sizing: border-box; }\n button, input, textarea, select { font: inherit; color: inherit; }\n button { min-height: 36px; padding: 8px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); cursor: pointer; }\n button:disabled { opacity: .5; cursor: default; }\n :is(button,input,textarea,select,[part=canvas],[part=minimap],[part=box],[part=frame]):focus-visible { outline: 2px solid var(--boe-token-surface-surface-brand, #0061d5); outline-offset: 2px; }\n :host {\n display: block;\n position: relative;\n isolation: isolate;\n min-width: 0;\n --boe-process-box-edge: color-mix(in srgb, var(--boe-token-text-text, #141413) 55%, var(--boe-token-surface-surface, #fff));\n color: var(--boe-token-text-text, #141413);\n background: var(--boe-token-surface-surface, #fff);\n font: 14px/1.5 var(--boe-token-font-family-base, Inter, sans-serif);\n }\n [part=sr-only], [part=status], [part=urgent-status] { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }\n [part=toolbar] {\n min-height: 56px;\n margin: 0;\n padding: 8px 16px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n flex-wrap: wrap;\n border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8);\n background: var(--boe-token-surface-surface, #fff);\n }\n [part=toolbar] button, [part=controls] button, [part=selection-toolbar] button {\n min-height: 30px;\n padding: 4px 10px;\n border: 1px solid transparent;\n border-radius: 8px;\n background: transparent;\n font-size: 13px;\n font-weight: 600;\n }\n [part=toolbar] svg, [part=controls] svg { width: 16px; height: 16px; display: block; }\n [part=toolbar] [data-command=undo], [part=toolbar] [data-command=redo], [part=controls] button:not([data-command=reset]) { width: 30px; height: 30px; padding: 6px; display: grid; place-items: center; }\n [part=controls] [data-command=snap][aria-pressed=true], [part=controls] [data-command=lock][aria-pressed=true] { background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 10%, var(--boe-token-surface-surface, #fff)); color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=toolbar] button:hover, [part=controls] button:hover, [part=selection-toolbar] button:hover {\n background: var(--boe-token-surface-surface-hover, #f4f4f4);\n }\n [part=toolbar] [data-command=tidy] { border-color: var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 18px; }\n [part=view-switch] { display: flex; gap: 2px; padding: 3px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 20px; }\n [part=view-switch] button { border-radius: 16px; }\n [part=view-switch] button[aria-pressed=true] { border-color: var(--boe-token-stroke-stroke, #e8e8e8); background: var(--boe-token-surface-surface, #fff); }\n [part=run-toggle] { display: flex; align-items: center; gap: 8px; white-space: nowrap; font-size: 13px; font-weight: 600; cursor: pointer; }\n [part=run-toggle] input { appearance: none; position: relative; width: 32px; height: 18px; margin: 0; border: 0; border-radius: 9px; background: var(--boe-token-surface-surface-hover, #f4f4f4); cursor: pointer; transition: background var(--boe-profile-motion-interactive, 200ms) ease-out; }\n [part=run-toggle] input::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--boe-token-surface-surface, #fff); box-shadow: 0 1px 2px rgb(0 0 0 / .25); transition: transform var(--boe-profile-motion-interactive, 200ms) ease-out; }\n [part=run-toggle] input:checked { background: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=run-toggle] input:checked::after { transform: translateX(14px); }\n [part=run-toggle] input:focus-visible { outline: 2px solid var(--boe-token-surface-surface-brand, #0061d5); outline-offset: 2px; }\n [part=toolbar] [data-command=checks-status] { white-space: nowrap; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=toolbar] [data-command=checks-status][data-state=bad] { color: var(--boe-token-text-status-text-error, #b92340); }\n [part=view-menu] { display: none; position: relative; }\n [part=view-menu] summary { list-style: none; padding: 4px 14px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 18px; font-size: 13px; font-weight: 600; cursor: pointer; }\n [part=view-menu][open] { z-index: 20; }\n [part=view-menu-options] { position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; width: 192px; padding: 6px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 10px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=view-menu] button { display: block; width: 100%; text-align: start; background: transparent; }\n [part=layout] {\n display: grid;\n grid-template-columns: 248px minmax(0, 1fr) 320px;\n gap: 0;\n min-height: 0;\n height: var(--boe-process-height, 660px);\n overflow: hidden;\n }\n [part=pane-drawer] { display: contents; color: inherit; }\n [part=canvas-stack] { display: grid; grid-template-rows: auto minmax(0, 1fr); min-width: 0; min-height: 0; }\n /* The hidden hold leaves row 1 empty. Keep the canvas in the flexible row\n explicitly; auto-placement otherwise puts its absolute world in a 0px row. */\n [part=canvas-stack] > [part=hold] { grid-row: 1; }\n [part=canvas-stack] > [part=canvas] { grid-row: 2; }\n [part=insert-chooser]::backdrop { background: rgb(0 0 0 / .45); }\n [part=pane-scrim] { position: absolute; inset: 0; z-index: 30; background: rgb(0 0 0 / .45); }\n [part=pane-title], [part=pane-close], [data-command=palette], [data-command=details] { display: none; }\n [part=palette], [part=inspector] {\n min-width: 0;\n overflow: auto;\n padding: 12px;\n border: 0;\n border-radius: 0;\n background: var(--boe-token-surface-surface, #fff);\n }\n [part=palette] { display: flex; flex-direction: column; gap: 12px; border-right: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }\n [part=palette-heading] { margin: 0 4px; font-size: 14px; font-weight: 650; line-height: 20px; }\n [part=skip-link] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }\n [part=skip-link]:focus-visible { position: static; width: auto; height: auto; clip-path: none; }\n [part=inspector] { border-left: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); padding: 16px 0; }\n [part=palette] label { font-size: 0; position: relative; }\n [part=search-icon] { position: absolute; left: 12px; top: 9px; width: 18px; height: 18px; color: var(--boe-token-text-text-secondary, #6f6f6f); pointer-events: none; }\n [part=palette] input {\n width: 100%; min-width: 0;\n height: 36px;\n padding: 0 12px 0 36px;\n border: 1px solid transparent;\n border-radius: 24px;\n background: var(--boe-token-surface-surface-hover, #f4f4f4);\n font-size: 13px;\n }\n [part=palette] input:focus-visible { border-color: var(--boe-token-surface-surface-brand, #0061d5); background: var(--boe-token-surface-surface, #fff); }\n [part=choices] { display: grid; align-content: start; gap: 4px; max-height: none; overflow: visible; }\n [part=group] { margin: 4px 4px 6px; font-size: 12px; font-weight: 650; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=choice] {\n display: grid; grid-template-columns: 20px minmax(0,1fr); gap: 0 10px;\n min-height: 44px; padding: 8px 10px; border: 1px solid transparent; border-radius: 10px;\n text-align: start; background: transparent; cursor: grab;\n }\n [part=choice]:hover { border-color: var(--boe-token-stroke-stroke, #e8e8e8); background: var(--boe-token-surface-surface-hover, #f4f4f4); }\n [part=choice-icon] { grid-row: span 2; width: 20px; height: 20px; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=choice][data-tone=accent] [part=choice-icon] { color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=choice-icon] svg { width: 20px; height: 20px; }\n [part=choice-name] { font-size: 13px; font-weight: 600; line-height: 1.3; }\n [part=choice-description] { grid-column: 2; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.35; }\n [part=palette-hint] { margin: 4px; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.45; }\n [part=canvas] {\n position: relative; min-width: 0; height: 100%; overflow: hidden;\n border: 0; border-radius: 0;\n background-color: var(--boe-token-surface-surface-secondary, #fbfbfb);\n background-image: radial-gradient(circle, color-mix(in srgb, var(--boe-token-text-text-secondary, #6f6f6f) 26%, transparent) 1px, transparent 1.2px);\n background-size: 12px 12px;\n touch-action: none; user-select: none; cursor: grab;\n }\n [part=canvas][data-panning] { cursor: grabbing; }\n [part=hold] { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 16px; border-bottom: 1px solid color-mix(in srgb, var(--boe-token-text-status-text-warning, #9a6b00) 45%, var(--boe-token-stroke-stroke, #e8e8e8)); background: color-mix(in srgb, var(--boe-token-surface-status-surface-inprogress, #ffc447) 14%, var(--boe-token-surface-surface, #fff)); color: var(--boe-token-text-status-text-warning, #6b4a00); font-size: 13px; }\n [part=hold-text] { flex: 1 1 280px; min-width: 0; }\n [part=hold] button { min-height: 28px; padding: 3px 8px; border: 1px solid currentColor; border-radius: 6px; background: transparent; font-size: 12px; font-weight: 650; white-space: nowrap; }\n [part=world] { position: absolute; inset: 0; transform-origin: 0 0; }\n [part=lines] { position: absolute; inset: 0; width: 1px; height: 1px; overflow: visible; pointer-events: none; z-index: 3; }\n [part=line] { stroke: var(--boe-token-text-text-secondary, #6f6f6f); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; fill: none; }\n [part=line][data-selected=true] { stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 2; }\n [part=line][data-drop=true] { stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 2.5; stroke-dasharray: 6 4; }\n [part=line-hit] { fill: none; stroke: transparent; stroke-width: 24; pointer-events: stroke; }\n [part=connection-preview] { fill: none; stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 2.5; stroke-dasharray: 6 4; }\n [part=pinned-end] { fill: var(--boe-token-surface-surface-brand, #0061d5); pointer-events: none; }\n [part=box], [part=frame] {\n position: absolute; touch-action: none; text-align: start; z-index: 4; display: grid; grid-template-columns: 20px minmax(0,1fr); align-content: center;\n gap: 2px 10px; min-width: 0; min-height: 64px; padding: 11px 12px;\n border: 1px solid var(--boe-process-box-edge, var(--boe-control-edge, #858585));\n border-radius: 8px; background: var(--boe-token-surface-surface, #fff);\n font-size: 13px; line-height: 1.3;\n transition: border-color var(--boe-profile-motion-interactive, 200ms) ease-out,\n background var(--boe-profile-motion-interactive, 200ms) ease-out;\n }\n [part=box]:hover, [part=frame]:hover { border-color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [data-connect-target=true] { border-color: var(--boe-token-surface-surface-brand, #0061d5) !important; }\n [part=box] strong, [part=frame] strong { overflow-wrap: anywhere; }\n [part=box] strong, [part=frame] strong { font-size: 13.5px; font-weight: 650; line-height: 1.3; }\n [part=box] small, [part=frame] small { grid-column: 2; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; line-height: 1.35; }\n [part=technical-description] { font: 12px/1.4 ui-monospace, 'SF Mono', Menlo, Consolas, monospace !important; overflow-wrap: anywhere; }\n [part=metrics] { grid-column: 2; display: flex; gap: 6px; flex-wrap: wrap; margin-top: 3px; font-size: 12px; line-height: 1.45; font-variant-numeric: tabular-nums; }\n [part=metrics][data-state=unmeasured] { color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=metric-separator] { color: var(--boe-token-text-text-tertiary, #767676); }\n [part=technical-summary] { overflow-wrap: anywhere; }\n [part=technical-inline-code] { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; }\n [part=metric-warning] { color: var(--boe-token-text-status-text-warning, #8a5800); }\n [part=icon] { grid-row: span 3; width: 20px; height: 20px; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=icon] svg { display: block; width: 20px; height: 20px; }\n [data-tone=accent] > [part=icon] { color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=box][aria-current=true], [part=frame][aria-current=true] {\n border: 1px solid var(--boe-token-surface-surface-brand, #0061d5);\n background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 7%, var(--boe-token-surface-surface, #fff));\n }\n [data-invalid=true] { border-color: var(--boe-token-text-status-text-error, #b92340) !important; }\n [part=problem] { grid-column: 1 / -1; color: var(--boe-token-text-status-text-error, #b92340); font-size: 12px; }\n [part=frame] { z-index: 1; align-content: start; border-radius: 12px; background: color-mix(in srgb, var(--boe-token-surface-surface, #fff) 78%, transparent); }\n [part=frame] small { grid-column: 2; }\n [part=loop-mark] { position: absolute; right: 12px; bottom: 8px; font-size: 20px; line-height: 1; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=frame-resize] { position: absolute; right: -12px; bottom: -12px; z-index: 8; width: 28px; height: 28px; min-height: 28px; padding: 0; border: 0; border-radius: 8px; background: var(--boe-token-surface-surface, #fff); box-shadow: 0 0 0 1px var(--boe-process-box-edge, #858585); cursor: nwse-resize; }\n [part=frame-resize]::before { content: ''; position: absolute; right: 7px; bottom: 7px; width: 11px; height: 11px; border-right: 2px solid var(--boe-token-text-text-secondary, #6f6f6f); border-bottom: 2px solid var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=frame]:not([aria-current=true]) [part=frame-resize] { visibility: hidden; }\n [data-shape=gateway], [data-shape=event] { width: 56px !important; height: 56px !important; min-height: 0; padding: 0; border: 0 !important; background: transparent !important; display: block; overflow: visible; }\n [data-shape=gateway]::before { content: ''; position: absolute; left: 8px; top: 8px; width: 40px; height: 40px; rotate: 45deg; border: 1.5px solid var(--boe-process-box-edge, var(--boe-control-edge, #858585)); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); }\n [data-shape=event]::before { content: ''; position: absolute; left: 8px; top: 8px; width: 40px; height: 40px; border: 1.5px solid var(--boe-process-box-edge, var(--boe-control-edge, #858585)); border-radius: 50%; background: var(--boe-token-surface-surface, #fff); }\n [data-shape=event][data-kind=finish]::before { border-width: 4px; }\n [data-shape=event][data-kind=scheduled-start]::after { content: ''; position: absolute; left: 13px; top: 13px; width: 30px; height: 30px; border: 1px solid currentColor; border-radius: 50%; }\n [data-shape=gateway] > [part=icon], [data-shape=event] > [part=icon] { position: absolute; left: 18px; top: 18px; z-index: 1; }\n [data-shape=gateway] > strong, [data-shape=event] > strong { position: absolute; top: 58px; left: 50%; width: 150px; translate: -50% 0; text-align: center; font-size: 12px; }\n [data-shape=gateway] > small { display: none; }\n [part=caption] { position: absolute; left: 50%; translate: -50% 0; width: max-content; max-width: 168px; padding: 1px 4px; border-radius: 4px; text-align: center; background: color-mix(in srgb, var(--boe-token-surface-surface-hover, #f4f4f4) 88%, transparent); }\n [part=caption][data-side=below] { top: 60px; }\n [part=caption][data-side=above] { bottom: 60px; }\n [part=caption] strong { font-size: 12.5px; font-weight: 600; line-height: 1.3; }\n [part=caption] small { display: block; font-weight: 400; }\n [part=caption] [part=technical-description] { font: 10.5px ui-monospace, 'SF Mono', Menlo, Consolas, monospace !important; white-space: nowrap; }\n [data-shape=event] > small { position: absolute; top: 75px; left: 50%; width: 172px; translate: -50% 0; text-align: center; font-size: 11px; line-height: 1.25; }\n [part=event-details] { position: absolute; top: 75px; left: 50%; width: 172px; translate: -50% 0; text-align: center; }\n [part=event-details] small { display: block; font-size: 11px; line-height: 1.25; }\n [data-shape=gateway][aria-current=true]::before, [data-shape=event][aria-current=true]::before { border-color: var(--boe-token-surface-surface-brand, #0061d5); background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 7%, var(--boe-token-surface-surface, #fff)); }\n [part=port] { position: absolute; z-index: 5; width: 24px; height: 24px; min-height: 24px; padding: 0; border: 0; border-radius: 50%; background: transparent; opacity: 0; }\n [part=port][data-side=north] { left: calc(50% - 12px); top: -12px; }\n [part=port][data-side=south] { left: calc(50% - 12px); bottom: -12px; }\n [part=port][data-side=east] { right: -12px; top: calc(50% - 12px); }\n [part=port][data-side=west] { left: -12px; top: calc(50% - 12px); }\n [part=port]::before { content: ''; display: block; width: 10px; height: 10px; margin: 7px; border: 1.5px solid var(--boe-token-surface-surface-brand, #0061d5); border-radius: 50%; background: var(--boe-token-surface-surface, #fff); }\n [part=port]:hover::before, [part=port]:focus-visible::before { width: 22px; height: 22px; margin: 1px; background: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=port]::after { position: absolute; inset: 1px; display: none; place-items: center; color: #fff; font-size: 15px; font-weight: 700; line-height: 1; }\n [part=port][data-side=north]::after { content: '\u2191'; }\n [part=port][data-side=east]::after { content: '\u2192'; }\n [part=port][data-side=south]::after { content: '\u2193'; }\n [part=port][data-side=west]::after { content: '\u2190'; }\n [part=port]:hover::after, [part=port]:focus-visible::after, [part=port][data-hot=true]::after { display: grid; }\n [part=port][data-hot=true] { opacity: 1; }\n [part=port][data-hot=true]::before { width: 22px; height: 22px; margin: 1px; background: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=end-grip] { position: absolute; z-index: 8; width: 24px; height: 24px; min-height: 24px; padding: 0; border: 0; border-radius: 50%; background: transparent; }\n [part=end-grip]::before { content: ''; display: block; width: 10px; height: 10px; margin: 7px; border: 1.5px solid var(--boe-token-surface-surface-brand, #0061d5); border-radius: 50%; background: var(--boe-token-surface-surface, #fff); }\n [part=box]:hover [part=port], [part=box]:focus-within [part=port], [part=box][aria-current=true] [part=port], [part=frame]:hover [part=port] { opacity: 1; }\n [part=connection] { position: absolute; z-index: 5; display: flex; align-items: center; gap: 4px; transform: translate(-50%,-50%); min-width: 0; min-height: 0; padding: 2px 6px; border-radius: 6px; background: var(--boe-token-surface-surface-secondary, #fbfbfb); font-size: 12px; font-weight: 600; white-space: nowrap; }\n /* Unlabelled lines still need a reachable midpoint for pointer insert/selection. */\n [part=connection]:has(> span:empty):not(:has(> small)) { padding: 0; background: transparent; min-width: calc(24px * var(--boe-process-inverse-zoom, 1)); min-height: calc(24px * var(--boe-process-inverse-zoom, 1)); }\n [part=connection] > small { margin-left: 4px; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 11px; font-weight: 400; font-variant-numeric: tabular-nums; }\n [part=connection-actions] { position: absolute; top: 100%; left: 50%; transform: translateX(-50%); display: flex; gap: 4px; width: max-content; padding: 4px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); opacity: 0; pointer-events: none; }\n [part=connection]:hover [part=connection-actions], [part=connection]:focus-within [part=connection-actions] { opacity: 1; pointer-events: auto; }\n [part=connection-actions] button { min-height: 32px; padding: 4px; font-size: 12px; }\n [part=note] { width: 208px; border: 1px dashed var(--boe-process-box-edge, var(--boe-control-edge, #858585)); border-radius: 8px; }\n [part=section] { z-index: 0; border: 1px solid var(--boe-process-box-edge, var(--boe-control-edge, #858585)); border-radius: 16px; background: color-mix(in srgb, var(--boe-token-surface-surface, #fff) 45%, transparent); }\n [part=section] strong { display: block; font-size: 12.5px; font-weight: 650; line-height: 1.3; }\n [part=section] small { display: block; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 11.5px; line-height: 1.35; }\n [part=note], [part=section] { position: absolute; padding: 8px; pointer-events: none; }\n [part=marquee] { position: absolute; border: 2px solid var(--boe-token-surface-surface-brand, #0061d5); background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 12%, transparent); pointer-events: none; }\n [part=connect-tooltip] { position: absolute; z-index: 20; max-width: 240px; padding: 5px 8px; border-radius: 7px; background: var(--boe-token-text-text, #141413); color: var(--boe-token-surface-surface, #fff); font-size: 12px; pointer-events: none; box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=connect-tooltip][data-invalid=true] { background: var(--boe-token-text-status-text-error, #b92340); color: #fff; }\n [part=ghost-box], [part=palette-ghost] { position: absolute; z-index: 5; display: flex; align-items: center; padding: 11px 12px; border: 1.5px dashed var(--boe-token-surface-surface-brand, #0061d5); border-radius: 8px; background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 10%, var(--boe-token-surface-surface, #fff)); font-size: 13px; font-weight: 650; pointer-events: none; }\n [part=guide] { position: absolute; background: var(--boe-token-surface-surface-brand, #0061d5); pointer-events: none; }\n [part=measure] { position: absolute; padding: 4px; background: var(--boe-token-surface-surface, #fff); font-size: 12px; pointer-events: none; }\n [part=insert-chooser] { max-width: calc(100vw - 32px); max-height: 65vh; overflow: auto; padding: 12px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); }\n [part=keyboard-chooser] { position: fixed; inset: auto; width: min(320px, calc(100vw - 24px)); max-height: min(420px, calc(100dvh - 24px)); margin: 0; overflow: auto; padding: 12px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); color: var(--boe-token-text-text, #141413); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=chooser-title] { margin: 0 0 10px; font-size: 12px; font-weight: 650; line-height: 1.4; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=controls] { position: absolute; left: 16px; bottom: 16px; z-index: 10; display: flex; align-items: center; gap: 2px; padding: 4px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=controls] [data-command=reset] { min-width: 56px; font-variant-numeric: tabular-nums; }\n [part=minimap] { position: absolute; right: 16px; bottom: 16px; width: 208px; height: 136px; touch-action: none; background: var(--boe-token-surface-surface, #fff); border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=minimap] rect:not([data-viewport]) { fill: color-mix(in srgb, var(--boe-token-text-text-secondary, #6f6f6f) 35%, transparent); }\n [part=minimap] rect[data-selected=true] { fill: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=minimap] rect[data-section] { fill: color-mix(in srgb, var(--boe-token-text-text-secondary, #6f6f6f) 8%, transparent); }\n [part=minimap] [data-viewport] { fill: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 8%, transparent); stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 1.5; vector-effect: non-scaling-stroke; }\n [part=selection-toolbar] { position: absolute; bottom: auto; z-index: 11; display: flex; flex-wrap: nowrap; gap: 2px; padding: 4px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); white-space: nowrap; }\n [part=selection-toolbar] button { display: inline-flex; align-items: center; gap: 4px; }\n [part=selection-plus] { font-size: 18px; line-height: 12px; font-weight: 500; }\n [part=checks] { display: grid; gap: 6px; margin: 0; padding: 0; }\n [part=checks] button { width: 100%; display: grid; grid-template-columns: 16px 1fr; align-items: start; gap: 8px; padding: 8px 10px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 10px; text-align: start; background: var(--boe-token-surface-surface, #fff); color: var(--boe-token-text-text, #222); line-height: 1.45; }\n [part=check-icon] { flex: 0 0 16px; width: 16px; height: 16px; margin-top: 1px; color: var(--boe-token-text-status-text-error, #b92340); }\n [part=checks] strong { display: block; font-size: 13px; font-weight: 600; line-height: 1.45; }\n [part=checks] small { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; }\n [part=check-icon][data-tone=success] { color: var(--boe-token-text-status-text-success, #138a58); }\n [part=problem] { display: flex; align-items: center; gap: 4px; }\n [part=problem] [part=check-icon] { flex-basis: 12px; width: 12px; height: 12px; margin: 0; }\n [part=checks-ready] { display: flex; align-items: center; gap: 8px; margin: 0; color: var(--boe-token-text-text, #222); font-size: 13px; line-height: 1.45; }\n [part=process-heading] { display: grid; gap: 2px; padding: 0 16px 12px; }\n [part=process-title] { font-size: 15px; line-height: 1.4; }\n [part=process-summary] { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; }\n [part=pane-tabs] { display: flex; flex-wrap: nowrap; gap: 4px; margin: 0; padding: 0 16px; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); overflow-x: auto; }\n [part=pane-tabs] button { flex: none; min-height: 40px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: transparent; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 13px; font-weight: 600; }\n [part=pane-tabs] button[aria-selected=true] { color: var(--boe-token-text-text, #141413); border-bottom-color: currentColor; }\n [part=editor], [part=pane-content] { padding: 8px 16px; }\n [part=editor] { display: grid; align-content: start; gap: 12px; }\n [part=inspector-kind] { display: none; }\n [part=inspector-purpose] { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; }\n [part=field] { display: grid; gap: 4px; }\n [part=field] label { display: grid; gap: 5px; font-size: 12.5px; font-weight: 650; }\n [part=field] :is(input:not([type=checkbox]),textarea,select) { width: 100%; min-height: 36px; padding: 7px 10px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); color: var(--boe-token-text-text, #141413); font-family: inherit; font-size: 13px; line-height: 1.4; }\n [part=field] textarea { min-height: 76px; resize: vertical; }\n [part=field]:has([part=action-options]) { position: relative; }\n [part=field]:has([part=action-options]) input { padding-right: 34px; }\n [part=action-caret] { position: absolute; z-index: 1; top: 25px; right: 2px; width: 32px; min-height: 32px; padding: 0; border: 0; background: transparent; font-size: 18px; }\n [part=action-options] { position: absolute; z-index: 30; top: calc(100% - 1px); left: 0; right: 0; max-height: 280px; overflow: auto; padding: 6px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 10px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }\n [part=action-options][hidden] { display: none; }\n [part=action-options] button { display: block; width: 100%; min-height: 36px; padding: 7px 9px; border: 0; border-radius: 7px; text-align: start; background: transparent; font-size: 12.5px; }\n [part=action-options] button:hover, [part=action-options] [aria-selected=true] { background: var(--boe-token-surface-surface-hover, #f4f4f4); }\n [part=action-options] button strong { display: block; font-size: 13px; font-weight: 650; }\n [part=action-options] button small { display: block; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=action-options] [part=action-back] { color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=field] input[type=checkbox] { justify-self: start; width: 18px; height: 18px; accent-color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=field] small { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.4; }\n [part=field] [part=field-problem] { color: var(--boe-token-text-status-text-error, #b92340); }\n [part=variable-chips] { display: flex; flex-wrap: wrap; gap: 4px; }\n [part=variable-chips] button { min-height: 24px; padding: 2px 8px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface-secondary, #fbfbfb); font-size: 11.5px; }\n [part=leads-to] { display: grid; gap: 6px; padding-top: 10px; border-top: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }\n [part=leads-to] h3 { margin: 0; font-size: 12.5px; }\n [part=lead-row] { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12.5px; }\n [part=lead-row] button, [part=leads-to] > button, [part=inspector-actions] button { min-height: 28px; padding: 4px 8px; font-size: 12px; }\n [part=inspector-metrics] { margin: 0; font-size: 12.5px; line-height: 1.5; font-variant-numeric: tabular-nums; }\n [part=inspector-metrics] h3 { margin: 0 0 6px; font-size: 12.5px; }\n [part=inspector-metrics] p { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=inspector-metrics] table { width: 100%; border-collapse: collapse; font-size: 13px; line-height: 1.45; }\n [part=inspector-metrics] :is(th,td) { padding: 5px 0; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); font-weight: 400; }\n [part=inspector-metrics] th { text-align: start; }\n [part=inspector-metrics] td { text-align: end; font-variant-numeric: tabular-nums; }\n [part=inspector-actions] { display: flex; gap: 8px; padding-top: 10px; border-top: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }\n [part=arrange-actions] { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 6px; }\n [part=arrange-actions] button { min-height: 32px; padding: 5px 7px; font-size: 12px; text-align: start; }\n [part=outline-intro] { margin: 4px 0 14px; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; line-height: 1.5; }\n [part=copy-outline] { justify-self: start; min-height: 32px; margin-top: 4px; padding: 0 14px; border-radius: 20px; font-size: 13px; font-weight: 600; letter-spacing: .01em; }\n [part=outline-list] { margin: 0; padding-left: 22px; font-size: 13.5px; line-height: 1.5; }\n [part=outline-list] [part=outline-list] { margin-top: 2px; }\n [part=outline-list] li { margin: 3px 0; padding-left: 2px; }\n [part=outline-list] li::marker { color: var(--boe-token-text-text-secondary, #6f6f6f); font-variant-numeric: tabular-nums; font-size: 12.5px; }\n [part=outline-list] button, [part=outline-list] strong { border: 0; border-radius: 4px; background: transparent; padding: 0; min-height: 24px; display: inline-block; font-size: 13.5px; font-weight: 600; line-height: 24px; text-align: start; }\n [part=outline-list] button:hover { color: var(--boe-token-surface-surface-brand, #0061d5); text-decoration: underline; text-underline-offset: 2px; }\n [part=outline-list] button[aria-current=true] { color: var(--boe-token-surface-surface-brand, #0061d5); }\n [part=outline-list] p { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; line-height: 1.5; }\n [part=inspector-heading] { margin: 0 0 2px; font-size: 15px; font-weight: 650; }\n [part=inspector-heading][data-single=true]:not(:focus-visible) { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }\n [part=variable-row], [part=connection-row] { display: grid; gap: 4px; padding: 10px 0; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); font-size: 12.5px; }\n :host([data-variables-editable]) [part=variable-row] { grid-template-columns: minmax(0,1fr) minmax(0,1fr) 32px; gap: 6px; align-items: center; }\n :host([data-variables-editable]) [part=variable-row] label:has([data-variable-key=name]) { grid-column: 1; grid-row: 1; }\n :host([data-variables-editable]) [part=variable-row] label:has([data-variable-key=value]) { grid-column: 2; grid-row: 1; }\n :host([data-variables-editable]) [part=variable-row] label:has([data-variable-key=scope]) { grid-column: 2; grid-row: 2; }\n :host([data-variables-editable]) [part=variable-remove] { grid-column: 3; grid-row: 1; }\n :host([data-variables-editable]) [part=variable-row] :is(input,select) { width: 100%; min-width: 0; min-height: 32px; border-radius: 10px; font-size: 12.5px; }\n :host([data-variables-editable]) [part=variable-row] p { grid-column: 1 / -1; }\n :host([data-variables-editable]) [part=variable-row] [part=field-problem] { color: var(--boe-token-text-status-text-error, #b92340); }\n [part=variable-remove], [part=variable-add] { min-height: 32px; align-self: end; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); color: inherit; cursor: pointer; }\n [part=variable-row] p { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); }\n [part=variable-scope] { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 11.5px; }\n [part=variable-row] label { display: grid; gap: 4px; font-weight: 650; }\n [part=variable-row] :is(input,select) { min-height: 36px; padding: 7px 10px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); }\n [part=help] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }\n :host([data-narrow]) [part=layout] { grid-template-columns: minmax(0,1fr); }\n :host([data-narrow]) [part=layout] { overflow: visible; }\n :host([data-narrow]) [part=pane-drawer] { display: none; position: absolute; z-index: 40; margin: 0; max-width: none; max-height: none; padding: 0; overflow: auto; border: 0; border-radius: 0; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .24)); }\n :host([data-narrow]) [part=pane-drawer][open] { display: block; }\n :host([data-narrow]) [part=pane-title] { display: block; position: absolute; top: 18px; left: 16px; margin: 0; font-size: 14px; font-weight: 650; line-height: 20px; }\n :host([data-narrow]) [part=pane-close], :host([data-narrow]) [data-command=palette], :host([data-narrow]) [data-command=details] { display: inline-block; }\n :host([data-narrow]) [part=pane-close] { position: absolute; top: 12px; right: 12px; z-index: 1; width: 28px; height: 28px; padding: 0; border-radius: 50%; font-size: 16px; font-weight: 600; line-height: 1; }\n :host([data-narrow]) [part=pane-drawer][data-pane=palette] { left: 0; top: 0; bottom: auto; width: min(320px, 86%); height: 100%; max-height: 100%; }\n :host([data-narrow]) [part=pane-drawer][data-pane=inspector] { left: 0; right: 0; top: auto; bottom: 0; width: 100%; height: min(62%, 560px); border-radius: 24px 24px 0 0; }\n :host([data-narrow]) [part=pane-drawer][data-pane=inspector]::before { content: ''; display: block; width: 36px; height: 4px; margin: 6px auto; border-radius: 2px; background: var(--boe-token-text-text-secondary, #767676); opacity: .55; }\n :host([data-narrow]) [part=palette], :host([data-narrow]) [part=inspector] { height: 100%; }\n :host([data-narrow]) [part=inspector] { border-left: 0; }\n :host([data-narrow]) [part=palette] { padding-top: 54px; }\n :host([data-narrow]) [part=palette-heading] { display: none; }\n :host([data-narrow]) [part=minimap] { display: none; }\n :host([data-narrow]) [part=toolbar] { justify-content: flex-start; }\n :host([data-narrow]) [data-command=palette] { order: -2; }\n :host([data-narrow]) [part=view-menu] { order: -1; }\n :host([data-narrow]) [part=view-switch], :host([data-narrow]) [part=run-toggle] { display: none; }\n :host([data-narrow]) [data-command=checks-status] { display: none; }\n :host([data-narrow]) [part=view-menu] { display: block; }\n :host([data-narrow]) [part=controls] { left: 12px; bottom: 12px; }\n :host([data-narrow]) [part=selection-toolbar] [part=selection-plus] + span { display: none; }\n :host([data-phone]) [data-command=tidy] { display: none; }\n :host([data-phone]) [data-command=undo], :host([data-phone]) [data-command=redo] { display: none; }\n @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0s !important; animation-duration: 0s !important; scroll-behavior: auto !important; } }\n";
@@ -126,7 +126,7 @@ export const processModelerDesign = `
126
126
  touch-action: none; user-select: none; cursor: grab;
127
127
  }
128
128
  [part=canvas][data-panning] { cursor: grabbing; }
129
- [part=hold] { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 16px; border-bottom: 1px solid var(--boe-token-stroke-status-stroke-warning, #9a6b00); background: var(--boe-token-surface-status-surface-warning, #fff7df); color: var(--boe-token-text-status-text-warning, #6b4a00); font-size: 13px; }
129
+ [part=hold] { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 10px 16px; border-bottom: 1px solid color-mix(in srgb, var(--boe-token-text-status-text-warning, #9a6b00) 45%, var(--boe-token-stroke-stroke, #e8e8e8)); background: color-mix(in srgb, var(--boe-token-surface-status-surface-inprogress, #ffc447) 14%, var(--boe-token-surface-surface, #fff)); color: var(--boe-token-text-status-text-warning, #6b4a00); font-size: 13px; }
130
130
  [part=hold-text] { flex: 1 1 280px; min-width: 0; }
131
131
  [part=hold] button { min-height: 28px; padding: 3px 8px; border: 1px solid currentColor; border-radius: 6px; background: transparent; font-size: 12px; font-weight: 650; white-space: nowrap; }
132
132
  [part=world] { position: absolute; inset: 0; transform-origin: 0 0; }
@@ -152,7 +152,11 @@ export const processModelerDesign = `
152
152
  [part=box] strong, [part=frame] strong { font-size: 13.5px; font-weight: 650; line-height: 1.3; }
153
153
  [part=box] small, [part=frame] small { grid-column: 2; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; line-height: 1.35; }
154
154
  [part=technical-description] { font: 12px/1.4 ui-monospace, 'SF Mono', Menlo, Consolas, monospace !important; overflow-wrap: anywhere; }
155
- [part=metrics] { grid-column: 2; font-size: 12px; font-variant-numeric: tabular-nums; }
155
+ [part=metrics] { grid-column: 2; display: flex; gap: 6px; flex-wrap: wrap; margin-top: 3px; font-size: 12px; line-height: 1.45; font-variant-numeric: tabular-nums; }
156
+ [part=metrics][data-state=unmeasured] { color: var(--boe-token-text-text-secondary, #6f6f6f); }
157
+ [part=metric-separator] { color: var(--boe-token-text-text-tertiary, #767676); }
158
+ [part=technical-summary] { overflow-wrap: anywhere; }
159
+ [part=technical-inline-code] { font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; }
156
160
  [part=metric-warning] { color: var(--boe-token-text-status-text-warning, #8a5800); }
157
161
  [part=icon] { grid-row: span 3; width: 20px; height: 20px; color: var(--boe-token-text-text-secondary, #6f6f6f); }
158
162
  [part=icon] svg { display: block; width: 20px; height: 20px; }
@@ -177,7 +181,15 @@ export const processModelerDesign = `
177
181
  [data-shape=gateway] > [part=icon], [data-shape=event] > [part=icon] { position: absolute; left: 18px; top: 18px; z-index: 1; }
178
182
  [data-shape=gateway] > strong, [data-shape=event] > strong { position: absolute; top: 58px; left: 50%; width: 150px; translate: -50% 0; text-align: center; font-size: 12px; }
179
183
  [data-shape=gateway] > small { display: none; }
184
+ [part=caption] { position: absolute; left: 50%; translate: -50% 0; width: max-content; max-width: 168px; padding: 1px 4px; border-radius: 4px; text-align: center; background: color-mix(in srgb, var(--boe-token-surface-surface-hover, #f4f4f4) 88%, transparent); }
185
+ [part=caption][data-side=below] { top: 60px; }
186
+ [part=caption][data-side=above] { bottom: 60px; }
187
+ [part=caption] strong { font-size: 12.5px; font-weight: 600; line-height: 1.3; }
188
+ [part=caption] small { display: block; font-weight: 400; }
189
+ [part=caption] [part=technical-description] { font: 10.5px ui-monospace, 'SF Mono', Menlo, Consolas, monospace !important; white-space: nowrap; }
180
190
  [data-shape=event] > small { position: absolute; top: 75px; left: 50%; width: 172px; translate: -50% 0; text-align: center; font-size: 11px; line-height: 1.25; }
191
+ [part=event-details] { position: absolute; top: 75px; left: 50%; width: 172px; translate: -50% 0; text-align: center; }
192
+ [part=event-details] small { display: block; font-size: 11px; line-height: 1.25; }
181
193
  [data-shape=gateway][aria-current=true]::before, [data-shape=event][aria-current=true]::before { border-color: var(--boe-token-surface-surface-brand, #0061d5); background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 7%, var(--boe-token-surface-surface, #fff)); }
182
194
  [part=port] { position: absolute; z-index: 5; width: 24px; height: 24px; min-height: 24px; padding: 0; border: 0; border-radius: 50%; background: transparent; opacity: 0; }
183
195
  [part=port][data-side=north] { left: calc(50% - 12px); top: -12px; }
@@ -221,15 +233,23 @@ export const processModelerDesign = `
221
233
  [part=controls] { position: absolute; left: 16px; bottom: 16px; z-index: 10; display: flex; align-items: center; gap: 2px; padding: 4px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }
222
234
  [part=controls] [data-command=reset] { min-width: 56px; font-variant-numeric: tabular-nums; }
223
235
  [part=minimap] { position: absolute; right: 16px; bottom: 16px; width: 208px; height: 136px; touch-action: none; background: var(--boe-token-surface-surface, #fff); border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); }
224
- [part=minimap] rect:not([data-viewport]) { fill: var(--boe-token-stroke-stroke-hover, #d3d3d3); }
225
- [part=minimap] [data-viewport] { fill: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 9%, transparent); stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 1; }
236
+ [part=minimap] rect:not([data-viewport]) { fill: color-mix(in srgb, var(--boe-token-text-text-secondary, #6f6f6f) 35%, transparent); }
237
+ [part=minimap] rect[data-selected=true] { fill: var(--boe-token-surface-surface-brand, #0061d5); }
238
+ [part=minimap] rect[data-section] { fill: color-mix(in srgb, var(--boe-token-text-text-secondary, #6f6f6f) 8%, transparent); }
239
+ [part=minimap] [data-viewport] { fill: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 8%, transparent); stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
226
240
  [part=selection-toolbar] { position: absolute; bottom: auto; z-index: 11; display: flex; flex-wrap: nowrap; gap: 2px; padding: 4px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 12px; background: var(--boe-token-surface-surface, #fff); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); white-space: nowrap; }
227
241
  [part=selection-toolbar] button { display: inline-flex; align-items: center; gap: 4px; }
228
242
  [part=selection-plus] { font-size: 18px; line-height: 12px; font-weight: 500; }
229
- [part=checks] { display: grid; gap: 6px; margin-top: 12px; }
230
- [part=checks] button { color: var(--boe-token-text-status-text-error, #b92340); }
243
+ [part=checks] { display: grid; gap: 6px; margin: 0; padding: 0; }
244
+ [part=checks] button { width: 100%; display: grid; grid-template-columns: 16px 1fr; align-items: start; gap: 8px; padding: 8px 10px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 10px; text-align: start; background: var(--boe-token-surface-surface, #fff); color: var(--boe-token-text-text, #222); line-height: 1.45; }
245
+ [part=check-icon] { flex: 0 0 16px; width: 16px; height: 16px; margin-top: 1px; color: var(--boe-token-text-status-text-error, #b92340); }
246
+ [part=checks] strong { display: block; font-size: 13px; font-weight: 600; line-height: 1.45; }
247
+ [part=checks] small { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; }
248
+ [part=check-icon][data-tone=success] { color: var(--boe-token-text-status-text-success, #138a58); }
249
+ [part=problem] { display: flex; align-items: center; gap: 4px; }
250
+ [part=problem] [part=check-icon] { flex-basis: 12px; width: 12px; height: 12px; margin: 0; }
251
+ [part=checks-ready] { display: flex; align-items: center; gap: 8px; margin: 0; color: var(--boe-token-text-text, #222); font-size: 13px; line-height: 1.45; }
231
252
  [part=process-heading] { display: grid; gap: 2px; padding: 0 16px 12px; }
232
- :host([embed-mode]) [part=view-switch], :host([embed-mode]) [part=run-toggle], :host([embed-mode]) [part=view-menu] { display: none; }
233
253
  [part=process-title] { font-size: 15px; line-height: 1.4; }
234
254
  [part=process-summary] { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; }
235
255
  [part=pane-tabs] { display: flex; flex-wrap: nowrap; gap: 4px; margin: 0; padding: 0 16px; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); overflow-x: auto; }
@@ -262,34 +282,42 @@ export const processModelerDesign = `
262
282
  [part=leads-to] h3 { margin: 0; font-size: 12.5px; }
263
283
  [part=lead-row] { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12.5px; }
264
284
  [part=lead-row] button, [part=leads-to] > button, [part=inspector-actions] button { min-height: 28px; padding: 4px 8px; font-size: 12px; }
265
- [part=inspector-metrics] { margin: 0; padding-top: 10px; border-top: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); font-size: 12px; font-variant-numeric: tabular-nums; }
285
+ [part=inspector-metrics] { margin: 0; font-size: 12.5px; line-height: 1.5; font-variant-numeric: tabular-nums; }
266
286
  [part=inspector-metrics] h3 { margin: 0 0 6px; font-size: 12.5px; }
267
- [part=inspector-metrics] p { margin: 0 0 8px; color: var(--boe-token-text-text-secondary, #6f6f6f); }
268
- [part=inspector-metrics] dl { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; margin: 0; }
269
- [part=inspector-metrics] dt { color: var(--boe-token-text-text-secondary, #6f6f6f); }
270
- [part=inspector-metrics] dd { margin: 0; font-weight: 650; }
287
+ [part=inspector-metrics] p { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); }
288
+ [part=inspector-metrics] table { width: 100%; border-collapse: collapse; font-size: 13px; line-height: 1.45; }
289
+ [part=inspector-metrics] :is(th,td) { padding: 5px 0; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); font-weight: 400; }
290
+ [part=inspector-metrics] th { text-align: start; }
291
+ [part=inspector-metrics] td { text-align: end; font-variant-numeric: tabular-nums; }
271
292
  [part=inspector-actions] { display: flex; gap: 8px; padding-top: 10px; border-top: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }
272
293
  [part=arrange-actions] { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 6px; }
273
294
  [part=arrange-actions] button { min-height: 32px; padding: 5px 7px; font-size: 12px; text-align: start; }
274
295
  [part=outline-intro] { margin: 4px 0 14px; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; line-height: 1.5; }
275
- [part=copy-outline] { justify-self: start; min-height: 28px; margin-bottom: 8px; padding: 4px 10px; border-radius: 16px; font-size: 12px; font-weight: 650; }
276
- [part=outline-list] { margin: 0; padding-left: 18px; display: grid; gap: 8px; }
277
- [part=outline-list] [part=outline-list] { margin: 6px 0 0; gap: 6px; }
278
- [part=outline-list] li { padding-left: 0; font-size: 12.5px; }
279
- [part=outline-list] li::marker { color: var(--boe-token-text-text-secondary, #6f6f6f); }
280
- [part=outline-list] button, [part=outline-list] strong { border: 0; border-radius: 4px; background: transparent; padding: 0; min-height: 0; font-size: 12.5px; font-weight: 650; line-height: 1.45; text-align: start; }
281
- [part=outline-list] button:hover { color: var(--boe-token-surface-surface-brand, #0061d5); text-decoration: underline; }
296
+ [part=copy-outline] { justify-self: start; min-height: 32px; margin-top: 4px; padding: 0 14px; border-radius: 20px; font-size: 13px; font-weight: 600; letter-spacing: .01em; }
297
+ [part=outline-list] { margin: 0; padding-left: 22px; font-size: 13.5px; line-height: 1.5; }
298
+ [part=outline-list] [part=outline-list] { margin-top: 2px; }
299
+ [part=outline-list] li { margin: 3px 0; padding-left: 2px; }
300
+ [part=outline-list] li::marker { color: var(--boe-token-text-text-secondary, #6f6f6f); font-variant-numeric: tabular-nums; font-size: 12.5px; }
301
+ [part=outline-list] button, [part=outline-list] strong { border: 0; border-radius: 4px; background: transparent; padding: 0; min-height: 24px; display: inline-block; font-size: 13.5px; font-weight: 600; line-height: 24px; text-align: start; }
302
+ [part=outline-list] button:hover { color: var(--boe-token-surface-surface-brand, #0061d5); text-decoration: underline; text-underline-offset: 2px; }
282
303
  [part=outline-list] button[aria-current=true] { color: var(--boe-token-surface-surface-brand, #0061d5); }
283
- [part=outline-list] p { margin: 2px 0 0; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.45; }
304
+ [part=outline-list] p { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; line-height: 1.5; }
284
305
  [part=inspector-heading] { margin: 0 0 2px; font-size: 15px; font-weight: 650; }
285
306
  [part=inspector-heading][data-single=true]:not(:focus-visible) { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
286
- [part=checks] { margin: 0; padding: 0; }
287
- [part=checks] button { width: 100%; border: 0; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 0; text-align: start; background: transparent; }
288
307
  [part=variable-row], [part=connection-row] { display: grid; gap: 4px; padding: 10px 0; border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); font-size: 12.5px; }
308
+ :host([data-variables-editable]) [part=variable-row] { grid-template-columns: minmax(0,1fr) minmax(0,1fr) 32px; gap: 6px; align-items: center; }
309
+ :host([data-variables-editable]) [part=variable-row] label:has([data-variable-key=name]) { grid-column: 1; grid-row: 1; }
310
+ :host([data-variables-editable]) [part=variable-row] label:has([data-variable-key=value]) { grid-column: 2; grid-row: 1; }
311
+ :host([data-variables-editable]) [part=variable-row] label:has([data-variable-key=scope]) { grid-column: 2; grid-row: 2; }
312
+ :host([data-variables-editable]) [part=variable-remove] { grid-column: 3; grid-row: 1; }
313
+ :host([data-variables-editable]) [part=variable-row] :is(input,select) { width: 100%; min-width: 0; min-height: 32px; border-radius: 10px; font-size: 12.5px; }
314
+ :host([data-variables-editable]) [part=variable-row] p { grid-column: 1 / -1; }
315
+ :host([data-variables-editable]) [part=variable-row] [part=field-problem] { color: var(--boe-token-text-status-text-error, #b92340); }
316
+ [part=variable-remove], [part=variable-add] { min-height: 32px; align-self: end; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); color: inherit; cursor: pointer; }
289
317
  [part=variable-row] p { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); }
290
318
  [part=variable-scope] { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 11.5px; }
291
319
  [part=variable-row] label { display: grid; gap: 4px; font-weight: 650; }
292
- [part=variable-row] input { min-height: 36px; padding: 7px 10px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); }
320
+ [part=variable-row] :is(input,select) { min-height: 36px; padding: 7px 10px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 8px; background: var(--boe-token-surface-surface, #fff); }
293
321
  [part=help] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
294
322
  :host([data-narrow]) [part=layout] { grid-template-columns: minmax(0,1fr); }
295
323
  :host([data-narrow]) [part=layout] { overflow: visible; }
@@ -302,6 +330,7 @@ export const processModelerDesign = `
302
330
  :host([data-narrow]) [part=pane-drawer][data-pane=inspector] { left: 0; right: 0; top: auto; bottom: 0; width: 100%; height: min(62%, 560px); border-radius: 24px 24px 0 0; }
303
331
  :host([data-narrow]) [part=pane-drawer][data-pane=inspector]::before { content: ''; display: block; width: 36px; height: 4px; margin: 6px auto; border-radius: 2px; background: var(--boe-token-text-text-secondary, #767676); opacity: .55; }
304
332
  :host([data-narrow]) [part=palette], :host([data-narrow]) [part=inspector] { height: 100%; }
333
+ :host([data-narrow]) [part=inspector] { border-left: 0; }
305
334
  :host([data-narrow]) [part=palette] { padding-top: 54px; }
306
335
  :host([data-narrow]) [part=palette-heading] { display: none; }
307
336
  :host([data-narrow]) [part=minimap] { display: none; }
@@ -310,7 +339,7 @@ export const processModelerDesign = `
310
339
  :host([data-narrow]) [part=view-menu] { order: -1; }
311
340
  :host([data-narrow]) [part=view-switch], :host([data-narrow]) [part=run-toggle] { display: none; }
312
341
  :host([data-narrow]) [data-command=checks-status] { display: none; }
313
- :host([data-narrow]:not([embed-mode])) [part=view-menu] { display: block; }
342
+ :host([data-narrow]) [part=view-menu] { display: block; }
314
343
  :host([data-narrow]) [part=controls] { left: 12px; bottom: 12px; }
315
344
  :host([data-narrow]) [part=selection-toolbar] [part=selection-plus] + span { display: none; }
316
345
  :host([data-phone]) [data-command=tidy] { display: none; }
@@ -1,4 +1,14 @@
1
1
  import type { FlowKind, NodePath } from "../flow-builder/model.js";
2
+ /** Plain-text technical lines supplied by the host; code lines use the mono face. */
3
+ export interface ProcessTechnicalDetail {
4
+ text: string;
5
+ format?: "code" | "text";
6
+ /** Optional plain-text runs replacing text, for code embedded within prose. */
7
+ segments?: readonly {
8
+ text: string;
9
+ format?: "code" | "text";
10
+ }[];
11
+ }
2
12
  export interface ProcessBox<N = unknown> {
3
13
  id: string;
4
14
  node: N;
@@ -7,6 +17,10 @@ export interface ProcessBox<N = unknown> {
7
17
  description?: string;
8
18
  /** Description used in Technical view; absent values fall back to description. */
9
19
  technicalDescription?: string;
20
+ /** Structured Technical view lines; when supplied, replace technicalDescription. */
21
+ technicalDetails?: readonly ProcessTechnicalDetail[];
22
+ /** False when this host does not time this task kind; default task metrics remain enabled. */
23
+ runMetrics?: boolean;
10
24
  /** Visual anatomy, independent of the host's kind identifier. */
11
25
  shape?: "task" | "gateway" | "event" | "frame";
12
26
  path?: NodePath;
@@ -49,6 +63,21 @@ export interface ProcessVariable {
49
63
  startingValue?: string;
50
64
  problem?: string;
51
65
  }
66
+ /** Host-owned variable edits; the host echoes the updated variables property. */
67
+ export type ProcessVariableEdit = {
68
+ type: 'add';
69
+ } | {
70
+ type: 'remove';
71
+ name: string;
72
+ } | {
73
+ type: 'rename';
74
+ name: string;
75
+ value: string;
76
+ } | {
77
+ type: 'scope';
78
+ name: string;
79
+ value: 'iteration' | 'process';
80
+ };
52
81
  /** Host-authored, readable outline; boxId links a row to a projected step. */
53
82
  export interface ProcessOutlineItem {
54
83
  title: string;
@@ -152,6 +181,8 @@ export interface ProcessLayout {
152
181
  }[]>;
153
182
  }
154
183
  export interface ProcessCheck {
184
+ /** Short problem title; message supplies its explanatory detail. */
185
+ title?: string;
155
186
  message: string;
156
187
  boxId?: string;
157
188
  path?: NodePath;
@@ -47,6 +47,7 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
47
47
  private lastDocument?;
48
48
  private connectionsValue;
49
49
  private variablesValue;
50
+ private variablesEditableValue;
50
51
  private outlineValue;
51
52
  private fieldsValue;
52
53
  private processTitleValue;
@@ -74,6 +75,10 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
74
75
  set connections(value: readonly ProcessConnection[]);
75
76
  get variables(): readonly ProcessVariable[];
76
77
  set variables(value: readonly ProcessVariable[]);
78
+ private pendingVariableRename?;
79
+ /** Opt in to name, scope, add and remove controls; edits remain host-owned. */
80
+ get variablesEditable(): boolean;
81
+ set variablesEditable(value: boolean);
77
82
  get outline(): readonly ProcessOutlineItem[];
78
83
  set outline(value: readonly ProcessOutlineItem[]);
79
84
  get fields(): Readonly<Record<string, readonly ProcessField[]>>;
@@ -164,12 +169,14 @@ export declare class ProcessModeler<D = ProcessProjection, N = unknown> extends
164
169
  zoomBy(factor: number): void;
165
170
  fit(): void;
166
171
  private fitTo;
172
+ private minimapBounds;
167
173
  private bounds;
168
174
  protected renderTemplate(): void;
169
175
  private setupPanes;
170
176
  private openDrawer;
171
177
  private closeDrawer;
172
178
  private renderPane;
179
+ private requestVariableEdit;
173
180
  private selectionCommand;
174
181
  private tidySelection;
175
182
  arrangeSelection(action: 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom' | 'distribute-horizontal' | 'distribute-vertical'): void;
@@ -7,12 +7,33 @@ import { restoreProcessPositions, snapshotProcessPositions, snapshotProcessProje
7
7
  import { processModelerDesign } from "./design.js";
8
8
  import { completeLayout, ProcessHistory, validateProjection, } from "./model.js";
9
9
  const svgElement = (tag) => document.createElementNS("http://www.w3.org/2000/svg", tag);
10
+ const checkGlyph = (success = false) => {
11
+ const icon = svgElement('svg');
12
+ icon.setAttribute('part', 'check-icon');
13
+ icon.setAttribute('viewBox', '0 0 16 16');
14
+ icon.setAttribute('aria-hidden', 'true');
15
+ icon.dataset.tone = success ? 'success' : 'error';
16
+ const circle = svgElement('circle');
17
+ circle.setAttribute('cx', '8');
18
+ circle.setAttribute('cy', '8');
19
+ circle.setAttribute('r', '7');
20
+ circle.setAttribute('fill', 'currentColor');
21
+ const mark = svgElement('path');
22
+ mark.setAttribute('d', success ? 'm4.5 8 2.5 2.5 4.5-5' : 'm5 5 6 6m0-6-6 6');
23
+ mark.setAttribute('fill', 'none');
24
+ mark.setAttribute('stroke', 'var(--boe-token-surface-surface,#fff)');
25
+ mark.setAttribute('stroke-width', '1.5');
26
+ mark.setAttribute('stroke-linecap', 'round');
27
+ icon.append(circle, mark);
28
+ return icon;
29
+ };
10
30
  const emit = (element, name, detail) => element.dispatchEvent(new CustomEvent(name, {
11
31
  detail,
12
32
  bubbles: true,
13
33
  composed: true,
14
34
  cancelable: true,
15
35
  }));
36
+ const formatFailedShare = (share) => `${Number((share * 100).toFixed(1))}%`;
16
37
  const formatRunDuration = (ms) => ms >= 1000 ? `${(ms / 1000).toFixed(ms >= 10000 ? 0 : 1)} s` : `${Math.round(ms)} ms`;
17
38
  /** Projects host documents without owning workflow schemas or persistence. */
18
39
  export class ProcessModeler extends BaseElement {
@@ -63,6 +84,7 @@ export class ProcessModeler extends BaseElement {
63
84
  lastDocument;
64
85
  connectionsValue = [];
65
86
  variablesValue = [];
87
+ variablesEditableValue = false;
66
88
  outlineValue = [];
67
89
  fieldsValue = {};
68
90
  processTitleValue = "Process";
@@ -96,7 +118,16 @@ export class ProcessModeler extends BaseElement {
96
118
  get connections() { return this.connectionsValue; }
97
119
  set connections(value) { this.connectionsValue = value; this.refresh(); }
98
120
  get variables() { return this.variablesValue; }
99
- set variables(value) { this.variablesValue = value; this.refresh(); }
121
+ set variables(value) {
122
+ this.variablesValue = value;
123
+ this.refresh();
124
+ if (this.pendingVariableRename && !value.some(v => v.name === this.pendingVariableRename.name) && value.some(v => v.name === this.pendingVariableRename.value))
125
+ this.pendingVariableRename = undefined;
126
+ }
127
+ pendingVariableRename;
128
+ /** Opt in to name, scope, add and remove controls; edits remain host-owned. */
129
+ get variablesEditable() { return this.variablesEditableValue; }
130
+ set variablesEditable(value) { this.variablesEditableValue = value; this.toggleAttribute('data-variables-editable', value); this.refresh(); }
100
131
  get outline() { return this.outlineValue; }
101
132
  set outline(value) { this.outlineValue = value; this.refresh(); }
102
133
  get fields() { return this.fieldsValue; }
@@ -219,7 +250,8 @@ export class ProcessModeler extends BaseElement {
219
250
  emit(this, "detail-changed", { detail: value });
220
251
  }
221
252
  get lastRun() { return this.lastRunValue; }
222
- set lastRun(value) { this.lastRunValue = value; this.inspected = undefined; this.refresh(); }
253
+ set lastRun(value) { this.lastRunValue = value; if (!value)
254
+ this.showLastRunValue = false; this.inspected = undefined; this.refresh(); }
223
255
  get showLastRun() { return this.showLastRunValue; }
224
256
  set showLastRun(value) { this.showLastRunValue = Boolean(value); this.inspected = undefined; this.refresh(); }
225
257
  get locked() {
@@ -561,6 +593,19 @@ export class ProcessModeler extends BaseElement {
561
593
  this.viewport.y = 20 - bounds.y * this.viewport.zoom;
562
594
  this.paintViewport();
563
595
  }
596
+ minimapBounds(canvas) {
597
+ const positions = this.projection.boxes.map(box => this.layoutValue.boxes[box.id]);
598
+ const view = { x: -this.viewport.x / this.viewport.zoom, y: -this.viewport.y / this.viewport.zoom, width: canvas.clientWidth / this.viewport.zoom, height: canvas.clientHeight / this.viewport.zoom };
599
+ const sections = this.layoutValue.sections ?? [];
600
+ const notes = this.layoutValue.notes ?? [];
601
+ const x = Math.min(view.x, ...positions.map(p => p.x), ...sections.map(s => s.x), ...notes.map(n => n.x));
602
+ const y = Math.min(view.y, ...positions.map(p => p.y), ...sections.map(s => s.y), ...notes.map(n => n.y));
603
+ const right = Math.max(view.x + view.width, ...positions.map(p => p.x + (p.width ?? 224)), ...sections.map(s => s.x + s.width), ...notes.map(n => n.x + 208));
604
+ const bottom = Math.max(view.y + view.height, ...positions.map(p => p.y + (p.height ?? 64)), ...sections.map(s => s.y + s.height), ...notes.map(n => n.y + 80));
605
+ const pad = 40, scale = Math.min(208 / (right - x + 2 * pad), 136 / (bottom - y + 2 * pad));
606
+ const width = 208 / scale, height = 136 / scale;
607
+ return { x: x - pad - (width - (right - x + 2 * pad)) / 2, y: y - pad - (height - (bottom - y + 2 * pad)) / 2, width, height };
608
+ }
564
609
  bounds() {
565
610
  const positions = this.projection.boxes.map((box) => this.layoutValue.boxes[box.id]);
566
611
  const x = Math.min(0, ...positions.map((pos) => pos.x));
@@ -796,7 +841,7 @@ export class ProcessModeler extends BaseElement {
796
841
  content.id = "process-pane-content";
797
842
  heading.after(tabs);
798
843
  inspector.append(content);
799
- root.querySelector('[part=checks]').removeAttribute("role");
844
+ root.querySelector('[part=checks]').setAttribute("role", "group");
800
845
  const canvas = root.querySelector('[part=canvas]');
801
846
  const hold = document.createElement('div');
802
847
  hold.setAttribute('part', 'hold');
@@ -947,7 +992,6 @@ export class ProcessModeler extends BaseElement {
947
992
  emit(this, 'outline-copy-request', { text: value });
948
993
  void navigator.clipboard?.writeText(value).then(() => this.setStatus('Outline copied')).catch(() => this.setStatus('Use your host copy action to copy the outline'));
949
994
  };
950
- content.append(copy);
951
995
  const appendOutline = (items, parent) => {
952
996
  const list = document.createElement("ol");
953
997
  list.setAttribute("part", "outline-list");
@@ -973,29 +1017,55 @@ export class ProcessModeler extends BaseElement {
973
1017
  parent.append(list);
974
1018
  };
975
1019
  appendOutline(outline, content);
1020
+ content.append(copy);
976
1021
  }
977
1022
  else if (this.activePane === "Checks") {
978
1023
  content.append(checks);
979
- if (!this.allChecks.length) {
980
- const message = document.createElement("p");
981
- message.textContent = "Ready to run";
982
- content.prepend(message);
983
- }
984
1024
  }
985
1025
  else if (this.activePane === "Variables") {
986
1026
  if (!this.variables.length)
987
1027
  content.textContent = 'No variables supplied by the host.';
988
- for (const variable of this.variables) {
1028
+ for (const [index, variable] of this.variables.entries()) {
989
1029
  const row = document.createElement('div');
990
1030
  row.setAttribute('part', 'variable-row');
991
- const heading = document.createElement('strong');
992
- heading.textContent = variable.name;
993
- row.append(heading);
994
- if (variable.scope) {
995
- const scope = document.createElement('span');
996
- scope.textContent = variable.scope;
997
- scope.setAttribute('part', 'variable-scope');
998
- row.append(scope);
1031
+ const identify = (control, key) => { control.dataset.variable = variable.name; control.dataset.variableKey = key; control.dataset.variableIndex = String(index); };
1032
+ if (this.variablesEditable) {
1033
+ const label = document.createElement('label');
1034
+ label.textContent = 'Name';
1035
+ const name = document.createElement('input');
1036
+ name.type = 'text';
1037
+ name.value = variable.name;
1038
+ name.disabled = this.locked;
1039
+ identify(name, 'name');
1040
+ name.onchange = () => this.requestVariableEdit({ type: 'rename', name: variable.name, value: name.value });
1041
+ label.append(name);
1042
+ row.append(label);
1043
+ const scopeLabel = document.createElement('label');
1044
+ scopeLabel.textContent = 'Scope';
1045
+ const scope = document.createElement('select');
1046
+ identify(scope, 'scope');
1047
+ scope.disabled = this.locked;
1048
+ for (const [value, text] of [['iteration', 'Each iteration'], ['process', 'The whole process']]) {
1049
+ const option = document.createElement('option');
1050
+ option.value = value;
1051
+ option.textContent = text;
1052
+ scope.append(option);
1053
+ }
1054
+ scope.value = variable.scope ?? 'iteration';
1055
+ scope.onchange = () => this.requestVariableEdit({ type: 'scope', name: variable.name, value: scope.value });
1056
+ scopeLabel.append(scope);
1057
+ row.append(scopeLabel);
1058
+ }
1059
+ else {
1060
+ const heading = document.createElement('strong');
1061
+ heading.textContent = variable.name;
1062
+ row.append(heading);
1063
+ if (variable.scope) {
1064
+ const scope = document.createElement('span');
1065
+ scope.textContent = variable.scope;
1066
+ scope.setAttribute('part', 'variable-scope');
1067
+ row.append(scope);
1068
+ }
999
1069
  }
1000
1070
  if (variable.description) {
1001
1071
  const description = document.createElement('p');
@@ -1007,7 +1077,7 @@ export class ProcessModeler extends BaseElement {
1007
1077
  label.textContent = 'Starting value';
1008
1078
  const input = document.createElement('input');
1009
1079
  input.type = 'text';
1010
- input.dataset.variable = variable.name;
1080
+ identify(input, 'value');
1011
1081
  input.value = variable.startingValue;
1012
1082
  input.disabled = this.locked;
1013
1083
  input.setAttribute('aria-invalid', String(Boolean(variable.problem)));
@@ -1015,14 +1085,39 @@ export class ProcessModeler extends BaseElement {
1015
1085
  label.append(input);
1016
1086
  row.append(label);
1017
1087
  }
1088
+ const scopeControl = row.querySelector('[data-variable-key=scope]')?.closest('label');
1089
+ if (scopeControl)
1090
+ row.append(scopeControl);
1018
1091
  if (variable.problem) {
1019
1092
  const problem = document.createElement('p');
1020
1093
  problem.setAttribute('part', 'field-problem');
1021
1094
  problem.textContent = variable.problem;
1022
1095
  row.append(problem);
1023
1096
  }
1097
+ if (this.variablesEditable) {
1098
+ const remove = document.createElement('button');
1099
+ remove.type = 'button';
1100
+ remove.setAttribute('part', 'variable-remove');
1101
+ remove.setAttribute('aria-label', `Remove ${variable.name || 'this variable'}`);
1102
+ remove.textContent = '×';
1103
+ remove.disabled = this.locked;
1104
+ identify(remove, 'remove');
1105
+ remove.onclick = () => this.requestVariableEdit({ type: 'remove', name: variable.name });
1106
+ row.append(remove);
1107
+ }
1024
1108
  content.append(row);
1025
1109
  }
1110
+ if (this.variablesEditable) {
1111
+ const add = document.createElement('button');
1112
+ add.type = 'button';
1113
+ add.setAttribute('part', 'variable-add');
1114
+ add.dataset.variable = '@add';
1115
+ add.dataset.variableKey = 'add';
1116
+ add.textContent = 'Add a variable';
1117
+ add.disabled = this.locked;
1118
+ add.onclick = () => this.requestVariableEdit({ type: 'add' });
1119
+ content.append(add);
1120
+ }
1026
1121
  }
1027
1122
  else if (this.activePane === "Connections") {
1028
1123
  if (!this.connections.length)
@@ -1047,6 +1142,13 @@ export class ProcessModeler extends BaseElement {
1047
1142
  content.textContent = "Tab: move between steps. Alt+arrows: select the nearest step that way. Arrows: move one grid square. Shift+arrows: move four. N: add the next step. Ctrl+Alt+arrows: add in a direction. Enter: edit. Delete: remove. Ctrl/Command+A: select all. Ctrl/Command+C/V/D: copy, paste, duplicate. Ctrl/Command+Z and Shift+Ctrl/Command+Z: undo and redo. Shift+1: fit the whole process. Shift+drag: select a region. Drag a port: connect. Escape: cancel.";
1048
1143
  }
1049
1144
  }
1145
+ requestVariableEdit(edit) {
1146
+ if (!this.locked) {
1147
+ if (edit.type === 'rename')
1148
+ this.pendingVariableRename = { name: edit.name, value: edit.value };
1149
+ emit(this, 'process-variable-edit-request', edit);
1150
+ }
1151
+ }
1050
1152
  selectionCommand(command) {
1051
1153
  if (this.locked)
1052
1154
  return;
@@ -1273,7 +1375,7 @@ export class ProcessModeler extends BaseElement {
1273
1375
  const rect = minimap.getBoundingClientRect();
1274
1376
  if (!rect.width || !rect.height)
1275
1377
  return;
1276
- const bounds = this.bounds();
1378
+ const bounds = this.minimapBounds(canvas);
1277
1379
  this.viewport.x =
1278
1380
  canvas.clientWidth / 2 -
1279
1381
  (bounds.x + ((event.clientX - rect.left) / rect.width) * bounds.width) *
@@ -2053,13 +2155,67 @@ export class ProcessModeler extends BaseElement {
2053
2155
  const title = document.createElement("strong");
2054
2156
  title.textContent = box.title;
2055
2157
  element.append(title);
2056
- const descriptionText = this.detailValue === "technical" ? box.technicalDescription ?? box.description : box.description;
2057
- if (descriptionText) {
2058
- const description = document.createElement("small");
2059
- description.textContent = descriptionText;
2060
- if (this.detailValue === "technical")
2061
- description.setAttribute("part", "technical-description");
2062
- element.append(description);
2158
+ let descriptionParent = element;
2159
+ if (shape === 'event' && this.detailValue === 'technical' && box.technicalDetails?.length) {
2160
+ const details = document.createElement('div');
2161
+ details.setAttribute('part', 'event-details');
2162
+ element.append(details);
2163
+ descriptionParent = details;
2164
+ }
2165
+ if (shape === 'gateway' && this.detailValue === 'technical' && box.technicalDetails?.length) {
2166
+ const caption = document.createElement('div');
2167
+ caption.setAttribute('part', 'caption');
2168
+ const position = this.layoutValue.boxes[box.id];
2169
+ let topUsed = false, bottomUsed = false;
2170
+ for (const line of this.projection.lines) {
2171
+ const points = this.routedLines.get(line.id);
2172
+ const end = line.from === box.id ? points?.[0] : line.to === box.id ? points?.at(-1) : undefined;
2173
+ if (!end)
2174
+ continue;
2175
+ if (Math.abs(end.y - position.y) < .01)
2176
+ topUsed = true;
2177
+ if (Math.abs(end.y - (position.y + 56)) < .01)
2178
+ bottomUsed = true;
2179
+ }
2180
+ caption.dataset.side = bottomUsed && !topUsed ? 'above' : 'below';
2181
+ caption.append(title);
2182
+ element.append(caption);
2183
+ descriptionParent = caption;
2184
+ }
2185
+ if (shape === 'task' && box.technicalDetails)
2186
+ icon.style.gridRow = 'span 4';
2187
+ if (this.detailValue === "technical" && box.technicalDetails) {
2188
+ for (const line of box.technicalDetails) {
2189
+ if (!line.text && !line.segments?.length)
2190
+ continue;
2191
+ const description = document.createElement("small");
2192
+ if (line.segments) {
2193
+ for (const segment of line.segments) {
2194
+ if (segment.format === "code") {
2195
+ const code = document.createElement("span");
2196
+ code.setAttribute("part", "technical-inline-code");
2197
+ code.textContent = segment.text;
2198
+ description.append(code);
2199
+ }
2200
+ else
2201
+ description.append(document.createTextNode(segment.text));
2202
+ }
2203
+ }
2204
+ else
2205
+ description.textContent = line.text;
2206
+ description.setAttribute("part", line.format === "code" ? "technical-description" : "technical-summary");
2207
+ descriptionParent.append(description);
2208
+ }
2209
+ }
2210
+ else {
2211
+ const descriptionText = this.detailValue === "technical" ? box.technicalDescription ?? box.description : box.description;
2212
+ if (descriptionText) {
2213
+ const description = document.createElement("small");
2214
+ description.textContent = descriptionText;
2215
+ if (this.detailValue === "technical")
2216
+ description.setAttribute("part", "technical-description");
2217
+ descriptionParent.append(description);
2218
+ }
2063
2219
  }
2064
2220
  if (box.frame && box.loopMark) {
2065
2221
  const loop = document.createElement('span');
@@ -2069,25 +2225,39 @@ export class ProcessModeler extends BaseElement {
2069
2225
  element.append(loop);
2070
2226
  }
2071
2227
  const metrics = this.showLastRunValue ? this.lastRunValue?.steps[box.id] : undefined;
2072
- if (this.showLastRunValue && this.lastRunValue && shape === 'task') {
2228
+ if (this.showLastRunValue && this.lastRunValue && shape === 'task' && box.runMetrics !== false) {
2073
2229
  const line = document.createElement("span");
2074
2230
  line.setAttribute("part", "metrics");
2075
- line.textContent = !metrics || metrics.notInRun ? "Not in the last run" : [
2076
- metrics.callsPerSecond === undefined ? "" : `${metrics.callsPerSecond.toFixed(1)}/s`,
2077
- metrics.p95Ms === undefined ? "" : `p95 ${formatRunDuration(metrics.p95Ms)}`,
2078
- ].filter(Boolean).join(" · ");
2079
- if (metrics?.failedShare !== undefined && metrics.failedShare > 0 && !metrics.notInRun) {
2080
- const failed = document.createElement('span');
2081
- failed.setAttribute('part', 'metric-warning');
2082
- failed.textContent = `${(metrics.failedShare * 100).toFixed(1)}% failed`;
2083
- line.append(document.createTextNode(' · '), failed);
2231
+ if (!metrics || metrics.notInRun) {
2232
+ line.dataset.state = 'unmeasured';
2233
+ line.textContent = "Not in the last run";
2234
+ }
2235
+ else {
2236
+ const parts = [];
2237
+ const add = (text, warning = false) => { const part = document.createElement('span'); part.textContent = text; if (warning)
2238
+ part.setAttribute('part', 'metric-warning'); parts.push(part); };
2239
+ if (metrics.callsPerSecond !== undefined)
2240
+ add(`${metrics.callsPerSecond.toFixed(1)}/s`);
2241
+ if (metrics.p95Ms !== undefined)
2242
+ add(`p95 ${formatRunDuration(metrics.p95Ms)}`);
2243
+ if (metrics.failedShare !== undefined && metrics.failedShare > 0)
2244
+ add(`${formatFailedShare(metrics.failedShare)} failed`, true);
2245
+ for (const [index, part] of parts.entries()) {
2246
+ if (index) {
2247
+ const separator = document.createElement('span');
2248
+ separator.setAttribute('part', 'metric-separator');
2249
+ separator.textContent = '·';
2250
+ line.append(document.createTextNode(' '), separator, document.createTextNode(' '));
2251
+ }
2252
+ line.append(part);
2253
+ }
2084
2254
  }
2085
2255
  element.append(line);
2086
2256
  }
2087
2257
  if (problem) {
2088
2258
  const message = document.createElement("span");
2089
2259
  message.setAttribute("part", "problem");
2090
- message.textContent = problem.message;
2260
+ message.append(checkGlyph(), document.createTextNode(problem.title ?? problem.message));
2091
2261
  element.append(message);
2092
2262
  }
2093
2263
  element.addEventListener("keydown", event => {
@@ -2433,16 +2603,32 @@ export class ProcessModeler extends BaseElement {
2433
2603
  renderChecks() {
2434
2604
  const checks = this.shadowRoot.querySelector("[part=checks]");
2435
2605
  checks.replaceChildren();
2606
+ if (!this.allChecks.length) {
2607
+ const message = document.createElement('p');
2608
+ message.setAttribute('part', 'checks-ready');
2609
+ message.append(checkGlyph(true), document.createTextNode('Ready to run. Every step connects from start to finish.'));
2610
+ checks.append(message);
2611
+ }
2436
2612
  const hold = this.shadowRoot.querySelector('[part=hold]');
2437
2613
  hold.hidden = this.allChecks.length === 0;
2438
2614
  hold.querySelector('[part=hold-text]').textContent = `${this.allChecks.length} ${this.allChecks.length === 1 ? 'problem needs' : 'problems need'} fixing before this drawing can be read back.`;
2439
2615
  this.allChecks.forEach((check) => {
2440
2616
  const button = document.createElement("button");
2441
2617
  button.type = "button";
2442
- button.textContent = check.message;
2443
2618
  const box = this.projection.boxes.find((box) => box.id === check.boxId ||
2444
2619
  (check.path &&
2445
2620
  JSON.stringify(box.path) === JSON.stringify(check.path)));
2621
+ const icon = checkGlyph();
2622
+ const text = document.createElement('span');
2623
+ const title = document.createElement('strong');
2624
+ title.textContent = check.title ? box ? `${box.title}: ${check.title.toLowerCase()}` : check.title : check.message;
2625
+ text.append(title);
2626
+ if (check.title) {
2627
+ const detail = document.createElement('small');
2628
+ detail.textContent = check.message;
2629
+ text.append(detail);
2630
+ }
2631
+ button.append(icon, text);
2446
2632
  button.addEventListener("click", () => {
2447
2633
  if (box) {
2448
2634
  this.select(box.id);
@@ -2665,18 +2851,22 @@ export class ProcessModeler extends BaseElement {
2665
2851
  return;
2666
2852
  const focusedControl = this.shadowRoot.activeElement;
2667
2853
  const focusedKey = focusedControl?.dataset.field ?? focusedControl?.dataset.variable;
2668
- const focusedType = focusedControl?.dataset.field ? 'field' : focusedControl?.dataset.variable ? 'variable' : null;
2854
+ const variableKey = focusedControl?.dataset.variableKey;
2855
+ const focusedType = focusedControl?.dataset.field !== undefined ? 'field' : focusedControl?.dataset.variable !== undefined ? 'variable' : null;
2669
2856
  const caret = focusedControl && 'selectionStart' in focusedControl ? focusedControl.selectionStart : null;
2670
2857
  const restoreControlFocus = () => {
2671
- if (!focusedKey || !focusedType)
2858
+ if (focusedKey === undefined || !focusedType)
2672
2859
  return;
2673
- const control = Array.from(this.shadowRoot.querySelectorAll('input,textarea')).find(item => item.dataset[focusedType] === focusedKey);
2860
+ const controls = Array.from(this.shadowRoot.querySelectorAll('input,textarea,select,button'));
2861
+ const control = controls.find(item => item.dataset[focusedType] === focusedKey && (focusedType !== 'variable' || item.dataset.variableKey === variableKey))
2862
+ ?? (focusedType === 'variable' ? controls.find(item => this.pendingVariableRename?.name === focusedKey && item.dataset.variable === this.pendingVariableRename.value && item.dataset.variableKey === variableKey) ?? controls.find(item => item.dataset.variableKey === 'add') : undefined);
2674
2863
  if (!control)
2675
2864
  return;
2676
2865
  control.focus();
2677
- if (caret !== null && control.type !== 'number' && control.type !== 'checkbox')
2866
+ if (caret !== null && (control instanceof HTMLInputElement || control instanceof HTMLTextAreaElement) && control.type !== 'number' && control.type !== 'checkbox')
2678
2867
  control.setSelectionRange(caret, caret);
2679
2868
  };
2869
+ this.shadowRoot.querySelectorAll('[part=minimap] [data-map-box]').forEach(rect => rect.dataset.selected = String(this.selectedIds.has(rect.dataset.mapBox)));
2680
2870
  this.shadowRoot.querySelectorAll('[part=line]').forEach(line => { const selected = line.dataset.lineId === this.selectedLineId; line.dataset.selected = String(selected); line.setAttribute('marker-end', `url(#${selected ? 'boe-process-arrow-brand' : 'boe-process-arrow'})`); });
2681
2871
  this.shadowRoot.querySelectorAll("[data-box-id]").forEach((element) => {
2682
2872
  element.setAttribute("aria-current", String(this.selectedIds.has(element.dataset.boxId)));
@@ -2687,7 +2877,7 @@ export class ProcessModeler extends BaseElement {
2687
2877
  });
2688
2878
  const editor = this.shadowRoot.querySelector("[part=editor]");
2689
2879
  const selected = this.selected;
2690
- const controlsKey = `${[...this.selectedIds].join(',')}|${this.locked}|${this.disableConnections}|${this.showLastRunValue}|${JSON.stringify(selected ? this.fieldsValue[selected.id] ?? [] : [])}`;
2880
+ const controlsKey = `${[...this.selectedIds].join(',')}|${this.locked}|${this.disableConnections}|${this.showLastRunValue}|${selected?.runMetrics}|${JSON.stringify(selected ? this.fieldsValue[selected.id] ?? [] : [])}`;
2691
2881
  this.shadowRoot.querySelector("[part=palette]").hidden = false;
2692
2882
  this.shadowRoot.querySelector('[part=selection-toolbar]').hidden = this.selectedIds.size === 0 && !this.selectedLineId;
2693
2883
  this.renderSelectionToolbar();
@@ -2784,7 +2974,7 @@ export class ProcessModeler extends BaseElement {
2784
2974
  connect.onclick = () => { this.connecting = selected.id; this.setStatus(`Select the next box to connect from ${selected.title}`); };
2785
2975
  leads.append(connect);
2786
2976
  editor.append(leads);
2787
- const metrics = this.showLastRunValue ? this.lastRunValue?.steps[selected.id] : undefined;
2977
+ const metrics = this.showLastRunValue && selected.runMetrics !== false ? this.lastRunValue?.steps[selected.id] : undefined;
2788
2978
  if (metrics) {
2789
2979
  const report = document.createElement('section');
2790
2980
  report.setAttribute('part', 'inspector-metrics');
@@ -2802,19 +2992,25 @@ export class ProcessModeler extends BaseElement {
2802
2992
  report.append(note);
2803
2993
  }
2804
2994
  else {
2805
- const list = document.createElement('dl');
2806
- for (const [label, value] of [['Per second', metrics.callsPerSecond === undefined ? '–' : metrics.callsPerSecond.toFixed(1)], ['95% finished within', metrics.p95Ms === undefined ? '–' : formatRunDuration(metrics.p95Ms)], ['Failed', metrics.failedShare === undefined ? '–' : `${(metrics.failedShare * 100).toFixed(1)}%`]]) {
2807
- const term = document.createElement('dt');
2995
+ const list = document.createElement('table');
2996
+ list.setAttribute('aria-label', 'Last run metrics');
2997
+ const body = document.createElement('tbody');
2998
+ list.append(body);
2999
+ for (const [label, value] of [['Per second', metrics.callsPerSecond === undefined ? '–' : metrics.callsPerSecond.toFixed(1)], ['95% finished within', metrics.p95Ms === undefined ? '–' : formatRunDuration(metrics.p95Ms)], ['Failed', metrics.failedShare === undefined ? '–' : formatFailedShare(metrics.failedShare)]]) {
3000
+ const row = document.createElement('tr');
3001
+ const term = document.createElement('th');
3002
+ term.scope = 'row';
2808
3003
  term.textContent = label;
2809
- const detail = document.createElement('dd');
3004
+ const detail = document.createElement('td');
2810
3005
  detail.textContent = value;
2811
3006
  if (label === 'Failed' && metrics.failedShare)
2812
3007
  detail.setAttribute('part', 'metric-warning');
2813
- list.append(term, detail);
3008
+ row.append(term, detail);
3009
+ body.append(row);
2814
3010
  }
2815
3011
  report.append(list);
2816
3012
  }
2817
- editor.append(report);
3013
+ editor.insertBefore(report, leads);
2818
3014
  }
2819
3015
  const actions = document.createElement('div');
2820
3016
  actions.setAttribute('part', 'inspector-actions');
@@ -2924,10 +3120,18 @@ export class ProcessModeler extends BaseElement {
2924
3120
  this.shadowRoot.querySelector("[data-command=reset]").textContent =
2925
3121
  `${Math.round(this.viewport.zoom * 100)}%`;
2926
3122
  const minimap = this.shadowRoot.querySelector("[part=minimap]");
2927
- const bounds = this.bounds();
3123
+ const bounds = this.minimapBounds(canvas);
2928
3124
  minimap.replaceChildren();
2929
3125
  minimap.setAttribute("viewBox", `${bounds.x} ${bounds.y} ${bounds.width} ${bounds.height}`);
2930
3126
  minimap.setAttribute("preserveAspectRatio", "none");
3127
+ for (const section of this.layoutValue.sections ?? []) {
3128
+ const rect = svgElement('rect');
3129
+ rect.dataset.section = 'true';
3130
+ for (const key of ['x', 'y', 'width', 'height'])
3131
+ rect.setAttribute(key, String(section[key]));
3132
+ rect.setAttribute('rx', '16');
3133
+ minimap.append(rect);
3134
+ }
2931
3135
  this.projection.boxes.forEach((box) => {
2932
3136
  const pos = this.layoutValue.boxes[box.id];
2933
3137
  const rect = svgElement("rect");
@@ -2935,6 +3139,11 @@ export class ProcessModeler extends BaseElement {
2935
3139
  rect.setAttribute("y", String(pos.y));
2936
3140
  rect.setAttribute("width", String(pos.width ?? 224));
2937
3141
  rect.setAttribute("height", String(pos.height ?? 64));
3142
+ rect.setAttribute('rx', box.frame ? '12' : '8');
3143
+ rect.dataset.mapBox = box.id;
3144
+ rect.dataset.selected = String(this.selectedIds.has(box.id));
3145
+ if (box.frame)
3146
+ rect.setAttribute('fill-opacity', '.35');
2938
3147
  minimap.append(rect);
2939
3148
  });
2940
3149
  const viewport = svgElement("rect");
@@ -2943,6 +3152,7 @@ export class ProcessModeler extends BaseElement {
2943
3152
  viewport.setAttribute("y", String(-this.viewport.y / this.viewport.zoom));
2944
3153
  viewport.setAttribute("width", String(canvas.clientWidth / this.viewport.zoom));
2945
3154
  viewport.setAttribute("height", String(canvas.clientHeight / this.viewport.zoom));
3155
+ viewport.setAttribute('rx', '4');
2946
3156
  minimap.append(viewport);
2947
3157
  }
2948
3158
  positionSelectionToolbar() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unofficialbox/box-open-elements",
3
- "version": "0.29.2",
3
+ "version": "0.31.0",
4
4
  "description": "Box Open Elements: an open, framework-agnostic design system and web component library for Box-style experiences",
5
5
  "license": "MIT",
6
6
  "homepage": "https://unofficialbox.github.io/box-open-elements",