@jay-framework/aiditor 0.18.4 → 0.19.1

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.
@@ -3,290 +3,1358 @@
3
3
  <meta charset="UTF-8" />
4
4
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
5
  <title>AIditor</title>
6
+ <!-- Styles: page.css (Harmony-inspired light theme) -->
6
7
  <style>
8
+ /* AIditor — Wix Harmony–inspired light editor shell */
9
+
10
+ :root {
11
+ --harmony-bg-workspace: #eef0f4;
12
+ --harmony-bg-surface: #ffffff;
13
+ --harmony-bg-subtle: #f7f8fa;
14
+ --harmony-bg-hover: #f0f2f5;
15
+ --harmony-border: #dfe3eb;
16
+ --harmony-border-strong: #c5cdd8;
17
+ --harmony-primary: #116dff;
18
+ --harmony-primary-hover: #0d5ee0;
19
+ --harmony-primary-soft: rgba(17, 109, 255, 0.1);
20
+ --harmony-text: #162d3d;
21
+ --harmony-text-secondary: #5a6b7d;
22
+ --harmony-text-muted: #8f9bb0;
23
+ --harmony-danger: #e84c3d;
24
+ --harmony-danger-soft: #fef2f1;
25
+ --harmony-success: #00a862;
26
+ --harmony-success-soft: #e8f8f0;
27
+ --harmony-warning: #f5a623;
28
+ --harmony-warning-soft: #fff8e6;
29
+ --harmony-shadow-sm: 0 1px 4px rgba(22, 45, 61, 0.06);
30
+ --harmony-shadow-md: 0 4px 24px rgba(22, 45, 61, 0.1);
31
+ --harmony-shadow-lg: 0 8px 40px rgba(22, 45, 61, 0.12);
32
+ --harmony-radius-sm: 6px;
33
+ --harmony-radius-md: 10px;
34
+ --harmony-radius-lg: 16px;
35
+ --harmony-radius-pill: 999px;
36
+ --harmony-sidebar-width: 52px;
37
+ --harmony-global-bar-height: 52px;
38
+ --harmony-secondary-bar-height: 44px;
39
+ --harmony-font: 'Madefor', 'Helvetica Neue', Helvetica, Arial, sans-serif;
40
+ --harmony-mono: ui-monospace, 'SF Mono', 'Cascadia Code', Consolas, monospace;
41
+ }
42
+
7
43
  *, *::before, *::after { box-sizing: border-box; }
