@unofficialbox/box-open-elements 0.25.0 → 0.27.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.
@@ -0,0 +1,288 @@
1
+ /** Riptide Diagram anatomy expressed through public Box Open Elements tokens. */
2
+ export const processModelerDesign = `
3
+ :host([hidden]), [hidden] { display: none !important; }
4
+ *, *::before, *::after { box-sizing: border-box; }
5
+ button, input, textarea, select { font: inherit; color: inherit; }
6
+ 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; }
7
+ button:disabled { opacity: .5; cursor: default; }
8
+ :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; }
9
+ :host {
10
+ display: block;
11
+ min-width: 0;
12
+ --boe-process-box-edge: color-mix(in srgb, var(--boe-token-text-text, #141413) 55%, var(--boe-token-surface-surface, #fff));
13
+ color: var(--boe-token-text-text, #141413);
14
+ background: var(--boe-token-surface-surface, #fff);
15
+ font: 14px/1.5 var(--boe-token-font-family-base, Inter, sans-serif);
16
+ }
17
+ [part=sr-only], [part=status] { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
18
+ [part=toolbar] {
19
+ min-height: 56px;
20
+ margin: 0;
21
+ padding: 8px 16px;
22
+ display: flex;
23
+ align-items: center;
24
+ justify-content: flex-end;
25
+ gap: 8px;
26
+ flex-wrap: wrap;
27
+ border-bottom: 1px solid var(--boe-token-stroke-stroke, #e8e8e8);
28
+ background: var(--boe-token-surface-surface, #fff);
29
+ }
30
+ [part=toolbar] button, [part=controls] button, [part=selection-toolbar] button {
31
+ min-height: 30px;
32
+ padding: 4px 10px;
33
+ border: 1px solid transparent;
34
+ border-radius: 8px;
35
+ background: transparent;
36
+ font-size: 13px;
37
+ font-weight: 600;
38
+ }
39
+ [part=toolbar] svg, [part=controls] svg { width: 16px; height: 16px; display: block; }
40
+ [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; }
41
+ [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); }
42
+ [part=toolbar] button:hover, [part=controls] button:hover, [part=selection-toolbar] button:hover {
43
+ background: var(--boe-token-surface-surface-hover, #f4f4f4);
44
+ }
45
+ [part=toolbar] [data-command=tidy] { border-color: var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 18px; }
46
+ [part=view-switch] { display: flex; gap: 2px; padding: 3px; border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); border-radius: 20px; }
47
+ [part=view-switch] button { border-radius: 16px; }
48
+ [part=view-switch] button[aria-pressed=true] { border-color: var(--boe-token-stroke-stroke, #e8e8e8); background: var(--boe-token-surface-surface, #fff); }
49
+ [part=run-toggle] { display: flex; align-items: center; gap: 6px; white-space: nowrap; font-size: 13px; font-weight: 600; }
50
+ [part=run-toggle] input { accent-color: var(--boe-token-surface-surface-brand, #0061d5); }
51
+ [part=view-menu] { display: none; position: relative; }
52
+ [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; }
53
+ [part=view-menu][open] { z-index: 20; }
54
+ [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)); }
55
+ [part=view-menu] button { display: block; width: 100%; text-align: start; background: transparent; }
56
+ [part=layout] {
57
+ display: grid;
58
+ grid-template-columns: 248px minmax(0, 1fr) 320px;
59
+ gap: 0;
60
+ min-height: 0;
61
+ height: var(--boe-process-height, 660px);
62
+ overflow: hidden;
63
+ }
64
+ [part=pane-drawer] { display: contents; color: inherit; }
65
+ [part=pane-drawer]::backdrop, [part=insert-chooser]::backdrop { background: rgb(0 0 0 / .45); }
66
+ [part=pane-close], [data-command=palette], [data-command=details] { display: none; }
67
+ [part=palette], [part=inspector] {
68
+ min-width: 0;
69
+ overflow: auto;
70
+ padding: 12px;
71
+ border: 0;
72
+ border-radius: 0;
73
+ background: var(--boe-token-surface-surface, #fff);
74
+ }
75
+ [part=palette] { display: flex; flex-direction: column; gap: 12px; border-right: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }
76
+ [part=skip-link] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
77
+ [part=skip-link]:focus-visible { position: static; width: auto; height: auto; clip-path: none; }
78
+ [part=inspector] { border-left: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); padding: 16px 0; }
79
+ [part=palette] label { font-size: 0; position: relative; }
80
+ [part=search-icon] { position: absolute; left: 12px; top: 9px; width: 18px; height: 18px; color: var(--boe-token-text-text-secondary, #6f6f6f); pointer-events: none; }
81
+ [part=palette] input {
82
+ width: 100%; min-width: 0;
83
+ height: 36px;
84
+ padding: 0 12px 0 36px;
85
+ border: 1px solid transparent;
86
+ border-radius: 24px;
87
+ background: var(--boe-token-surface-surface-hover, #f4f4f4);
88
+ font-size: 13px;
89
+ }
90
+ [part=palette] input:focus-visible { border-color: var(--boe-token-surface-surface-brand, #0061d5); background: var(--boe-token-surface-surface, #fff); }
91
+ [part=choices] { display: grid; align-content: start; gap: 4px; max-height: none; overflow: visible; }
92
+ [part=group] { margin: 4px 4px 6px; font-size: 12px; font-weight: 650; color: var(--boe-token-text-text-secondary, #6f6f6f); }
93
+ [part=choice] {
94
+ display: grid; grid-template-columns: 20px minmax(0,1fr); gap: 0 10px;
95
+ min-height: 44px; padding: 8px 10px; border: 1px solid transparent; border-radius: 10px;
96
+ text-align: start; background: transparent; cursor: grab;
97
+ }
98
+ [part=choice]:hover { border-color: var(--boe-token-stroke-stroke, #e8e8e8); background: var(--boe-token-surface-surface-hover, #f4f4f4); }
99
+ [part=choice-icon] { grid-row: span 2; width: 20px; height: 20px; color: var(--boe-token-text-text-secondary, #6f6f6f); }
100
+ [part=choice][data-tone=accent] [part=choice-icon] { color: var(--boe-token-surface-surface-brand, #0061d5); }
101
+ [part=choice-icon] svg { width: 20px; height: 20px; }
102
+ [part=choice-name] { font-size: 13px; font-weight: 600; line-height: 1.3; }
103
+ [part=choice-description] { grid-column: 2; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.35; }
104
+ [part=palette-hint] { margin: 4px; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.45; }
105
+ [part=canvas] {
106
+ position: relative; min-width: 0; height: 100%; overflow: hidden;
107
+ border: 0; border-radius: 0;
108
+ background-color: var(--boe-token-surface-surface-secondary, #fbfbfb);
109
+ background-image: radial-gradient(circle, var(--boe-token-stroke-stroke-hover, #d3d3d3) 1px, transparent 1.2px);
110
+ background-size: 12px 12px;
111
+ touch-action: none; user-select: none; cursor: grab;
112
+ }
113
+ [part=canvas][data-panning] { cursor: grabbing; }
114
+ [part=hold] { position: absolute; z-index: 12; top: 12px; left: 50%; translate: -50% 0; display: flex; align-items: center; gap: 12px; max-width: calc(100% - 24px); padding: 8px 12px; border: 1px solid var(--boe-token-stroke-status-stroke-warning, #9a6b00); border-radius: 8px; background: var(--boe-token-surface-status-surface-warning, #fff7df); color: var(--boe-token-text-status-text-warning, #6b4a00); box-shadow: var(--boe-shadow-overlay, 0 4px 12px rgb(0 0 0 / .16)); font-size: 12.5px; cursor: default; }
115
+ [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; }
116
+ [part=world] { position: absolute; inset: 0; transform-origin: 0 0; }
117
+ [part=lines] { position: absolute; inset: 0; width: 1px; height: 1px; overflow: visible; pointer-events: none; z-index: 3; }
118
+ [part=line] { stroke: var(--boe-token-text-text-secondary, #6f6f6f); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; fill: none; }
119
+ [part=line][data-selected=true] { stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 2; }
120
+ [part=line][data-drop=true] { stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 2.5; stroke-dasharray: 6 4; }
121
+ [part=line-hit] { fill: none; stroke: transparent; stroke-width: 24; pointer-events: stroke; }
122
+ [part=connection-preview] { fill: none; stroke: var(--boe-token-surface-surface-brand, #0061d5); stroke-width: 2.5; stroke-dasharray: 6 4; }
123
+ [part=pinned-end] { fill: var(--boe-token-surface-surface-brand, #0061d5); pointer-events: none; }
124
+ [part=box], [part=frame] {
125
+ position: absolute; touch-action: none; text-align: start; z-index: 4; display: grid; grid-template-columns: 20px minmax(0,1fr); align-content: center;
126
+ gap: 2px 10px; min-width: 0; min-height: 64px; padding: 11px 12px;
127
+ border: 1px solid var(--boe-process-box-edge, var(--boe-control-edge, #858585));
128
+ border-radius: 8px; background: var(--boe-token-surface-surface, #fff);
129
+ font-size: 13px; line-height: 1.3;
130
+ transition: border-color var(--boe-profile-motion-interactive, 200ms) ease-out,
131
+ background var(--boe-profile-motion-interactive, 200ms) ease-out;
132
+ }
133
+ [part=box]:hover, [part=frame]:hover { border-color: var(--boe-token-text-text-secondary, #6f6f6f); }
134
+ [data-connect-target=true] { border-color: var(--boe-token-surface-surface-brand, #0061d5) !important; }
135
+ [part=box] strong, [part=frame] strong { overflow-wrap: anywhere; }
136
+ [part=box] strong, [part=frame] strong { font-size: 13.5px; font-weight: 650; line-height: 1.3; }
137
+ [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; }
138
+ [part=technical-description] { font: 12px/1.4 ui-monospace, 'SF Mono', Menlo, Consolas, monospace !important; overflow-wrap: anywhere; }
139
+ [part=metrics] { grid-column: 2; font-size: 12px; font-variant-numeric: tabular-nums; }
140
+ [part=metric-warning] { color: var(--boe-token-text-status-text-warning, #8a5800); }
141
+ [part=icon] { grid-row: span 3; width: 20px; height: 20px; color: var(--boe-token-text-text-secondary, #6f6f6f); }
142
+ [part=icon] svg { display: block; width: 20px; height: 20px; }
143
+ [data-tone=accent] > [part=icon] { color: var(--boe-token-surface-surface-brand, #0061d5); }
144
+ [part=box][aria-current=true], [part=frame][aria-current=true] {
145
+ border: 1px solid var(--boe-token-surface-surface-brand, #0061d5);
146
+ background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 7%, var(--boe-token-surface-surface, #fff));
147
+ }
148
+ [data-invalid=true] { border-color: var(--boe-token-text-status-text-error, #b92340) !important; }
149
+ [part=problem] { grid-column: 1 / -1; color: var(--boe-token-text-status-text-error, #b92340); font-size: 12px; }
150
+ [part=frame] { z-index: 1; align-content: start; border-radius: 12px; background: color-mix(in srgb, var(--boe-token-surface-surface, #fff) 78%, transparent); }
151
+ [part=frame] small { grid-column: 2; }
152
+ [part=loop-mark] { position: absolute; right: 12px; bottom: 8px; font-size: 20px; line-height: 1; color: var(--boe-token-text-text-secondary, #6f6f6f); }
153
+ [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; }
154
+ [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); }
155
+ [part=frame]:not([aria-current=true]) [part=frame-resize] { visibility: hidden; }
156
+ [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; }
157
+ [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); }
158
+ [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); }
159
+ [data-shape=event][data-kind=finish]::before { border-width: 4px; }
160
+ [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%; }
161
+ [data-shape=gateway] > [part=icon], [data-shape=event] > [part=icon] { position: absolute; left: 18px; top: 18px; z-index: 1; }
162
+ [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; }
163
+ [data-shape=gateway] > small { display: none; }
164
+ [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; }
165
+ [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)); }
166
+ [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; }
167
+ [part=port][data-side=north] { left: calc(50% - 12px); top: -12px; }
168
+ [part=port][data-side=south] { left: calc(50% - 12px); bottom: -12px; }
169
+ [part=port][data-side=east] { right: -12px; top: calc(50% - 12px); }
170
+ [part=port][data-side=west] { left: -12px; top: calc(50% - 12px); }
171
+ [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); }
172
+ [part=port]:hover::before, [part=port]:focus-visible::before { width: 22px; height: 22px; margin: 1px; background: var(--boe-token-surface-surface-brand, #0061d5); }
173
+ [part=port]::after { position: absolute; inset: 1px; display: none; place-items: center; color: #fff; font-size: 15px; font-weight: 700; line-height: 1; }
174
+ [part=port][data-side=north]::after { content: '↑'; }
175
+ [part=port][data-side=east]::after { content: '→'; }
176
+ [part=port][data-side=south]::after { content: '↓'; }
177
+ [part=port][data-side=west]::after { content: '←'; }
178
+ [part=port]:hover::after, [part=port]:focus-visible::after, [part=port][data-hot=true]::after { display: grid; }
179
+ [part=port][data-hot=true] { opacity: 1; }
180
+ [part=port][data-hot=true]::before { width: 22px; height: 22px; margin: 1px; background: var(--boe-token-surface-surface-brand, #0061d5); }
181
+ [part=end-grip] { position: absolute; z-index: 8; width: 24px; height: 24px; min-height: 24px; padding: 0; border: 0; border-radius: 50%; background: transparent; }
182
+ [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); }
183
+ [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; }
184
+ [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; }
185
+ [part=connection]:has(> span:empty) { padding: 0; background: transparent; min-width: 0; min-height: 0; }
186
+ [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; }
187
+ [part=connection]:hover [part=connection-actions], [part=connection]:focus-within [part=connection-actions] { opacity: 1; pointer-events: auto; }
188
+ [part=connection-actions] button { min-height: 32px; padding: 4px; font-size: 12px; }
189
+ [part=note] { width: 208px; border: 1px dashed var(--boe-process-box-edge, var(--boe-control-edge, #858585)); border-radius: 8px; }
190
+ [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); }
191
+ [part=section] strong { display: block; font-size: 12.5px; font-weight: 650; line-height: 1.3; }
192
+ [part=section] small { display: block; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 11.5px; line-height: 1.35; }
193
+ [part=note], [part=section] { position: absolute; padding: 8px; pointer-events: none; }
194
+ [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; }
195
+ [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)); }
196
+ [part=connect-tooltip][data-invalid=true] { background: var(--boe-token-text-status-text-error, #b92340); color: #fff; }
197
+ [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; }
198
+ [part=guide] { position: absolute; background: var(--boe-token-surface-surface-brand, #0061d5); pointer-events: none; }
199
+ [part=measure] { position: absolute; padding: 4px; background: var(--boe-token-surface-surface, #fff); font-size: 12px; pointer-events: none; }
200
+ [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); }
201
+ [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)); }
202
+ [part=controls] [data-command=reset] { min-width: 56px; font-variant-numeric: tabular-nums; }
203
+ [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)); }
204
+ [part=minimap] rect:not([data-viewport]) { fill: var(--boe-token-stroke-stroke-hover, #d3d3d3); }
205
+ [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; }
206
+ [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; }
207
+ [part=checks] { display: grid; gap: 6px; margin-top: 12px; }
208
+ [part=checks] button { color: var(--boe-token-text-status-text-error, #b92340); }
209
+ [part=process-heading] { display: grid; gap: 2px; padding: 0 16px 12px; }
210
+ :host([embed-mode]) [part=process-heading], :host([embed-mode]) [part=view-switch], :host([embed-mode]) [part=run-toggle], :host([embed-mode]) [part=view-menu] { display: none; }
211
+ [part=process-title] { font-size: 15px; line-height: 1.4; }
212
+ [part=process-summary] { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; }
213
+ [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; }
214
+ [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; }
215
+ [part=pane-tabs] button[aria-selected=true] { color: var(--boe-token-text-text, #141413); border-bottom-color: currentColor; }
216
+ [part=editor], [part=pane-content] { padding: 8px 16px; }
217
+ [part=editor] { display: grid; align-content: start; gap: 12px; }
218
+ [part=inspector-kind] { display: none; }
219
+ [part=inspector-purpose] { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; }
220
+ [part=field] { display: grid; gap: 4px; }
221
+ [part=field] label { display: grid; gap: 5px; font-size: 12.5px; font-weight: 650; }
222
+ [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; }
223
+ [part=field] textarea { min-height: 76px; resize: vertical; }
224
+ [part=field]:has([part=action-options]) { position: relative; }
225
+ [part=field]:has([part=action-options]) input { padding-right: 34px; }
226
+ [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; }
227
+ [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)); }
228
+ [part=action-options][hidden] { display: none; }
229
+ [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; }
230
+ [part=action-options] button:hover, [part=action-options] [aria-selected=true] { background: var(--boe-token-surface-surface-hover, #f4f4f4); }
231
+ [part=action-options] button strong { display: block; font-size: 13px; font-weight: 650; }
232
+ [part=action-options] button small { display: block; color: var(--boe-token-text-text-secondary, #6f6f6f); }
233
+ [part=action-options] [part=action-back] { color: var(--boe-token-text-text-secondary, #6f6f6f); }
234
+ [part=field] input[type=checkbox] { justify-self: start; width: 18px; height: 18px; accent-color: var(--boe-token-surface-surface-brand, #0061d5); }
235
+ [part=field] small { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.4; }
236
+ [part=field] [part=field-problem] { color: var(--boe-token-text-status-text-error, #b92340); }
237
+ [part=variable-chips] { display: flex; flex-wrap: wrap; gap: 4px; }
238
+ [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; }
239
+ [part=leads-to] { display: grid; gap: 6px; padding-top: 10px; border-top: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }
240
+ [part=leads-to] h3 { margin: 0; font-size: 12.5px; }
241
+ [part=lead-row] { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12.5px; }
242
+ [part=lead-row] button, [part=leads-to] > button, [part=inspector-actions] button { min-height: 28px; padding: 4px 8px; font-size: 12px; }
243
+ [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; }
244
+ [part=inspector-metrics] h3 { margin: 0 0 6px; font-size: 12.5px; }
245
+ [part=inspector-metrics] dl { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; margin: 0; }
246
+ [part=inspector-metrics] dt { color: var(--boe-token-text-text-secondary, #6f6f6f); }
247
+ [part=inspector-metrics] dd { margin: 0; font-weight: 650; }
248
+ [part=inspector-actions] { display: flex; gap: 8px; padding-top: 10px; border-top: 1px solid var(--boe-token-stroke-stroke, #e8e8e8); }
249
+ [part=arrange-actions] { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 6px; }
250
+ [part=arrange-actions] button { min-height: 32px; padding: 5px 7px; font-size: 12px; text-align: start; }
251
+ [part=outline-intro] { margin: 4px 0 14px; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12.5px; line-height: 1.5; }
252
+ [part=copy-outline] { justify-self: start; min-height: 28px; margin-bottom: 8px; padding: 4px 10px; border-radius: 16px; font-size: 12px; font-weight: 650; }
253
+ [part=outline-list] { margin: 0; padding-left: 18px; display: grid; gap: 8px; }
254
+ [part=outline-list] [part=outline-list] { margin: 6px 0 0; gap: 6px; }
255
+ [part=outline-list] li { padding-left: 0; font-size: 12.5px; }
256
+ [part=outline-list] li::marker { color: var(--boe-token-text-text-secondary, #6f6f6f); }
257
+ [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; }
258
+ [part=outline-list] button:hover { color: var(--boe-token-surface-surface-brand, #0061d5); text-decoration: underline; }
259
+ [part=outline-list] button[aria-current=true] { color: var(--boe-token-surface-surface-brand, #0061d5); }
260
+ [part=outline-list] p { margin: 2px 0 0; color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 12px; line-height: 1.45; }
261
+ [part=inspector-heading] { margin: 0 0 2px; font-size: 15px; font-weight: 650; }
262
+ [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; }
263
+ [part=checks] { margin: 0; padding: 0; }
264
+ [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; }
265
+ [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; }
266
+ [part=variable-row] p { margin: 0; color: var(--boe-token-text-text-secondary, #6f6f6f); }
267
+ [part=variable-scope] { color: var(--boe-token-text-text-secondary, #6f6f6f); font-size: 11.5px; }
268
+ [part=variable-row] label { display: grid; gap: 4px; font-weight: 650; }
269
+ [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); }
270
+ [part=help] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
271
+ :host([data-narrow]) [part=layout] { grid-template-columns: minmax(0,1fr); }
272
+ :host([data-narrow]) [part=pane-drawer] { display: none; position: fixed; 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)); }
273
+ :host([data-narrow]) [part=pane-drawer][open] { display: block; }
274
+ :host([data-narrow]) [part=pane-close], :host([data-narrow]) [data-command=palette], :host([data-narrow]) [data-command=details] { display: inline-block; }
275
+ :host([data-narrow]) [part=pane-close] { position: absolute; top: 12px; right: 12px; z-index: 1; min-height: 28px; padding: 4px 9px; border-radius: 14px; font-size: 12px; }
276
+ :host([data-narrow]) [part=pane-drawer][data-pane=palette] { left: 0; top: 0; bottom: 0; width: min(320px, 86vw); }
277
+ :host([data-narrow]) [part=pane-drawer][data-pane=inspector] { left: 0; right: 0; top: auto; bottom: 0; width: 100%; height: min(62vh, 560px); border-radius: 24px 24px 0 0; }
278
+ :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-surface-surface-secondary, #e8e8e8); }
279
+ :host([data-narrow]) [part=palette], :host([data-narrow]) [part=inspector] { height: 100%; }
280
+ :host([data-narrow]) [part=palette] { padding-top: 54px; }
281
+ :host([data-narrow]) [part=minimap] { display: none; }
282
+ :host([data-narrow]) [part=toolbar] { justify-content: flex-start; }
283
+ :host([data-narrow]) [part=view-switch], :host([data-narrow]) [part=run-toggle] { display: none; }
284
+ :host([data-narrow]) [part=view-menu] { display: block; }
285
+ :host([data-narrow]) [part=controls] { left: 12px; bottom: 12px; }
286
+ :host([data-phone]) [data-command=tidy] { display: none; }
287
+ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0s !important; animation-duration: 0s !important; scroll-behavior: auto !important; } }
288
+ `;
@@ -14,5 +14,7 @@ export declare function arrangeProcess(projection: ProcessProjection): ProcessLa
14
14
  export declare function routeProcessLine(line: ProcessLine, layout: ProcessLayout, projection: ProcessProjection): ProcessPoint[];