8
- html, body { margin: 0; padding: 0; height: 100%; background: #252526; color: #d4d4d4; font-family: 'Segoe UI', system-ui, sans-serif; }
9
- .setup-screen { height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; background: #1e1e1e; gap: 10px; }
10
- .setup-title { margin: 0 0 4px; font-size: 28px; color: #9cdcfe; }
11
- .setup-desc { margin: 0 0 20px; font-size: 14px; color: #888; }
44
+
45
+ html, body {
46
+ margin: 0;
47
+ padding: 0;
48
+ height: 100%;
49
+ background: var(--harmony-bg-workspace);
50
+ color: var(--harmony-text);
51
+ font-family: var(--harmony-font);
52
+ -webkit-font-smoothing: antialiased;
53
+ }
54
+
55
+ /* ── Setup screen ── */
56
+ .setup-screen {
57
+ height: 100vh;
58
+ display: flex;
59
+ flex-direction: column;
60
+ align-items: center;
61
+ justify-content: center;
62
+ background: var(--harmony-bg-workspace);
63
+ gap: 10px;
64
+ }
65
+ .setup-title { margin: 0 0 4px; font-size: 28px; font-weight: 600; color: var(--harmony-text); }
66
+ .setup-desc { margin: 0 0 20px; font-size: 14px; color: var(--harmony-text-secondary); }
12
67
  .setup-form { display: flex; flex-direction: column; gap: 6px; width: 360px; }
13
- .setup-label { font-size: 12px; color: #aaa; margin-top: 8px; }
14
- .setup-input { background: #252526; color: #d4d4d4; border: 1px solid #3e3e3e; border-radius: 6px; padding: 10px 14px; font-size: 13px; outline: none; font-family: monospace; width: 100%; }
15
- .setup-input:focus { border-color: #0e639c; }
16
- .setup-hint { margin: 2px 0 0; font-size: 11px; color: #555; }
17
- .setup-btn { margin-top: 16px; background: #0e639c; color: #fff; border: none; border-radius: 6px; padding: 10px 24px; font-size: 14px; cursor: pointer; align-self: flex-start; }
18
- .setup-btn:hover { background: #1177bb; }
68
+ .setup-label { font-size: 12px; color: var(--harmony-text-secondary); margin-top: 8px; }
69
+ .setup-input {
70
+ background: var(--harmony-bg-surface);
71
+ color: var(--harmony-text);
72
+ border: 1px solid var(--harmony-border);
73
+ border-radius: var(--harmony-radius-sm);
74
+ padding: 10px 14px;
75
+ font-size: 13px;
76
+ outline: none;
77
+ font-family: var(--harmony-mono);
78
+ width: 100%;
79
+ }
80
+ .setup-input:focus { border-color: var(--harmony-primary); box-shadow: 0 0 0 3px var(--harmony-primary-soft); }
81
+ .setup-hint { margin: 2px 0 0; font-size: 11px; color: var(--harmony-text-muted); }
82
+ .setup-btn {
83
+ margin-top: 16px;
84
+ background: var(--harmony-primary);
85
+ color: #fff;
86
+ border: none;
87
+ border-radius: var(--harmony-radius-pill);
88
+ padding: 10px 24px;
89
+ font-size: 14px;
90
+ font-weight: 600;
91
+ cursor: pointer;
92
+ align-self: flex-start;
93
+ }
94
+ .setup-btn:hover { background: var(--harmony-primary-hover); }
19
95
  .setup-btn:disabled { opacity: 0.45; cursor: not-allowed; }
20
- .bootstrap-msg { max-width: 420px; text-align: center; line-height: 1.45; color: #f48771; }
21
- .root { display: flex; height: 100vh; overflow: hidden; flex-direction: column; }
22
- .main-panel { flex: 1; padding: 0; overflow: hidden; background: #252526; display: flex; flex-direction: column; min-height: 0; }
23
- .main-top-bar { flex-shrink: 0; display: flex; align-items: center; gap: 10px; padding: 12px 20px 0; flex-wrap: wrap; }
24
- .main-top-bar-spacer { flex: 1; min-width: 8px; }
25
- .reset-btn { background: #2d2d30; border: 1px solid #3e3e3e; color: #ccc; cursor: pointer; font-size: 14px; padding: 8px 12px; border-radius: 6px; line-height: 1; }
26
- .reset-btn:hover { color: #fff; border-color: #9cdcfe; }
27
- .route-picker-stack { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; width: 100%; }
28
- .aiditor-dropdown { width: 100%; min-width: 240px; background: #1e1e1e; color: #d4d4d4; border: 1px solid #9cdcfe; border-radius: 6px; padding: 8px 32px 8px 12px; font-size: 13px; font-family: ui-monospace, monospace; cursor: pointer; outline: none; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%239cdcfe' d='M3 4.5L6 8l3-3.5H3z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; }
29
- .aiditor-dropdown:focus { border-color: #3794ff; box-shadow: 0 0 0 1px rgba(55,148,255,0.35); }
30
- .aiditor-dropdown option { background: #f3f3f3; color: #1e1e1e; }
31
- .preview-stack { flex: 1; display: flex; flex-direction: column; min-height: 0; padding: 12px 20px 16px; gap: 10px; }
32
- .preview-url-row { display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap; }
33
- .url-bar-wrap { flex: 1; min-width: 200px; }
34
- .url-bar { font-size: 12px; font-family: monospace; color: #9cdcfe; background: #1e1e1e; border: 1px solid #3e3e3e; border-radius: 6px; padding: 8px 12px; word-break: break-all; }
35
- .preview-visual-tools { display: flex; flex-shrink: 0; gap: 4px; align-items: center; }
36
- .visual-tool-btn { background: #2d2d30; color: #ccc; border: 1px solid #3e3e3e; border-radius: 6px; padding: 6px 10px; font-size: 12px; cursor: pointer; line-height: 1; }
37
- .visual-tool-btn:hover { background: #3e3e42; color: #fff; }
38
- .visual-tool-on { background: #37373d !important; border-color: #9cdcfe !important; color: #9cdcfe !important; }
39
- .preview-loading { font-size: 13px; color: #888; }
40
- .preview-error { font-size: 13px; color: #f48771; background: #3a1f1f; border-radius: 6px; padding: 10px 12px; }
96
+ .bootstrap-msg { max-width: 420px; text-align: center; line-height: 1.45; color: var(--harmony-danger); }
97
+
98
+ /* ── Root layout ── */
99
+ .root {
100
+ display: flex;
101
+ height: 100vh;
102
+ overflow: hidden;
103
+ flex-direction: column;
104
+ background: var(--harmony-bg-workspace);
105
+ }
106
+
107
+ /* ── Top bar (single line) ── */
108
+ .editor-topbar {
109
+ flex-shrink: 0;
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: space-between;
113
+ gap: 20px;
114
+ height: 56px;
115
+ padding: 0 24px;
116
+ background: var(--harmony-bg-surface);
117
+ border-bottom: 1px solid var(--harmony-border);
118
+ z-index: 40;
119
+ }
120
+ .editor-topbar-left {
121
+ display: flex;
122
+ align-items: center;
123
+ gap: 12px;
124
+ min-width: 0;
125
+ flex: 1;
126
+ }
127
+ .editor-topbar-right {
128
+ display: flex;
129
+ align-items: center;
130
+ gap: 10px;
131
+ flex-shrink: 0;
132
+ }
133
+
134
+ /* ── Main stage + floating annotate dock ── */
135
+ .editor-stage {
136
+ flex: 1;
137
+ display: flex;
138
+ flex-direction: column;
139
+ min-height: 0;
140
+ overflow: hidden;
141
+ position: relative;
142
+ background: var(--harmony-bg-workspace);
143
+ }
144
+
145
+ .canvas-workspace {
146
+ flex: 1;
147
+ display: flex;
148
+ flex-direction: column;
149
+ min-height: 0;
150
+ padding: 20px 28px 72px;
151
+ overflow: hidden;
152
+ }
153
+
154
+ .canvas-window {
155
+ flex: 1;
156
+ display: flex;
157
+ flex-direction: column;
158
+ min-height: 0;
159
+ max-width: 1280px;
160
+ width: 100%;
161
+ margin: 0 auto;
162
+ background: var(--harmony-bg-surface);
163
+ border: 1px solid var(--harmony-border);
164
+ border-radius: var(--harmony-radius-lg);
165
+ box-shadow: var(--harmony-shadow-md);
166
+ overflow: hidden;
167
+ }
168
+
169
+ .canvas-chrome {
170
+ flex-shrink: 0;
171
+ display: flex;
172
+ align-items: center;
173
+ gap: 12px;
174
+ padding: 10px 16px;
175
+ background: var(--harmony-bg-subtle);
176
+ border-bottom: 1px solid var(--harmony-border);
177
+ }
178
+ .canvas-chrome-left { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
179
+ .canvas-chrome-right { display: flex; align-items: center; gap: 4px; flex-shrink: 0; margin-left: auto; }
180
+ .canvas-page-badge {
181
+ font-size: 12px;
182
+ font-weight: 600;
183
+ color: var(--harmony-text-secondary);
184
+ white-space: nowrap;
185
+ }
186
+
187
+ /* Floating annotation toolbar — centered at bottom of canvas stage */
188
+ .annotate-dock {
189
+ position: absolute;
190
+ bottom: 20px;
191
+ left: 50%;
192
+ transform: translateX(-50%);
193
+ z-index: 60;
194
+ display: flex;
195
+ align-items: center;
196
+ gap: 2px;
197
+ padding: 5px 8px;
198
+ background: var(--harmony-bg-surface);
199
+ border: 1px solid var(--harmony-border);
200
+ border-radius: var(--harmony-radius-pill);
201
+ box-shadow: 0 6px 28px rgba(22, 45, 61, 0.14), 0 2px 6px rgba(22, 45, 61, 0.06);
202
+ pointer-events: auto;
203
+ }
204
+ .annotate-dock-label {
205
+ font-size: 12px;
206
+ font-weight: 600;
207
+ color: var(--harmony-text-secondary);
208
+ padding: 0 8px 0 4px;
209
+ white-space: nowrap;
210
+ border-right: 1px solid var(--harmony-border);
211
+ margin-right: 4px;
212
+ }
213
+
214
+ /* ── Global top bar aliases (legacy class names) ── */
215
+ .harmony-global-bar {
216
+ flex-shrink: 0;
217
+ display: flex;
218
+ align-items: center;
219
+ justify-content: space-between;
220
+ gap: 20px;
221
+ height: 56px;
222
+ padding: 0 24px;
223
+ background: var(--harmony-bg-surface);
224
+ border-bottom: 1px solid var(--harmony-border);
225
+ }
226
+ .harmony-global-left {
227
+ display: flex;
228
+ align-items: center;
229
+ gap: 12px;
230
+ min-width: 0;
231
+ flex: 1;
232
+ }
233
+ .harmony-global-spacer { display: none; }
234
+ .harmony-global-right {
235
+ display: flex;
236
+ align-items: center;
237
+ gap: 10px;
238
+ flex-shrink: 0;
239
+ }
240
+ .harmony-page-select-wrap {
241
+ display: flex;
242
+ align-items: center;
243
+ gap: 8px;
244
+ min-width: 0;
245
+ }
246
+ .harmony-page-label {
247
+ font-size: 13px;
248
+ font-weight: 600;
249
+ color: var(--harmony-text-secondary);
250
+ white-space: nowrap;
251
+ }
252
+ .harmony-path-select {
253
+ display: flex;
254
+ align-items: center;
255
+ gap: 8px;
256
+ min-width: 0;
257
+ }
258
+
259
+ .aiditor-logo {
260
+ font-size: 17px;
261
+ font-weight: 700;
262
+ letter-spacing: -0.3px;
263
+ color: var(--harmony-text);
264
+ flex-shrink: 0;
265
+ font-family: var(--harmony-font);
266
+ }
267
+ .aiditor-logo-ai { color: var(--harmony-primary); }
268
+
269
+ .aiditor-dropdown {
270
+ min-width: 180px;
271
+ max-width: 320px;
272
+ background: var(--harmony-bg-surface);
273
+ color: var(--harmony-text);
274
+ border: 1px solid var(--harmony-border);
275
+ border-radius: var(--harmony-radius-sm);
276
+ padding: 7px 32px 7px 12px;
277
+ font-size: 13px;
278
+ font-family: var(--harmony-mono);
279
+ cursor: pointer;
280
+ outline: none;
281
+ appearance: none;
282
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%235a6b7d' d='M3 4.5L6 8l3-3.5H3z'/%3E%3C/svg%3E");
283
+ background-repeat: no-repeat;
284
+ background-position: right 10px center;
285
+ }
286
+ .aiditor-dropdown:focus {
287
+ border-color: var(--harmony-primary);
288
+ box-shadow: 0 0 0 3px var(--harmony-primary-soft);
289
+ }
290
+ .aiditor-dropdown option { background: #fff; color: var(--harmony-text); }
291
+ .harmony-page-select { flex: 1; min-width: 160px; }
292
+ .preview-path-select { flex: 1; min-width: 0; max-width: 400px; }
41
293
  .path-select-row { display: flex; align-items: center; gap: 8px; width: 100%; }
42
- .preview-path-select { flex: 1; min-width: 0; max-width: 560px; }
43
- .params-loading-hint { font-size: 11px; color: #888; white-space: nowrap; flex-shrink: 0; }
294
+ .params-loading-hint { font-size: 11px; color: var(--harmony-text-muted); white-space: nowrap; flex-shrink: 0; }
295
+
296
+ /* Harmony buttons */
297
+ .harmony-btn-primary {
298
+ background: var(--harmony-primary);
299
+ color: #fff;
300
+ border: none;
301
+ border-radius: var(--harmony-radius-pill);
302
+ padding: 7px 16px;
303
+ font-size: 13px;
304
+ font-weight: 600;
305
+ cursor: pointer;
306
+ flex-shrink: 0;
307
+ white-space: nowrap;
308
+ }
309
+ .harmony-btn-primary:hover { background: var(--harmony-primary-hover); }
310
+ .harmony-btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
311
+
312
+ .harmony-btn-secondary {
313
+ background: var(--harmony-bg-surface);
314
+ color: var(--harmony-text);
315
+ border: 1px solid var(--harmony-border);
316
+ border-radius: var(--harmony-radius-pill);
317
+ padding: 7px 14px;
318
+ font-size: 13px;
319
+ font-weight: 500;
320
+ cursor: pointer;
321
+ flex-shrink: 0;
322
+ white-space: nowrap;
323
+ }
324
+ .harmony-btn-secondary:hover { background: var(--harmony-bg-hover); border-color: var(--harmony-border-strong); }
325
+ .harmony-btn-secondary:disabled { opacity: 0.5; cursor: not-allowed; }
326
+
327
+ .add-page-open-btn { /* inherits harmony-btn-primary */ }
328
+ .add-page-from-brief-btn { /* inherits harmony-btn-secondary */ }
329
+ .project-settings-btn { /* inherits harmony-btn-secondary */ }
330
+
331
+ .harmony-editor-body,
332
+ .harmony-sidebar,
333
+ .harmony-secondary-bar { display: none !important; }
334
+ .harmony-workspace { display: contents; }
335
+ .preview-visual-tools { display: flex; flex-shrink: 0; gap: 2px; align-items: center; }
336
+
337
+ .visual-tool-btn {
338
+ background: transparent;
339
+ color: var(--harmony-text-secondary);
340
+ border: none;
341
+ border-radius: var(--harmony-radius-sm);
342
+ padding: 7px 10px;
343
+ font-size: 12px;
344
+ cursor: pointer;
345
+ line-height: 1;
346
+ display: inline-flex;
347
+ align-items: center;
348
+ justify-content: center;
349
+ min-width: 34px;
350
+ min-height: 34px;
351
+ }
352
+ .visual-tool-btn:hover { background: var(--harmony-bg-hover); color: var(--harmony-text); }
353
+ .visual-tool-on {
354
+ background: var(--harmony-primary-soft) !important;
355
+ color: var(--harmony-primary) !important;
356
+ }
357
+ .tool-group-sep {
358
+ width: 1px;
359
+ background: var(--harmony-border);
360
+ align-self: stretch;
361
+ margin: 0 4px;
362
+ flex-shrink: 0;
363
+ }
364
+
365
+ /* Canvas aliases */
366
+ .harmony-canvas-area,
367
+ .canvas-workspace {
368
+ flex: 1;
369
+ display: flex;
370
+ flex-direction: column;
371
+ min-height: 0;
372
+ padding: 20px 28px 72px;
373
+ gap: 10px;
374
+ overflow: hidden;
375
+ }
376
+ .harmony-canvas-window,
377
+ .canvas-window {
378
+ flex: 1;
379
+ display: flex;
380
+ flex-direction: column;
381
+ min-height: 0;
382
+ background: var(--harmony-bg-surface);
383
+ border: 1px solid var(--harmony-border);
384
+ border-radius: var(--harmony-radius-lg);
385
+ box-shadow: var(--harmony-shadow-md);
386
+ overflow: hidden;
387
+ }
388
+
389
+ .harmony-canvas-chrome {
390
+ flex-shrink: 0;
391
+ display: flex;
392
+ align-items: center;
393
+ gap: 12px;
394
+ padding: 10px 16px;
395
+ background: var(--harmony-bg-subtle);
396
+ border-bottom: 1px solid var(--harmony-border);
397
+ }
398
+ .harmony-canvas-chrome-left { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
399
+ .harmony-canvas-page-badge {
400
+ font-size: 12px;
401
+ font-weight: 600;
402
+ color: var(--harmony-text-secondary);
403
+ background: var(--harmony-bg-surface);
404
+ border: 1px solid var(--harmony-border);
405
+ border-radius: var(--harmony-radius-sm);
406
+ padding: 4px 10px;
407
+ }
408
+ .harmony-url-bar-wrap { flex: 1; min-width: 0; }
409
+ .url-bar-wrap { flex: 1; min-width: 200px; }
410
+ .url-bar {
411
+ font-size: 12px;
412
+ font-family: var(--harmony-mono);
413
+ color: var(--harmony-text-secondary);
414
+ background: var(--harmony-bg-surface);
415
+ border: 1px solid var(--harmony-border);
416
+ border-radius: var(--harmony-radius-sm);
417
+ padding: 7px 12px;
418
+ word-break: break-all;
419
+ }
420
+
421
+ .preview-loading { font-size: 13px; color: var(--harmony-text-muted); }
422
+ .preview-error {
423
+ font-size: 13px;
424
+ color: var(--harmony-danger);
425
+ background: var(--harmony-danger-soft);
426
+ border-radius: var(--harmony-radius-sm);
427
+ padding: 10px 12px;
428
+ border: 1px solid rgba(232, 76, 61, 0.2);
429
+ }
430
+
44
431
  /* isolation: Chrome Element Capture requires a stacking context on the capture target */
45
- .preview-frame-wrap { flex: 1; min-height: 0; border: 1px solid #3e3e3e; border-radius: 8px; overflow: visible; background: #1e1e1e; position: relative; isolation: isolate; }
432
+ .preview-frame-wrap {
433
+ flex: 1;
434
+ min-height: 0;
435
+ border: none;
436
+ border-radius: 0;
437
+ overflow: visible;
438
+ background: var(--harmony-bg-surface);
439
+ position: relative;
440
+ isolation: isolate;
441
+ }
442
+ .harmony-canvas-content { flex: 1; }
46
443
  .preview-frame { width: 100%; height: 100%; min-height: 360px; border: none; display: block; }
444
+ .preview-frame-tablet { align-self: center; width: 768px; max-width: 100%; }
445
+ .preview-frame-mobile { align-self: center; width: 390px; max-width: 100%; }
446
+
447
+ /* ── Visual annotations ── */
47
448
  .visual-overlay { position: absolute; inset: 0; z-index: 2; }
48
449
  .visual-overlay-none { pointer-events: none; }
49
- .point-marker { position: absolute; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%; background: #c586ff; border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.5); }
50
- .point-marker-idx { position: absolute; left: 10px; top: -18px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 4px; background: #c586ff; color: #1e1e1e; font-size: 10px; font-weight: 700; line-height: 16px; text-align: center; pointer-events: none; }
51
- .area-rect { position: absolute; border: 2px dashed #c586ff; background: rgba(197, 134, 255, 0.12); pointer-events: none; }
52
- .area-marker-idx { position: absolute; left: 4px; top: 4px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 4px; background: #c586ff; color: #1e1e1e; font-size: 10px; font-weight: 700; line-height: 18px; text-align: center; pointer-events: none; z-index: 1; }
53
- .area-rect-draft { border-style: solid; border-color: #9cdcfe; background: rgba(156, 220, 254, 0.08); }
54
- .arrow-pending-dot { position: absolute; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: #9cdcfe; border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.5); pointer-events: none; }
450
+ .point-marker {
451
+ position: absolute;
452
+ width: 14px;
453
+ height: 14px;
454
+ margin: -7px 0 0 -7px;
455
+ border-radius: 50%;
456
+ background: var(--harmony-primary);
457
+ border: 2px solid #fff;
458
+ box-shadow: var(--harmony-shadow-sm);
459
+ }
460
+ .point-marker-idx {
461
+ position: absolute;
462
+ left: 10px;
463
+ top: -18px;
464
+ min-width: 16px;
465
+ height: 16px;
466
+ padding: 0 4px;
467
+ border-radius: 4px;
468
+ background: var(--harmony-primary);
469
+ color: #fff;
470
+ font-size: 10px;
471
+ font-weight: 700;
472
+ line-height: 16px;
473
+ text-align: center;
474
+ pointer-events: none;
475
+ }
476
+ .area-rect {
477
+ position: absolute;
478
+ border: 2px dashed var(--harmony-primary);
479
+ background: var(--harmony-primary-soft);
480
+ pointer-events: none;
481
+ }
482
+ .area-marker-idx {
483
+ position: absolute;
484
+ left: 4px;
485
+ top: 4px;
486
+ min-width: 18px;
487
+ height: 18px;
488
+ padding: 0 5px;
489
+ border-radius: 4px;
490
+ background: var(--harmony-primary);
491
+ color: #fff;
492
+ font-size: 10px;
493
+ font-weight: 700;
494
+ line-height: 18px;
495
+ text-align: center;
496
+ pointer-events: none;
497
+ z-index: 1;
498
+ }
499
+ .area-rect-draft { border-style: solid; border-color: var(--harmony-primary); background: var(--harmony-primary-soft); }
500
+ .arrow-pending-dot {
501
+ position: absolute;
502
+ width: 10px;
503
+ height: 10px;
504
+ margin: -5px 0 0 -5px;
505
+ border-radius: 50%;
506
+ background: var(--harmony-primary);
507
+ border: 2px solid #fff;
508
+ box-shadow: var(--harmony-shadow-sm);
509
+ pointer-events: none;
510
+ }
55
511
  .arrow-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
56
- .arrow-svg line { stroke: #c586ff; stroke-width: 2; marker-end: url(#aiditor-arrowhead); }
57
- .arrow-end-pin { position: absolute; width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; background: #c586ff; color: #1e1e1e; border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.5); font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center; pointer-events: none; z-index: 3; }
512
+ .arrow-svg line { stroke: var(--harmony-primary); stroke-width: 2; marker-end: url(#aiditor-arrowhead); }
513
+ .arrow-end-pin {
514
+ position: absolute;
515
+ width: 22px;
516
+ height: 22px;
517
+ margin: -11px 0 0 -11px;
518
+ border-radius: 50%;
519
+ background: var(--harmony-primary);
520
+ color: #fff;
521
+ border: 2px solid #fff;
522
+ box-shadow: var(--harmony-shadow-sm);
523
+ font-size: 11px;
524
+ font-weight: 700;
525
+ display: flex;
526
+ align-items: center;
527
+ justify-content: center;
528
+ pointer-events: none;
529
+ z-index: 3;
530
+ }
58
531
  .visual-popovers { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
59
- .visual-popover { position: absolute; width: 280px; max-width: min(280px, calc(100% - 16px)); display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; background: #252526; border: 1px solid #9cdcfe; border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.45); box-sizing: border-box; transform: translate(10px, 10px); pointer-events: auto; }
60
- /* Keep card on-screen when anchor is near right/bottom (default opens down-right). */
532
+ .visual-popover {
533
+ position: absolute;
534
+ width: 280px;
535
+ max-width: min(280px, calc(100% - 16px));
536
+ max-height: min(560px, calc(100vh - 96px));
537
+ display: flex;
538
+ flex-direction: column;
539
+ gap: 8px;
540
+ padding: 12px 14px;
541
+ background: var(--harmony-bg-surface);
542
+ border: 1px solid var(--harmony-border);
543
+ border-radius: var(--harmony-radius-md);
544
+ box-shadow: var(--harmony-shadow-lg);
545
+ box-sizing: border-box;
546
+ transform: translate(10px, 10px);
547
+ pointer-events: auto;
548
+ overflow-y: auto;
549
+ overflow-x: hidden;
550
+ min-height: 0;
551
+ }
61
552
  .visual-popover-flip-x { transform: translate(calc(-100% - 14px), 10px); }
62
553
  .visual-popover-flip-y { transform: translate(10px, calc(-100% - 14px)); }
63
554
  .visual-popover-flip-x.visual-popover-flip-y { transform: translate(calc(-100% - 14px), calc(-100% - 14px)); }
64
555
  .visual-annotation-row-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
65
- .visual-annotation-kind { font-size: 11px; color: #9cdcfe; font-weight: 600; }
556
+ .visual-annotation-kind { font-size: 11px; color: var(--harmony-primary); font-weight: 600; }
66
557
  .visual-annotation-actions { display: flex; gap: 6px; flex-shrink: 0; }
67
- .visual-annotation-remove { background: transparent; color: #888; border: 1px solid #3e3e3e; border-radius: 4px; padding: 4px 8px; font-size: 11px; cursor: pointer; }
68
- .visual-annotation-remove:hover { color: #f48771; border-color: #f48771; }
69
- .visual-annotation-run { background: #0e639c; color: #fff; border: none; border-radius: 4px; padding: 4px 10px; font-size: 11px; cursor: pointer; }
70
- .visual-annotation-run:hover { background: #1177bb; }
558
+ .visual-annotation-remove {
559
+ background: transparent;
560
+ color: var(--harmony-text-muted);
561
+ border: 1px solid var(--harmony-border);
562
+ border-radius: var(--harmony-radius-sm);
563
+ padding: 4px 8px;
564
+ font-size: 11px;
565
+ cursor: pointer;
566
+ }
567
+ .visual-annotation-remove:hover { color: var(--harmony-danger); border-color: var(--harmony-danger); }
568
+ .visual-annotation-run {
569
+ background: var(--harmony-primary);
570
+ color: #fff;
571
+ border: none;
572
+ border-radius: var(--harmony-radius-sm);
573
+ padding: 4px 10px;
574
+ font-size: 11px;
575
+ font-weight: 600;
576
+ cursor: pointer;
577
+ }
578
+ .visual-annotation-run:hover { background: var(--harmony-primary-hover); }
71
579
  .visual-annotation-run:disabled { opacity: 0.45; cursor: not-allowed; }
72
- .visual-annotation-instruction { width: 100%; min-height: 48px; resize: vertical; background: #252526; color: #d4d4d4; border: 1px solid #3e3e3e; border-radius: 6px; padding: 6px 8px; font-size: 12px; font-family: inherit; outline: none; }
73
- .visual-annotation-instruction:focus { border-color: #0e639c; }
580
+ .visual-annotation-instruction {
581
+ width: 100%;
582
+ min-height: 48px;
583
+ resize: vertical;
584
+ background: var(--harmony-bg-surface);
585
+ color: var(--harmony-text);
586
+ border: 1px solid var(--harmony-border);
587
+ border-radius: var(--harmony-radius-sm);
588
+ padding: 6px 8px;
589
+ font-size: 12px;
590
+ font-family: inherit;
591
+ outline: none;
592
+ }
593
+ .visual-annotation-instruction:focus { border-color: var(--harmony-primary); box-shadow: 0 0 0 3px var(--harmony-primary-soft); }
74
594
  .visual-annotation-files { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
75
595
  .visual-attach-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
76
- .visual-attach-btn { background: #2d2d30; color: #ccc; border: 1px solid #3e3e3e; border-radius: 4px; padding: 4px 8px; font-size: 11px; cursor: pointer; }
77
- .visual-attach-btn:hover { border-color: #9cdcfe; color: #fff; }
596
+ .visual-attach-btn {
597
+ background: var(--harmony-bg-subtle);
598
+ color: var(--harmony-text-secondary);
599
+ border: 1px solid var(--harmony-border);
600
+ border-radius: var(--harmony-radius-sm);
601
+ padding: 4px 8px;
602
+ font-size: 11px;
603
+ cursor: pointer;
604
+ }
605
+ .visual-attach-btn:hover { border-color: var(--harmony-primary); color: var(--harmony-primary); }
78
606
  .visual-attachment-chips { display: flex; flex-wrap: wrap; gap: 6px; }
79
- .visual-attachment-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; background: #1e1e1e; border: 1px solid #3e3e3e; border-radius: 6px; padding: 4px 6px; font-size: 11px; color: #ccc; }
80
- .visual-attachment-thumb { width: 36px; height: 36px; object-fit: cover; border-radius: 4px; flex-shrink: 0; background: #2d2d30; }
607
+ .visual-attachment-chip {
608
+ display: inline-flex;
609
+ align-items: center;
610
+ gap: 6px;
611
+ max-width: 100%;
612
+ background: var(--harmony-bg-subtle);
613
+ border: 1px solid var(--harmony-border);
614
+ border-radius: var(--harmony-radius-sm);
615
+ padding: 4px 6px;
616
+ font-size: 11px;
617
+ color: var(--harmony-text-secondary);
618
+ }
619
+ .visual-attachment-thumb { width: 36px; height: 36px; object-fit: cover; border-radius: 4px; flex-shrink: 0; background: var(--harmony-bg-hover); }
81
620
  .visual-attachment-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 160px; }
82
- .visual-attachment-remove-file { background: transparent; border: none; color: #888; cursor: pointer; font-size: 14px; line-height: 1; padding: 0 4px; }
83
- .visual-attachment-remove-file:hover { color: #f48771; }
621
+ .visual-attachment-remove-file { background: transparent; border: none; color: var(--harmony-text-muted); cursor: pointer; font-size: 14px; line-height: 1; padding: 0 4px; }
622
+ .visual-attachment-remove-file:hover { color: var(--harmony-danger); }
84
623
  .file-input-hidden { display: none; }
85
- .visual-error { font-size: 12px; color: #f48771; }
86
- .visual-submit-error { font-size: 12px; color: #f48771; margin: 0; padding: 0 2px; }
87
- .visual-submit-progress { font-size: 12px; color: #9cdcfe; margin: 0; padding: 0 2px; }
88
- .bottom-panel { flex-shrink: 0; display: flex; flex-direction: column; background: #1e1e1e; border-top: 1px solid #3e3e3e; min-height: 32px; max-height: 80vh; height: 200px; }
624
+ .visual-error { font-size: 12px; color: var(--harmony-danger); }
625
+ .visual-submit-error { font-size: 12px; color: var(--harmony-danger); margin: 0; padding: 0 2px; }
626
+ .visual-submit-progress { font-size: 12px; color: var(--harmony-primary); margin: 0; padding: 0 2px; }
627
+
628
+ .video-record-btn { border-color: var(--harmony-primary) !important; color: var(--harmony-primary) !important; }
629
+ .video-record-active { animation: pulse-rec 1.2s ease-in-out infinite; }
630
+ @keyframes pulse-rec { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }
631
+
632
+ /* ── Bottom agent panel ── */
633
+ .bottom-panel {
634
+ flex-shrink: 0;
635
+ display: flex;
636
+ flex-direction: column;
637
+ background: var(--harmony-bg-surface);
638
+ border-top: 1px solid var(--harmony-border);
639
+ min-height: 32px;
640
+ max-height: 80vh;
641
+ height: 200px;
642
+ box-shadow: 0 -2px 12px rgba(22, 45, 61, 0.06);
643
+ }
89
644
  .bottom-panel-collapsed { max-height: 32px; overflow: hidden; }
90
645
  .bottom-panel-resize { height: 4px; cursor: ns-resize; background: transparent; flex-shrink: 0; }
91
- .bottom-panel-resize:hover, .bottom-panel-resize:active { background: #007acc; }
92
- .bottom-panel-header { display: flex; align-items: center; gap: 8px; padding: 6px 12px; flex-shrink: 0; cursor: pointer; user-select: none; }
93
- .bottom-panel-title { font-size: 11px; font-weight: 600; color: #ccc; text-transform: uppercase; letter-spacing: 0.5px; }
94
- .bottom-panel-running { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #89d185; animation: pulse-dot 1.2s ease-in-out infinite; margin-left: 4px; }
646
+ .bottom-panel-resize:hover, .bottom-panel-resize:active { background: var(--harmony-primary); }
647
+ .bottom-panel-header {
648
+ display: flex;
649
+ align-items: center;
650
+ gap: 8px;
651
+ padding: 6px 16px;
652
+ flex-shrink: 0;
653
+ cursor: pointer;
654
+ user-select: none;
655
+ background: var(--harmony-bg-subtle);
656
+ }
657
+ .bottom-panel-title {
658
+ font-size: 11px;
659
+ font-weight: 600;
660
+ color: var(--harmony-text-secondary);
661
+ text-transform: uppercase;
662
+ letter-spacing: 0.5px;
663
+ }
664
+ .bottom-panel-running {
665
+ display: inline-block;
666
+ width: 8px;
667
+ height: 8px;
668
+ border-radius: 50%;
669
+ background: var(--harmony-success);
670
+ animation: pulse-dot 1.2s ease-in-out infinite;
671
+ margin-left: 4px;
672
+ }
95
673
  @keyframes pulse-dot { 0%,100% { opacity: 1; } 50% { opacity: 0.3; } }
96
- .bottom-panel-toggle { background: none; border: none; color: #888; font-size: 14px; cursor: pointer; padding: 0 4px; line-height: 1; }
97
- .bottom-panel-toggle:hover { color: #fff; }
674
+ .bottom-panel-toggle { background: none; border: none; color: var(--harmony-text-muted); font-size: 14px; cursor: pointer; padding: 0 4px; line-height: 1; }
675
+ .bottom-panel-toggle:hover { color: var(--harmony-text); }
98
676
  .bottom-panel-spacer { flex: 1; }
99
- .bottom-panel-clear { background: none; border: none; color: #666; font-size: 11px; cursor: pointer; padding: 2px 6px; }
100
- .bottom-panel-clear:hover { color: #ccc; }
101
- .output-panel { overflow-y: auto; padding: 8px 12px; font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; font-size: 12px; line-height: 1.5; white-space: pre-wrap; word-break: break-word; flex: 1; min-height: 0; }
102
- .chunk { color: #d4d4d4; }
103
- .chunk-status { color: #888; font-style: italic; }
104
- .chunk-tool { color: #569cd6; }
105
- .chunk-error { color: #f48771; }
106
- .chunk-thinking { color: #666; font-style: italic; }
107
- .chunk-result { color: #89d185; }
108
- .chunk-user { color: #c5e1a5; }
109
- .chunk-user-prefix { color: #888; }
110
- .agent-chat-row { display: flex; gap: 8px; padding: 8px 12px; border-top: 1px solid #3e3e3e; flex-shrink: 0; align-items: flex-end; }
111
- .agent-chat-input { flex: 1; min-height: 32px; max-height: 96px; resize: none; background: #252526; color: #d4d4d4; border: 1px solid #3e3e3e; border-radius: 4px; padding: 6px 8px; font-family: 'Segoe UI', system-ui, sans-serif; font-size: 12px; line-height: 1.4; }
112
- .agent-chat-input:focus { outline: none; border-color: #007acc; }
677
+ .bottom-panel-clear { background: none; border: none; color: var(--harmony-text-muted); font-size: 11px; cursor: pointer; padding: 2px 6px; }
678
+ .bottom-panel-clear:hover { color: var(--harmony-text); }
679
+ .output-panel {
680
+ overflow-y: auto;
681
+ padding: 8px 16px;
682
+ font-family: var(--harmony-mono);
683
+ font-size: 12px;
684
+ line-height: 1.5;
685
+ white-space: pre-wrap;
686
+ word-break: break-word;
687
+ flex: 1;
688
+ min-height: 0;
689
+ background: var(--harmony-bg-surface);
690
+ }
691
+ .chunk { color: var(--harmony-text); }
692
+ .chunk-status { color: var(--harmony-text-muted); font-style: italic; }
693
+ .chunk-tool { color: var(--harmony-primary); }
694
+ .chunk-error { color: var(--harmony-danger); }
695
+ .chunk-thinking { color: var(--harmony-text-muted); font-style: italic; }
696
+ .chunk-result { color: var(--harmony-success); }
697
+ .chunk-user { color: var(--harmony-text); }
698
+ .chunk-user-prefix { color: var(--harmony-text-muted); }
699
+ .agent-chat-row {
700
+ display: flex;
701
+ gap: 8px;
702
+ padding: 8px 16px;
703
+ border-top: 1px solid var(--harmony-border);
704
+ flex-shrink: 0;
705
+ align-items: flex-end;
706
+ background: var(--harmony-bg-subtle);
707
+ }
708
+ .agent-chat-input {
709
+ flex: 1;
710
+ min-height: 32px;
711
+ max-height: 96px;
712
+ resize: none;
713
+ background: var(--harmony-bg-surface);
714
+ color: var(--harmony-text);
715
+ border: 1px solid var(--harmony-border);
716
+ border-radius: var(--harmony-radius-sm);
717
+ padding: 6px 10px;
718
+ font-family: var(--harmony-font);
719
+ font-size: 12px;
720
+ line-height: 1.4;
721
+ }
722
+ .agent-chat-input:focus { outline: none; border-color: var(--harmony-primary); box-shadow: 0 0 0 3px var(--harmony-primary-soft); }
113
723
  .agent-chat-input:disabled { opacity: 0.6; cursor: not-allowed; }
114
- .agent-chat-send { background: #0e639c; color: #fff; border: none; border-radius: 4px; padding: 6px 14px; font-size: 12px; font-weight: 600; cursor: pointer; flex-shrink: 0; height: 32px; }
115
- .agent-chat-send:hover:not(:disabled) { background: #1177bb; }
724
+ .agent-chat-send {
725
+ background: var(--harmony-primary);
726
+ color: #fff;
727
+ border: none;
728
+ border-radius: var(--harmony-radius-pill);
729
+ padding: 6px 16px;
730
+ font-size: 12px;
731
+ font-weight: 600;
732
+ cursor: pointer;
733
+ flex-shrink: 0;
734
+ height: 32px;
735
+ }
736
+ .agent-chat-send:hover:not(:disabled) { background: var(--harmony-primary-hover); }
116
737
  .agent-chat-send:disabled { opacity: 0.45; cursor: not-allowed; }
117
- .tool-group-sep { width: 1px; background: #3e3e3e; align-self: stretch; margin: 0 4px; flex-shrink: 0; }
118
- .file-link { color: #569cd6; text-decoration: underline; cursor: pointer; }
119
- .file-link:hover { color: #9cdcfe; }
120
- .chunk-tool-prefix { color: #569cd6; }
121
- .file-preview-overlay { position: fixed; inset: 0; z-index: 200; background: rgba(0,0,0,0.78); display: flex; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box; }
122
- .file-preview-panel { background: #1e1e1e; border: 1px solid #3e3e3e; border-radius: 10px; width: min(900px, 96vw); max-height: 90vh; display: flex; flex-direction: column; overflow: hidden; }
123
- .file-preview-header { display: flex; align-items: center; gap: 8px; padding: 10px 16px; border-bottom: 1px solid #3e3e3e; flex-shrink: 0; }
124
- .file-preview-title { font-size: 12px; color: #ccc; font-family: 'Cascadia Code', 'Fira Code', monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
125
- .file-preview-close { background: none; border: none; color: #888; font-size: 18px; cursor: pointer; padding: 0 4px; line-height: 1; flex-shrink: 0; }
126
- .file-preview-close:hover { color: #fff; }
738
+
739
+ .file-link { color: var(--harmony-primary); text-decoration: underline; cursor: pointer; }
740
+ .file-link:hover { color: var(--harmony-primary-hover); }
741
+ .chunk-tool-prefix { color: var(--harmony-primary); }
742
+
743
+ /* ── Result banner ── */
744
+ .add-page-result-slot { flex-shrink: 0; }
745
+ .add-page-result-banner {
746
+ margin: 0 24px 8px;
747
+ padding: 10px 14px;
748
+ border-radius: var(--harmony-radius-md);
749
+ font-size: 12px;
750
+ display: flex;
751
+ flex-wrap: wrap;
752
+ align-items: center;
753
+ gap: 10px;
754
+ }
755
+ .add-page-result-success { background: var(--harmony-success-soft); border: 1px solid rgba(0, 168, 98, 0.25); color: var(--harmony-success); }
756
+ .add-page-result-failed { background: var(--harmony-danger-soft); border: 1px solid rgba(232, 76, 61, 0.25); color: var(--harmony-danger); }
757
+ .add-page-result-actions { display: flex; gap: 8px; margin-left: auto; }
758
+ .add-page-result-btn {
759
+ background: var(--harmony-bg-surface);
760
+ color: var(--harmony-text-secondary);
761
+ border: 1px solid var(--harmony-border);
762
+ border-radius: var(--harmony-radius-sm);
763
+ padding: 4px 10px;
764
+ font-size: 11px;
765
+ cursor: pointer;
766
+ }
767
+ .add-page-result-btn:hover { background: var(--harmony-bg-hover); color: var(--harmony-text); }
768
+
769
+ /* ── Modals & overlays ── */
770
+ .file-preview-overlay {
771
+ position: fixed;
772
+ inset: 0;
773
+ z-index: 200;
774
+ background: rgba(22, 45, 61, 0.45);
775
+ display: flex;
776
+ align-items: center;
777
+ justify-content: center;
778
+ padding: 20px;
779
+ box-sizing: border-box;
780
+ }
781
+ .file-preview-panel {
782
+ background: var(--harmony-bg-surface);
783
+ border: 1px solid var(--harmony-border);
784
+ border-radius: var(--harmony-radius-lg);
785
+ width: min(900px, 96vw);
786
+ max-height: 90vh;
787
+ display: flex;
788
+ flex-direction: column;
789
+ overflow: hidden;
790
+ box-shadow: var(--harmony-shadow-lg);
791
+ }
792
+ .file-preview-header {
793
+ display: flex;
794
+ align-items: center;
795
+ gap: 8px;
796
+ padding: 12px 16px;
797
+ border-bottom: 1px solid var(--harmony-border);
798
+ flex-shrink: 0;
799
+ background: var(--harmony-bg-subtle);
800
+ }
801
+ .file-preview-title {
802
+ font-size: 12px;
803
+ color: var(--harmony-text);
804
+ font-family: var(--harmony-mono);
805
+ overflow: hidden;
806
+ text-overflow: ellipsis;
807
+ white-space: nowrap;
808
+ flex: 1;
809
+ }
810
+ .file-preview-close { background: none; border: none; color: var(--harmony-text-muted); font-size: 18px; cursor: pointer; padding: 0 4px; line-height: 1; flex-shrink: 0; }
811
+ .file-preview-close:hover { color: var(--harmony-text); }
127
812
  .file-preview-body { flex: 1; overflow: auto; padding: 16px; min-height: 0; }
128
- .file-preview-text { font-family: 'Cascadia Code', 'Fira Code', monospace; font-size: 12px; line-height: 1.5; color: #d4d4d4; white-space: pre-wrap; word-break: break-word; margin: 0; }
813
+ .file-preview-text { font-family: var(--harmony-mono); font-size: 12px; line-height: 1.5; color: var(--harmony-text); white-space: pre-wrap; word-break: break-word; margin: 0; }
129
814
  .file-preview-image { max-width: 100%; max-height: 70vh; display: block; margin: 0 auto; }
130
- .file-preview-loading { color: #888; font-style: italic; font-size: 12px; }
131
- .aiditor-logo { font-size: 18px; font-weight: 700; letter-spacing: -0.5px; color: #d4d4d4; flex-shrink: 0; font-family: 'Segoe UI', system-ui, sans-serif; }
132
- .aiditor-logo-ai { color: #f44747; }
133
- .preview-frame-tablet { align-self: center; width: 768px; max-width: 100%; }
134
- .preview-frame-mobile { align-self: center; width: 390px; max-width: 100%; }
135
- .video-record-btn { border-color: #c586ff !important; color: #e0d0ff !important; }
136
- .video-record-active { animation: pulse-rec 1.2s ease-in-out infinite; }
137
- @keyframes pulse-rec { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }
138
- .video-review-overlay { position: fixed; inset: 0; z-index: 200; background: rgba(0,0,0,0.78); display: flex; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box; }
139
- .video-review-panel { background: #252526; border: 1px solid #3e3e3e; border-radius: 10px; width: min(1100px, 96vw); max-height: 94vh; display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; overflow: auto; }
140
- .video-review-header { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
141
- .video-review-title { font-size: 15px; font-weight: 600; color: #9cdcfe; margin: 0; }
142
- .video-review-meta { font-size: 12px; color: #888; }
143
- .video-review-tools { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
815
+ .file-preview-loading { color: var(--harmony-text-muted); font-style: italic; font-size: 12px; }
816
+
817
+ .video-review-overlay, .snapshot-overlay {
818
+ position: fixed;
819
+ inset: 0;
820
+ z-index: 200;
821
+ background: rgba(22, 45, 61, 0.45);
822
+ display: flex;
823
+ align-items: center;
824
+ justify-content: center;
825
+ padding: 20px;
826
+ box-sizing: border-box;
827
+ }
828
+ .video-review-panel, .snapshot-panel {
829
+ background: var(--harmony-bg-surface);
830
+ border: 1px solid var(--harmony-border);
831
+ border-radius: var(--harmony-radius-lg);
832
+ width: min(1100px, 96vw);
833
+ max-height: 94vh;
834
+ display: flex;
835
+ flex-direction: column;
836
+ gap: 10px;
837
+ padding: 14px 16px;
838
+ overflow: auto;
839
+ box-shadow: var(--harmony-shadow-lg);
840
+ }
841
+ .snapshot-panel { width: min(1200px, 96vw); overflow: hidden; }
842
+ .video-review-header, .snapshot-header { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
843
+ .video-review-title, .snapshot-title { font-size: 15px; font-weight: 600; color: var(--harmony-text); margin: 0; }
844
+ .video-review-meta { font-size: 12px; color: var(--harmony-text-muted); }
845
+ .video-review-tools, .snapshot-tools { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
144
846
  .video-review-transport { display: flex; align-items: center; gap: 10px; width: 100%; }
145
- .video-play-pause-btn { flex-shrink: 0; width: 40px; height: 36px; border-radius: 6px; border: 1px solid #555; background: #3c3c3c; color: #eee; font-size: 16px; line-height: 1; cursor: pointer; }
146
- .video-play-pause-btn:hover { background: #4a4a4a; border-color: #9cdcfe; }
847
+ .video-play-pause-btn {
848
+ flex-shrink: 0;
849
+ width: 40px;
850
+ height: 36px;
851
+ border-radius: var(--harmony-radius-sm);
852
+ border: 1px solid var(--harmony-border);
853
+ background: var(--harmony-bg-subtle);
854
+ color: var(--harmony-text);
855
+ font-size: 16px;
856
+ line-height: 1;
857
+ cursor: pointer;
858
+ }
859
+ .video-play-pause-btn:hover { background: var(--harmony-bg-hover); border-color: var(--harmony-primary); }
147
860
  .video-timeline-wrap { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
148
- .video-timeline { width: 100%; accent-color: #0e639c; }
861
+ .video-timeline { width: 100%; accent-color: var(--harmony-primary); }
149
862
  .video-timeline-markers { position: relative; height: 10px; margin: 0 2px; }
150
- .video-timeline-marker { position: absolute; top: 0; width: 10px; margin-left: -5px; height: 10px; background: #c586ff; border-radius: 1px; transform: translateX(-50%); cursor: pointer; }
151
- .video-review-overlay .arrow-svg line { marker-end: url(#aiditor-video-arrowhead); }
152
- .video-review-actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; margin-top: 4px; }
153
- .video-review-secondary { background: #3c3c3c; color: #ddd; border: 1px solid #555; border-radius: 6px; padding: 8px 16px; font-size: 13px; cursor: pointer; }
154
- .video-review-secondary:hover { background: #4a4a4a; }
155
- .video-review-primary { background: #0e639c; color: #fff; border: none; border-radius: 6px; padding: 8px 18px; font-size: 13px; cursor: pointer; }
156
- .video-review-primary:hover { background: #1177bb; }
157
- .video-review-primary:disabled { opacity: 0.45; cursor: not-allowed; }
158
- .snapshot-overlay { position: fixed; inset: 0; z-index: 200; background: rgba(0,0,0,0.78); display: flex; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box; }
159
- .snapshot-panel { background: #252526; border: 1px solid #3e3e3e; border-radius: 10px; width: min(1200px, 96vw); max-height: 94vh; display: flex; flex-direction: column; gap: 10px; padding: 14px 16px; overflow: hidden; }
160
- .snapshot-header { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-shrink: 0; }
161
- .snapshot-title { font-size: 15px; font-weight: 600; color: #9cdcfe; margin: 0; }
162
- .snapshot-close { background: none; border: none; color: #888; font-size: 18px; cursor: pointer; padding: 0 4px; line-height: 1; }
163
- .snapshot-close:hover { color: #fff; }
164
- .snapshot-tools { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; flex-shrink: 0; }
863
+ .video-timeline-marker {
864
+ position: absolute;
865
+ top: 0;
866
+ width: 10px;
867
+ margin-left: -5px;
868
+ height: 10px;
869
+ background: var(--harmony-primary);
870
+ border-radius: 1px;
871
+ transform: translateX(-50%);
872
+ cursor: pointer;
873
+ }
874
+ .video-review-actions, .snapshot-footer { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; margin-top: 4px; }
875
+ .video-review-secondary, .snapshot-secondary {
876
+ background: var(--harmony-bg-surface);
877
+ color: var(--harmony-text);
878
+ border: 1px solid var(--harmony-border);
879
+ border-radius: var(--harmony-radius-pill);
880
+ padding: 8px 16px;
881
+ font-size: 13px;
882
+ cursor: pointer;
883
+ }
884
+ .video-review-secondary:hover, .snapshot-secondary:hover { background: var(--harmony-bg-hover); }
885
+ .video-review-primary, .snapshot-primary {
886
+ background: var(--harmony-primary);
887
+ color: #fff;
888
+ border: none;
889
+ border-radius: var(--harmony-radius-pill);
890
+ padding: 8px 18px;
891
+ font-size: 13px;
892
+ font-weight: 600;
893
+ cursor: pointer;
894
+ }
895
+ .video-review-primary:hover, .snapshot-primary:hover { background: var(--harmony-primary-hover); }
896
+ .video-review-primary:disabled, .snapshot-primary:disabled { opacity: 0.45; cursor: not-allowed; }
897
+ .snapshot-close { background: none; border: none; color: var(--harmony-text-muted); font-size: 18px; cursor: pointer; padding: 0 4px; line-height: 1; }
898
+ .snapshot-close:hover { color: var(--harmony-text); }
165
899
  .snapshot-body { display: flex; gap: 14px; flex: 1; min-height: 0; overflow: hidden; }
166
- .snapshot-capture-area { flex: 2; min-width: 0; position: relative; display: flex; align-items: center; justify-content: center; background: #1e1e1e; border-radius: 8px; overflow: hidden; }
900
+ .snapshot-capture-area {
901
+ flex: 2;
902
+ min-width: 0;
903
+ position: relative;
904
+ display: flex;
905
+ align-items: center;
906
+ justify-content: center;
907
+ background: var(--harmony-bg-subtle);
908
+ border-radius: var(--harmony-radius-md);
909
+ overflow: hidden;
910
+ border: 1px solid var(--harmony-border);
911
+ }
167
912
  .snapshot-img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; user-select: none; -webkit-user-drag: none; }
168
913
  .snapshot-img-overlay { position: absolute; inset: 0; z-index: 2; }
169
914
  .snapshot-img-overlay-none { pointer-events: none; }
170
915
  .snapshot-annotations-panel { flex: 1; min-width: 220px; max-width: 340px; display: flex; flex-direction: column; gap: 8px; overflow-y: auto; }
171
- .snapshot-annotation-card { background: #1e1e1e; border: 1px solid #3e3e3e; border-radius: 8px; padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
916
+ .snapshot-annotation-card {
917
+ background: var(--harmony-bg-subtle);
918
+ border: 1px solid var(--harmony-border);
919
+ border-radius: var(--harmony-radius-md);
920
+ padding: 10px 12px;
921
+ display: flex;
922
+ flex-direction: column;
923
+ gap: 6px;
924
+ }
172
925
  .snapshot-annotation-card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
173
- .snapshot-annotation-kind { font-size: 11px; color: #9cdcfe; font-weight: 600; }
174
- .snapshot-annotation-remove { background: transparent; color: #888; border: 1px solid #3e3e3e; border-radius: 4px; padding: 4px 8px; font-size: 11px; cursor: pointer; }
175
- .snapshot-annotation-remove:hover { color: #f48771; border-color: #f48771; }
176
- .snapshot-empty-hint { color: #888; font-size: 12px; font-style: italic; padding: 8px 0; }
177
- .snapshot-footer { display: flex; gap: 10px; justify-content: flex-end; align-items: center; flex-wrap: wrap; flex-shrink: 0; margin-top: 4px; }
178
- .snapshot-secondary { background: #3c3c3c; color: #ddd; border: 1px solid #555; border-radius: 6px; padding: 8px 16px; font-size: 13px; cursor: pointer; }
179
- .snapshot-secondary:hover { background: #4a4a4a; }
180
- .snapshot-primary { background: #0e639c; color: #fff; border: none; border-radius: 6px; padding: 8px 18px; font-size: 13px; cursor: pointer; }
181
- .snapshot-primary:hover { background: #1177bb; }
182
- .snapshot-primary:disabled { opacity: 0.45; cursor: not-allowed; }
183
- .snapshot-discard-confirm { display: flex; align-items: center; gap: 10px; font-size: 13px; color: #f48771; }
926
+ .snapshot-annotation-kind { font-size: 11px; color: var(--harmony-primary); font-weight: 600; }
927
+ .snapshot-annotation-remove {
928
+ background: transparent;
929
+ color: var(--harmony-text-muted);
930
+ border: 1px solid var(--harmony-border);
931
+ border-radius: var(--harmony-radius-sm);
932
+ padding: 4px 8px;
933
+ font-size: 11px;
934
+ cursor: pointer;
935
+ }
936
+ .snapshot-annotation-remove:hover { color: var(--harmony-danger); border-color: var(--harmony-danger); }
937
+ .snapshot-empty-hint { color: var(--harmony-text-muted); font-size: 12px; font-style: italic; padding: 8px 0; }
938
+ .snapshot-discard-confirm { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--harmony-danger); }
184
939
  .snapshot-discard-confirm-msg { flex: 1; }
185
- .snapshot-overlay .arrow-svg line { marker-end: url(#aiditor-snapshot-arrowhead); }
186
- .add-page-open-btn { margin-left: 12px; background: #0e639c; color: #fff; border: none; border-radius: 6px; padding: 6px 14px; font-size: 12px; font-weight: 600; cursor: pointer; flex-shrink: 0; }
187
- .add-page-open-btn:hover { background: #1177bb; }
188
- .add-page-open-btn:disabled { opacity: 0.5; cursor: not-allowed; }
189
- .add-page-from-brief-btn { margin-left: 8px; background: #2d4a2d; color: #c5e1a5; border: 1px solid #4a6a4a; border-radius: 6px; padding: 6px 14px; font-size: 12px; font-weight: 600; cursor: pointer; flex-shrink: 0; }
190
- .add-page-from-brief-btn:hover { background: #3a5a3a; color: #fff; }
191
- .add-page-from-brief-btn:disabled { opacity: 0.5; cursor: not-allowed; }
192
- .add-page-overlay { position: fixed; inset: 0; z-index: 300; background: rgba(0,0,0,0.45); display: flex; justify-content: flex-end; }
193
- .project-settings-overlay { position: fixed; inset: 0; z-index: 350; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; padding: 24px; box-sizing: border-box; }
194
- .project-settings-dialog { background: #252526; border: 1px solid #3e3e3e; border-radius: 8px; width: min(520px, 100%); max-height: min(80vh, 640px); display: flex; flex-direction: column; overflow: hidden; }
195
- .project-settings-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid #3e3e3e; }
196
- .project-settings-title { font-size: 14px; font-weight: 600; color: #fff; }
197
- .project-settings-close { background: none; border: none; color: #888; font-size: 20px; cursor: pointer; line-height: 1; }
198
- .project-settings-body { padding: 14px 16px; overflow: auto; display: flex; flex-direction: column; gap: 12px; }
199
- .project-settings-btn { background: #333; color: #ccc; border: 1px solid #3e3e3e; border-radius: 4px; padding: 6px 12px; font-size: 12px; cursor: pointer; }
200
- .project-settings-btn:hover { background: #444; color: #fff; }
201
- .add-page-plugin-picker { width: 100%; background: #252526; color: #ccc; border: 1px solid #3e3e3e; border-radius: 4px; font-size: 12px; padding: 6px 8px; margin-top: 6px; }
202
- .add-page-manage-link { font-size: 11px; color: #9cdcfe; cursor: pointer; margin-top: 6px; background: none; border: none; padding: 0; text-align: left; }
203
- .add-page-slideover { width: min(480px, 100vw); height: 100%; background: #1e1e1e; border-left: 1px solid #3e3e3e; display: flex; flex-direction: column; box-shadow: -4px 0 24px rgba(0,0,0,0.4); position: relative; }
204
- .add-page-header { display: flex; align-items: center; gap: 8px; padding: 14px 16px; border-bottom: 1px solid #3e3e3e; flex-shrink: 0; }
205
- .add-page-title { font-size: 14px; font-weight: 600; color: #9cdcfe; flex: 1; }
206
- .add-page-close { background: none; border: none; color: #888; font-size: 20px; cursor: pointer; line-height: 1; padding: 0 4px; }
207
- .add-page-close:hover { color: #fff; }
208
- .add-page-body { flex: 1; overflow: auto; padding: 14px 16px; display: flex; flex-direction: column; gap: 16px; }
209
- .add-page-section-label { font-size: 11px; font-weight: 600; color: #888; text-transform: uppercase; letter-spacing: 0.4px; margin-bottom: 6px; }
210
- .add-page-section-header-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
211
- .add-page-section-header-row .add-page-section-label { margin-bottom: 0; flex: 1; }
212
- .add-page-fill-from-image-btn { background: #2d2d30; color: #9cdcfe; border: 1px solid #3e3e3e; border-radius: 4px; padding: 4px 10px; font-size: 11px; font-weight: 600; cursor: pointer; flex-shrink: 0; }
213
- .add-page-fill-from-image-btn:hover { background: #3c3c3c; color: #fff; }
214
- .add-page-fill-from-image-btn:disabled { opacity: 0.45; cursor: not-allowed; }
215
- .add-page-suggested-route { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; background: #252526; border: 1px solid #3e3e3e; border-radius: 6px; padding: 8px 10px; font-size: 12px; color: #ccc; margin-bottom: 8px; }
216
- .add-page-suggested-route code { font-family: ui-monospace, monospace; color: #ce9178; }
217
- .add-page-brief-fill-popover { position: absolute; inset: 0; z-index: 10; background: rgba(0,0,0,0.55); display: flex; align-items: center; justify-content: center; padding: 16px; box-sizing: border-box; }
218
- .add-page-brief-fill-panel { background: #252526; border: 1px solid #3e3e3e; border-radius: 8px; width: min(420px, 100%); max-height: 90%; overflow: auto; padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; }
219
- .add-page-brief-fill-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
220
- .add-page-brief-fill-title { font-size: 13px; font-weight: 600; color: #9cdcfe; }
221
- .add-page-brief-fill-context { width: 100%; min-height: 64px; background: #1e1e1e; color: #d4d4d4; border: 1px solid #3e3e3e; border-radius: 6px; padding: 8px; font-size: 12px; font-family: ui-monospace, monospace; resize: vertical; box-sizing: border-box; }
222
- .add-page-brief-fill-dropzone { border: 1px dashed #3e3e3e; border-radius: 8px; padding: 14px; text-align: center; color: #888; font-size: 12px; cursor: pointer; }
223
- .add-page-brief-fill-dropzone-disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
224
- .add-page-brief-fill-context:disabled { opacity: 0.6; cursor: not-allowed; }
225
- .add-page-brief-fill-dropzone:focus { outline: 1px solid #0e639c; }
226
- .add-page-brief-fill-thumbs { display: flex; flex-wrap: wrap; gap: 8px; }
227
- .add-page-brief-fill-thumb { position: relative; width: 72px; height: 72px; border-radius: 6px; overflow: hidden; border: 1px solid #3e3e3e; background: #1e1e1e; }
228
- .add-page-brief-fill-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
229
- .add-page-brief-fill-thumb-remove { position: absolute; top: 2px; right: 2px; background: rgba(0,0,0,0.7); color: #fff; border: none; border-radius: 3px; width: 18px; height: 18px; font-size: 12px; line-height: 1; cursor: pointer; padding: 0; }
230
- .add-page-brief-fill-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }
231
- .add-page-route-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
232
- .add-page-route-input { flex: 1; min-width: 160px; background: #252526; color: #d4d4d4; border: 1px solid #3e3e3e; border-radius: 6px; padding: 8px 10px; font-size: 13px; font-family: ui-monospace, monospace; box-sizing: border-box; }
233
- .add-page-route-input:focus { border-color: #0e639c; outline: none; }
234
- .add-page-route-badge { font-size: 10px; color: #ce9178; background: #2d2d30; padding: 2px 8px; border-radius: 4px; }
235
- .add-page-field-error { font-size: 12px; color: #f48771; margin-top: 4px; }
236
- .add-page-hint { font-size: 12px; color: #888; margin-top: 4px; }
237
- .add-page-textarea { width: 100%; min-height: 120px; background: #252526; color: #d4d4d4; border: 1px solid #3e3e3e; border-radius: 6px; padding: 10px; font-size: 12px; font-family: ui-monospace, monospace; resize: vertical; box-sizing: border-box; outline: none; }
238
- .add-page-textarea:focus { border-color: #0e639c; }
239
- .add-page-dropzone { border: 1px dashed #3e3e3e; border-radius: 8px; padding: 16px; text-align: center; color: #888; font-size: 12px; }
240
- .add-page-chips { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
241
- .add-page-chip { display: flex; align-items: center; gap: 8px; background: #252526; border: 1px solid #3e3e3e; border-radius: 6px; padding: 6px 8px; font-size: 11px; }
242
- .add-page-chip-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #ccc; }
243
- .add-page-chip-path { font-size: 10px; color: #666; font-family: ui-monospace, monospace; }
244
- .add-page-chip select { background: #1e1e1e; color: #ccc; border: 1px solid #3e3e3e; border-radius: 4px; font-size: 11px; padding: 2px 4px; }
245
- .add-page-chip-remove { background: none; border: none; color: #888; cursor: pointer; font-size: 14px; padding: 0 4px; }
246
- .add-page-chip-remove:hover { color: #f48771; }
247
- .add-page-plugins { border: 1px solid #3e3e3e; border-radius: 6px; padding: 10px; margin-top: 8px; display: flex; flex-direction: column; gap: 12px; max-height: 320px; overflow: auto; }
248
- .add-page-plugins-zone-title { font-size: 11px; font-weight: 600; color: #aaa; text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 4px; }
249
- .add-page-plugin-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 11px; border-bottom: 1px solid #2d2d30; }
250
- .add-page-plugin-row:last-child { border-bottom: none; }
251
- .add-page-plugin-label { flex: 1; color: #ccc; }
252
- .add-page-plugin-btn { background: #333; color: #ccc; border: 1px solid #3e3e3e; border-radius: 4px; padding: 2px 8px; font-size: 10px; cursor: pointer; }
253
- .add-page-plugin-btn:hover { background: #444; color: #fff; }
254
- .add-page-plugin-btn:disabled { opacity: 0.45; cursor: not-allowed; }
255
- .add-page-setup-ok { color: #89d185; font-size: 10px; }
256
- .add-page-setup-warn { color: #dcdcaa; font-size: 10px; }
257
- .add-page-setup-error { color: #f48771; font-size: 10px; }
258
- .add-page-plugin-contract { padding-left: 0; font-size: 11px; color: #999; display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
259
- .add-page-plugin-contract-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; border-bottom: 1px solid #2d2d30; }
260
- .add-page-plugin-contract-row:last-child { border-bottom: none; }
261
- .add-page-plugin-contract-name { flex: 1; color: #ccc; font-size: 11px; }
262
- .add-page-plugin-contract-added { font-size: 10px; color: #89d185; }
263
- .add-page-plugin-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
264
- .add-page-plugin-chip { background: #2d2d30; border: 1px solid #3e3e3e; border-radius: 4px; padding: 2px 6px; font-size: 10px; color: #ccc; display: flex; align-items: center; gap: 4px; }
265
- .add-page-plugin-chip-remove { background: none; border: none; color: #888; cursor: pointer; padding: 0 2px; }
266
- .add-page-plugins-warn { font-size: 11px; color: #dcdcaa; margin-top: 4px; }
267
- .add-page-install-live { font-size: 11px; color: #888; }
268
- .add-page-local-plugin-form { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; padding-top: 8px; border-top: 1px solid #3e3e3e; }
269
- .add-page-local-plugin-form input { background: #252526; color: #ccc; border: 1px solid #3e3e3e; border-radius: 4px; padding: 4px 6px; font-size: 11px; }
270
- .annotation-binding { margin-top: 6px; border-top: 1px solid #3e3e3e; padding-top: 6px; }
271
- .annotation-binding-toggle { background: none; border: none; color: #9cdcfe; font-size: 11px; cursor: pointer; padding: 0; text-align: left; }
272
- .annotation-binding-panel { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; font-size: 11px; color: #ccc; }
273
- .annotation-binding-preview { font-size: 10px; color: #89d185; margin: 0; }
274
- .annotation-binding-panel label { display: flex; flex-direction: column; gap: 2px; }
275
- .annotation-binding-panel select { background: #252526; color: #ccc; border: 1px solid #3e3e3e; border-radius: 4px; font-size: 11px; }
276
- .annotation-binding-scope-row { display: flex; gap: 10px; flex-wrap: wrap; }
277
- .annotation-binding-install { background: #0e639c; color: #fff; border: none; border-radius: 4px; padding: 4px 8px; font-size: 10px; cursor: pointer; align-self: flex-start; }
278
- .add-page-footer { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid #3e3e3e; flex-shrink: 0; }
279
- .add-page-btn { flex: 1; padding: 10px; border-radius: 6px; font-size: 13px; font-weight: 600; cursor: pointer; border: 1px solid #3e3e3e; }
280
- .add-page-btn-cancel { background: #2d2d30; color: #ccc; }
281
- .add-page-btn-primary { background: #0e639c; color: #fff; border-color: #0e639c; }
282
- .add-page-btn-primary:disabled { opacity: 0.45; cursor: not-allowed; }
283
- .add-page-result-banner { margin: 0 20px 8px; padding: 10px 14px; border-radius: 8px; font-size: 12px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
284
- .add-page-result-success { background: #1e3a1e; border: 1px solid #3a5a3a; color: #89d185; }
285
- .add-page-result-failed { background: #3a1f1f; border: 1px solid #5a3030; color: #f48771; }
286
- .add-page-result-actions { display: flex; gap: 8px; margin-left: auto; }
287
- .add-page-result-btn { background: #333; color: #ccc; border: 1px solid #3e3e3e; border-radius: 4px; padding: 4px 10px; font-size: 11px; cursor: pointer; }
288
- .add-page-result-btn:hover { background: #444; color: #fff; }
289
- .add-page-hidden-file { display: none; }
940
+
941
+ /* ── Add Page slideover ── */
942
+ .add-page-overlay {
943
+ position: fixed;
944
+ inset: 0;
945
+ z-index: 300;
946
+ background: rgba(22, 45, 61, 0.35);
947
+ display: flex;
948
+ justify-content: flex-end;
949
+ }
950
+ .project-settings-overlay {
951
+ position: fixed;
952
+ inset: 0;
953
+ z-index: 350;
954
+ background: rgba(22, 45, 61, 0.4);
955
+ display: flex;
956
+ align-items: center;
957
+ justify-content: center;
958
+ padding: 24px;
959
+ box-sizing: border-box;
960
+ }
961
+ .project-settings-dialog {
962
+ background: var(--harmony-bg-surface);
963
+ border: 1px solid var(--harmony-border);
964
+ border-radius: var(--harmony-radius-lg);
965
+ width: min(520px, 100%);
966
+ max-height: min(80vh, 640px);
967
+ display: flex;
968
+ flex-direction: column;
969
+ overflow: hidden;
970
+ box-shadow: var(--harmony-shadow-lg);
971
+ }
972
+ .project-settings-header {
973
+ display: flex;
974
+ align-items: center;
975
+ justify-content: space-between;
976
+ padding: 14px 16px;
977
+ border-bottom: 1px solid var(--harmony-border);
978
+ background: var(--harmony-bg-subtle);
979
+ }
980
+ .project-settings-title { font-size: 14px; font-weight: 600; color: var(--harmony-text); }
981
+ .project-settings-close { background: none; border: none; color: var(--harmony-text-muted); font-size: 20px; cursor: pointer; line-height: 1; }
982
+ .project-settings-body { padding: 14px 16px; overflow: auto; display: flex; flex-direction: column; gap: 12px; }
983
+ .add-page-slideover {
984
+ width: min(480px, 100vw);
985
+ height: 100%;
986
+ background: var(--harmony-bg-surface);
987
+ border-left: 1px solid var(--harmony-border);
988
+ display: flex;
989
+ flex-direction: column;
990
+ box-shadow: var(--harmony-shadow-lg);
991
+ position: relative;
992
+ }
993
+ .add-page-header {
994
+ display: flex;
995
+ align-items: center;
996
+ gap: 8px;
997
+ padding: 14px 16px;
998
+ border-bottom: 1px solid var(--harmony-border);
999
+ flex-shrink: 0;
1000
+ background: var(--harmony-bg-subtle);
1001
+ }
1002
+ .add-page-title { font-size: 14px; font-weight: 600; color: var(--harmony-text); flex: 1; }
1003
+ .add-page-close { background: none; border: none; color: var(--harmony-text-muted); font-size: 20px; cursor: pointer; line-height: 1; padding: 0 4px; }
1004
+ .add-page-close:hover { color: var(--harmony-text); }
1005
+ .add-page-body { flex: 1; overflow: auto; padding: 14px 16px; display: flex; flex-direction: column; gap: 16px; }
1006
+ .add-page-section-label { font-size: 11px; font-weight: 600; color: var(--harmony-text-muted); text-transform: uppercase; letter-spacing: 0.4px; margin-bottom: 6px; }
1007
+ .add-page-section-header-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
1008
+ .add-page-section-header-row .add-page-section-label { margin-bottom: 0; flex: 1; }
1009
+ .add-page-fill-from-image-btn {
1010
+ background: var(--harmony-bg-subtle);
1011
+ color: var(--harmony-primary);
1012
+ border: 1px solid var(--harmony-border);
1013
+ border-radius: var(--harmony-radius-sm);
1014
+ padding: 4px 10px;
1015
+ font-size: 11px;
1016
+ font-weight: 600;
1017
+ cursor: pointer;
1018
+ flex-shrink: 0;
1019
+ }
1020
+ .add-page-fill-from-image-btn:hover { background: var(--harmony-primary-soft); }
1021
+ .add-page-fill-from-image-btn:disabled { opacity: 0.45; cursor: not-allowed; }
1022
+ .add-page-suggested-route {
1023
+ display: flex;
1024
+ flex-wrap: wrap;
1025
+ align-items: center;
1026
+ gap: 8px;
1027
+ background: var(--harmony-bg-subtle);
1028
+ border: 1px solid var(--harmony-border);
1029
+ border-radius: var(--harmony-radius-sm);
1030
+ padding: 8px 10px;
1031
+ font-size: 12px;
1032
+ color: var(--harmony-text-secondary);
1033
+ margin-bottom: 8px;
1034
+ }
1035
+ .add-page-suggested-route code { font-family: var(--harmony-mono); color: var(--harmony-primary); }
1036
+ .add-page-brief-fill-popover {
1037
+ position: absolute;
1038
+ inset: 0;
1039
+ z-index: 10;
1040
+ background: rgba(22, 45, 61, 0.4);
1041
+ display: flex;
1042
+ align-items: center;
1043
+ justify-content: center;
1044
+ padding: 16px;
1045
+ box-sizing: border-box;
1046
+ }
1047
+ .add-page-brief-fill-panel {
1048
+ background: var(--harmony-bg-surface);
1049
+ border: 1px solid var(--harmony-border);
1050
+ border-radius: var(--harmony-radius-md);
1051
+ width: min(420px, 100%);
1052
+ max-height: 90%;
1053
+ overflow: auto;
1054
+ padding: 14px 16px;
1055
+ display: flex;
1056
+ flex-direction: column;
1057
+ gap: 10px;
1058
+ box-shadow: var(--harmony-shadow-lg);
1059
+ }
1060
+ .add-page-brief-fill-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
1061
+ .add-page-brief-fill-title { font-size: 13px; font-weight: 600; color: var(--harmony-text); }
1062
+ .add-page-brief-fill-context {
1063
+ width: 100%;
1064
+ min-height: 64px;
1065
+ background: var(--harmony-bg-surface);
1066
+ color: var(--harmony-text);
1067
+ border: 1px solid var(--harmony-border);
1068
+ border-radius: var(--harmony-radius-sm);
1069
+ padding: 8px;
1070
+ font-size: 12px;
1071
+ font-family: var(--harmony-mono);
1072
+ resize: vertical;
1073
+ box-sizing: border-box;
1074
+ }
1075
+ .add-page-brief-fill-dropzone {
1076
+ border: 1px dashed var(--harmony-border-strong);
1077
+ border-radius: var(--harmony-radius-md);
1078
+ padding: 14px;
1079
+ text-align: center;
1080
+ color: var(--harmony-text-muted);
1081
+ font-size: 12px;
1082
+ cursor: pointer;
1083
+ }
1084
+ .add-page-brief-fill-dropzone-disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
1085
+ .add-page-brief-fill-context:disabled { opacity: 0.6; cursor: not-allowed; }
1086
+ .add-page-brief-fill-dropzone:focus { outline: none; border-color: var(--harmony-primary); box-shadow: 0 0 0 3px var(--harmony-primary-soft); }
1087
+ .add-page-brief-fill-thumbs { display: flex; flex-wrap: wrap; gap: 8px; }
1088
+ .add-page-brief-fill-thumb {
1089
+ position: relative;
1090
+ width: 72px;
1091
+ height: 72px;
1092
+ border-radius: var(--harmony-radius-sm);
1093
+ overflow: hidden;
1094
+ border: 1px solid var(--harmony-border);
1095
+ background: var(--harmony-bg-subtle);
1096
+ }
1097
+ .add-page-brief-fill-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
1098
+ .add-page-brief-fill-thumb-remove {
1099
+ position: absolute;
1100
+ top: 2px;
1101
+ right: 2px;
1102
+ background: rgba(22, 45, 61, 0.7);
1103
+ color: #fff;
1104
+ border: none;
1105
+ border-radius: 3px;
1106
+ width: 18px;
1107
+ height: 18px;
1108
+ font-size: 12px;
1109
+ line-height: 1;
1110
+ cursor: pointer;
1111
+ padding: 0;
1112
+ }
1113
+ .add-page-brief-fill-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }
1114
+ .add-page-route-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
1115
+ .add-page-route-input {
1116
+ flex: 1;
1117
+ min-width: 160px;
1118
+ background: var(--harmony-bg-surface);
1119
+ color: var(--harmony-text);
1120
+ border: 1px solid var(--harmony-border);
1121
+ border-radius: var(--harmony-radius-sm);
1122
+ padding: 8px 10px;
1123
+ font-size: 13px;
1124
+ font-family: var(--harmony-mono);
1125
+ box-sizing: border-box;
1126
+ }
1127
+ .add-page-route-input:focus { border-color: var(--harmony-primary); outline: none; box-shadow: 0 0 0 3px var(--harmony-primary-soft); }
1128
+ .add-page-route-badge { font-size: 10px; color: var(--harmony-primary); background: var(--harmony-primary-soft); padding: 2px 8px; border-radius: 4px; }
1129
+ .add-page-field-error { font-size: 12px; color: var(--harmony-danger); margin-top: 4px; }
1130
+ .add-page-hint { font-size: 12px; color: var(--harmony-text-muted); margin-top: 4px; }
1131
+ .add-page-textarea {
1132
+ width: 100%;
1133
+ min-height: 120px;
1134
+ background: var(--harmony-bg-surface);
1135
+ color: var(--harmony-text);
1136
+ border: 1px solid var(--harmony-border);
1137
+ border-radius: var(--harmony-radius-sm);
1138
+ padding: 10px;
1139
+ font-size: 12px;
1140
+ font-family: var(--harmony-mono);
1141
+ resize: vertical;
1142
+ box-sizing: border-box;
1143
+ outline: none;
1144
+ }
1145
+ .add-page-textarea:focus { border-color: var(--harmony-primary); box-shadow: 0 0 0 3px var(--harmony-primary-soft); }
1146
+ .add-page-dropzone {
1147
+ border: 1px dashed var(--harmony-border-strong);
1148
+ border-radius: var(--harmony-radius-md);
1149
+ padding: 16px;
1150
+ text-align: center;
1151
+ color: var(--harmony-text-muted);
1152
+ font-size: 12px;
1153
+ }
1154
+ .add-page-chips { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
1155
+ .add-page-chip {
1156
+ display: flex;
1157
+ align-items: center;
1158
+ gap: 8px;
1159
+ background: var(--harmony-bg-subtle);
1160
+ border: 1px solid var(--harmony-border);
1161
+ border-radius: var(--harmony-radius-sm);
1162
+ padding: 6px 8px;
1163
+ font-size: 11px;
1164
+ }
1165
+ .add-page-chip-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--harmony-text-secondary); }
1166
+ .add-page-chip-path { font-size: 10px; color: var(--harmony-text-muted); font-family: var(--harmony-mono); }
1167
+ .add-page-chip select { background: var(--harmony-bg-surface); color: var(--harmony-text); border: 1px solid var(--harmony-border); border-radius: 4px; font-size: 11px; padding: 2px 4px; }
1168
+ .add-page-chip-remove { background: none; border: none; color: var(--harmony-text-muted); cursor: pointer; font-size: 14px; padding: 0 4px; }
1169
+ .add-page-chip-remove:hover { color: var(--harmony-danger); }
1170
+ .add-page-plugins {
1171
+ border: 1px solid var(--harmony-border);
1172
+ border-radius: var(--harmony-radius-md);
1173
+ padding: 10px;
1174
+ margin-top: 8px;
1175
+ display: flex;
1176
+ flex-direction: column;
1177
+ gap: 12px;
1178
+ max-height: 320px;
1179
+ overflow: auto;
1180
+ }
1181
+ .add-menu-panel.add-page-plugins,
1182
+ .annotation-add-menu-panel.add-menu-panel {
1183
+ max-height: min(320px, 42vh);
1184
+ overflow: hidden;
1185
+ gap: 8px;
1186
+ min-height: 0;
1187
+ display: flex;
1188
+ flex-direction: column;
1189
+ }
1190
+ .add-menu-panel .add-page-plugins-zone-title { flex-shrink: 0; }
1191
+ .add-menu-panel .add-menu-panel-attached { flex: 0 1 auto; min-height: 0; max-height: 120px; overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch; }
1192
+ .add-menu-panel .add-page-plugin-chips { margin-top: 0; }
1193
+ .add-menu-panel .add-page-btn,
1194
+ .add-menu-panel .add-page-manage-link,
1195
+ .add-menu-panel .add-page-hint,
1196
+ .add-menu-panel .add-page-field-error,
1197
+ .add-menu-panel .add-menu-route-params,
1198
+ .add-menu-panel .add-page-suggested-route,
1199
+ .add-menu-panel .add-menu-route-confirm { flex-shrink: 0; }
1200
+ .add-menu-panel .add-menu-popover { flex-shrink: 0; min-height: 180px; max-height: min(240px, 36vh); margin-top: 4px; }
1201
+ .add-menu-panel .add-menu-nav { min-height: 140px; }
1202
+ .add-page-plugins-zone-title { font-size: 11px; font-weight: 600; color: var(--harmony-text-secondary); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 4px; }
1203
+ .add-page-plugin-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 11px; border-bottom: 1px solid var(--harmony-border); }
1204
+ .add-page-plugin-row:last-child { border-bottom: none; }
1205
+ .add-page-plugin-label { flex: 1; color: var(--harmony-text-secondary); }
1206
+ .add-page-plugin-btn {
1207
+ background: var(--harmony-bg-subtle);
1208
+ color: var(--harmony-text-secondary);
1209
+ border: 1px solid var(--harmony-border);
1210
+ border-radius: var(--harmony-radius-sm);
1211
+ padding: 2px 8px;
1212
+ font-size: 10px;
1213
+ cursor: pointer;
1214
+ }
1215
+ .add-page-plugin-btn:hover { background: var(--harmony-bg-hover); color: var(--harmony-text); }
1216
+ .add-page-plugin-btn:disabled { opacity: 0.45; cursor: not-allowed; }
1217
+ .add-page-plugin-btn-primary { background: var(--harmony-primary); color: #fff; border-color: var(--harmony-primary); }
1218
+ .add-page-setup-ok { color: var(--harmony-success); font-size: 10px; }
1219
+ .add-page-setup-warn { color: var(--harmony-warning); font-size: 10px; }
1220
+ .add-page-setup-error { color: var(--harmony-danger); font-size: 10px; }
1221
+ .add-page-plugin-contract { padding-left: 0; font-size: 11px; color: var(--harmony-text-muted); display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
1222
+ .add-page-plugin-contract-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; border-bottom: 1px solid var(--harmony-border); }
1223
+ .add-page-plugin-contract-row:last-child { border-bottom: none; }
1224
+ .add-page-plugin-contract-name { flex: 1; color: var(--harmony-text-secondary); font-size: 11px; }
1225
+ .add-page-plugin-contract-added { font-size: 10px; color: var(--harmony-success); }
1226
+ .add-page-plugin-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
1227
+ .add-page-plugin-chip {
1228
+ background: var(--harmony-bg-subtle);
1229
+ border: 1px solid var(--harmony-border);
1230
+ border-radius: var(--harmony-radius-sm);
1231
+ padding: 2px 6px;
1232
+ font-size: 10px;
1233
+ color: var(--harmony-text-secondary);
1234
+ display: flex;
1235
+ align-items: center;
1236
+ gap: 4px;
1237
+ }
1238
+ .add-page-plugin-chip-remove { background: none; border: none; color: var(--harmony-text-muted); cursor: pointer; padding: 0 2px; }
1239
+ .add-page-plugins-warn { font-size: 11px; color: var(--harmony-warning); margin-top: 4px; }
1240
+ .add-page-install-live { font-size: 11px; color: var(--harmony-text-muted); }
1241
+ .add-page-local-plugin-form { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--harmony-border); }
1242
+ .add-page-local-plugin-form input {
1243
+ background: var(--harmony-bg-surface);
1244
+ color: var(--harmony-text);
1245
+ border: 1px solid var(--harmony-border);
1246
+ border-radius: var(--harmony-radius-sm);
1247
+ padding: 4px 6px;
1248
+ font-size: 11px;
1249
+ }
1250
+ .add-page-plugin-picker {
1251
+ width: 100%;
1252
+ background: var(--harmony-bg-surface);
1253
+ color: var(--harmony-text);
1254
+ border: 1px solid var(--harmony-border);
1255
+ border-radius: var(--harmony-radius-sm);
1256
+ font-size: 12px;
1257
+ padding: 6px 8px;
1258
+ margin-top: 6px;
1259
+ }
1260
+ .add-page-manage-link { font-size: 11px; color: var(--harmony-primary); cursor: pointer; margin-top: 6px; background: none; border: none; padding: 0; text-align: left; }
1261
+ .annotation-binding { margin-top: 6px; border-top: 1px solid var(--harmony-border); padding-top: 6px; }
1262
+ .annotation-add-menu { margin-top: 6px; border-top: 1px solid var(--harmony-border); padding-top: 6px; }
1263
+ .annotation-add-menu-toggle { background: none; border: none; color: var(--harmony-primary); font-size: 11px; cursor: pointer; padding: 0; text-align: left; }
1264
+ .annotation-add-menu-panel { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; font-size: 11px; color: var(--harmony-text-secondary); }
1265
+ .change-request-add-menu { margin-top: 8px; padding: 10px 12px; border: 1px solid var(--harmony-border); border-radius: var(--harmony-radius-md); background: var(--harmony-bg-subtle); }
1266
+ .add-menu-route-params { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; }
1267
+ .add-menu-popover {
1268
+ border: 1px solid var(--harmony-border);
1269
+ border-radius: var(--harmony-radius-sm);
1270
+ padding: 8px;
1271
+ background: var(--harmony-bg-subtle);
1272
+ margin-top: 6px;
1273
+ display: flex;
1274
+ flex-direction: column;
1275
+ gap: 6px;
1276
+ min-height: 0;
1277
+ max-width: 100%;
1278
+ max-height: min(320px, 50vh);
1279
+ overflow: hidden;
1280
+ }
1281
+ .add-menu-popover-header {
1282
+ display: flex;
1283
+ justify-content: space-between;
1284
+ align-items: center;
1285
+ font-size: 11px;
1286
+ font-weight: 600;
1287
+ color: var(--harmony-text-secondary);
1288
+ border-bottom: 1px solid var(--harmony-border);
1289
+ padding-bottom: 4px;
1290
+ margin-bottom: 4px;
1291
+ flex-shrink: 0;
1292
+ }
1293
+ .add-menu-popover-header button { background: none; border: none; color: var(--harmony-text-muted); font-size: 14px; cursor: pointer; padding: 0 4px; }
1294
+ .add-menu-popover-header button:hover { color: var(--harmony-text); }
1295
+ .add-menu-nav { display: flex; flex-direction: column; gap: 4px; flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; padding-right: 2px; -webkit-overflow-scrolling: touch; }
1296
+ .add-menu-nav-row { display: contents; }
1297
+ .add-menu-nav-btn {
1298
+ background: var(--harmony-bg-surface);
1299
+ color: var(--harmony-text-secondary);
1300
+ border: 1px solid var(--harmony-border);
1301
+ border-radius: var(--harmony-radius-sm);
1302
+ padding: 4px 8px;
1303
+ font-size: 11px;
1304
+ cursor: pointer;
1305
+ text-align: left;
1306
+ }
1307
+ .add-menu-nav-btn:hover { background: var(--harmony-bg-hover); color: var(--harmony-text); border-color: var(--harmony-primary); }
1308
+ .add-menu-item-btn {
1309
+ background: var(--harmony-primary);
1310
+ color: #fff;
1311
+ border: none;
1312
+ border-radius: var(--harmony-radius-sm);
1313
+ padding: 4px 8px;
1314
+ font-size: 11px;
1315
+ cursor: pointer;
1316
+ text-align: left;
1317
+ }
1318
+ .add-menu-item-btn:hover { background: var(--harmony-primary-hover); }
1319
+ .annotation-binding-preview { font-size: 10px; color: var(--harmony-success); margin: 0; }
1320
+ .annotation-binding-panel label { display: flex; flex-direction: column; gap: 2px; }
1321
+ .annotation-binding-panel select { background: var(--harmony-bg-surface); color: var(--harmony-text); border: 1px solid var(--harmony-border); border-radius: 4px; font-size: 11px; }
1322
+ .annotation-binding-scope-row { display: flex; gap: 10px; flex-wrap: wrap; }
1323
+ .annotation-binding-install {
1324
+ background: var(--harmony-primary);
1325
+ color: #fff;
1326
+ border: none;
1327
+ border-radius: var(--harmony-radius-sm);
1328
+ padding: 4px 8px;
1329
+ font-size: 10px;
1330
+ cursor: pointer;
1331
+ align-self: flex-start;
1332
+ }
1333
+ .add-page-footer { display: flex; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--harmony-border); flex-shrink: 0; background: var(--harmony-bg-subtle); }
1334
+ .add-page-btn { flex: 1; padding: 10px; border-radius: var(--harmony-radius-pill); font-size: 13px; font-weight: 600; cursor: pointer; border: 1px solid var(--harmony-border); }
1335
+ .add-page-btn-cancel { background: var(--harmony-bg-surface); color: var(--harmony-text-secondary); }
1336
+ .add-page-btn-primary { background: var(--harmony-primary); color: #fff; border-color: var(--harmony-primary); }
1337
+ .add-page-btn-primary:disabled { opacity: 0.45; cursor: not-allowed; }
1338
+ .add-page-hidden-file { display: none; }
1339
+
1340
+ /* Legacy class aliases (kept for compatibility) */
1341
+ .main-panel { flex: 1; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
1342
+ .main-top-bar { display: none; }
1343
+ .preview-stack { display: contents; }
1344
+ .preview-url-row { display: none; }
1345
+ .reset-btn {
1346
+ background: var(--harmony-bg-surface);
1347
+ border: 1px solid var(--harmony-border);
1348
+ color: var(--harmony-text-secondary);
1349
+ cursor: pointer;
1350
+ font-size: 14px;
1351
+ padding: 8px 12px;
1352
+ border-radius: var(--harmony-radius-pill);
1353
+ line-height: 1;
1354
+ }
1355
+ .reset-btn:hover { color: var(--harmony-text); border-color: var(--harmony-border-strong); }
1356
+ .route-picker-stack { display: contents; }
1357
+ .arrow-svg defs polygon { fill: #116dff; }
290
1358
  </style>
291
1359
  <script type="application/jay-data">
292
1360
  data:
@@ -393,31 +1461,34 @@ data:
393
1461
  name: string
394
1462
  thumbUrl: string
395
1463
  annotationId: string
396
- bindingSectionOpen: boolean
397
- showBindingControls: boolean
398
- showMarkerHasBindingChips: boolean
399
- showMarkerBindingEmptyHint: boolean
400
- markerBindingChips:
1464
+ addMenuSectionOpen: boolean
1465
+ showAddMenuControls: boolean
1466
+ showMarkerAddMenuChips: boolean
1467
+ showMarkerAddMenuEmptyHint: boolean
1468
+ markerAddMenuChips:
401
1469
  - rowKey: string
402
- label: string
403
- pluginName: string
404
- packageName: string
405
- contractName: string
406
- scope: string
407
- markerPluginOptions:
1470
+ itemId: string
1471
+ title: string
1472
+ subtitle: string
1473
+ addMenuSelectedCategory: string
1474
+ showAddMenuItemPicker: boolean
1475
+ markerPickerNavRows:
408
1476
  - rowKey: string
409
- value: string
410
1477
  label: string
411
- showMarkerContractPicker: boolean
412
- markerPickerPluginLabel: string
413
- markerContractPickerRows:
1478
+ value: string
1479
+ kind: enum (category | subCategory | item)
1480
+ showMarkerPickerLoading: boolean
1481
+ showMarkerPickerCatalogEmpty: boolean
1482
+ crAddMenuParamCollisionWarning: string
1483
+ crAddMenuRouteParamHint: string
1484
+ showCrAddMenuRouteParams: boolean
1485
+ crAddMenuRouteParamRows:
414
1486
  - rowKey: string
415
- pluginName: string
416
- packageName: string
417
- contractName: string
418
- description: string
419
- onPage: boolean
420
- componentKey: string
1487
+ name: string
1488
+ showCrRouteParamConfirm: boolean
1489
+ crPendingRouteParamTitle: string
1490
+ showCrPlannedRoutePanel: boolean
1491
+ crPlannedRoute: string
421
1492
  recordingDraftUi:
422
1493
  id: string
423
1494
  kindLabel: string
@@ -504,31 +1575,34 @@ data:
504
1575
  name: string
505
1576
  thumbUrl: string
506
1577
  annotationId: string
507
- bindingSectionOpen: boolean
508
- showBindingControls: boolean
509
- showMarkerHasBindingChips: boolean
510
- showMarkerBindingEmptyHint: boolean
511
- markerBindingChips:
1578
+ addMenuSectionOpen: boolean
1579
+ showAddMenuControls: boolean
1580
+ showMarkerAddMenuChips: boolean
1581
+ showMarkerAddMenuEmptyHint: boolean
1582
+ markerAddMenuChips:
512
1583
  - rowKey: string
513
- label: string
514
- pluginName: string
515
- packageName: string
516
- contractName: string
517
- scope: string
518
- markerPluginOptions:
1584
+ itemId: string
1585
+ title: string
1586
+ subtitle: string
1587
+ addMenuSelectedCategory: string
1588
+ showAddMenuItemPicker: boolean
1589
+ markerPickerNavRows:
519
1590
  - rowKey: string
520
- value: string
521
1591
  label: string
522
- showMarkerContractPicker: boolean
523
- markerPickerPluginLabel: string
524
- markerContractPickerRows:
1592
+ value: string
1593
+ kind: enum (category | subCategory | item)
1594
+ showMarkerPickerLoading: boolean
1595
+ showMarkerPickerCatalogEmpty: boolean
1596
+ crAddMenuParamCollisionWarning: string
1597
+ crAddMenuRouteParamHint: string
1598
+ showCrAddMenuRouteParams: boolean
1599
+ crAddMenuRouteParamRows:
525
1600
  - rowKey: string
526
- pluginName: string
527
- packageName: string
528
- contractName: string
529
- description: string
530
- onPage: boolean
531
- componentKey: string
1601
+ name: string
1602
+ showCrRouteParamConfirm: boolean
1603
+ crPendingRouteParamTitle: string
1604
+ showCrPlannedRoutePanel: boolean
1605
+ crPlannedRoute: string
532
1606
  showVideoAnnotationsPanel: boolean
533
1607
  videoModalOverlayPointerNone: boolean
534
1608
  videoSubmitError: string
@@ -605,31 +1679,34 @@ data:
605
1679
  name: string
606
1680
  thumbUrl: string
607
1681
  annotationId: string
608
- bindingSectionOpen: boolean
609
- showBindingControls: boolean
610
- showMarkerHasBindingChips: boolean
611
- showMarkerBindingEmptyHint: boolean
612
- markerBindingChips:
1682
+ addMenuSectionOpen: boolean
1683
+ showAddMenuControls: boolean
1684
+ showMarkerAddMenuChips: boolean
1685
+ showMarkerAddMenuEmptyHint: boolean
1686
+ markerAddMenuChips:
613
1687
  - rowKey: string
614
- label: string
615
- pluginName: string
616
- packageName: string
617
- contractName: string
618
- scope: string
619
- markerPluginOptions:
1688
+ itemId: string
1689
+ title: string
1690
+ subtitle: string
1691
+ addMenuSelectedCategory: string
1692
+ showAddMenuItemPicker: boolean
1693
+ markerPickerNavRows:
620
1694
  - rowKey: string
621
- value: string
622
1695
  label: string
623
- showMarkerContractPicker: boolean
624
- markerPickerPluginLabel: string
625
- markerContractPickerRows:
1696
+ value: string
1697
+ kind: enum (category | subCategory | item)
1698
+ showMarkerPickerLoading: boolean
1699
+ showMarkerPickerCatalogEmpty: boolean
1700
+ crAddMenuParamCollisionWarning: string
1701
+ crAddMenuRouteParamHint: string
1702
+ showCrAddMenuRouteParams: boolean
1703
+ crAddMenuRouteParamRows:
626
1704
  - rowKey: string
627
- pluginName: string
628
- packageName: string
629
- contractName: string
630
- description: string
631
- onPage: boolean
632
- componentKey: string
1705
+ name: string
1706
+ showCrRouteParamConfirm: boolean
1707
+ crPendingRouteParamTitle: string
1708
+ showCrPlannedRoutePanel: boolean
1709
+ crPlannedRoute: string
633
1710
  showSnapshotAnnotationsPanel: boolean
634
1711
  showSnapshotSubmitError: boolean
635
1712
  snapshotSubmitError: string
@@ -694,32 +1771,52 @@ data:
694
1771
  projectLocalPluginName: string
695
1772
  projectLocalPackageName: string
696
1773
  projectLocalPath: string
697
- showAddPagePluginsPanel: boolean
698
- showAddPagePagePluginsZone: boolean
699
- addPagePluginPickerOptions:
1774
+ showAddMenuPanel: boolean
1775
+ showAddMenuChips: boolean
1776
+ addMenuChipRows:
1777
+ - rowKey: string
1778
+ itemId: string
1779
+ title: string
1780
+ subtitle: string
1781
+ annotationId?: string
1782
+ showAddMenuEmptyHint: boolean
1783
+ showAddMenuPopover: boolean
1784
+ addMenuNavRows:
700
1785
  - rowKey: string
1786
+ label: string
701
1787
  value: string
1788
+ kind: enum (category | subCategory | item)
1789
+ addMenuSelectedCategory: string
1790
+ showMarkerAddMenuPopover: boolean
1791
+ markerAddMenuPopoverLeftPct: number
1792
+ markerAddMenuPopoverTopPct: number
1793
+ markerAddMenuPickerAnnotationId: string
1794
+ markerAddMenuNavRows:
1795
+ - rowKey: string
702
1796
  label: string
703
- addPagePluginPickerValue: string
704
- showAddPageContractPicker: boolean
705
- addPagePickerPluginLabel: string
706
- addPageContractPickerRows:
1797
+ value: string
1798
+ kind: enum (category | subCategory | item)
1799
+ markerAddMenuSelectedCategory: string
1800
+ showMarkerAddMenuPickerLoading: boolean
1801
+ showMarkerAddMenuPickerCatalogEmpty: boolean
1802
+ crAddMenuParamCollisionWarning: string
1803
+ crAddMenuRouteParamHint: string
1804
+ showCrAddMenuRouteParams: boolean
1805
+ crAddMenuRouteParamRows:
707
1806
  - rowKey: string
708
- pluginName: string
709
- packageName: string
710
- contractName: string
711
- description: string
712
- onPage: boolean
713
- componentKey: string
714
- addPagePagePluginChips:
1807
+ name: string
1808
+ showCrRouteParamConfirm: boolean
1809
+ crPendingRouteParamTitle: string
1810
+ showCrPlannedRoutePanel: boolean
1811
+ crPlannedRoute: string
1812
+ addMenuParamCollisionWarning: string
1813
+ addMenuRouteParamHint: string
1814
+ showAddMenuRouteParams: boolean
1815
+ addMenuRouteParamRows:
715
1816
  - rowKey: string
716
- label: string
717
- pluginName: string
718
- packageName: string
719
- contractName: string
720
- componentKey: string
721
- showAddPageHasPagePluginChips: boolean
722
- showAddPagePagePluginsEmptyHint: boolean
1817
+ name: string
1818
+ showAddMenuRouteParamConfirm: boolean
1819
+ addMenuPendingRouteParamTitle: string
723
1820
  showAddPageResultBanner: boolean
724
1821
  addPageResultBannerClass: string
725
1822
  addPageResultBannerMessage: string
@@ -759,11 +1856,13 @@ data:
759
1856
 
760
1857
  <!-- Main screen -->
761
1858
  <div class="root" if="isMainVisible">
762
- <main class="main-panel">
763
- <div class="main-top-bar" if="hasPages">
764
- <div class="route-picker-stack">
1859
+ <header class="editor-topbar harmony-global-bar" if="hasPages">
1860
+ <div class="editor-topbar-left harmony-global-left">
1861
+ <span class="aiditor-logo"><span class="aiditor-logo-ai">AI</span>ditor</span>
1862
+ <div class="harmony-page-select-wrap">
1863
+ <span class="harmony-page-label">Page</span>
765
1864
  <select
766
- class="aiditor-dropdown"
1865
+ class="aiditor-dropdown harmony-page-select"
767
1866
  ref="pageRouteSelect"
768
1867
  value="{selectedRouteSelectValue}"
769
1868
  aria-label="Page route"
@@ -771,64 +1870,52 @@ data:
771
1870
  <option value="" disabled>Select a route…</option>
772
1871
  <option forEach="pageSelectOptions" trackBy="url" value="{url}">{label}</option>
773
1872
  </select>
774
- <div class="path-select-row">
775
- <select
776
- class="aiditor-dropdown preview-path-select"
777
- if="showPathSelect"
778
- ref="previewPathSelect"
779
- value="{selectedPreviewPath}"
780
- aria-label="URL instance"
781
- >
782
- <option forEach="previewPathOptions" trackBy="path" value="{path}">{path}</option>
783
- </select>
784
- <span class="params-loading-hint" if="paramsLoadingHint">{paramsLoadingHint}</span>
785
- </div>
786
1873
  </div>
787
- <button type="button" class="project-settings-btn" ref="projectSettingsBtn" disabled="isRunning">Project settings</button>
788
- <button type="button" class="add-page-open-btn" ref="addPageOpenBtn" disabled="isRunning">Add Page</button>
789
- <button type="button" class="add-page-from-brief-btn" ref="addPageFromBriefBtn" if="showAddPageFromBriefBtn" disabled="isRunning">Page Briefs</button>
1874
+ <div class="path-select-row harmony-path-select" if="showPathSelect">
1875
+ <select
1876
+ class="aiditor-dropdown preview-path-select"
1877
+ ref="previewPathSelect"
1878
+ value="{selectedPreviewPath}"
1879
+ aria-label="URL instance"
1880
+ >
1881
+ <option forEach="previewPathOptions" trackBy="path" value="{path}">{path}</option>
1882
+ </select>
1883
+ <span class="params-loading-hint" if="paramsLoadingHint">{paramsLoadingHint}</span>
1884
+ </div>
1885
+ </div>
1886
+ <div class="editor-topbar-right harmony-global-right">
1887
+ <button type="button" class="harmony-btn-secondary project-settings-btn" ref="projectSettingsBtn" disabled="isRunning">Settings</button>
1888
+ <button type="button" class="harmony-btn-primary add-page-open-btn" ref="addPageOpenBtn" disabled="isRunning">+ Add Page</button>
1889
+ <button type="button" class="harmony-btn-secondary add-page-from-brief-btn" ref="addPageFromBriefBtn" if="showAddPageFromBriefBtn" disabled="isRunning">Page Briefs</button>
790
1890
  </div>
1891
+ </header>
791
1892
 
792
- <div class="preview-stack" if="isPreviewMode">
793
- <div class="preview-url-row">
794
- <span class="aiditor-logo"><span class="aiditor-logo-ai">AI</span>ditor</span>
795
- <div class="url-bar-wrap">
796
- <div class="url-bar">{previewUrlBar}</div>
797
- </div>
798
- <div class="preview-visual-tools" if="showVisualToolbar">
799
- <button type="button" class="{breakpointDesktopOn ? visual-tool-on} visual-tool-btn" ref="breakpointDesktopBtn" title="Desktop (1280px)"><svg width="16" height="13" viewBox="0 0 16 13" fill="none"><rect x="0.7" y="0.7" width="14.6" height="9.1" rx="1.1" stroke="currentColor" stroke-width="1.4"/><path d="M5.5 9.8v2M10.5 9.8v2M3.5 11.8h9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg></button>
800
- <button type="button" class="{breakpointTabletOn ? visual-tool-on} visual-tool-btn" ref="breakpointTabletBtn" title="Tablet (768px)"><svg width="10" height="14" viewBox="0 0 10 14" fill="none"><rect x="0.7" y="0.7" width="8.6" height="12.6" rx="1.1" stroke="currentColor" stroke-width="1.4"/><circle cx="5" cy="11.5" r="0.8" fill="currentColor"/></svg></button>
801
- <button type="button" class="{breakpointMobileOn ? visual-tool-on} visual-tool-btn" ref="breakpointMobileBtn" title="Mobile (390px)"><svg width="8" height="14" viewBox="0 0 8 14" fill="none"><rect x="0.7" y="0.7" width="6.6" height="12.6" rx="1.1" stroke="currentColor" stroke-width="1.4"/><line x1="2.5" y1="11.5" x2="5.5" y2="11.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg></button>
802
- <span class="tool-group-sep"></span>
803
- <button type="button" class="{visualToolNoneOn ? visual-tool-on} visual-tool-btn" ref="visualToolNoneBtn" title="Select">⤢</button>
804
- <button type="button" class="{visualToolPointOn ? visual-tool-on} visual-tool-btn" ref="visualToolPointBtn" title="Point">⊙</button>
805
- <button type="button" class="{visualToolAreaOn ? visual-tool-on} visual-tool-btn" ref="visualToolAreaBtn" title="Area">▢</button>
806
- <button type="button" class="{visualToolArrowOn ? visual-tool-on} visual-tool-btn" ref="visualToolArrowBtn" title="Arrow">↗</button>
807
- <button
808
- type="button"
809
- class="{isVideoRecording ? video-record-active} video-record-btn visual-tool-btn"
810
- ref="videoRecordBtn"
811
- disabled="videoRecordDisabled"
812
- title="Record preview"
813
- >{videoRecordLabel}</button>
814
- <button
815
- type="button"
816
- class="visual-tool-btn freeze-btn"
817
- ref="freezeBtn"
818
- disabled="freezeDisabled"
819
- title="Freeze page state"
820
- >❄</button>
821
- </div>
822
- </div>
1893
+ <input
1894
+ type="file"
1895
+ class="file-input-hidden"
1896
+ ref="visualAttachFileInput"
1897
+ multiple
1898
+ />
1899
+
1900
+ <div class="editor-stage">
1901
+ <div class="canvas-workspace harmony-canvas-area" if="isPreviewMode">
823
1902
  <div class="preview-loading" if="previewLoading">{paramsLoadingHint}</div>
824
1903
  <div class="preview-error" if="previewError">{previewError}</div>
825
- <input
826
- type="file"
827
- class="file-input-hidden"
828
- ref="visualAttachFileInput"
829
- multiple
830
- />
831
- <div class="{breakpointTabletOn ? preview-frame-tablet} {breakpointMobileOn ? preview-frame-mobile} preview-frame-wrap" if="showPreviewIframe" ref="previewCaptureRoot">
1904
+ <div class="canvas-window harmony-canvas-window" if="showPreviewIframe">
1905
+ <div class="canvas-chrome harmony-canvas-chrome">
1906
+ <div class="canvas-chrome-left harmony-canvas-chrome-left">
1907
+ <span class="canvas-page-badge harmony-canvas-page-badge">Preview</span>
1908
+ </div>
1909
+ <div class="url-bar-wrap harmony-url-bar-wrap">
1910
+ <div class="url-bar">{previewUrlBar}</div>
1911
+ </div>
1912
+ <div class="canvas-chrome-right harmony-breakpoint-tools" if="showVisualToolbar">
1913
+ <button type="button" class="{breakpointDesktopOn ? visual-tool-on} visual-tool-btn" ref="breakpointDesktopBtn" title="Desktop (1280px)"><svg width="16" height="13" viewBox="0 0 16 13" fill="none"><rect x="0.7" y="0.7" width="14.6" height="9.1" rx="1.1" stroke="currentColor" stroke-width="1.4"/><path d="M5.5 9.8v2M10.5 9.8v2M3.5 11.8h9" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg></button>
1914
+ <button type="button" class="{breakpointTabletOn ? visual-tool-on} visual-tool-btn" ref="breakpointTabletBtn" title="Tablet (768px)"><svg width="10" height="14" viewBox="0 0 10 14" fill="none"><rect x="0.7" y="0.7" width="8.6" height="12.6" rx="1.1" stroke="currentColor" stroke-width="1.4"/><circle cx="5" cy="11.5" r="0.8" fill="currentColor"/></svg></button>
1915
+ <button type="button" class="{breakpointMobileOn ? visual-tool-on} visual-tool-btn" ref="breakpointMobileBtn" title="Mobile (390px)"><svg width="8" height="14" viewBox="0 0 8 14" fill="none"><rect x="0.7" y="0.7" width="6.6" height="12.6" rx="1.1" stroke="currentColor" stroke-width="1.4"/><line x1="2.5" y1="11.5" x2="5.5" y2="11.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg></button>
1916
+ </div>
1917
+ </div>
1918
+ <div class="{breakpointTabletOn ? preview-frame-tablet} {breakpointMobileOn ? preview-frame-mobile} preview-frame-wrap harmony-canvas-content" ref="previewCaptureRoot">
832
1919
  <iframe class="preview-frame" ref="previewIframe" src="{previewSrc}" title="Page preview"></iframe>
833
1920
  <div class="{visualOverlayPointerNone ? visual-overlay-none} visual-overlay" ref="visualOverlay">
834
1921
  <div
@@ -858,7 +1945,7 @@ data:
858
1945
  <svg class="arrow-svg" if="hasVisualArrowLines" viewBox="0 0 100 100" preserveAspectRatio="none">
859
1946
  <defs>
860
1947
  <marker id="aiditor-arrowhead" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto">
861
- <polygon points="0 0, 8 4, 0 8" fill="#c586ff" />
1948
+ <polygon points="0 0, 8 4, 0 8" fill="#116dff" />
862
1949
  </marker>
863
1950
  </defs>
864
1951
  <line
@@ -949,31 +2036,48 @@ data:
949
2036
  data-annotation-id="{id}"
950
2037
  value="{instruction}"
951
2038
  ></textarea>
952
- <div class="annotation-binding">
953
- <button type="button" class="annotation-binding-toggle">Components (optional)</button>
954
- <div class="annotation-binding-panel" if="showBindingControls">
955
- <div if="showMarkerHasBindingChips">
956
- <div class="add-page-plugins-zone-title">Components on this marker</div>
2039
+ <div class="annotation-add-menu">
2040
+ <button type="button" class="annotation-add-menu-toggle">Add Menu (optional)</button>
2041
+ <div class="annotation-add-menu-panel add-menu-panel" if="showAddMenuControls">
2042
+ <div class="add-menu-panel-attached">
2043
+ <div if="showMarkerAddMenuChips">
2044
+ <div class="add-page-plugins-zone-title">Add Menu on this marker</div>
957
2045
  <div class="add-page-plugin-chips">
958
- <span class="add-page-plugin-chip" forEach="markerBindingChips" trackBy="rowKey">{label}<button type="button" class="add-page-plugin-chip-remove" data-marker-remove-binding="1" data-plugin="{pluginName}" data-contract="{contractName}" title="Remove from marker">×</button></span>
2046
+ <span class="add-page-plugin-chip" forEach="markerAddMenuChips" trackBy="rowKey">{title}<span class="add-page-plugin-chip-sub">{subtitle}</span><button type="button" class="add-page-plugin-chip-remove" data-marker-add-menu-remove="1" data-item-id="{itemId}" title="Remove">×</button></span>
959
2047
  </div>
960
2048
  </div>
961
- <p class="add-page-hint" if="showMarkerBindingEmptyHint">No components yet pick a plugin below and click Add for each component you need.</p>
962
- <div class="add-page-plugins-zone-title">Add component</div>
963
- <label class="add-page-hint">Plugin
964
- <select class="annotation-binding-plugin">
965
- <option value="">— Select plugin —</option>
966
- <option forEach="markerPluginOptions" trackBy="rowKey" value="{value}">{label}</option>
967
- </select>
968
- </label>
969
- <button type="button" class="add-page-manage-link" data-marker-manage-plugins="1">Manage plugins…</button>
970
- <div if="showMarkerContractPicker">
971
- <p class="add-page-hint">{markerPickerPluginLabel}</p>
972
- <div class="add-page-plugin-contract">
973
- <div class="add-page-plugin-contract-row" forEach="markerContractPickerRows" trackBy="rowKey">
974
- <span class="add-page-plugin-contract-name">{contractName}</span>
975
- <button type="button" class="add-page-plugin-btn" if="!onPage" data-marker-add-contract="1" data-plugin="{pluginName}" data-package="{packageName}" data-contract="{contractName}" data-key="{componentKey}">Add</button>
976
- <span class="add-page-plugin-contract-added" if="onPage">Added</span>
2049
+ <p class="add-page-hint" if="showMarkerAddMenuEmptyHint">No resources attached on this marker click + Add to pick from the catalog.</p>
2050
+ <button type="button" class="add-page-btn add-page-btn-cancel" data-marker-add-menu-open="1">+ Add</button>
2051
+ <button type="button" class="add-page-manage-link" data-marker-add-menu-manage="1">Manage plugins…</button>
2052
+ <p class="add-page-field-error" if="crAddMenuParamCollisionWarning">{crAddMenuParamCollisionWarning}</p>
2053
+ <p class="add-page-hint" if="crAddMenuRouteParamHint">{crAddMenuRouteParamHint}</p>
2054
+ <div class="add-menu-route-params" if="showCrAddMenuRouteParams">
2055
+ <span class="add-page-hint">Route params:</span>
2056
+ <button type="button" class="add-page-param-btn" forEach="crAddMenuRouteParamRows" trackBy="rowKey" data-cr-route-param="1" data-param="{name}">[{name}]</button>
2057
+ </div>
2058
+ <div class="add-page-suggested-route" if="showCrPlannedRoutePanel">
2059
+ <div class="add-page-section-label">Planned page route</div>
2060
+ <input type="text" class="add-page-route-input cr-planned-route-input" value="{crPlannedRoute}" placeholder="/products/[slug]" />
2061
+ </div>
2062
+ <div class="add-menu-route-confirm" if="showCrRouteParamConfirm">
2063
+ <p>Adding <strong>{crPendingRouteParamTitle}</strong> requires a dynamic route. Files change only after the agent completes the task.</p>
2064
+ <button type="button" class="add-page-btn add-page-btn-primary" data-cr-route-param-confirm="1">Add anyway</button>
2065
+ <button type="button" class="add-page-btn add-page-btn-cancel" data-cr-route-param-cancel="1">Cancel</button>
2066
+ </div>
2067
+ </div>
2068
+ <div class="add-menu-popover" if="showAddMenuItemPicker">
2069
+ <div class="add-menu-popover-header">
2070
+ <span if="!addMenuSelectedCategory">Pick a category</span>
2071
+ <span if="addMenuSelectedCategory">Pick an item</span>
2072
+ <button type="button" data-marker-add-menu-close="1">×</button>
2073
+ </div>
2074
+ <p class="add-page-hint" if="showMarkerPickerLoading">Loading catalog…</p>
2075
+ <p class="add-page-hint" if="showMarkerPickerCatalogEmpty">Add Menu catalog is empty. Run <code>yarn setup ui-kit --force</code> (and other plugins) in the project, then click + Add again.</p>
2076
+ <div class="add-menu-nav">
2077
+ <div class="add-menu-nav-row" forEach="markerPickerNavRows" trackBy="rowKey">
2078
+ <button type="button" class="add-menu-nav-btn" if="kind===category" data-marker-add-menu-category="1" data-category="{value}">{label}</button>
2079
+ <button type="button" class="add-menu-nav-btn" if="kind===subCategory" data-marker-add-menu-subcategory="1" data-subcategory="{value}">{label}</button>
2080
+ <button type="button" class="add-menu-item-btn" if="kind===item" data-marker-add-menu-pick="1" data-item-id="{value}">{label}</button>
977
2081
  </div>
978
2082
  </div>
979
2083
  </div>
@@ -1002,10 +2106,33 @@ data:
1002
2106
  </div>
1003
2107
  </div>
1004
2108
  </div>
2109
+ </div>
1005
2110
  <p class="visual-submit-error" if="showVisualSubmitError">{visualSubmitError}</p>
1006
2111
  </div>
1007
2112
 
1008
- </main>
2113
+ <div class="annotate-dock preview-visual-tools" if="isPreviewMode && showVisualToolbar">
2114
+ <span class="annotate-dock-label">Annotate</span>
2115
+ <button type="button" class="{visualToolNoneOn ? visual-tool-on} visual-tool-btn" ref="visualToolNoneBtn" title="Select">⤢</button>
2116
+ <button type="button" class="{visualToolPointOn ? visual-tool-on} visual-tool-btn" ref="visualToolPointBtn" title="Point">⊙</button>
2117
+ <button type="button" class="{visualToolAreaOn ? visual-tool-on} visual-tool-btn" ref="visualToolAreaBtn" title="Area">▢</button>
2118
+ <button type="button" class="{visualToolArrowOn ? visual-tool-on} visual-tool-btn" ref="visualToolArrowBtn" title="Arrow">↗</button>
2119
+ <span class="tool-group-sep"></span>
2120
+ <button
2121
+ type="button"
2122
+ class="{isVideoRecording ? video-record-active} video-record-btn visual-tool-btn"
2123
+ ref="videoRecordBtn"
2124
+ disabled="videoRecordDisabled"
2125
+ title="Record preview"
2126
+ >{videoRecordLabel}</button>
2127
+ <button
2128
+ type="button"
2129
+ class="visual-tool-btn freeze-btn"
2130
+ ref="freezeBtn"
2131
+ disabled="freezeDisabled"
2132
+ title="Freeze page state"
2133
+ >❄</button>
2134
+ </div>
2135
+ </div>
1009
2136
  <div class="add-page-result-slot" ref="addPageResultBannerSlot">
1010
2137
  <div class="{addPageResultBannerClass} add-page-result-banner" if="showAddPageResultBanner">
1011
2138
  <span>{addPageResultBannerMessage}</span>
@@ -1018,7 +2145,7 @@ data:
1018
2145
  <div class="{bottomPanelClass}">
1019
2146
  <div class="bottom-panel-resize" ref="bottomPanelResize"></div>
1020
2147
  <div class="bottom-panel-header" ref="bottomPanelHeader">
1021
- <span class="bottom-panel-title">Agent output</span>
2148
+ <span class="bottom-panel-title">AI Assistant</span>
1022
2149
  <span class="bottom-panel-running" if="showBottomPanelRunning"></span>
1023
2150
  <span class="bottom-panel-spacer"></span>
1024
2151
  <button type="button" class="bottom-panel-clear" ref="bottomPanelClearBtn">Clear</button>
@@ -1099,6 +2226,12 @@ data:
1099
2226
  <span class="add-page-route-badge" if="addPageIsDynamicRoute">Dynamic route</span>
1100
2227
  </div>
1101
2228
  <p class="add-page-field-error" if="showAddPageRouteError">{addPageRouteError}</p>
2229
+ <p class="add-page-field-error" if="addMenuParamCollisionWarning">{addMenuParamCollisionWarning}</p>
2230
+ <p class="add-page-hint" if="addMenuRouteParamHint">{addMenuRouteParamHint}</p>
2231
+ <div class="add-menu-route-params" ref="addPageRouteParamsPanel" if="showAddMenuRouteParams">
2232
+ <span class="add-page-hint">Route params:</span>
2233
+ <button type="button" class="add-page-param-btn" forEach="addMenuRouteParamRows" trackBy="rowKey" data-add-menu-param="1" data-param="{name}">[{name}]</button>
2234
+ </div>
1102
2235
  <div class="add-page-suggested-route" if="showSuggestedRouteBanner">
1103
2236
  <span>Suggested route: <code>{suggestedRouteLabel}</code></span>
1104
2237
  <button type="button" class="add-page-btn add-page-btn-primary" ref="addPageSuggestedRouteApplyBtn" style="flex:0;padding:4px 10px;font-size:11px">Apply route</button>
@@ -1111,36 +2244,41 @@ data:
1111
2244
  <button type="button" class="add-page-fill-from-image-btn" ref="addPageFillContentFromImageBtn" title="Generate markdown from screenshot(s) using AI" disabled="briefFillDisabled">Fill from image</button>
1112
2245
  </div>
1113
2246
  <p class="add-page-hint">Behavior, plugins, contracts, interactions, copy.</p>
1114
- <textarea class="add-page-textarea" ref="addPageContentMd" placeholder="# Pricing page&#10;- Headless: none (static marketing page)&#10;- Show 3 tiers: Starter / Pro / Enterprise">{addPageContentMd}</textarea>
1115
- <div class="add-page-plugins" ref="addPagePluginsPanel" if="showAddPagePluginsPanel" aria-live="polite">
1116
- <div if="showAddPagePagePluginsZone">
1117
- <div class="add-page-plugins-zone-title">Plugins on this page</div>
1118
- <div if="showAddPageHasPagePluginChips">
1119
- <div class="add-page-plugins-zone-title">Components on this page</div>
1120
- <div class="add-page-plugin-chips">
1121
- <span class="add-page-plugin-chip" forEach="addPagePagePluginChips" trackBy="rowKey">{label}<button type="button" class="add-page-plugin-chip-remove" data-add-page-remove-chip="1" data-plugin="{pluginName}" data-package="{packageName}" data-contract="{contractName}" title="Remove from page">×</button></span>
1122
- </div>
2247
+ <textarea class="add-page-textarea" ref="addPageContentMd" placeholder="# Pricing page&#10;- Headless: none (static marketing page)&#10;- Show 3 tiers: Starter / Pro / Enterprise" value="{addPageContentMd}"></textarea>
2248
+ <div class="add-page-plugins add-menu-panel" ref="addMenuPanel" aria-live="polite">
2249
+ <div class="add-page-plugins-zone-title">Add Menu</div>
2250
+ <div class="add-menu-panel-attached">
2251
+ <div if="showAddMenuChips" class="add-page-plugin-chips">
2252
+ <span class="add-page-plugin-chip" forEach="addMenuChipRows" trackBy="rowKey">
2253
+ {title}<span class="add-page-plugin-chip-sub">{subtitle}</span>
2254
+ <button type="button" class="add-page-plugin-chip-remove" data-add-menu-remove-chip="1" data-item-id="{itemId}" title="Remove">×</button>
2255
+ <button type="button" class="add-page-plugin-chip-at" data-add-menu-at-title="1" data-title="{title}" title="Insert @Title">@</button>
2256
+ </span>
2257
+ </div>
2258
+ <p class="add-page-hint" if="showAddMenuEmptyHint">Install plugins in Project settings to unlock Add Menu items.</p>
2259
+ <button type="button" class="add-page-btn add-page-btn-cancel" data-add-menu-open="1">+ Add</button>
2260
+ <button type="button" class="add-page-manage-link" data-add-menu-manage-plugins="1">Manage plugins…</button>
2261
+ </div>
2262
+ <div class="add-menu-popover" if="showAddMenuPopover">
2263
+ <div class="add-menu-popover-header">
2264
+ <span if="!addMenuSelectedCategory">Pick a category</span>
2265
+ <span if="addMenuSelectedCategory">Pick an item</span>
2266
+ <button type="button" data-add-menu-close="1">×</button>
1123
2267
  </div>
1124
- <p class="add-page-hint" if="showAddPagePagePluginsEmptyHint">No components yet — pick a plugin below and click Add on each component you need.</p>
1125
- <div class="add-page-plugins-zone-title">Add component</div>
1126
- <label class="add-page-hint">Plugin
1127
- <select class="add-page-plugin-picker" ref="addPagePluginPicker" value="{addPagePluginPickerValue}">
1128
- <option value="">— Select plugin —</option>
1129
- <option forEach="addPagePluginPickerOptions" trackBy="rowKey" value="{value}">{label}</option>
1130
- </select>
1131
- </label>
1132
- <button type="button" class="add-page-manage-link" data-add-page-manage-plugins="1">Manage plugins…</button>
1133
- <div if="showAddPageContractPicker">
1134
- <p class="add-page-hint">{addPagePickerPluginLabel}</p>
1135
- <div class="add-page-plugin-contract">
1136
- <div class="add-page-plugin-contract-row" forEach="addPageContractPickerRows" trackBy="rowKey">
1137
- <span class="add-page-plugin-contract-name">{contractName}</span>
1138
- <button type="button" class="add-page-plugin-btn" if="!onPage" data-add-page-add-contract="1" data-plugin="{pluginName}" data-package="{packageName}" data-contract="{contractName}" data-key="{componentKey}">Add</button>
1139
- <span class="add-page-plugin-contract-added" if="onPage">Added</span>
1140
- </div>
2268
+ <div class="add-menu-nav">
2269
+ <div class="add-menu-nav-row" forEach="addMenuNavRows" trackBy="rowKey">
2270
+ <button type="button" class="add-menu-nav-btn" if="kind===category" data-add-menu-category="1" data-category="{value}">{label}</button>
2271
+ <button type="button" class="add-menu-nav-btn" if="kind===subCategory" data-add-menu-subcategory="1" data-subcategory="{value}">{label}</button>
2272
+ <button type="button" class="add-menu-item-btn" if="kind===item" data-add-menu-pick="1" data-item-id="{value}">{label}</button>
1141
2273
  </div>
1142
2274
  </div>
1143
2275
  </div>
2276
+ <div class="add-menu-route-confirm" if="showAddMenuRouteParamConfirm">
2277
+ <p><strong>This component needs a dynamic page route</strong></p>
2278
+ <p>Adding <strong>{addMenuPendingRouteParamTitle}</strong> will require updating the page URL. Files change only after the agent completes the task.</p>
2279
+ <button type="button" class="add-page-btn add-page-btn-primary" data-add-menu-route-confirm="1">Add anyway</button>
2280
+ <button type="button" class="add-page-btn add-page-btn-cancel" data-add-menu-route-cancel="1">Cancel</button>
2281
+ </div>
1144
2282
  </div>
1145
2283
  </section>
1146
2284
  <section>
@@ -1149,7 +2287,7 @@ data:
1149
2287
  <button type="button" class="add-page-fill-from-image-btn" ref="addPageFillDesignFromImageBtn" title="Generate markdown from screenshot(s) using AI" disabled="briefFillDisabled">Fill from image</button>
1150
2288
  </div>
1151
2289
  <p class="add-page-hint">Layout, colors, typography, breakpoints.</p>
1152
- <textarea class="add-page-textarea" ref="addPageDesignMd" placeholder="- Match site header from home&#10;- Hero: centered H1, muted subtitle (#888)">{addPageDesignMd}</textarea>
2290
+ <textarea class="add-page-textarea" ref="addPageDesignMd" placeholder="- Match site header from home&#10;- Hero: centered H1, muted subtitle (#888)" value="{addPageDesignMd}"></textarea>
1153
2291
  <p class="add-page-hint" if="addPageShowDesignHint">Add a mock or screenshot for better layout fidelity.</p>
1154
2292
  </section>
1155
2293
  <section>
@@ -1207,7 +2345,7 @@ data:
1207
2345
  <div class="{bottomPanelClass}">
1208
2346
  <div class="bottom-panel-resize" ref="bottomPanelResize"></div>
1209
2347
  <div class="bottom-panel-header" ref="bottomPanelHeader">
1210
- <span class="bottom-panel-title">Agent output</span>
2348
+ <span class="bottom-panel-title">AI Assistant</span>
1211
2349
  <span class="bottom-panel-running" if="showBottomPanelRunning"></span>
1212
2350
  <span class="bottom-panel-spacer"></span>
1213
2351
  <button type="button" class="bottom-panel-clear" ref="bottomPanelClearBtn">Clear</button>
@@ -1294,7 +2432,7 @@ data:
1294
2432
  <svg class="arrow-svg" if="hasVideoArrowLines" viewBox="0 0 100 100" preserveAspectRatio="none">
1295
2433
  <defs>
1296
2434
  <marker id="aiditor-video-arrowhead" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto">
1297
- <polygon points="0 0, 8 4, 0 8" fill="#c586ff" />
2435
+ <polygon points="0 0, 8 4, 0 8" fill="#116dff" />
1298
2436
  </marker>
1299
2437
  </defs>
1300
2438
  <line
@@ -1334,31 +2472,48 @@ data:
1334
2472
  data-annotation-id="{id}"
1335
2473
  value="{instruction}"
1336
2474
  ></textarea>
1337
- <div class="annotation-binding">
1338
- <button type="button" class="annotation-binding-toggle">Components (optional)</button>
1339
- <div class="annotation-binding-panel" if="showBindingControls">
1340
- <div if="showMarkerHasBindingChips">
1341
- <div class="add-page-plugins-zone-title">Components on this marker</div>
2475
+ <div class="annotation-add-menu">
2476
+ <button type="button" class="annotation-add-menu-toggle">Add Menu (optional)</button>
2477
+ <div class="annotation-add-menu-panel add-menu-panel" if="showAddMenuControls">
2478
+ <div class="add-menu-panel-attached">
2479
+ <div if="showMarkerAddMenuChips">
2480
+ <div class="add-page-plugins-zone-title">Add Menu on this marker</div>
1342
2481
  <div class="add-page-plugin-chips">
1343
- <span class="add-page-plugin-chip" forEach="markerBindingChips" trackBy="rowKey">{label}<button type="button" class="add-page-plugin-chip-remove" data-marker-remove-binding="1" data-plugin="{pluginName}" data-contract="{contractName}" title="Remove from marker">×</button></span>
2482
+ <span class="add-page-plugin-chip" forEach="markerAddMenuChips" trackBy="rowKey">{title}<span class="add-page-plugin-chip-sub">{subtitle}</span><button type="button" class="add-page-plugin-chip-remove" data-marker-add-menu-remove="1" data-item-id="{itemId}" title="Remove">×</button></span>
1344
2483
  </div>
1345
2484
  </div>
1346
- <p class="add-page-hint" if="showMarkerBindingEmptyHint">No components yet pick a plugin below and click Add for each component you need.</p>
1347
- <div class="add-page-plugins-zone-title">Add component</div>
1348
- <label class="add-page-hint">Plugin
1349
- <select class="annotation-binding-plugin">
1350
- <option value="">— Select plugin —</option>
1351
- <option forEach="markerPluginOptions" trackBy="rowKey" value="{value}">{label}</option>
1352
- </select>
1353
- </label>
1354
- <button type="button" class="add-page-manage-link" data-marker-manage-plugins="1">Manage plugins…</button>
1355
- <div if="showMarkerContractPicker">
1356
- <p class="add-page-hint">{markerPickerPluginLabel}</p>
1357
- <div class="add-page-plugin-contract">
1358
- <div class="add-page-plugin-contract-row" forEach="markerContractPickerRows" trackBy="rowKey">
1359
- <span class="add-page-plugin-contract-name">{contractName}</span>
1360
- <button type="button" class="add-page-plugin-btn" if="!onPage" data-marker-add-contract="1" data-plugin="{pluginName}" data-package="{packageName}" data-contract="{contractName}" data-key="{componentKey}">Add</button>
1361
- <span class="add-page-plugin-contract-added" if="onPage">Added</span>
2485
+ <p class="add-page-hint" if="showMarkerAddMenuEmptyHint">No resources attached on this marker click + Add to pick from the catalog.</p>
2486
+ <button type="button" class="add-page-btn add-page-btn-cancel" data-marker-add-menu-open="1">+ Add</button>
2487
+ <button type="button" class="add-page-manage-link" data-marker-add-menu-manage="1">Manage plugins…</button>
2488
+ <p class="add-page-field-error" if="crAddMenuParamCollisionWarning">{crAddMenuParamCollisionWarning}</p>
2489
+ <p class="add-page-hint" if="crAddMenuRouteParamHint">{crAddMenuRouteParamHint}</p>
2490
+ <div class="add-menu-route-params" if="showCrAddMenuRouteParams">
2491
+ <span class="add-page-hint">Route params:</span>
2492
+ <button type="button" class="add-page-param-btn" forEach="crAddMenuRouteParamRows" trackBy="rowKey" data-cr-route-param="1" data-param="{name}">[{name}]</button>
2493
+ </div>
2494
+ <div class="add-page-suggested-route" if="showCrPlannedRoutePanel">
2495
+ <div class="add-page-section-label">Planned page route</div>
2496
+ <input type="text" class="add-page-route-input cr-planned-route-input" value="{crPlannedRoute}" placeholder="/products/[slug]" />
2497
+ </div>
2498
+ <div class="add-menu-route-confirm" if="showCrRouteParamConfirm">
2499
+ <p>Adding <strong>{crPendingRouteParamTitle}</strong> requires a dynamic route. Files change only after the agent completes the task.</p>
2500
+ <button type="button" class="add-page-btn add-page-btn-primary" data-cr-route-param-confirm="1">Add anyway</button>
2501
+ <button type="button" class="add-page-btn add-page-btn-cancel" data-cr-route-param-cancel="1">Cancel</button>
2502
+ </div>
2503
+ </div>
2504
+ <div class="add-menu-popover" if="showAddMenuItemPicker">
2505
+ <div class="add-menu-popover-header">
2506
+ <span if="!addMenuSelectedCategory">Pick a category</span>
2507
+ <span if="addMenuSelectedCategory">Pick an item</span>
2508
+ <button type="button" data-marker-add-menu-close="1">×</button>
2509
+ </div>
2510
+ <p class="add-page-hint" if="showMarkerPickerLoading">Loading catalog…</p>
2511
+ <p class="add-page-hint" if="showMarkerPickerCatalogEmpty">Add Menu catalog is empty. Run <code>yarn setup ui-kit --force</code> (and other plugins) in the project, then click + Add again.</p>
2512
+ <div class="add-menu-nav">
2513
+ <div class="add-menu-nav-row" forEach="markerPickerNavRows" trackBy="rowKey">
2514
+ <button type="button" class="add-menu-nav-btn" if="kind===category" data-marker-add-menu-category="1" data-category="{value}">{label}</button>
2515
+ <button type="button" class="add-menu-nav-btn" if="kind===subCategory" data-marker-add-menu-subcategory="1" data-subcategory="{value}">{label}</button>
2516
+ <button type="button" class="add-menu-item-btn" if="kind===item" data-marker-add-menu-pick="1" data-item-id="{value}">{label}</button>
1362
2517
  </div>
1363
2518
  </div>
1364
2519
  </div>
@@ -1461,7 +2616,7 @@ data:
1461
2616
  <svg class="arrow-svg" if="hasSnapshotArrowLines" viewBox="0 0 100 100" preserveAspectRatio="none">
1462
2617
  <defs>
1463
2618
  <marker id="aiditor-snapshot-arrowhead" markerWidth="8" markerHeight="8" refX="6" refY="4" orient="auto">
1464
- <polygon points="0 0, 8 4, 0 8" fill="#c586ff" />
2619
+ <polygon points="0 0, 8 4, 0 8" fill="#116dff" />
1465
2620
  </marker>
1466
2621
  </defs>
1467
2622
  <line
@@ -1500,31 +2655,48 @@ data:
1500
2655
  data-annotation-id="{id}"
1501
2656
  value="{instruction}"
1502
2657
  ></textarea>
1503
- <div class="annotation-binding">
1504
- <button type="button" class="annotation-binding-toggle">Components (optional)</button>
1505
- <div class="annotation-binding-panel" if="showBindingControls">
1506
- <div if="showMarkerHasBindingChips">
1507
- <div class="add-page-plugins-zone-title">Components on this marker</div>
2658
+ <div class="annotation-add-menu">
2659
+ <button type="button" class="annotation-add-menu-toggle">Add Menu (optional)</button>
2660
+ <div class="annotation-add-menu-panel add-menu-panel" if="showAddMenuControls">
2661
+ <div class="add-menu-panel-attached">
2662
+ <div if="showMarkerAddMenuChips">
2663
+ <div class="add-page-plugins-zone-title">Add Menu on this marker</div>
1508
2664
  <div class="add-page-plugin-chips">
1509
- <span class="add-page-plugin-chip" forEach="markerBindingChips" trackBy="rowKey">{label}<button type="button" class="add-page-plugin-chip-remove" data-marker-remove-binding="1" data-plugin="{pluginName}" data-contract="{contractName}" title="Remove from marker">×</button></span>
2665
+ <span class="add-page-plugin-chip" forEach="markerAddMenuChips" trackBy="rowKey">{title}<span class="add-page-plugin-chip-sub">{subtitle}</span><button type="button" class="add-page-plugin-chip-remove" data-marker-add-menu-remove="1" data-item-id="{itemId}" title="Remove">×</button></span>
1510
2666
  </div>
1511
2667
  </div>
1512
- <p class="add-page-hint" if="showMarkerBindingEmptyHint">No components yet pick a plugin below and click Add for each component you need.</p>
1513
- <div class="add-page-plugins-zone-title">Add component</div>
1514
- <label class="add-page-hint">Plugin
1515
- <select class="annotation-binding-plugin">
1516
- <option value="">— Select plugin —</option>
1517
- <option forEach="markerPluginOptions" trackBy="rowKey" value="{value}">{label}</option>
1518
- </select>
1519
- </label>
1520
- <button type="button" class="add-page-manage-link" data-marker-manage-plugins="1">Manage plugins…</button>
1521
- <div if="showMarkerContractPicker">
1522
- <p class="add-page-hint">{markerPickerPluginLabel}</p>
1523
- <div class="add-page-plugin-contract">
1524
- <div class="add-page-plugin-contract-row" forEach="markerContractPickerRows" trackBy="rowKey">
1525
- <span class="add-page-plugin-contract-name">{contractName}</span>
1526
- <button type="button" class="add-page-plugin-btn" if="!onPage" data-marker-add-contract="1" data-plugin="{pluginName}" data-package="{packageName}" data-contract="{contractName}" data-key="{componentKey}">Add</button>
1527
- <span class="add-page-plugin-contract-added" if="onPage">Added</span>
2668
+ <p class="add-page-hint" if="showMarkerAddMenuEmptyHint">No resources attached on this marker click + Add to pick from the catalog.</p>
2669
+ <button type="button" class="add-page-btn add-page-btn-cancel" data-marker-add-menu-open="1">+ Add</button>
2670
+ <button type="button" class="add-page-manage-link" data-marker-add-menu-manage="1">Manage plugins…</button>
2671
+ <p class="add-page-field-error" if="crAddMenuParamCollisionWarning">{crAddMenuParamCollisionWarning}</p>
2672
+ <p class="add-page-hint" if="crAddMenuRouteParamHint">{crAddMenuRouteParamHint}</p>
2673
+ <div class="add-menu-route-params" if="showCrAddMenuRouteParams">
2674
+ <span class="add-page-hint">Route params:</span>
2675
+ <button type="button" class="add-page-param-btn" forEach="crAddMenuRouteParamRows" trackBy="rowKey" data-cr-route-param="1" data-param="{name}">[{name}]</button>
2676
+ </div>
2677
+ <div class="add-page-suggested-route" if="showCrPlannedRoutePanel">
2678
+ <div class="add-page-section-label">Planned page route</div>
2679
+ <input type="text" class="add-page-route-input cr-planned-route-input" value="{crPlannedRoute}" placeholder="/products/[slug]" />
2680
+ </div>
2681
+ <div class="add-menu-route-confirm" if="showCrRouteParamConfirm">
2682
+ <p>Adding <strong>{crPendingRouteParamTitle}</strong> requires a dynamic route. Files change only after the agent completes the task.</p>
2683
+ <button type="button" class="add-page-btn add-page-btn-primary" data-cr-route-param-confirm="1">Add anyway</button>
2684
+ <button type="button" class="add-page-btn add-page-btn-cancel" data-cr-route-param-cancel="1">Cancel</button>
2685
+ </div>
2686
+ </div>
2687
+ <div class="add-menu-popover" if="showAddMenuItemPicker">
2688
+ <div class="add-menu-popover-header">
2689
+ <span if="!addMenuSelectedCategory">Pick a category</span>
2690
+ <span if="addMenuSelectedCategory">Pick an item</span>
2691
+ <button type="button" data-marker-add-menu-close="1">×</button>
2692
+ </div>
2693
+ <p class="add-page-hint" if="showMarkerPickerLoading">Loading catalog…</p>
2694
+ <p class="add-page-hint" if="showMarkerPickerCatalogEmpty">Add Menu catalog is empty. Run <code>yarn setup ui-kit --force</code> (and other plugins) in the project, then click + Add again.</p>
2695
+ <div class="add-menu-nav">
2696
+ <div class="add-menu-nav-row" forEach="markerPickerNavRows" trackBy="rowKey">
2697
+ <button type="button" class="add-menu-nav-btn" if="kind===category" data-marker-add-menu-category="1" data-category="{value}">{label}</button>
2698
+ <button type="button" class="add-menu-nav-btn" if="kind===subCategory" data-marker-add-menu-subcategory="1" data-subcategory="{value}">{label}</button>
2699
+ <button type="button" class="add-menu-item-btn" if="kind===item" data-marker-add-menu-pick="1" data-item-id="{value}">{label}</button>
1528
2700
  </div>
1529
2701
  </div>
1530
2702
  </div>