15
15
  /** Halfway along the polyline's length, not halfway between its endpoints. */
16
16
  export declare function lineMidpoint(points: readonly ProcessPoint[]): ProcessPoint;
17
+ /** SVG route with small rounded orthogonal turns, retaining exact endpoints. */
18
+ export declare function roundedProcessPath(points: readonly ProcessPoint[], radius?: number): string;
17
19
  /** Segment-distance hit testing, including zero-length and diagonal segments. */
18
20
  export declare function nearProcessLine(point: ProcessPoint, points: readonly ProcessPoint[], tolerance?: number): boolean;
@@ -53,8 +53,9 @@ export function arrangeProcess(projection) {
53
53
  const sizes = new Map();
54
54
  for (const box of siblings) {
55
55
  const group = measureGroup(box.id);
56
- const width = box.frame ? Math.max(320, group.width + PADDING * 2) : 220;
57
- const height = box.frame ? Math.max(180, group.height + HEADER + PADDING) : 96;
56
+ const compact = box.shape === "gateway" || box.shape === "event";
57
+ const width = box.frame ? Math.max(320, group.width + PADDING * 2) : compact ? 56 : 224;
58
+ const height = box.frame ? Math.max(180, group.height + HEADER + PADDING) : compact ? 56 : 64;
58
59
  sizes.set(box.id, { x: 0, y: 0, width, height });
59
60
  // Store local child coordinates until the parent's absolute position is known.
60
61
  for (const [id, position] of group.positions)
@@ -88,8 +89,9 @@ export function arrangeProcess(projection) {
88
89
  place(roots.positions, 40, 40);
89
90
  return result;
90
91
  }
91
- function rectangle(position, frame = false) {
92
- return { ...position, width: position.width ?? (frame ? 320 : 220), height: position.height ?? (frame ? 180 : 96) };
92
+ function rectangle(position, box) {
93
+ const compact = box?.shape === "gateway" || box?.shape === "event";
94
+ return { ...position, width: position.width ?? (box?.frame ? 320 : compact ? 56 : 224), height: position.height ?? (box?.frame ? 180 : compact ? 56 : 64) };
93
95
  }
94
96
  const center = (box) => ({ x: box.x + box.width / 2, y: box.y + box.height / 2 });
95
97
  const distance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
@@ -232,8 +234,8 @@ export function routeProcessLine(line, layout, projection) {
232
234
  const fromPosition = layout.boxes[line.from], toPosition = layout.boxes[line.to];
233
235
  if (!fromPosition || !toPosition)
234
236
  return [];
235
- const from = rectangle(fromPosition, boxes.get(line.from)?.frame);
236
- const to = rectangle(toPosition, boxes.get(line.to)?.frame);
237
+ const from = rectangle(fromPosition, boxes.get(line.from));
238
+ const to = rectangle(toPosition, boxes.get(line.to));
237
239
  const excluded = new Set();
238
240
  for (const id of [line.from, line.to]) {
239
241
  let parent = boxes.get(id)?.parentId;
@@ -243,7 +245,7 @@ export function routeProcessLine(line, layout, projection) {
243
245
  }
244
246
  }
245
247
  const obstacleBoxes = projection.boxes.filter(box => !excluded.has(box.id) && layout.boxes[box.id]);
246
- const obstacles = obstacleBoxes.map(box => rectangle(layout.boxes[box.id], box.frame));
248
+ const obstacles = obstacleBoxes.map(box => rectangle(layout.boxes[box.id], box));
247
249
  const waypoints = (layout.lines?.[line.id] ?? line.points ?? []).map(point => ({ ...point }));
248
250
  if (waypoints.some(point => !Number.isFinite(point.x) || !Number.isFinite(point.y)))
249
251
  return [];
@@ -292,6 +294,27 @@ export function lineMidpoint(points) {
292
294
  }
293
295
  return { ...points[0] };
294
296
  }
297
+ /** SVG route with small rounded orthogonal turns, retaining exact endpoints. */
298
+ export function roundedProcessPath(points, radius = 6) {
299
+ if (!points.length)
300
+ return "";
301
+ const commands = [`M ${points[0].x} ${points[0].y}`];
302
+ for (let index = 1; index < points.length - 1; index++) {
303
+ const previous = points[index - 1], corner = points[index], next = points[index + 1];
304
+ const beforeLength = Math.hypot(corner.x - previous.x, corner.y - previous.y);
305
+ const afterLength = Math.hypot(next.x - corner.x, next.y - corner.y);
306
+ if (!beforeLength || !afterLength || (corner.x - previous.x) * (next.y - corner.y) === (corner.y - previous.y) * (next.x - corner.x)) {
307
+ commands.push(`L ${corner.x} ${corner.y}`);
308
+ continue;
309
+ }
310
+ const turn = Math.min(radius, beforeLength / 2, afterLength / 2);
311
+ const enter = { x: corner.x - (corner.x - previous.x) / beforeLength * turn, y: corner.y - (corner.y - previous.y) / beforeLength * turn };
312
+ const leave = { x: corner.x + (next.x - corner.x) / afterLength * turn, y: corner.y + (next.y - corner.y) / afterLength * turn };
313
+ commands.push(`L ${enter.x} ${enter.y}`, `Q ${corner.x} ${corner.y} ${leave.x} ${leave.y}`);
314
+ }
315
+ commands.push(`L ${points.at(-1).x} ${points.at(-1).y}`);
316
+ return commands.join(" ");
317
+ }
295
318
  /** Segment-distance hit testing, including zero-length and diagonal segments. */
296
319
  export function nearProcessLine(point, points, tolerance = 16) {
297
320
  if (tolerance < 0 || !points.length)
@@ -5,11 +5,17 @@ export interface ProcessBox<N = unknown> {
5
5
  kind: string;
6
6
  title: string;
7
7
  description?: string;
8
+ /** Description used in Technical view; absent values fall back to description. */
9
+ technicalDescription?: string;
10
+ /** Visual anatomy, independent of the host's kind identifier. */
11
+ shape?: "task" | "gateway" | "event" | "frame";
8
12
  path?: NodePath;
9
13
  /** Host identity at this path, used to reject stale saved positions. */
10
14
  fingerprint?: string;
11
15
  /** A frame draws behind its children and connects as one box. */
12
16
  frame?: boolean;
17
+ /** Show the loop mark in a repeating frame without inferring host semantics from its kind name. */
18
+ loopMark?: boolean;
13
19
  parentId?: string;
14
20
  }
15
21
  export interface ProcessLine {
@@ -25,17 +31,47 @@ export interface ProcessLine {
25
31
  x: number;
26
32
  y: number;
27
33
  }[];
34
+ /** Optional last-run traffic share, between 0 and 1. */
35
+ share?: number;
28
36
  }
29
37
  export type ProcessSide = "north" | "east" | "south" | "west";
30
38
  export interface ProcessConnection {
31
39
  name: string;
32
40
  kind: string;
33
41
  id?: string;
42
+ signIn?: string;
34
43
  }
35
44
  export interface ProcessVariable {
36
45
  name: string;
37
46
  value?: unknown;
38
47
  description?: string;
48
+ scope?: string;
49
+ startingValue?: string;
50
+ problem?: string;
51
+ }
52
+ /** Host-authored, readable outline; boxId links a row to a projected step. */
53
+ export interface ProcessOutlineItem {
54
+ title: string;
55
+ description?: string;
56
+ boxId?: string;
57
+ children?: readonly ProcessOutlineItem[];
58
+ }
59
+ /** Host-supplied field values; the modeler draws controls and requests edits. */
60
+ export interface ProcessField {
61
+ key: string;
62
+ label: string;
63
+ kind: "text" | "multiline" | "number" | "choice" | "boolean" | "expression" | "search" | "action";
64
+ value: string | number | boolean;
65
+ description?: string;
66
+ options?: readonly {
67
+ value: string;
68
+ label: string;
69
+ group?: string;
70
+ }[];
71
+ placeholder?: string;
72
+ required?: boolean;
73
+ disabled?: boolean;
74
+ problem?: string;
39
75
  }
40
76
  export interface ProcessPositionSnapshot {
41
77
  path?: NodePath;
@@ -56,11 +92,35 @@ export interface ProcessProjection<N = unknown> {
56
92
  boxes: readonly ProcessBox<N>[];
57
93
  lines: readonly ProcessLine[];
58
94
  }
95
+ export interface ProcessKind extends FlowKind {
96
+ /** Alternative terms included in palette search. */
97
+ aliases?: readonly string[];
98
+ /** Host kind names never dictate the reusable visual anatomy. */
99
+ shape?: ProcessBox["shape"];
100
+ /** Notes and sections live in layout rather than the host workflow graph. */
101
+ placement?: "note" | "section";
102
+ }
103
+ export interface ProcessStepMetrics {
104
+ callsPerSecond?: number;
105
+ p95Ms?: number;
106
+ failedShare?: number;
107
+ /** True when the step was not measured in this run. */
108
+ notInRun?: boolean;
109
+ }
110
+ export interface ProcessLastRun {
111
+ label: string;
112
+ /** Keys are projected box IDs, supplied by the host. */
113
+ steps: Readonly<Record<string, ProcessStepMetrics>>;
114
+ }
59
115
  export interface ProcessModel<D = unknown, N = unknown> {
60
116
  project(document: D): ProcessProjection<N>;
61
117
  /** Optional host arrangement, used by Tidy up and for missing positions. */
62
118
  arrange?(projection: ProcessProjection<N>): ProcessLayout;
63
- /** Host-specific semantics supplement the generic free-graph checks. */
119
+ /**
120
+ * The host's workflow read-back/validation. When supplied it is authoritative:
121
+ * generic vocabulary-based graph checks are not added on top. A host may call
122
+ * graphChecks itself with its own kind names if it wants those checks too.
123
+ */
64
124
  validate?(document: D, projection: ProcessProjection<N>): readonly ProcessCheck[];
65
125
  }
66
126
  export interface BoxPosition {
@@ -80,6 +140,7 @@ export interface ProcessLayout {
80
140
  sections?: {
81
141
  id: string;
82
142
  title: string;
143
+ description?: string;
83
144
  x: number;
84
145
  y: number;
85
146
  width: number;
@@ -96,8 +157,9 @@ export interface ProcessCheck {
96
157
  path?: NodePath;
97
158
  }
98
159
  export interface ProcessEdit {
99
- type: "add" | "delete" | "connect" | "disconnect" | "insert" | "reparent";
160
+ type: "add" | "delete" | "duplicate" | "connect" | "disconnect" | "reattach" | "insert" | "reparent";
100
161
  boxId?: string;
162
+ sourceId?: string;
101
163
  from?: string;
102
164
  to?: string;
103
165
  lineId?: string;
@@ -106,6 +168,9 @@ export interface ProcessEdit {
106
168
  parentId?: string;
107
169
  fromSide?: ProcessSide;
108
170
  toSide?: ProcessSide;
171
+ /** Optional branch presentation requested by a directional add. */
172
+ routeLabel?: string;
173
+ dashed?: boolean;
109
174
  }
110
175
  export interface ReversibleProcessEdit {
111
176
  undo(): void;
@@ -35,10 +35,10 @@ export function completeLayout(projection, layout) {
35
35
  .filter((child) => child.parentId === box.id)
36
36
  .map(measure);
37
37
  const size = {
38
- width: Math.max(box.frame ? 320 : 220, ...children.map((child) => child.width + 40)),
38
+ width: Math.max(box.frame || box.shape === "frame" ? 320 : box.shape === "gateway" || box.shape === "event" ? 56 : 224, ...children.map((child) => child.width + 40)),
39
39
  height: box.frame
40
40
  ? Math.max(180, 64 + children.reduce((sum, child) => sum + child.height + 24, 0))
41
- : 96,
41
+ : box.shape === "gateway" || box.shape === "event" ? 56 : 64,
42
42
  };
43
43
  sizes.set(box.id, size);
44
44
  return size;