@erd-studio/renderer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/LICENSE +167 -0
  2. package/README.md +132 -0
  3. package/dist/chunk-3PJCC7BX.js +5049 -0
  4. package/dist/chunk-6XQXDZ4R.js +0 -0
  5. package/dist/chunk-HOQPSLHQ.js +90 -0
  6. package/dist/chunk-QZGU5NZH.js +0 -0
  7. package/dist/chunk-WOTSQZCQ.js +151 -0
  8. package/dist/editor.js +124 -0
  9. package/dist/index.js +16 -0
  10. package/dist/sizing.js +16 -0
  11. package/dist/store.js +15 -0
  12. package/dist/styles.css +2963 -0
  13. package/dist/types/ErdCanvas.d.ts +54 -0
  14. package/dist/types/canvas/CanvasBackdrop.d.ts +7 -0
  15. package/dist/types/canvas/flowTypes.d.ts +10 -0
  16. package/dist/types/canvas/useCanvasGraph.d.ts +37 -0
  17. package/dist/types/components/DetailPanel/BulkColumnActions.d.ts +15 -0
  18. package/dist/types/components/DetailPanel/ColumnEditor.d.ts +19 -0
  19. package/dist/types/components/DetailPanel/DescriptionEditor.d.ts +16 -0
  20. package/dist/types/components/DetailPanel/DetailPanel.d.ts +10 -0
  21. package/dist/types/components/DetailPanel/GrainEditor.d.ts +16 -0
  22. package/dist/types/components/DetailPanel/ModelRationale.d.ts +27 -0
  23. package/dist/types/components/DetailPanel/RationaleField.d.ts +28 -0
  24. package/dist/types/components/DetailPanel/RoleEditor.d.ts +13 -0
  25. package/dist/types/components/Graph/AnnotationEdge.d.ts +11 -0
  26. package/dist/types/components/Graph/AnnotationNode.d.ts +18 -0
  27. package/dist/types/components/Graph/ColumnTooltip.d.ts +25 -0
  28. package/dist/types/components/Graph/FkEdge.d.ts +21 -0
  29. package/dist/types/components/Graph/HoverTip.d.ts +47 -0
  30. package/dist/types/components/Graph/ModelNode.d.ts +21 -0
  31. package/dist/types/components/Legend/Legend.d.ts +11 -0
  32. package/dist/types/components/common/ColumnRowEditor.d.ts +75 -0
  33. package/dist/types/components/common/DataTypeSelect.d.ts +20 -0
  34. package/dist/types/components/common/KeyBadge.d.ts +16 -0
  35. package/dist/types/components/common/KeyBadgeGroup.d.ts +20 -0
  36. package/dist/types/editor.d.ts +27 -0
  37. package/dist/types/hooks/useColumnExpansion.d.ts +36 -0
  38. package/dist/types/hooks/useColumnReorder.d.ts +36 -0
  39. package/dist/types/hooks/useFocusWithinRow.d.ts +23 -0
  40. package/dist/types/hooks/useLongPressDrag.d.ts +31 -0
  41. package/dist/types/host/canvasEnvironment.d.ts +36 -0
  42. package/dist/types/index.d.ts +5 -0
  43. package/dist/types/lib/annotationColors.d.ts +13 -0
  44. package/dist/types/lib/badgeLabels.d.ts +63 -0
  45. package/dist/types/lib/cardinalityUtils.d.ts +14 -0
  46. package/dist/types/lib/dataTypeColors.d.ts +15 -0
  47. package/dist/types/lib/dragHandleSides.d.ts +27 -0
  48. package/dist/types/lib/edgeDistribution.d.ts +165 -0
  49. package/dist/types/lib/graphTransformer.d.ts +65 -0
  50. package/dist/types/lib/nodeOverlays.d.ts +41 -0
  51. package/dist/types/lib/nodeSizing.d.ts +50 -0
  52. package/dist/types/lib/stageColors.d.ts +16 -0
  53. package/dist/types/sizing.d.ts +1 -0
  54. package/dist/types/store/editorStore.d.ts +185 -0
  55. package/dist/types/store.d.ts +2 -0
  56. package/dist/types/types/graph.d.ts +145 -0
  57. package/package.json +72 -0
@@ -0,0 +1,2963 @@
1
+ @import "@xyflow/react/dist/style.css";
2
+
3
+ /* src/components/common/KeyBadge.css */
4
+ .key-badge {
5
+ display: inline-block;
6
+ padding: 0 3px;
7
+ border-radius: 2px;
8
+ font-size: 9px;
9
+ font-weight: 700;
10
+ line-height: 1.5;
11
+ letter-spacing: 0.3px;
12
+ transition:
13
+ opacity 0.15s ease,
14
+ background 0.15s ease,
15
+ color 0.15s ease;
16
+ }
17
+ .key-badge--clickable {
18
+ cursor: pointer;
19
+ user-select: none;
20
+ }
21
+ .key-badge--clickable:hover {
22
+ filter: brightness(1.15);
23
+ }
24
+ .key-badge--clickable:focus {
25
+ outline: 2px solid var(--focus-border);
26
+ outline-offset: 1px;
27
+ }
28
+ .key-badge--inactive {
29
+ opacity: 0.3;
30
+ background: rgba(128, 128, 128, 0.15);
31
+ color: var(--vscode-descriptionForeground, #888);
32
+ }
33
+ .key-badge--inactive:hover {
34
+ opacity: 0.6;
35
+ }
36
+ .key-badge--active {
37
+ opacity: 1;
38
+ }
39
+ .key-badge--pk.key-badge--active {
40
+ background: rgba(234, 179, 8, 0.2);
41
+ color: #ca8a04;
42
+ }
43
+ .key-badge--fk.key-badge--active {
44
+ background: rgba(59, 130, 246, 0.2);
45
+ color: #3b82f6;
46
+ }
47
+ .key-badge--nk.key-badge--active {
48
+ background: rgba(168, 85, 247, 0.2);
49
+ color: #a855f7;
50
+ }
51
+ .key-badge--planned.key-badge--active,
52
+ .key-badge--missing.key-badge--active {
53
+ opacity: 0.85;
54
+ }
55
+
56
+ /* src/components/common/DataTypeSelect.css */
57
+ .data-type-select {
58
+ position: relative;
59
+ display: inline-block;
60
+ }
61
+ .data-type-select--disabled {
62
+ opacity: 0.6;
63
+ pointer-events: none;
64
+ }
65
+ .data-type-select__trigger {
66
+ display: flex;
67
+ align-items: center;
68
+ gap: 4px;
69
+ padding: 2px 6px;
70
+ border: 1px solid var(--input-border, var(--panel-border));
71
+ border-radius: 2px;
72
+ background: var(--input-bg);
73
+ color: var(--input-fg, var(--editor-fg));
74
+ font-family: var(--vscode-editor-font-family, monospace);
75
+ font-size: 11px;
76
+ cursor: pointer;
77
+ min-width: 70px;
78
+ text-align: left;
79
+ }
80
+ .data-type-select__trigger:hover {
81
+ background: var(--vscode-list-hoverBackground, rgba(255, 255, 255, 0.05));
82
+ }
83
+ .data-type-select__trigger:focus {
84
+ outline: 1px solid var(--focus-border);
85
+ outline-offset: -1px;
86
+ border-color: var(--focus-border);
87
+ }
88
+ .data-type-select--open .data-type-select__trigger {
89
+ border-color: var(--focus-border);
90
+ }
91
+ .data-type-select__value {
92
+ flex: 1;
93
+ }
94
+ .data-type-select__arrow {
95
+ font-size: 10px;
96
+ color: var(--vscode-descriptionForeground, #888);
97
+ }
98
+ .data-type-select__dropdown {
99
+ position: fixed;
100
+ margin: 2px 0 0 0;
101
+ padding: 2px 0;
102
+ list-style: none;
103
+ background: var(--vscode-dropdown-background, var(--panel-bg));
104
+ border: 1px solid var(--vscode-dropdown-border, var(--panel-border));
105
+ border-radius: 3px;
106
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
107
+ z-index: 9999;
108
+ max-height: 200px;
109
+ overflow-y: auto;
110
+ min-width: 90px;
111
+ }
112
+ .data-type-select__dropdown:focus {
113
+ outline: none;
114
+ }
115
+ .data-type-select__option {
116
+ padding: 4px 8px;
117
+ font-family: var(--vscode-editor-font-family, monospace);
118
+ font-size: 11px;
119
+ color: var(--vscode-dropdown-foreground, var(--editor-fg));
120
+ cursor: pointer;
121
+ }
122
+ .data-type-select__option:hover,
123
+ .data-type-select__option:focus {
124
+ background: var(--vscode-list-hoverBackground, rgba(255, 255, 255, 0.1));
125
+ outline: none;
126
+ }
127
+ .data-type-select__option--selected {
128
+ background: var(--vscode-list-activeSelectionBackground, rgba(0, 120, 212, 0.3));
129
+ color: var(--vscode-list-activeSelectionForeground, var(--editor-fg));
130
+ }
131
+ .data-type-select__option--selected:hover,
132
+ .data-type-select__option--selected:focus {
133
+ background: var(--vscode-list-activeSelectionBackground, rgba(0, 120, 212, 0.4));
134
+ }
135
+
136
+ /* src/components/Graph/ColumnTooltip.css */
137
+ .column-tooltip {
138
+ position: fixed;
139
+ z-index: 10000;
140
+ min-width: 260px;
141
+ max-width: 420px;
142
+ padding: 10px 14px;
143
+ background: var(--vscode-editorHoverWidget-background, var(--panel-bg, #252526));
144
+ border: 1px solid var(--vscode-editorHoverWidget-border, var(--panel-border, #454545));
145
+ border-radius: 6px;
146
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
147
+ font-size: 13px;
148
+ line-height: 1.5;
149
+ color: var(--vscode-editorHoverWidget-foreground, var(--editor-fg, #d4d4d4));
150
+ pointer-events: none;
151
+ opacity: 0;
152
+ white-space: normal;
153
+ word-wrap: break-word;
154
+ transition: opacity 0.12s ease;
155
+ }
156
+ .column-tooltip--visible {
157
+ opacity: 1;
158
+ }
159
+ .column-tooltip::after {
160
+ content: "";
161
+ position: absolute;
162
+ top: 100%;
163
+ left: 50%;
164
+ transform: translateX(-50%);
165
+ border: 5px solid transparent;
166
+ border-top-color: var(--vscode-editorHoverWidget-border, var(--panel-border, #454545));
167
+ }
168
+ .column-tooltip--flipped::after {
169
+ top: auto;
170
+ bottom: 100%;
171
+ border-top-color: transparent;
172
+ border-bottom-color: var(--vscode-editorHoverWidget-border, var(--panel-border, #454545));
173
+ }
174
+ .column-tooltip__header {
175
+ display: flex;
176
+ align-items: baseline;
177
+ gap: 8px;
178
+ margin-bottom: 6px;
179
+ }
180
+ .column-tooltip__name {
181
+ font-weight: 600;
182
+ font-size: 13px;
183
+ flex: 1;
184
+ overflow: hidden;
185
+ text-overflow: ellipsis;
186
+ }
187
+ .column-tooltip__type {
188
+ flex-shrink: 0;
189
+ font-family: var(--vscode-editor-font-family, monospace);
190
+ font-size: 12px;
191
+ color: var(--vscode-descriptionForeground, #888);
192
+ }
193
+ .column-tooltip__description {
194
+ padding: 6px 0;
195
+ border-top: 1px solid var(--vscode-editorHoverWidget-border, var(--panel-border, #454545));
196
+ color: var(--vscode-editorHoverWidget-foreground, var(--editor-fg, #d4d4d4));
197
+ font-size: 13px;
198
+ }
199
+ .column-tooltip__details {
200
+ padding-top: 6px;
201
+ border-top: 1px solid var(--vscode-editorHoverWidget-border, var(--panel-border, #454545));
202
+ display: flex;
203
+ flex-direction: column;
204
+ gap: 4px;
205
+ }
206
+ .column-tooltip__row {
207
+ display: flex;
208
+ gap: 10px;
209
+ }
210
+ .column-tooltip__label {
211
+ flex-shrink: 0;
212
+ font-weight: 600;
213
+ font-size: 11px;
214
+ text-transform: uppercase;
215
+ letter-spacing: 0.3px;
216
+ color: var(--vscode-descriptionForeground, #888);
217
+ min-width: 52px;
218
+ }
219
+ .column-tooltip__value {
220
+ font-size: 13px;
221
+ }
222
+
223
+ /* src/components/Graph/HoverTip.css */
224
+ .hover-tip {
225
+ position: fixed;
226
+ z-index: 10000;
227
+ max-width: 320px;
228
+ padding: 6px 10px;
229
+ background: var(--vscode-editorHoverWidget-background, var(--panel-bg, #252526));
230
+ border: 1px solid var(--vscode-editorHoverWidget-border, var(--panel-border, #454545));
231
+ border-radius: 5px;
232
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
233
+ font-size: 12px;
234
+ line-height: 1.45;
235
+ color: var(--vscode-editorHoverWidget-foreground, var(--editor-fg, #d4d4d4));
236
+ pointer-events: none;
237
+ opacity: 0;
238
+ white-space: normal;
239
+ word-wrap: break-word;
240
+ transition: opacity 0.12s ease;
241
+ }
242
+ .hover-tip--visible {
243
+ opacity: 1;
244
+ }
245
+
246
+ /* src/components/Graph/ModelNode.css */
247
+ .model-node {
248
+ width: max-content;
249
+ min-width: 200px;
250
+ max-width: 480px;
251
+ background: var(--editor-bg);
252
+ border: 2px solid var(--panel-border);
253
+ border-radius: 6px;
254
+ font-size: 12px;
255
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
256
+ overflow: hidden;
257
+ }
258
+ .model-node--logical {
259
+ border-color: var(--stage-logical);
260
+ }
261
+ .model-node--physical {
262
+ border-color: var(--stage-physical);
263
+ }
264
+ .model-node--ghost {
265
+ border-color: var(--stage-ghost);
266
+ border-style: dashed;
267
+ opacity: 0.65;
268
+ }
269
+ .model-node--ghost-disabled {
270
+ border-style: dotted;
271
+ }
272
+ .model-node--disc-extra {
273
+ box-shadow: 0 0 0 2px var(--discrepancy-extra), 0 0 12px 2px rgba(245, 158, 11, 0.35);
274
+ }
275
+ .model-node--selected {
276
+ box-shadow: 0 0 0 2px var(--stage-logical), 0 0 10px 1px rgba(96, 165, 250, 0.4);
277
+ }
278
+ .model-node--physical.model-node--selected {
279
+ box-shadow: 0 0 0 2px var(--stage-physical), 0 0 10px 1px rgba(34, 197, 94, 0.4);
280
+ }
281
+ .model-node--disc-extra.model-node--selected {
282
+ box-shadow: 0 0 0 2px var(--discrepancy-extra), 0 0 12px 2px rgba(245, 158, 11, 0.35);
283
+ }
284
+ .model-node--dimmed {
285
+ opacity: 0.25;
286
+ filter: grayscale(0.4);
287
+ transition: opacity 0.15s ease, filter 0.15s ease;
288
+ }
289
+ .model-node--dimmed:hover {
290
+ opacity: 0.4;
291
+ }
292
+ .model-node--ghost.model-node--dimmed {
293
+ opacity: 0.3;
294
+ }
295
+ .model-node__header {
296
+ display: flex;
297
+ align-items: center;
298
+ gap: 8px;
299
+ padding: 6px 10px;
300
+ background: var(--panel-bg);
301
+ border-bottom: 1px solid var(--panel-border);
302
+ font-weight: 600;
303
+ line-height: 1.3;
304
+ }
305
+ .model-node__name {
306
+ flex: 1;
307
+ white-space: nowrap;
308
+ }
309
+ .model-node__badge {
310
+ flex-shrink: 0;
311
+ padding: 1px 5px;
312
+ border-radius: 3px;
313
+ font-size: 10px;
314
+ font-weight: 700;
315
+ letter-spacing: 0.5px;
316
+ background: var(--button-bg);
317
+ color: var(--button-fg);
318
+ }
319
+ .model-node__source {
320
+ flex-shrink: 0;
321
+ padding: 1px 5px;
322
+ border-radius: 3px;
323
+ font-size: 9px;
324
+ font-weight: 700;
325
+ letter-spacing: 0.3px;
326
+ background: var(--dim-fg);
327
+ color: var(--editor-bg);
328
+ }
329
+ .model-node__source--catalog {
330
+ background: var(--ok-bg);
331
+ color: var(--ok-fg);
332
+ }
333
+ .model-node__badge--layer {
334
+ opacity: 0.7;
335
+ font-style: italic;
336
+ }
337
+ .model-node__discrepancy-badge {
338
+ flex-shrink: 0;
339
+ display: inline-flex;
340
+ align-items: center;
341
+ gap: 2px;
342
+ padding: 1px 5px;
343
+ border-radius: 3px;
344
+ font-size: 10px;
345
+ font-weight: 700;
346
+ background: rgba(204, 167, 0, 0.2);
347
+ color: var(--vscode-editorWarning-foreground, #cca700);
348
+ }
349
+ .model-node__rationale-badge {
350
+ flex-shrink: 0;
351
+ padding: 1px 5px;
352
+ border-radius: 3px;
353
+ font-size: 9px;
354
+ font-weight: 700;
355
+ letter-spacing: 0.3px;
356
+ background: rgba(139, 92, 246, 0.2);
357
+ color: #8b5cf6;
358
+ }
359
+ .model-node__role-badge {
360
+ flex-shrink: 0;
361
+ padding: 1px 5px;
362
+ border-radius: 3px;
363
+ font-size: 9px;
364
+ font-weight: 700;
365
+ letter-spacing: 0.3px;
366
+ }
367
+ .model-node__grain {
368
+ padding: 1px 10px 4px;
369
+ font-size: 10px;
370
+ font-weight: 400;
371
+ line-height: 1.3;
372
+ color: var(--editor-fg);
373
+ opacity: 0.6;
374
+ overflow: hidden;
375
+ text-overflow: ellipsis;
376
+ white-space: nowrap;
377
+ border-bottom: 1px solid var(--panel-border);
378
+ }
379
+ .model-node__columns {
380
+ padding: 2px 0;
381
+ }
382
+ .model-node__column {
383
+ position: relative;
384
+ display: flex;
385
+ align-items: center;
386
+ gap: 6px;
387
+ padding: 3px 10px;
388
+ line-height: 1.4;
389
+ cursor: grab;
390
+ user-select: none;
391
+ transition: box-shadow 0.15s ease, filter 0.15s ease;
392
+ }
393
+ .model-node__column:hover {
394
+ background: var(--selection-bg);
395
+ }
396
+ .model-node__column--pressing {
397
+ cursor: grabbing;
398
+ animation: column-press-pulse 0.4s ease-in-out infinite;
399
+ }
400
+ @keyframes column-press-pulse {
401
+ 0%, 100% {
402
+ box-shadow: inset 0 0 0 2px var(--focus-border);
403
+ filter: brightness(1.15);
404
+ }
405
+ 50% {
406
+ box-shadow: inset 0 0 0 2px var(--focus-border), 0 0 8px 2px var(--focus-border);
407
+ filter: brightness(1.25);
408
+ }
409
+ }
410
+ .model-node__column--dragging {
411
+ cursor: grabbing;
412
+ opacity: 0.6;
413
+ box-shadow: inset 0 0 0 2px var(--focus-border);
414
+ }
415
+ .model-node__column--drop-target {
416
+ background: rgba(0, 127, 212, 0.18) !important;
417
+ box-shadow: inset 0 0 0 2px var(--focus-border), 0 0 10px 2px rgba(0, 127, 212, 0.35);
418
+ filter: brightness(1.2);
419
+ cursor: crosshair;
420
+ transition: box-shadow 0.1s ease, background 0.1s ease;
421
+ }
422
+ .model-node__column--relationship-highlight {
423
+ background: var(--selection-bg) !important;
424
+ box-shadow: inset 0 0 0 1.5px var(--focus-border), 0 0 6px 1px rgba(0, 127, 212, 0.25);
425
+ filter: brightness(1.15);
426
+ transition:
427
+ box-shadow 0.15s ease,
428
+ background 0.15s ease,
429
+ filter 0.15s ease;
430
+ }
431
+ .model-node__column--disc-extra {
432
+ background: rgba(245, 158, 11, 0.1);
433
+ border-left: 2px solid var(--discrepancy-extra);
434
+ }
435
+ .model-node__column--disc-mismatch {
436
+ background: rgba(239, 68, 68, 0.08);
437
+ border-left: 2px solid var(--discrepancy-mismatch);
438
+ }
439
+ .model-node__column--disc-missing {
440
+ opacity: 0.45;
441
+ cursor: default;
442
+ font-style: italic;
443
+ }
444
+ .model-node__column--disc-missing .model-node__col-name {
445
+ text-decoration: line-through;
446
+ color: var(--stage-ghost);
447
+ }
448
+ .model-node__col-disc-badge {
449
+ flex-shrink: 0;
450
+ padding: 0 4px;
451
+ border-radius: 3px;
452
+ font-size: 9px;
453
+ font-weight: 600;
454
+ text-transform: uppercase;
455
+ letter-spacing: 0.3px;
456
+ }
457
+ .model-node__col-disc-badge--extra {
458
+ background: rgba(245, 158, 11, 0.2);
459
+ color: var(--discrepancy-extra);
460
+ }
461
+ .model-node__col-disc-badge--missing {
462
+ background: rgba(156, 163, 175, 0.2);
463
+ color: var(--stage-ghost);
464
+ }
465
+ .model-node__col-type--mismatch {
466
+ display: flex;
467
+ flex-direction: column;
468
+ gap: 1px;
469
+ font-size: 10px;
470
+ line-height: 1.3;
471
+ }
472
+ .model-node__col-type-line {
473
+ display: flex;
474
+ align-items: baseline;
475
+ gap: 3px;
476
+ white-space: nowrap;
477
+ }
478
+ .model-node__col-type-stage {
479
+ font-size: 9px;
480
+ opacity: 0.7;
481
+ text-transform: capitalize;
482
+ }
483
+ .model-node__separator {
484
+ display: flex;
485
+ align-items: center;
486
+ gap: 8px;
487
+ padding: 4px 10px;
488
+ margin: 2px 0;
489
+ border-top: 1px dashed var(--warning-fg);
490
+ border-bottom: 1px dashed var(--warning-fg);
491
+ background: rgba(204, 167, 0, 0.08);
492
+ }
493
+ .model-node__separator-label {
494
+ font-size: 9px;
495
+ font-weight: 600;
496
+ text-transform: uppercase;
497
+ letter-spacing: 0.5px;
498
+ color: var(--warning-fg);
499
+ }
500
+ .model-node__separator--disc {
501
+ border-top: 1px dashed var(--stage-ghost);
502
+ border-bottom: 1px dashed var(--stage-ghost);
503
+ background: rgba(156, 163, 175, 0.06);
504
+ }
505
+ .model-node__separator-label--missing {
506
+ color: var(--stage-ghost);
507
+ }
508
+ .model-node__separator--subtle {
509
+ height: 1px;
510
+ padding: 0;
511
+ margin: 2px 0;
512
+ border-top: 1px solid var(--panel-border);
513
+ border-bottom: none;
514
+ background: transparent;
515
+ opacity: 0.6;
516
+ }
517
+ .model-node__col-indicators {
518
+ display: flex;
519
+ gap: 2px;
520
+ flex-shrink: 0;
521
+ }
522
+ .model-node__col-name {
523
+ flex: 1;
524
+ white-space: nowrap;
525
+ }
526
+ .model-node__col-name--editable:hover,
527
+ .model-node__col-type--editable:hover {
528
+ text-decoration: underline dotted;
529
+ cursor: text;
530
+ }
531
+ .model-node__col-type {
532
+ flex-shrink: 0;
533
+ color: var(--vscode-descriptionForeground, #888);
534
+ font-size: 11px;
535
+ font-family: var(--vscode-editor-font-family, monospace);
536
+ }
537
+ .model-node__col-edit-input {
538
+ min-width: 0;
539
+ background: var(--vscode-input-background, #3c3c3c);
540
+ color: var(--vscode-input-foreground, #ccc);
541
+ border: 1px solid var(--vscode-focusBorder, #007fd4);
542
+ border-radius: 3px;
543
+ font-size: 12px;
544
+ font-family: inherit;
545
+ padding: 1px 4px;
546
+ outline: none;
547
+ line-height: 1.3;
548
+ }
549
+ .model-node__col-edit-input--name {
550
+ flex: 1;
551
+ }
552
+ .model-node__col-edit-input--type {
553
+ flex: 0 0 auto;
554
+ width: 80px;
555
+ font-size: 11px;
556
+ font-family: var(--vscode-editor-font-family, monospace);
557
+ }
558
+ .model-node__col-reorder-handle {
559
+ flex-shrink: 0;
560
+ cursor: grab;
561
+ color: var(--vscode-descriptionForeground, #888);
562
+ opacity: 0.3;
563
+ font-size: 10px;
564
+ user-select: none;
565
+ line-height: 1;
566
+ transition: opacity 0.1s ease;
567
+ padding: 4px 6px;
568
+ margin: -4px -2px -4px -6px;
569
+ }
570
+ .model-node__col-reorder-handle:hover {
571
+ opacity: 0.85;
572
+ }
573
+ .model-node__col-reorder-handle:active {
574
+ cursor: grabbing;
575
+ opacity: 1;
576
+ }
577
+ .model-node__column--reorder-dragging {
578
+ opacity: 0.35;
579
+ }
580
+ .model-node__column--reorder-target {
581
+ box-shadow: 0 -2px 0 0 var(--vscode-focusBorder, #007fd4);
582
+ }
583
+ .model-node__col-edit-error {
584
+ position: absolute;
585
+ bottom: -16px;
586
+ left: 10px;
587
+ font-size: 10px;
588
+ color: var(--vscode-errorForeground, #f48771);
589
+ white-space: nowrap;
590
+ z-index: 10;
591
+ background: var(--vscode-editor-background, #1e1e1e);
592
+ padding: 0 4px;
593
+ border-radius: 2px;
594
+ }
595
+ .model-node__col-delete {
596
+ flex-shrink: 0;
597
+ display: flex;
598
+ align-items: center;
599
+ justify-content: center;
600
+ width: 16px;
601
+ height: 16px;
602
+ padding: 0;
603
+ border: none;
604
+ border-radius: 3px;
605
+ background: rgba(239, 68, 68, 0.1);
606
+ color: #ef4444;
607
+ font-size: 13px;
608
+ line-height: 1;
609
+ cursor: pointer;
610
+ opacity: 0;
611
+ transition: opacity 0.1s ease, background 0.1s ease;
612
+ }
613
+ .model-node__column:hover .model-node__col-delete {
614
+ opacity: 1;
615
+ }
616
+ .model-node__col-delete:hover {
617
+ background: rgba(239, 68, 68, 0.25);
618
+ }
619
+ .model-node__col-badge {
620
+ flex-shrink: 0;
621
+ font-size: 9px;
622
+ line-height: 1;
623
+ opacity: 0.7;
624
+ }
625
+ .model-node__col-badge--scd {
626
+ color: #6366f1;
627
+ }
628
+ .model-node__col-badge--additive {
629
+ color: #e11d48;
630
+ }
631
+ .model-node__empty {
632
+ padding: 8px 10px;
633
+ color: var(--vscode-descriptionForeground, #888);
634
+ font-style: italic;
635
+ text-align: center;
636
+ }
637
+ .model-node__expand-button {
638
+ display: block;
639
+ width: 100%;
640
+ padding: 6px 10px;
641
+ margin: 0;
642
+ background: var(--panel-bg);
643
+ border: none;
644
+ border-top: 1px solid var(--panel-border);
645
+ color: var(--vscode-textLink-foreground, #3b82f6);
646
+ font-size: 11px;
647
+ font-weight: 500;
648
+ cursor: pointer;
649
+ text-align: center;
650
+ transition: background 0.15s ease, color 0.15s ease;
651
+ }
652
+ .model-node__expand-button:hover {
653
+ background: var(--selection-bg);
654
+ color: var(--vscode-textLink-activeForeground, #2563eb);
655
+ }
656
+ .model-node__expand-button:active {
657
+ background: var(--button-bg);
658
+ color: var(--button-fg);
659
+ }
660
+ .model-node__footer {
661
+ padding: 4px 10px;
662
+ border-top: 1px solid var(--panel-border);
663
+ background: var(--panel-bg);
664
+ text-align: center;
665
+ font-size: 11px;
666
+ color: var(--vscode-descriptionForeground, #888);
667
+ }
668
+ .model-node__footer-disc {
669
+ color: var(--discrepancy-extra);
670
+ font-weight: 500;
671
+ }
672
+ .react-flow__node.selected .model-node {
673
+ box-shadow: 0 0 0 2px var(--vscode-focusBorder, #007fd4), 0 2px 8px rgba(0, 127, 212, 0.3);
674
+ }
675
+ .react-flow__node.dragging .model-node {
676
+ opacity: 0.85;
677
+ box-shadow: 0 0 0 2px var(--vscode-focusBorder, #007fd4), 0 4px 12px rgba(0, 0, 0, 0.25);
678
+ }
679
+
680
+ /* src/components/Graph/FkEdge.css */
681
+ .fk-edge {
682
+ stroke-width: 2;
683
+ fill: none;
684
+ }
685
+ .fk-edge--logical {
686
+ stroke: var(--stage-logical);
687
+ }
688
+ .fk-edge--physical {
689
+ stroke: var(--stage-physical);
690
+ }
691
+ .fk-edge--ghost {
692
+ stroke: var(--stage-ghost);
693
+ stroke-dasharray: 5 3;
694
+ }
695
+ .fk-edge--discrepancy-extra {
696
+ stroke: var(--discrepancy-extra);
697
+ stroke-dasharray: 5 3;
698
+ }
699
+ .fk-edge--discrepancy-missing {
700
+ stroke: var(--stage-ghost);
701
+ stroke-dasharray: 5 3;
702
+ }
703
+ .fk-edge--discrepancy-cardinality-mismatch {
704
+ stroke: var(--discrepancy-mismatch);
705
+ }
706
+ .fk-edge--dimmed {
707
+ opacity: 0.25;
708
+ filter: grayscale(0.4);
709
+ transition: opacity 0.15s ease, filter 0.15s ease;
710
+ }
711
+ .fk-edge--dimmed:hover {
712
+ opacity: 0.4;
713
+ }
714
+ .fk-edge__label {
715
+ position: absolute;
716
+ pointer-events: none;
717
+ font-size: 14px;
718
+ font-weight: 700;
719
+ line-height: 1;
720
+ }
721
+ .fk-edge__label--many {
722
+ font-size: 22px;
723
+ }
724
+ .fk-edge__label--logical {
725
+ color: var(--stage-logical);
726
+ }
727
+ .fk-edge__label--physical {
728
+ color: var(--stage-physical);
729
+ }
730
+ .fk-edge__label--ghost {
731
+ color: var(--stage-ghost);
732
+ }
733
+ .fk-edge__label--discrepancy-extra {
734
+ color: var(--discrepancy-extra);
735
+ }
736
+ .fk-edge__label--discrepancy-missing {
737
+ color: var(--stage-ghost);
738
+ }
739
+ .fk-edge__label--discrepancy-cardinality-mismatch {
740
+ color: var(--discrepancy-mismatch);
741
+ }
742
+ .fk-edge__mismatch-badge {
743
+ position: absolute;
744
+ display: flex;
745
+ align-items: center;
746
+ justify-content: center;
747
+ width: 18px;
748
+ height: 18px;
749
+ border-radius: 50%;
750
+ background: var(--discrepancy-mismatch);
751
+ color: #fff;
752
+ font-size: 11px;
753
+ font-weight: 700;
754
+ pointer-events: none;
755
+ box-shadow: 0 1px 4px rgba(239, 68, 68, 0.4);
756
+ }
757
+ .fk-edge__label--dimmed {
758
+ opacity: 0.25;
759
+ filter: grayscale(0.4);
760
+ transition: opacity 0.15s ease, filter 0.15s ease;
761
+ }
762
+ .fk-edge:hover {
763
+ stroke-width: 3;
764
+ }
765
+ .fk-edge__swap-zone {
766
+ position: absolute;
767
+ width: 28px;
768
+ height: 28px;
769
+ display: flex;
770
+ align-items: center;
771
+ justify-content: center;
772
+ pointer-events: all;
773
+ }
774
+ .fk-edge__swap-zone--dimmed {
775
+ display: none;
776
+ }
777
+ .fk-edge__swap-btn {
778
+ display: flex;
779
+ align-items: center;
780
+ justify-content: center;
781
+ width: 22px;
782
+ height: 22px;
783
+ padding: 0;
784
+ border: 1px solid var(--panel-border);
785
+ border-radius: 4px;
786
+ background: var(--panel-bg);
787
+ color: var(--editor-fg);
788
+ font-size: 13px;
789
+ line-height: 1;
790
+ cursor: pointer;
791
+ pointer-events: all;
792
+ opacity: 0.85;
793
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
794
+ transition:
795
+ opacity 0.1s ease,
796
+ border-color 0.1s ease,
797
+ background 0.1s ease;
798
+ }
799
+ .fk-edge__swap-btn:hover {
800
+ opacity: 1;
801
+ border-color: var(--focus-border);
802
+ background: var(--button-bg);
803
+ color: var(--button-fg);
804
+ }
805
+
806
+ /* src/components/Graph/AnnotationNode.css */
807
+ .annotation-node {
808
+ min-width: 160px;
809
+ min-height: 80px;
810
+ padding: 10px 12px;
811
+ border-radius: 4px;
812
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
813
+ font-size: 12px;
814
+ line-height: 1.4;
815
+ cursor: grab;
816
+ border-left: 4px solid transparent;
817
+ position: relative;
818
+ }
819
+ .annotation-node--yellow {
820
+ background: #fef3c7;
821
+ border-left-color: #f59e0b;
822
+ color: #78350f;
823
+ }
824
+ .annotation-node--blue {
825
+ background: #dbeafe;
826
+ border-left-color: #3b82f6;
827
+ color: #1e3a5f;
828
+ }
829
+ .annotation-node--green {
830
+ background: #dcfce7;
831
+ border-left-color: #22c55e;
832
+ color: #14532d;
833
+ }
834
+ .annotation-node--pink {
835
+ background: #fce7f3;
836
+ border-left-color: #ec4899;
837
+ color: #831843;
838
+ }
839
+ .annotation-node--orange {
840
+ background: #fed7aa;
841
+ border-left-color: #f97316;
842
+ color: #7c2d12;
843
+ }
844
+ body[data-vscode-theme-kind=vscode-dark] .annotation-node--yellow,
845
+ body[data-vscode-theme-kind=vscode-high-contrast] .annotation-node--yellow {
846
+ background: #422006;
847
+ color: #fcd34d;
848
+ }
849
+ body[data-vscode-theme-kind=vscode-dark] .annotation-node--blue,
850
+ body[data-vscode-theme-kind=vscode-high-contrast] .annotation-node--blue {
851
+ background: #172554;
852
+ color: #93c5fd;
853
+ }
854
+ body[data-vscode-theme-kind=vscode-dark] .annotation-node--green,
855
+ body[data-vscode-theme-kind=vscode-high-contrast] .annotation-node--green {
856
+ background: #052e16;
857
+ color: #86efac;
858
+ }
859
+ body[data-vscode-theme-kind=vscode-dark] .annotation-node--pink,
860
+ body[data-vscode-theme-kind=vscode-high-contrast] .annotation-node--pink {
861
+ background: #500724;
862
+ color: #f9a8d4;
863
+ }
864
+ body[data-vscode-theme-kind=vscode-dark] .annotation-node--orange,
865
+ body[data-vscode-theme-kind=vscode-high-contrast] .annotation-node--orange {
866
+ background: #431407;
867
+ color: #fdba74;
868
+ }
869
+ .annotation-node--selected {
870
+ outline: 2px solid var(--focus-border, #007fd4);
871
+ outline-offset: 1px;
872
+ }
873
+ .react-flow__node-annotation.selected .annotation-node {
874
+ box-shadow: none;
875
+ }
876
+ .annotation-node--readonly {
877
+ opacity: 0.85;
878
+ cursor: default;
879
+ }
880
+ .annotation-node__text {
881
+ white-space: pre-wrap;
882
+ word-break: break-word;
883
+ user-select: none;
884
+ }
885
+ .annotation-node__placeholder {
886
+ opacity: 0.5;
887
+ font-style: italic;
888
+ }
889
+ .annotation-node__textarea {
890
+ width: 100%;
891
+ min-height: 60px;
892
+ background: transparent;
893
+ border: none;
894
+ outline: none;
895
+ resize: vertical;
896
+ font-family: inherit;
897
+ font-size: inherit;
898
+ line-height: inherit;
899
+ color: inherit;
900
+ padding: 0;
901
+ margin: 0;
902
+ }
903
+ .annotation-node__toolbar {
904
+ position: absolute;
905
+ top: 4px;
906
+ right: 4px;
907
+ z-index: 2;
908
+ display: flex;
909
+ align-items: center;
910
+ gap: 2px;
911
+ }
912
+ .annotation-node__link-handle {
913
+ display: flex;
914
+ align-items: center;
915
+ justify-content: center;
916
+ width: 20px;
917
+ height: 20px;
918
+ border-radius: 3px;
919
+ font-size: 12px;
920
+ cursor: grab;
921
+ opacity: 0;
922
+ transition: opacity 0.15s ease, background 0.1s ease;
923
+ user-select: none;
924
+ }
925
+ .annotation-node:hover .annotation-node__link-handle {
926
+ opacity: 0.5;
927
+ }
928
+ .annotation-node__link-handle:hover {
929
+ opacity: 1 !important;
930
+ background: rgba(0, 0, 0, 0.1);
931
+ }
932
+ body[data-vscode-theme-kind=vscode-dark] .annotation-node__link-handle:hover {
933
+ background: rgba(255, 255, 255, 0.1);
934
+ }
935
+ .annotation-node__toolbar-toggle {
936
+ display: flex;
937
+ align-items: center;
938
+ justify-content: center;
939
+ width: 20px;
940
+ height: 20px;
941
+ border: none;
942
+ border-radius: 3px;
943
+ background: transparent;
944
+ color: inherit;
945
+ font-size: 14px;
946
+ cursor: pointer;
947
+ opacity: 0;
948
+ transition: opacity 0.15s ease, background 0.1s ease;
949
+ letter-spacing: 1px;
950
+ }
951
+ .annotation-node:hover .annotation-node__toolbar-toggle {
952
+ opacity: 0.6;
953
+ }
954
+ .annotation-node__toolbar-toggle:hover {
955
+ opacity: 1 !important;
956
+ background: rgba(0, 0, 0, 0.1);
957
+ }
958
+ body[data-vscode-theme-kind=vscode-dark] .annotation-node__toolbar-toggle:hover {
959
+ background: rgba(255, 255, 255, 0.1);
960
+ }
961
+ .annotation-node__toolbar-panel {
962
+ position: absolute;
963
+ top: 24px;
964
+ right: 0;
965
+ width: 150px;
966
+ background: var(--panel-bg, #252526);
967
+ border: 1px solid var(--panel-border, #404040);
968
+ border-radius: 6px;
969
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
970
+ padding: 6px;
971
+ display: flex;
972
+ flex-direction: column;
973
+ gap: 4px;
974
+ }
975
+ .annotation-node__color-row {
976
+ display: flex;
977
+ gap: 4px;
978
+ padding: 2px 0;
979
+ }
980
+ .annotation-node__color-swatch {
981
+ width: 18px;
982
+ height: 18px;
983
+ border: 2px solid transparent;
984
+ border-radius: 4px;
985
+ cursor: pointer;
986
+ padding: 0;
987
+ transition: border-color 0.15s ease, transform 0.1s ease;
988
+ }
989
+ .annotation-node__color-swatch:hover {
990
+ transform: scale(1.15);
991
+ }
992
+ .annotation-node__color-swatch--active {
993
+ border-color: var(--editor-fg, #d4d4d4);
994
+ }
995
+ .annotation-node__link-row {
996
+ padding: 2px 0;
997
+ }
998
+ .annotation-node__link-select {
999
+ width: 100%;
1000
+ max-width: 100%;
1001
+ padding: 3px 6px;
1002
+ border: 1px solid var(--panel-border, #404040);
1003
+ border-radius: 4px;
1004
+ background: var(--input-bg, #3c3c3c);
1005
+ color: var(--input-fg, #cccccc);
1006
+ font-family: inherit;
1007
+ font-size: 11px;
1008
+ cursor: pointer;
1009
+ overflow: hidden;
1010
+ text-overflow: ellipsis;
1011
+ }
1012
+ .annotation-node__delete-btn {
1013
+ width: 100%;
1014
+ padding: 4px 6px;
1015
+ border: none;
1016
+ border-radius: 4px;
1017
+ background: transparent;
1018
+ color: var(--error-fg, #f48771);
1019
+ font-family: inherit;
1020
+ font-size: 11px;
1021
+ cursor: pointer;
1022
+ text-align: left;
1023
+ transition: background 0.1s ease;
1024
+ }
1025
+ .annotation-node__delete-btn:hover {
1026
+ background: rgba(239, 68, 68, 0.15);
1027
+ }
1028
+ .annotation-node__resize-handle {
1029
+ position: absolute;
1030
+ bottom: 0;
1031
+ right: 0;
1032
+ width: 12px;
1033
+ height: 12px;
1034
+ cursor: nwse-resize;
1035
+ opacity: 0;
1036
+ transition: opacity 0.15s ease;
1037
+ z-index: 2;
1038
+ }
1039
+ .annotation-node__resize-handle::after {
1040
+ content: "";
1041
+ position: absolute;
1042
+ bottom: 3px;
1043
+ right: 3px;
1044
+ width: 6px;
1045
+ height: 6px;
1046
+ border-right: 2px solid currentColor;
1047
+ border-bottom: 2px solid currentColor;
1048
+ opacity: 0.4;
1049
+ }
1050
+ .annotation-node:hover .annotation-node__resize-handle {
1051
+ opacity: 1;
1052
+ }
1053
+ .annotation-node__link-badge {
1054
+ margin-top: 6px;
1055
+ padding: 2px 6px;
1056
+ border-radius: 3px;
1057
+ font-size: 10px;
1058
+ opacity: 0.7;
1059
+ background: rgba(0, 0, 0, 0.08);
1060
+ display: inline-block;
1061
+ max-width: 100%;
1062
+ overflow: hidden;
1063
+ text-overflow: ellipsis;
1064
+ white-space: nowrap;
1065
+ }
1066
+ body[data-vscode-theme-kind=vscode-dark] .annotation-node__link-badge,
1067
+ body[data-vscode-theme-kind=vscode-high-contrast] .annotation-node__link-badge {
1068
+ background: rgba(255, 255, 255, 0.1);
1069
+ }
1070
+
1071
+ /* src/components/common/KeyBadgeGroup.css */
1072
+ .key-badge-group {
1073
+ position: relative;
1074
+ display: inline-flex;
1075
+ flex-shrink: 0;
1076
+ }
1077
+ .key-badge-group__trigger {
1078
+ display: inline-flex;
1079
+ align-items: center;
1080
+ gap: 3px;
1081
+ padding: 1px 4px;
1082
+ border: 1px solid transparent;
1083
+ border-radius: 3px;
1084
+ background: transparent;
1085
+ color: var(--editor-fg);
1086
+ font-size: 12px;
1087
+ cursor: default;
1088
+ min-width: 24px;
1089
+ min-height: 18px;
1090
+ }
1091
+ .key-badge-group--editable .key-badge-group__trigger {
1092
+ cursor: pointer;
1093
+ border-color: var(--panel-border, #404040);
1094
+ }
1095
+ .key-badge-group--editable .key-badge-group__trigger:hover {
1096
+ background: var(--input-bg, rgba(255, 255, 255, 0.05));
1097
+ border-color: var(--vscode-focusBorder, #007fd4);
1098
+ }
1099
+ .key-badge-group--open .key-badge-group__trigger {
1100
+ border-color: var(--vscode-focusBorder, #007fd4);
1101
+ background: var(--input-bg, rgba(255, 255, 255, 0.05));
1102
+ }
1103
+ .key-badge-group__trigger:disabled {
1104
+ cursor: default;
1105
+ opacity: 1;
1106
+ }
1107
+ .key-badge-group__selected {
1108
+ display: inline-flex;
1109
+ align-items: center;
1110
+ gap: 2px;
1111
+ }
1112
+ .key-badge-group__empty {
1113
+ color: var(--vscode-descriptionForeground, #888);
1114
+ font-size: 10px;
1115
+ padding: 0 2px;
1116
+ }
1117
+ .key-badge-group__arrow {
1118
+ color: var(--vscode-descriptionForeground, #888);
1119
+ font-size: 8px;
1120
+ margin-left: 2px;
1121
+ line-height: 1;
1122
+ }
1123
+ .key-badge-group__warning {
1124
+ display: inline-flex;
1125
+ align-items: center;
1126
+ justify-content: center;
1127
+ width: 12px;
1128
+ height: 12px;
1129
+ margin-left: 2px;
1130
+ font-size: 9px;
1131
+ font-weight: 700;
1132
+ line-height: 1;
1133
+ border-radius: 50%;
1134
+ background: rgba(249, 115, 22, 0.2);
1135
+ color: #f97316;
1136
+ cursor: help;
1137
+ }
1138
+ .key-badge-group__dropdown {
1139
+ position: fixed;
1140
+ z-index: 1000;
1141
+ min-width: 180px;
1142
+ padding: 4px 0;
1143
+ background: var(--panel-bg, #252526);
1144
+ border: 1px solid var(--panel-border, #404040);
1145
+ border-radius: 4px;
1146
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
1147
+ }
1148
+ .key-badge-group__option {
1149
+ display: flex;
1150
+ align-items: center;
1151
+ gap: 8px;
1152
+ padding: 6px 10px;
1153
+ cursor: pointer;
1154
+ transition: background 0.1s ease;
1155
+ }
1156
+ .key-badge-group__option:hover {
1157
+ background: var(--input-bg, rgba(255, 255, 255, 0.05));
1158
+ }
1159
+ .key-badge-group__option:focus {
1160
+ outline: none;
1161
+ background: var(--input-bg, rgba(255, 255, 255, 0.08));
1162
+ }
1163
+ .key-badge-group__checkbox {
1164
+ display: inline-flex;
1165
+ align-items: center;
1166
+ justify-content: center;
1167
+ width: 14px;
1168
+ height: 14px;
1169
+ border: 1px solid var(--vscode-descriptionForeground, #888);
1170
+ border-radius: 2px;
1171
+ font-size: 10px;
1172
+ color: transparent;
1173
+ flex-shrink: 0;
1174
+ }
1175
+ .key-badge-group__option--active .key-badge-group__checkbox {
1176
+ background: var(--vscode-focusBorder, #007fd4);
1177
+ border-color: var(--vscode-focusBorder, #007fd4);
1178
+ color: #fff;
1179
+ }
1180
+ .key-badge-group__label {
1181
+ display: flex;
1182
+ flex-direction: column;
1183
+ gap: 1px;
1184
+ min-width: 0;
1185
+ }
1186
+ .key-badge-group__label-text {
1187
+ font-size: 12px;
1188
+ color: var(--editor-fg);
1189
+ font-weight: 500;
1190
+ }
1191
+ .key-badge-group__label-desc {
1192
+ font-size: 10px;
1193
+ color: var(--vscode-descriptionForeground, #888);
1194
+ white-space: nowrap;
1195
+ overflow: hidden;
1196
+ text-overflow: ellipsis;
1197
+ }
1198
+
1199
+ /* src/components/common/ColumnRowEditor.css */
1200
+ .column-row-editor {
1201
+ display: flex;
1202
+ flex-direction: column;
1203
+ gap: 0;
1204
+ padding: 0;
1205
+ border-radius: 3px;
1206
+ line-height: 1.4;
1207
+ position: relative;
1208
+ }
1209
+ .column-row-editor__main {
1210
+ display: flex;
1211
+ align-items: center;
1212
+ gap: 6px;
1213
+ padding: 4px 6px;
1214
+ border-radius: 3px;
1215
+ }
1216
+ .column-row-editor--built .column-row-editor__main {
1217
+ background: var(--model-built-bg);
1218
+ }
1219
+ .column-row-editor--built:hover .column-row-editor__main {
1220
+ background: rgba(34, 197, 94, 0.15);
1221
+ }
1222
+ .column-row-editor--planned .column-row-editor__main {
1223
+ background: var(--model-design-bg);
1224
+ }
1225
+ .column-row-editor--planned:hover .column-row-editor__main {
1226
+ background: rgba(249, 115, 22, 0.15);
1227
+ }
1228
+ .column-row-editor--built.column-row-editor--expanded:hover .column-row-editor__main,
1229
+ .column-row-editor--planned.column-row-editor--expanded:hover .column-row-editor__main {
1230
+ background: rgba(255, 255, 255, 0.06);
1231
+ }
1232
+ .column-row-editor--approved .column-row-editor__main {
1233
+ background: var(--model-approved-bg);
1234
+ }
1235
+ .column-row-editor--approved:hover .column-row-editor__main {
1236
+ background: rgba(20, 184, 166, 0.15);
1237
+ }
1238
+ .column-row-editor--editable {
1239
+ cursor: pointer;
1240
+ }
1241
+ .column-row-editor--editing .column-row-editor__main {
1242
+ background: var(--input-bg);
1243
+ border: 1px solid var(--focus-border);
1244
+ padding: 3px 5px;
1245
+ }
1246
+ .column-row-editor--expanded {
1247
+ background: var(--vscode-editor-inactiveSelectionBackground, rgba(255, 255, 255, 0.04));
1248
+ border-radius: 4px;
1249
+ }
1250
+ .column-row-editor--expanded .column-row-editor__main {
1251
+ border-bottom-left-radius: 0;
1252
+ border-bottom-right-radius: 0;
1253
+ }
1254
+ .column-row-editor__name {
1255
+ flex: 1;
1256
+ overflow: hidden;
1257
+ text-overflow: ellipsis;
1258
+ white-space: nowrap;
1259
+ color: var(--editor-fg);
1260
+ font-size: 12px;
1261
+ min-width: 0;
1262
+ }
1263
+ .column-row-editor--editable .column-row-editor__name:hover {
1264
+ text-decoration: underline;
1265
+ text-decoration-style: dotted;
1266
+ }
1267
+ .column-row-editor__placeholder {
1268
+ color: var(--vscode-descriptionForeground, #888);
1269
+ font-style: italic;
1270
+ }
1271
+ .column-row-editor__type {
1272
+ flex-shrink: 0;
1273
+ color: var(--vscode-descriptionForeground, #888);
1274
+ font-size: 11px;
1275
+ font-family: var(--vscode-editor-font-family, monospace);
1276
+ }
1277
+ .column-row-editor--editable .column-row-editor__type:hover {
1278
+ text-decoration: underline;
1279
+ text-decoration-style: dotted;
1280
+ }
1281
+ .column-row-editor__type-select {
1282
+ flex-shrink: 0;
1283
+ width: 90px;
1284
+ }
1285
+ .column-row-editor__input {
1286
+ flex: 1;
1287
+ padding: 2px 4px;
1288
+ border: 1px solid var(--input-border, var(--panel-border));
1289
+ border-radius: 2px;
1290
+ background: var(--input-bg);
1291
+ color: var(--input-fg, var(--editor-fg));
1292
+ font-size: 12px;
1293
+ min-width: 0;
1294
+ }
1295
+ .column-row-editor__input:focus {
1296
+ outline: none;
1297
+ border-color: var(--focus-border);
1298
+ }
1299
+ .column-row-editor__input--error {
1300
+ border-color: var(--error-fg, #f48771);
1301
+ }
1302
+ .column-row-editor__input::placeholder {
1303
+ color: var(--vscode-descriptionForeground, #888);
1304
+ opacity: 0.7;
1305
+ }
1306
+ .column-row-editor__delete {
1307
+ flex-shrink: 0;
1308
+ display: flex;
1309
+ align-items: center;
1310
+ justify-content: center;
1311
+ width: 18px;
1312
+ height: 18px;
1313
+ padding: 0;
1314
+ border: none;
1315
+ border-radius: 3px;
1316
+ background: rgba(239, 68, 68, 0.1);
1317
+ color: #ef4444;
1318
+ font-size: 14px;
1319
+ line-height: 1;
1320
+ cursor: pointer;
1321
+ opacity: 0;
1322
+ transition: opacity 0.1s ease, background 0.1s ease;
1323
+ }
1324
+ .column-row-editor:hover .column-row-editor__delete {
1325
+ opacity: 1;
1326
+ }
1327
+ .column-row-editor__delete:hover {
1328
+ background: rgba(239, 68, 68, 0.25);
1329
+ }
1330
+ .column-row-editor__delete-confirm {
1331
+ flex-shrink: 0;
1332
+ display: flex;
1333
+ align-items: center;
1334
+ gap: 2px;
1335
+ animation: delete-confirm-fade-in 0.15s ease;
1336
+ }
1337
+ @keyframes delete-confirm-fade-in {
1338
+ from {
1339
+ opacity: 0;
1340
+ transform: translateX(4px);
1341
+ }
1342
+ to {
1343
+ opacity: 1;
1344
+ transform: translateX(0);
1345
+ }
1346
+ }
1347
+ .column-row-editor__delete-confirm-yes {
1348
+ padding: 1px 6px;
1349
+ border: 1px solid rgba(239, 68, 68, 0.5);
1350
+ border-radius: 3px;
1351
+ background: rgba(239, 68, 68, 0.15);
1352
+ color: var(--vscode-errorForeground, #f48771);
1353
+ font-size: 10px;
1354
+ font-weight: 600;
1355
+ cursor: pointer;
1356
+ white-space: nowrap;
1357
+ transition: background 0.1s ease;
1358
+ }
1359
+ .column-row-editor__delete-confirm-yes:hover {
1360
+ background: rgba(239, 68, 68, 0.3);
1361
+ }
1362
+ .column-row-editor__delete-confirm-no {
1363
+ display: flex;
1364
+ align-items: center;
1365
+ justify-content: center;
1366
+ width: 16px;
1367
+ height: 16px;
1368
+ padding: 0;
1369
+ border: none;
1370
+ border-radius: 3px;
1371
+ background: transparent;
1372
+ color: var(--vscode-descriptionForeground, #888);
1373
+ font-size: 10px;
1374
+ cursor: pointer;
1375
+ transition: color 0.1s ease, background 0.1s ease;
1376
+ }
1377
+ .column-row-editor__delete-confirm-no:hover {
1378
+ color: var(--editor-fg);
1379
+ background: rgba(255, 255, 255, 0.08);
1380
+ }
1381
+ .column-row-editor__error {
1382
+ position: absolute;
1383
+ left: 42px;
1384
+ top: 100%;
1385
+ padding: 2px 6px;
1386
+ background: var(--panel-bg);
1387
+ border: 1px solid var(--error-fg, #f48771);
1388
+ border-radius: 3px;
1389
+ font-size: 10px;
1390
+ color: var(--error-fg, #f48771);
1391
+ white-space: nowrap;
1392
+ z-index: 10;
1393
+ margin-top: 2px;
1394
+ }
1395
+ .column-row-editor__approve {
1396
+ flex-shrink: 0;
1397
+ display: flex;
1398
+ align-items: center;
1399
+ justify-content: center;
1400
+ width: 18px;
1401
+ height: 18px;
1402
+ padding: 0;
1403
+ border: 1px solid var(--model-approved, #14b8a6);
1404
+ border-radius: 3px;
1405
+ background: transparent;
1406
+ color: var(--model-approved, #14b8a6);
1407
+ font-size: 12px;
1408
+ line-height: 1;
1409
+ cursor: pointer;
1410
+ opacity: 0.6;
1411
+ transition: opacity 0.1s ease, background 0.1s ease;
1412
+ }
1413
+ .column-row-editor:hover .column-row-editor__approve {
1414
+ opacity: 1;
1415
+ }
1416
+ .column-row-editor__approve:hover {
1417
+ background: var(--model-approved-bg, rgba(20, 184, 166, 0.15));
1418
+ }
1419
+ .column-row-editor__approve--approved {
1420
+ background: var(--model-approved, #14b8a6);
1421
+ color: var(--model-approved-text, #fff);
1422
+ opacity: 1;
1423
+ }
1424
+ .column-row-editor__approve--approved:hover {
1425
+ background: var(--model-design, #f97316);
1426
+ border-color: var(--model-design, #f97316);
1427
+ color: var(--model-design-text, #fff);
1428
+ }
1429
+ .column-row-editor__chevron {
1430
+ flex-shrink: 0;
1431
+ display: flex;
1432
+ align-items: center;
1433
+ justify-content: center;
1434
+ width: 16px;
1435
+ height: 16px;
1436
+ padding: 0;
1437
+ border: none;
1438
+ border-radius: 2px;
1439
+ background: transparent;
1440
+ color: var(--vscode-descriptionForeground, #888);
1441
+ font-size: 10px;
1442
+ line-height: 1;
1443
+ cursor: pointer;
1444
+ transition: color 0.1s ease, background 0.1s ease;
1445
+ }
1446
+ .column-row-editor__chevron:hover {
1447
+ color: var(--editor-fg);
1448
+ background: rgba(255, 255, 255, 0.08);
1449
+ }
1450
+ .column-row-editor--expanded .column-row-editor__chevron {
1451
+ color: var(--editor-fg);
1452
+ }
1453
+ .column-row-editor__info-badge {
1454
+ flex-shrink: 0;
1455
+ display: flex;
1456
+ align-items: center;
1457
+ justify-content: center;
1458
+ width: 14px;
1459
+ height: 14px;
1460
+ font-size: 10px;
1461
+ color: var(--vscode-descriptionForeground, #888);
1462
+ cursor: pointer;
1463
+ opacity: 0.7;
1464
+ transition: opacity 0.1s ease, color 0.1s ease;
1465
+ }
1466
+ .column-row-editor__info-badge:hover {
1467
+ opacity: 1;
1468
+ color: var(--button-bg, #3b82f6);
1469
+ }
1470
+ .column-row-editor__description-area {
1471
+ padding: 6px 8px 8px 28px;
1472
+ border-top: 1px solid var(--panel-border);
1473
+ }
1474
+ .column-row-editor__description-text {
1475
+ font-size: 11px;
1476
+ color: var(--editor-fg);
1477
+ line-height: 1.5;
1478
+ white-space: pre-wrap;
1479
+ word-break: break-word;
1480
+ }
1481
+ .column-row-editor--editable .column-row-editor__description-text {
1482
+ cursor: pointer;
1483
+ padding: 4px 6px;
1484
+ border-radius: 3px;
1485
+ margin: -4px -6px;
1486
+ }
1487
+ .column-row-editor--editable .column-row-editor__description-text:hover {
1488
+ background: rgba(255, 255, 255, 0.05);
1489
+ }
1490
+ .column-row-editor__description-text--empty {
1491
+ color: var(--vscode-descriptionForeground, #888);
1492
+ font-style: italic;
1493
+ }
1494
+ .column-row-editor__description-input {
1495
+ width: 100%;
1496
+ min-height: 48px;
1497
+ padding: 6px 8px;
1498
+ border: 1px solid var(--input-border, var(--panel-border));
1499
+ border-radius: 3px;
1500
+ background: var(--input-bg);
1501
+ color: var(--input-fg, var(--editor-fg));
1502
+ font-size: 11px;
1503
+ font-family: inherit;
1504
+ line-height: 1.5;
1505
+ resize: vertical;
1506
+ }
1507
+ .column-row-editor__description-input:focus {
1508
+ outline: none;
1509
+ border-color: var(--focus-border);
1510
+ }
1511
+ .column-row-editor__description-input::placeholder {
1512
+ color: var(--vscode-descriptionForeground, #888);
1513
+ opacity: 0.7;
1514
+ }
1515
+ .column-row-editor__metadata-row {
1516
+ display: flex;
1517
+ align-items: center;
1518
+ gap: 8px;
1519
+ padding: 3px 8px 3px 28px;
1520
+ }
1521
+ .column-row-editor__metadata-label {
1522
+ flex-shrink: 0;
1523
+ font-size: 11px;
1524
+ color: var(--vscode-descriptionForeground, #888);
1525
+ min-width: 60px;
1526
+ }
1527
+ .column-row-editor__metadata-select {
1528
+ flex: 1;
1529
+ padding: 2px 4px;
1530
+ border: 1px solid var(--vscode-input-border, var(--vscode-editorGroup-border, #444));
1531
+ background: var(--vscode-input-background, #3c3c3c);
1532
+ color: var(--vscode-input-foreground, #ccc);
1533
+ font-size: 11px;
1534
+ border-radius: 3px;
1535
+ cursor: pointer;
1536
+ }
1537
+ .column-row-editor__metadata-select:focus {
1538
+ outline: 1px solid var(--vscode-focusBorder, #007fd4);
1539
+ outline-offset: -1px;
1540
+ }
1541
+ .column-row-editor__metadata-select:disabled {
1542
+ opacity: 0.6;
1543
+ cursor: default;
1544
+ }
1545
+ .column-row-editor__discrepancy {
1546
+ display: flex;
1547
+ align-items: center;
1548
+ gap: 6px;
1549
+ padding: 4px 8px 4px 28px;
1550
+ background: rgba(204, 167, 0, 0.08);
1551
+ border-top: 1px solid rgba(204, 167, 0, 0.2);
1552
+ font-size: 11px;
1553
+ line-height: 1.4;
1554
+ }
1555
+ .column-row-editor__discrepancy--rejected {
1556
+ background: rgba(239, 68, 68, 0.06);
1557
+ border-top-color: rgba(239, 68, 68, 0.2);
1558
+ }
1559
+ .column-row-editor__discrepancy-icon {
1560
+ flex-shrink: 0;
1561
+ color: var(--vscode-editorWarning-foreground, #cca700);
1562
+ font-size: 12px;
1563
+ }
1564
+ .column-row-editor__discrepancy--rejected .column-row-editor__discrepancy-icon {
1565
+ color: var(--vscode-errorForeground, #f48771);
1566
+ }
1567
+ .column-row-editor__discrepancy-detail {
1568
+ flex: 1;
1569
+ min-width: 0;
1570
+ color: var(--vscode-descriptionForeground, #888);
1571
+ }
1572
+ .column-row-editor__discrepancy-label {
1573
+ color: var(--vscode-editorWarning-foreground, #cca700);
1574
+ font-weight: 600;
1575
+ }
1576
+ .column-row-editor__discrepancy--rejected .column-row-editor__discrepancy-label {
1577
+ color: var(--vscode-errorForeground, #f48771);
1578
+ }
1579
+ .column-row-editor__discrepancy-expected {
1580
+ color: var(--vscode-editorWarning-foreground, #cca700);
1581
+ font-family: var(--vscode-editor-font-family, monospace);
1582
+ font-size: 11px;
1583
+ }
1584
+ .column-row-editor__discrepancy-actual {
1585
+ color: var(--vscode-descriptionForeground, #888);
1586
+ font-family: var(--vscode-editor-font-family, monospace);
1587
+ font-size: 11px;
1588
+ }
1589
+ .column-row-editor__discrepancy-actions {
1590
+ flex-shrink: 0;
1591
+ display: flex;
1592
+ gap: 4px;
1593
+ }
1594
+ .column-row-editor__discrepancy-btn {
1595
+ padding: 1px 6px;
1596
+ border: 1px solid var(--panel-border);
1597
+ border-radius: 3px;
1598
+ background: transparent;
1599
+ color: var(--editor-fg);
1600
+ font-size: 10px;
1601
+ cursor: pointer;
1602
+ transition: background 0.1s ease, color 0.1s ease;
1603
+ }
1604
+ .column-row-editor__discrepancy-btn:hover {
1605
+ background: rgba(255, 255, 255, 0.1);
1606
+ }
1607
+ .column-row-editor__discrepancy-btn--accept {
1608
+ border-color: var(--model-approved, #14b8a6);
1609
+ color: var(--model-approved, #14b8a6);
1610
+ }
1611
+ .column-row-editor__discrepancy-btn--accept:hover {
1612
+ background: var(--model-approved-bg, rgba(20, 184, 166, 0.15));
1613
+ }
1614
+ .column-row-editor__discrepancy-btn--reject {
1615
+ border-color: var(--vscode-errorForeground, #f48771);
1616
+ color: var(--vscode-errorForeground, #f48771);
1617
+ }
1618
+ .column-row-editor__discrepancy-btn--reject:hover {
1619
+ background: rgba(239, 68, 68, 0.15);
1620
+ }
1621
+ .column-row-editor__drag-handle {
1622
+ flex-shrink: 0;
1623
+ cursor: grab;
1624
+ color: var(--vscode-descriptionForeground, #888);
1625
+ opacity: 0.35;
1626
+ padding: 0 2px;
1627
+ font-size: 12px;
1628
+ user-select: none;
1629
+ line-height: 1;
1630
+ transition: opacity 0.1s ease;
1631
+ }
1632
+ .column-row-editor__drag-handle:hover {
1633
+ opacity: 0.85;
1634
+ }
1635
+ .column-row-editor__drag-handle:active {
1636
+ cursor: grabbing;
1637
+ opacity: 1;
1638
+ }
1639
+ .column-row-editor__drag-handle--hidden {
1640
+ visibility: hidden;
1641
+ pointer-events: none;
1642
+ }
1643
+ .column-row-editor--dragging {
1644
+ opacity: 0.4;
1645
+ }
1646
+ .column-row-editor--selected .column-row-editor__main {
1647
+ background: var(--vscode-list-activeSelectionBackground, rgba(4, 57, 94, 0.7));
1648
+ }
1649
+ .column-row-editor--selected .column-row-editor__name,
1650
+ .column-row-editor--selected .column-row-editor__type {
1651
+ color: var(--vscode-list-activeSelectionForeground, #fff);
1652
+ }
1653
+ .column-row-editor--selected .column-row-editor__drag-handle {
1654
+ color: var(--vscode-list-activeSelectionForeground, #fff);
1655
+ }
1656
+ .column-row-editor--drag-over {
1657
+ box-shadow: 0 -2px 0 0 var(--vscode-focusBorder, #007fd4);
1658
+ }
1659
+
1660
+ /* src/components/DetailPanel/BulkColumnActions.css */
1661
+ .bulk-column-actions {
1662
+ display: flex;
1663
+ align-items: center;
1664
+ gap: 6px;
1665
+ padding: 4px 8px;
1666
+ border: 1px solid var(--vscode-panel-border, #404040);
1667
+ border-radius: 4px;
1668
+ background: var(--vscode-editor-selectionBackground, rgba(4, 57, 94, 0.3));
1669
+ font-size: 11px;
1670
+ }
1671
+ .bulk-column-actions__count {
1672
+ color: var(--vscode-descriptionForeground, #888);
1673
+ font-size: 10px;
1674
+ white-space: nowrap;
1675
+ margin-right: 2px;
1676
+ }
1677
+ .bulk-column-actions__divider {
1678
+ width: 1px;
1679
+ height: 16px;
1680
+ background: var(--vscode-panel-border, #404040);
1681
+ flex-shrink: 0;
1682
+ }
1683
+ .bulk-column-actions__btn {
1684
+ padding: 2px 6px;
1685
+ border: 1px solid var(--vscode-panel-border, #404040);
1686
+ border-radius: 3px;
1687
+ background: transparent;
1688
+ color: var(--vscode-editor-foreground, #d4d4d4);
1689
+ font-size: 10px;
1690
+ cursor: pointer;
1691
+ white-space: nowrap;
1692
+ transition: background 0.1s ease;
1693
+ }
1694
+ .bulk-column-actions__btn:hover {
1695
+ background: rgba(255, 255, 255, 0.08);
1696
+ }
1697
+ .bulk-column-actions__btn--danger {
1698
+ color: var(--vscode-errorForeground, #f48771);
1699
+ border-color: var(--vscode-errorForeground, #f48771);
1700
+ }
1701
+ .bulk-column-actions__btn--danger:hover {
1702
+ background: rgba(244, 135, 113, 0.12);
1703
+ }
1704
+ .bulk-column-actions__btn--clear {
1705
+ padding: 2px 4px;
1706
+ border: none;
1707
+ color: var(--vscode-descriptionForeground, #888);
1708
+ font-size: 12px;
1709
+ margin-left: auto;
1710
+ }
1711
+ .bulk-column-actions__btn--clear:hover {
1712
+ color: var(--vscode-editor-foreground, #d4d4d4);
1713
+ }
1714
+ .bulk-column-actions__key-btn {
1715
+ padding: 1px 5px;
1716
+ border: 1px solid var(--vscode-panel-border, #404040);
1717
+ border-radius: 3px;
1718
+ background: transparent;
1719
+ color: var(--vscode-descriptionForeground, #888);
1720
+ font-size: 9px;
1721
+ font-weight: 600;
1722
+ cursor: pointer;
1723
+ transition:
1724
+ background 0.1s ease,
1725
+ color 0.1s ease,
1726
+ border-color 0.1s ease;
1727
+ }
1728
+ .bulk-column-actions__key-btn:hover {
1729
+ background: rgba(255, 255, 255, 0.08);
1730
+ color: var(--vscode-editor-foreground, #d4d4d4);
1731
+ }
1732
+ .bulk-column-actions__key-btn--active {
1733
+ background: rgba(59, 130, 246, 0.15);
1734
+ border-color: var(--vscode-focusBorder, #007fd4);
1735
+ color: var(--vscode-focusBorder, #007fd4);
1736
+ }
1737
+ .bulk-column-actions__key-btn--active:hover {
1738
+ background: rgba(59, 130, 246, 0.25);
1739
+ }
1740
+ .bulk-column-actions__type-select {
1741
+ font-size: 10px;
1742
+ }
1743
+
1744
+ /* src/components/DetailPanel/ColumnEditor.css */
1745
+ .column-editor {
1746
+ display: flex;
1747
+ flex-direction: column;
1748
+ gap: 8px;
1749
+ }
1750
+ .column-editor__header {
1751
+ display: flex;
1752
+ align-items: center;
1753
+ justify-content: space-between;
1754
+ gap: 8px;
1755
+ }
1756
+ .column-editor__header-actions {
1757
+ display: flex;
1758
+ align-items: center;
1759
+ gap: 6px;
1760
+ }
1761
+ .column-editor__expand-controls {
1762
+ display: flex;
1763
+ align-items: center;
1764
+ gap: 2px;
1765
+ }
1766
+ .column-editor__expand-btn {
1767
+ position: relative;
1768
+ display: flex;
1769
+ align-items: center;
1770
+ justify-content: center;
1771
+ width: 20px;
1772
+ height: 20px;
1773
+ padding: 0;
1774
+ border: none;
1775
+ border-radius: 3px;
1776
+ background: transparent;
1777
+ color: var(--vscode-descriptionForeground, #888);
1778
+ font-size: 12px;
1779
+ cursor: pointer;
1780
+ transition: color 0.1s ease, background 0.1s ease;
1781
+ }
1782
+ .column-editor__expand-btn:hover {
1783
+ color: var(--editor-fg);
1784
+ background: rgba(255, 255, 255, 0.08);
1785
+ }
1786
+ .column-editor__expand-btn::after {
1787
+ content: attr(data-tooltip);
1788
+ position: absolute;
1789
+ top: 100%;
1790
+ left: 50%;
1791
+ transform: translateX(-50%);
1792
+ margin-top: 4px;
1793
+ padding: 3px 6px;
1794
+ background: var(--vscode-editorWidget-background, #252526);
1795
+ border: 1px solid var(--panel-border);
1796
+ border-radius: 3px;
1797
+ font-size: 10px;
1798
+ white-space: nowrap;
1799
+ color: var(--editor-fg);
1800
+ opacity: 0;
1801
+ visibility: hidden;
1802
+ transition: opacity 0.1s ease, visibility 0.1s ease;
1803
+ pointer-events: none;
1804
+ z-index: 100;
1805
+ }
1806
+ .column-editor__expand-btn:hover::after {
1807
+ opacity: 1;
1808
+ visibility: visible;
1809
+ }
1810
+ .column-editor__title {
1811
+ margin: 0;
1812
+ font-size: 11px;
1813
+ font-weight: 600;
1814
+ text-transform: uppercase;
1815
+ letter-spacing: 0.5px;
1816
+ color: var(--vscode-descriptionForeground, #888);
1817
+ }
1818
+ .column-editor__add-btn {
1819
+ padding: 3px 8px;
1820
+ border: 1px dashed var(--panel-border);
1821
+ border-radius: 3px;
1822
+ background: transparent;
1823
+ color: var(--button-bg);
1824
+ font-size: 10px;
1825
+ font-weight: 500;
1826
+ cursor: pointer;
1827
+ transition: background 0.1s ease, border-color 0.1s ease;
1828
+ }
1829
+ .column-editor__add-btn:hover:not(:disabled) {
1830
+ background: rgba(59, 130, 246, 0.08);
1831
+ border-color: var(--button-bg);
1832
+ }
1833
+ .column-editor__add-btn:disabled {
1834
+ opacity: 0.5;
1835
+ cursor: not-allowed;
1836
+ }
1837
+ .column-editor__list {
1838
+ display: flex;
1839
+ flex-direction: column;
1840
+ gap: 1px;
1841
+ }
1842
+ .column-editor__empty {
1843
+ padding: 8px 6px;
1844
+ color: var(--vscode-descriptionForeground, #888);
1845
+ font-style: italic;
1846
+ text-align: center;
1847
+ font-size: 11px;
1848
+ }
1849
+ .column-editor__separator {
1850
+ display: flex;
1851
+ align-items: center;
1852
+ gap: 8px;
1853
+ padding: 6px 0;
1854
+ }
1855
+ .column-editor__separator::before,
1856
+ .column-editor__separator::after {
1857
+ content: "";
1858
+ flex: 1;
1859
+ height: 1px;
1860
+ background: var(--panel-border);
1861
+ }
1862
+ .column-editor__separator-text {
1863
+ font-size: 9px;
1864
+ font-weight: 600;
1865
+ letter-spacing: 1px;
1866
+ color: var(--model-design);
1867
+ text-transform: uppercase;
1868
+ }
1869
+ .column-editor__separator--approved .column-editor__separator-text {
1870
+ color: var(--model-approved);
1871
+ }
1872
+ .column-editor__add-btn--bottom {
1873
+ width: 100%;
1874
+ margin-top: 6px;
1875
+ justify-content: center;
1876
+ }
1877
+ .column-editor__accept-all-btn {
1878
+ padding: 3px 8px;
1879
+ border: 1px solid var(--vscode-editorWarning-foreground, #cca700);
1880
+ border-radius: 3px;
1881
+ background: rgba(204, 167, 0, 0.1);
1882
+ color: var(--vscode-editorWarning-foreground, #cca700);
1883
+ font-size: 10px;
1884
+ font-weight: 500;
1885
+ cursor: pointer;
1886
+ transition: background 0.1s ease;
1887
+ }
1888
+ .column-editor__accept-all-btn:hover {
1889
+ background: rgba(204, 167, 0, 0.2);
1890
+ }
1891
+
1892
+ /* src/components/DetailPanel/DetailPanel.css */
1893
+ .detail-panel {
1894
+ width: 340px;
1895
+ max-height: calc(100vh - 100px);
1896
+ overflow-y: auto;
1897
+ background: var(--panel-bg);
1898
+ border: 1px solid var(--panel-border);
1899
+ border-radius: 6px;
1900
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
1901
+ font-size: 12px;
1902
+ }
1903
+ .detail-panel__header {
1904
+ display: flex;
1905
+ align-items: center;
1906
+ justify-content: space-between;
1907
+ gap: 8px;
1908
+ padding: 10px 12px;
1909
+ border-bottom: 1px solid var(--panel-border);
1910
+ background: var(--panel-bg);
1911
+ position: sticky;
1912
+ top: 0;
1913
+ z-index: 1;
1914
+ }
1915
+ .detail-panel__title {
1916
+ margin: 0;
1917
+ font-size: 14px;
1918
+ font-weight: 600;
1919
+ color: var(--editor-fg);
1920
+ overflow: hidden;
1921
+ text-overflow: ellipsis;
1922
+ white-space: nowrap;
1923
+ flex: 1;
1924
+ min-width: 0;
1925
+ }
1926
+ .detail-panel__title--editable {
1927
+ cursor: pointer;
1928
+ }
1929
+ .detail-panel__title--editable:hover {
1930
+ text-decoration: underline;
1931
+ text-decoration-style: dotted;
1932
+ text-underline-offset: 3px;
1933
+ }
1934
+ .detail-panel__title-input {
1935
+ flex: 1;
1936
+ min-width: 0;
1937
+ margin: 0;
1938
+ padding: 2px 6px;
1939
+ font-size: 14px;
1940
+ font-weight: 600;
1941
+ color: var(--editor-fg);
1942
+ background: var(--input-bg, var(--vscode-input-background, #3c3c3c));
1943
+ border: 1px solid var(--focus-border, var(--vscode-focusBorder, #007fd4));
1944
+ border-radius: 3px;
1945
+ outline: none;
1946
+ font-family: inherit;
1947
+ }
1948
+ .detail-panel__title-edit {
1949
+ flex: 1;
1950
+ min-width: 0;
1951
+ display: flex;
1952
+ flex-direction: column;
1953
+ gap: 3px;
1954
+ }
1955
+ .detail-panel__title-input--error {
1956
+ border-color: var(--vscode-errorForeground, #f48771);
1957
+ }
1958
+ .detail-panel__title-error {
1959
+ font-size: 10px;
1960
+ color: var(--vscode-errorForeground, #f48771);
1961
+ line-height: 1.2;
1962
+ }
1963
+ .detail-panel__title-edit-btn {
1964
+ flex-shrink: 0;
1965
+ display: flex;
1966
+ align-items: center;
1967
+ justify-content: center;
1968
+ width: 22px;
1969
+ height: 22px;
1970
+ padding: 0;
1971
+ border: none;
1972
+ border-radius: 3px;
1973
+ background: transparent;
1974
+ color: var(--vscode-descriptionForeground, #888);
1975
+ font-size: 13px;
1976
+ line-height: 1;
1977
+ cursor: pointer;
1978
+ opacity: 0;
1979
+ transition:
1980
+ opacity 0.15s ease,
1981
+ background 0.1s ease,
1982
+ color 0.1s ease;
1983
+ }
1984
+ .detail-panel__header:hover .detail-panel__title-edit-btn {
1985
+ opacity: 1;
1986
+ }
1987
+ .detail-panel__title-edit-btn:hover {
1988
+ background: var(--button-bg);
1989
+ color: var(--button-fg);
1990
+ }
1991
+ .detail-panel__close {
1992
+ flex-shrink: 0;
1993
+ display: flex;
1994
+ align-items: center;
1995
+ justify-content: center;
1996
+ width: 24px;
1997
+ height: 24px;
1998
+ border: none;
1999
+ border-radius: 4px;
2000
+ background: transparent;
2001
+ color: var(--editor-fg);
2002
+ font-size: 18px;
2003
+ line-height: 1;
2004
+ cursor: pointer;
2005
+ transition: background 0.1s ease, color 0.1s ease;
2006
+ }
2007
+ .detail-panel__close:hover {
2008
+ background: var(--button-bg);
2009
+ color: var(--button-fg);
2010
+ }
2011
+ .detail-panel__section {
2012
+ padding: 10px 12px;
2013
+ border-bottom: 1px solid var(--panel-border);
2014
+ }
2015
+ .detail-panel__section:last-child {
2016
+ border-bottom: none;
2017
+ }
2018
+ .detail-panel__section-title {
2019
+ margin: 0 0 8px 0;
2020
+ font-size: 11px;
2021
+ font-weight: 600;
2022
+ text-transform: uppercase;
2023
+ letter-spacing: 0.5px;
2024
+ color: var(--vscode-descriptionForeground, #888);
2025
+ }
2026
+ .detail-panel__metadata {
2027
+ display: flex;
2028
+ flex-direction: column;
2029
+ gap: 6px;
2030
+ }
2031
+ .detail-panel__metadata-row {
2032
+ display: flex;
2033
+ align-items: center;
2034
+ gap: 8px;
2035
+ }
2036
+ .detail-panel__label {
2037
+ font-weight: 500;
2038
+ color: var(--vscode-descriptionForeground, #888);
2039
+ min-width: 50px;
2040
+ }
2041
+ .detail-panel__value {
2042
+ color: var(--editor-fg);
2043
+ font-family: var(--vscode-editor-font-family, monospace);
2044
+ font-size: 11px;
2045
+ }
2046
+ .detail-panel__label--wide {
2047
+ min-width: 84px;
2048
+ }
2049
+ .detail-panel__value--provenance {
2050
+ font-family: inherit;
2051
+ color: var(--dim-fg);
2052
+ }
2053
+ .detail-panel__status-badge {
2054
+ padding: 2px 6px;
2055
+ border-radius: 3px;
2056
+ font-size: 10px;
2057
+ font-weight: 600;
2058
+ text-transform: uppercase;
2059
+ letter-spacing: 0.5px;
2060
+ }
2061
+ .detail-panel__status-badge--built {
2062
+ background: var(--model-built-bg);
2063
+ color: var(--model-built);
2064
+ }
2065
+ .detail-panel__status-badge--design {
2066
+ background: var(--model-design-bg);
2067
+ color: var(--model-design);
2068
+ }
2069
+ .detail-panel__status-badge--missing {
2070
+ background: var(--model-missing-bg);
2071
+ color: var(--model-missing);
2072
+ }
2073
+ .detail-panel__status-badge--approved {
2074
+ background: var(--model-approved-bg);
2075
+ color: var(--model-approved);
2076
+ }
2077
+ .detail-panel__approve-btn {
2078
+ margin-left: auto;
2079
+ padding: 2px 8px;
2080
+ border: 1px solid var(--model-approved);
2081
+ border-radius: 3px;
2082
+ background: transparent;
2083
+ color: var(--model-approved);
2084
+ font-size: 10px;
2085
+ font-weight: 500;
2086
+ cursor: pointer;
2087
+ transition: background 0.15s ease, color 0.15s ease;
2088
+ }
2089
+ .detail-panel__approve-btn:hover {
2090
+ background: var(--model-approved);
2091
+ color: var(--model-approved-text, #fff);
2092
+ }
2093
+ .detail-panel__approve-btn--unapprove {
2094
+ border-color: var(--model-design);
2095
+ color: var(--model-design);
2096
+ }
2097
+ .detail-panel__approve-btn--unapprove:hover {
2098
+ background: var(--model-design);
2099
+ color: var(--model-design-text, #fff);
2100
+ }
2101
+ .detail-panel__description {
2102
+ margin: 8px 0 0 0;
2103
+ color: var(--editor-fg);
2104
+ line-height: 1.5;
2105
+ font-size: 11px;
2106
+ }
2107
+ .detail-panel__columns {
2108
+ display: flex;
2109
+ flex-direction: column;
2110
+ gap: 1px;
2111
+ }
2112
+ .detail-panel__column {
2113
+ display: flex;
2114
+ align-items: center;
2115
+ gap: 6px;
2116
+ padding: 4px 6px;
2117
+ border-radius: 3px;
2118
+ line-height: 1.4;
2119
+ }
2120
+ .detail-panel__column--built {
2121
+ background: rgba(34, 197, 94, 0.08);
2122
+ }
2123
+ .detail-panel__column--built:hover {
2124
+ background: rgba(34, 197, 94, 0.15);
2125
+ }
2126
+ .detail-panel__column--planned,
2127
+ .detail-panel__column--missing {
2128
+ background: rgba(249, 115, 22, 0.1);
2129
+ }
2130
+ .detail-panel__column--planned:hover,
2131
+ .detail-panel__column--missing:hover {
2132
+ background: rgba(249, 115, 22, 0.18);
2133
+ }
2134
+ .detail-panel__col-indicators {
2135
+ display: flex;
2136
+ gap: 2px;
2137
+ flex-shrink: 0;
2138
+ min-width: 36px;
2139
+ }
2140
+ .detail-panel__pk,
2141
+ .detail-panel__fk {
2142
+ display: inline-block;
2143
+ padding: 0 3px;
2144
+ border-radius: 2px;
2145
+ font-size: 9px;
2146
+ font-weight: 700;
2147
+ line-height: 1.5;
2148
+ letter-spacing: 0.3px;
2149
+ }
2150
+ .detail-panel__pk {
2151
+ background: rgba(234, 179, 8, 0.2);
2152
+ color: #ca8a04;
2153
+ }
2154
+ .detail-panel__fk {
2155
+ background: rgba(59, 130, 246, 0.2);
2156
+ color: #3b82f6;
2157
+ }
2158
+ .detail-panel__col-name {
2159
+ flex: 1;
2160
+ overflow: hidden;
2161
+ text-overflow: ellipsis;
2162
+ white-space: nowrap;
2163
+ color: var(--editor-fg);
2164
+ }
2165
+ .detail-panel__col-type {
2166
+ flex-shrink: 0;
2167
+ color: var(--vscode-descriptionForeground, #888);
2168
+ font-size: 11px;
2169
+ font-family: var(--vscode-editor-font-family, monospace);
2170
+ }
2171
+ .detail-panel__empty {
2172
+ padding: 8px 6px;
2173
+ color: var(--vscode-descriptionForeground, #888);
2174
+ font-style: italic;
2175
+ text-align: center;
2176
+ }
2177
+ .detail-panel__relationships {
2178
+ display: flex;
2179
+ flex-direction: column;
2180
+ gap: 4px;
2181
+ }
2182
+ .detail-panel__relationship {
2183
+ display: flex;
2184
+ align-items: center;
2185
+ gap: 6px;
2186
+ padding: 5px 6px;
2187
+ border-radius: 3px;
2188
+ line-height: 1.4;
2189
+ font-size: 11px;
2190
+ }
2191
+ .detail-panel__relationship--built {
2192
+ background: rgba(59, 130, 246, 0.08);
2193
+ }
2194
+ .detail-panel__relationship--approved {
2195
+ background: rgba(20, 184, 166, 0.1);
2196
+ }
2197
+ .detail-panel__relationship--design {
2198
+ background: rgba(249, 115, 22, 0.1);
2199
+ }
2200
+ .detail-panel__relationship--clickable {
2201
+ cursor: pointer;
2202
+ transition: background 0.1s ease;
2203
+ }
2204
+ .detail-panel__relationship--clickable:hover {
2205
+ background: rgba(128, 128, 128, 0.2);
2206
+ }
2207
+ .detail-panel__relationship--clickable:focus {
2208
+ outline: 1px solid var(--focus-border);
2209
+ outline-offset: -1px;
2210
+ }
2211
+ .detail-panel__rel-direction {
2212
+ flex-shrink: 0;
2213
+ font-weight: 700;
2214
+ font-size: 12px;
2215
+ width: 16px;
2216
+ text-align: center;
2217
+ color: var(--vscode-descriptionForeground, #888);
2218
+ }
2219
+ .detail-panel__rel-columns {
2220
+ flex: 1;
2221
+ display: flex;
2222
+ align-items: center;
2223
+ gap: 4px;
2224
+ overflow: hidden;
2225
+ min-width: 0;
2226
+ }
2227
+ .detail-panel__rel-local {
2228
+ font-weight: 600;
2229
+ color: var(--editor-fg);
2230
+ white-space: nowrap;
2231
+ overflow: hidden;
2232
+ text-overflow: ellipsis;
2233
+ }
2234
+ .detail-panel__rel-arrow {
2235
+ color: var(--vscode-descriptionForeground, #888);
2236
+ flex-shrink: 0;
2237
+ }
2238
+ .detail-panel__rel-target {
2239
+ color: var(--editor-fg);
2240
+ font-family: var(--vscode-editor-font-family, monospace);
2241
+ overflow: hidden;
2242
+ text-overflow: ellipsis;
2243
+ white-space: nowrap;
2244
+ }
2245
+ .detail-panel__rel-cardinality {
2246
+ flex-shrink: 0;
2247
+ padding: 1px 4px;
2248
+ border-radius: 2px;
2249
+ font-size: 9px;
2250
+ font-weight: 500;
2251
+ background: rgba(128, 128, 128, 0.15);
2252
+ color: var(--vscode-descriptionForeground, #888);
2253
+ white-space: nowrap;
2254
+ }
2255
+ .detail-panel__rel-delete {
2256
+ flex-shrink: 0;
2257
+ display: flex;
2258
+ align-items: center;
2259
+ justify-content: center;
2260
+ width: 20px;
2261
+ height: 20px;
2262
+ padding: 0;
2263
+ border: none;
2264
+ border-radius: 3px;
2265
+ background: transparent;
2266
+ color: var(--vscode-descriptionForeground, #888);
2267
+ font-size: 16px;
2268
+ line-height: 1;
2269
+ cursor: pointer;
2270
+ transition: background 0.1s ease, color 0.1s ease;
2271
+ }
2272
+ .detail-panel__rel-delete:hover {
2273
+ background: rgba(239, 68, 68, 0.15);
2274
+ color: #ef4444;
2275
+ }
2276
+ .detail-panel__rel-approve {
2277
+ flex-shrink: 0;
2278
+ display: flex;
2279
+ align-items: center;
2280
+ justify-content: center;
2281
+ width: 20px;
2282
+ height: 20px;
2283
+ padding: 0;
2284
+ border: 1px solid var(--model-approved, #14b8a6);
2285
+ border-radius: 3px;
2286
+ background: transparent;
2287
+ color: var(--model-approved, #14b8a6);
2288
+ font-size: 12px;
2289
+ line-height: 1;
2290
+ cursor: pointer;
2291
+ opacity: 0.6;
2292
+ transition: opacity 0.1s ease, background 0.1s ease;
2293
+ }
2294
+ .detail-panel__relationship:hover .detail-panel__rel-approve {
2295
+ opacity: 1;
2296
+ }
2297
+ .detail-panel__rel-approve:hover {
2298
+ background: var(--model-approved-bg, rgba(20, 184, 166, 0.15));
2299
+ }
2300
+ .detail-panel__rel-approve--approved {
2301
+ background: var(--model-approved, #14b8a6);
2302
+ color: var(--model-approved-text, #fff);
2303
+ opacity: 1;
2304
+ }
2305
+ .detail-panel__rel-approve--approved:hover {
2306
+ background: var(--model-design, #f97316);
2307
+ border-color: var(--model-design, #f97316);
2308
+ color: var(--model-design-text, #fff);
2309
+ }
2310
+ .detail-panel__stub-label {
2311
+ display: flex;
2312
+ align-items: center;
2313
+ gap: 6px;
2314
+ font-size: 12px;
2315
+ color: var(--editor-fg);
2316
+ cursor: pointer;
2317
+ user-select: none;
2318
+ }
2319
+ .detail-panel__stub-label input[type=checkbox] {
2320
+ accent-color: var(--button-bg);
2321
+ width: 13px;
2322
+ height: 13px;
2323
+ cursor: pointer;
2324
+ flex-shrink: 0;
2325
+ }
2326
+ .detail-panel__section--actions {
2327
+ display: flex;
2328
+ flex-direction: column;
2329
+ gap: 8px;
2330
+ }
2331
+ .detail-panel__button {
2332
+ padding: 6px 12px;
2333
+ border: 1px solid var(--panel-border);
2334
+ border-radius: 4px;
2335
+ background: var(--button-bg);
2336
+ color: var(--button-fg);
2337
+ font-size: 12px;
2338
+ font-weight: 500;
2339
+ cursor: pointer;
2340
+ transition: background 0.1s ease, border-color 0.1s ease;
2341
+ }
2342
+ .detail-panel__button:hover {
2343
+ background: var(--button-hover-bg);
2344
+ border-color: var(--focus-border);
2345
+ }
2346
+ .detail-panel__button--danger {
2347
+ align-self: flex-start;
2348
+ background: transparent;
2349
+ color: #dc6b6b;
2350
+ border-color: rgba(220, 107, 107, 0.25);
2351
+ font-size: 11px;
2352
+ padding: 4px 10px;
2353
+ }
2354
+ .detail-panel__button--danger:hover {
2355
+ background: rgba(220, 107, 107, 0.1);
2356
+ color: #ef4444;
2357
+ border-color: rgba(239, 68, 68, 0.4);
2358
+ }
2359
+ .detail-panel__button--warning {
2360
+ align-self: flex-start;
2361
+ background: rgba(204, 167, 0, 0.1);
2362
+ color: var(--vscode-editorWarning-foreground, #cca700);
2363
+ border-color: var(--vscode-editorWarning-foreground, #cca700);
2364
+ font-size: 11px;
2365
+ padding: 4px 10px;
2366
+ }
2367
+ .detail-panel__button--warning:hover {
2368
+ background: rgba(204, 167, 0, 0.2);
2369
+ }
2370
+ .detail-panel__confirm-label {
2371
+ font-size: 11px;
2372
+ color: var(--editor-fg);
2373
+ line-height: 1.4;
2374
+ }
2375
+ .detail-panel__confirm-actions {
2376
+ display: flex;
2377
+ gap: 6px;
2378
+ }
2379
+ .detail-panel__confirm-actions .detail-panel__button {
2380
+ flex: 1;
2381
+ font-size: 12px;
2382
+ padding: 6px 12px;
2383
+ }
2384
+ .detail-panel__confirm-actions .detail-panel__button--danger {
2385
+ align-self: auto;
2386
+ background: rgba(239, 68, 68, 0.1);
2387
+ color: #ef4444;
2388
+ border-color: rgba(239, 68, 68, 0.3);
2389
+ }
2390
+ .detail-panel__confirm-actions .detail-panel__button--danger:hover {
2391
+ background: rgba(239, 68, 68, 0.2);
2392
+ border-color: #ef4444;
2393
+ }
2394
+ .detail-panel__rationale-section {
2395
+ display: flex;
2396
+ flex-direction: column;
2397
+ gap: 8px;
2398
+ }
2399
+ .detail-panel__rationale-toggle {
2400
+ display: flex;
2401
+ align-items: center;
2402
+ gap: 4px;
2403
+ padding: 0;
2404
+ border: none;
2405
+ background: none;
2406
+ cursor: pointer;
2407
+ color: var(--vscode-descriptionForeground, #888);
2408
+ font-size: 11px;
2409
+ font-weight: 600;
2410
+ text-transform: uppercase;
2411
+ letter-spacing: 0.5px;
2412
+ font-family: inherit;
2413
+ }
2414
+ .detail-panel__rationale-toggle:hover {
2415
+ color: var(--editor-fg);
2416
+ }
2417
+ .detail-panel__rationale-chevron {
2418
+ display: inline-block;
2419
+ font-size: 10px;
2420
+ transition: transform 0.15s ease;
2421
+ }
2422
+ .detail-panel__rationale-chevron--open {
2423
+ transform: rotate(90deg);
2424
+ }
2425
+ .detail-panel__rationale-count {
2426
+ font-weight: 400;
2427
+ font-size: 10px;
2428
+ color: var(--vscode-descriptionForeground, #888);
2429
+ opacity: 0.7;
2430
+ }
2431
+ .detail-panel__rationale-body {
2432
+ display: flex;
2433
+ flex-direction: column;
2434
+ gap: 8px;
2435
+ }
2436
+ .detail-panel__rationale-header {
2437
+ display: flex;
2438
+ align-items: center;
2439
+ justify-content: space-between;
2440
+ gap: 6px;
2441
+ }
2442
+ .detail-panel__rationale-edit-btn {
2443
+ flex-shrink: 0;
2444
+ display: flex;
2445
+ align-items: center;
2446
+ justify-content: center;
2447
+ width: 22px;
2448
+ height: 22px;
2449
+ padding: 0;
2450
+ border: none;
2451
+ border-radius: 3px;
2452
+ background: transparent;
2453
+ color: var(--vscode-descriptionForeground, #888);
2454
+ font-size: 13px;
2455
+ line-height: 1;
2456
+ cursor: pointer;
2457
+ opacity: 0;
2458
+ transition:
2459
+ opacity 0.15s ease,
2460
+ background 0.1s ease,
2461
+ color 0.1s ease;
2462
+ }
2463
+ .detail-panel__rationale-section:hover .detail-panel__rationale-edit-btn {
2464
+ opacity: 1;
2465
+ }
2466
+ .detail-panel__rationale-edit-btn:hover {
2467
+ background: var(--button-bg);
2468
+ color: var(--button-fg);
2469
+ }
2470
+ .detail-panel__rationale-field {
2471
+ display: flex;
2472
+ flex-direction: column;
2473
+ gap: 2px;
2474
+ }
2475
+ .detail-panel__rationale-label {
2476
+ font-size: 10px;
2477
+ font-weight: 600;
2478
+ text-transform: uppercase;
2479
+ letter-spacing: 0.5px;
2480
+ color: #8b5cf6;
2481
+ }
2482
+ .detail-panel__rationale-text {
2483
+ margin: 0;
2484
+ font-size: 11px;
2485
+ line-height: 1.5;
2486
+ color: var(--editor-fg);
2487
+ white-space: pre-wrap;
2488
+ }
2489
+ .detail-panel__rationale-textarea {
2490
+ width: 100%;
2491
+ min-height: 40px;
2492
+ padding: 4px 6px;
2493
+ border: 1px solid var(--focus-border, var(--vscode-focusBorder, #007fd4));
2494
+ border-radius: 3px;
2495
+ background: var(--input-bg, var(--vscode-input-background, #3c3c3c));
2496
+ color: var(--editor-fg);
2497
+ font-family: inherit;
2498
+ font-size: 11px;
2499
+ line-height: 1.5;
2500
+ resize: vertical;
2501
+ outline: none;
2502
+ box-sizing: border-box;
2503
+ }
2504
+ .detail-panel__rationale-textarea::placeholder {
2505
+ color: var(--vscode-descriptionForeground, #888);
2506
+ opacity: 0.6;
2507
+ }
2508
+ .detail-panel__rationale-actions {
2509
+ display: flex;
2510
+ gap: 6px;
2511
+ }
2512
+ .detail-panel__rationale-actions .detail-panel__button {
2513
+ flex: 1;
2514
+ padding: 4px 10px;
2515
+ font-size: 11px;
2516
+ }
2517
+ .detail-panel__rationale-add-btn {
2518
+ padding: 6px 12px;
2519
+ border: 1px dashed var(--vscode-descriptionForeground, #888);
2520
+ border-radius: 4px;
2521
+ background: transparent;
2522
+ color: var(--vscode-descriptionForeground, #888);
2523
+ font-size: 11px;
2524
+ cursor: pointer;
2525
+ transition:
2526
+ background 0.1s ease,
2527
+ color 0.1s ease,
2528
+ border-color 0.1s ease;
2529
+ }
2530
+ .detail-panel__rationale-add-btn:hover {
2531
+ background: rgba(139, 92, 246, 0.08);
2532
+ color: #8b5cf6;
2533
+ border-color: #8b5cf6;
2534
+ }
2535
+ .detail-panel__role-section {
2536
+ display: flex;
2537
+ flex-direction: column;
2538
+ gap: 6px;
2539
+ }
2540
+ .detail-panel__role-select {
2541
+ padding: 4px 6px;
2542
+ border: 1px solid var(--input-border, var(--panel-border));
2543
+ background: var(--input-bg);
2544
+ color: var(--input-fg);
2545
+ font-size: 12px;
2546
+ border-radius: 3px;
2547
+ cursor: pointer;
2548
+ width: 100%;
2549
+ }
2550
+ .detail-panel__role-select:focus {
2551
+ outline: 1px solid var(--focus-border);
2552
+ outline-offset: -1px;
2553
+ }
2554
+ .detail-panel__grain-section {
2555
+ display: flex;
2556
+ flex-direction: column;
2557
+ gap: 8px;
2558
+ }
2559
+ .detail-panel__grain-section:hover .detail-panel__rationale-edit-btn {
2560
+ opacity: 1;
2561
+ }
2562
+
2563
+ /* src/components/Legend/Legend.css */
2564
+ .legend-toggle {
2565
+ z-index: 10;
2566
+ }
2567
+ .legend-toggle__button {
2568
+ display: flex;
2569
+ align-items: center;
2570
+ justify-content: center;
2571
+ width: 28px;
2572
+ height: 28px;
2573
+ border: 1px solid var(--panel-border);
2574
+ border-radius: 6px;
2575
+ background: var(--panel-bg);
2576
+ color: var(--editor-fg);
2577
+ font-size: 16px;
2578
+ font-weight: 600;
2579
+ cursor: pointer;
2580
+ transition: background 0.1s ease, border-color 0.1s ease;
2581
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
2582
+ }
2583
+ .legend-toggle__button:hover {
2584
+ background: var(--button-bg);
2585
+ color: var(--button-fg);
2586
+ }
2587
+ .legend {
2588
+ max-width: 260px;
2589
+ background: var(--panel-bg);
2590
+ border: 1px solid var(--panel-border);
2591
+ border-radius: 6px;
2592
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);
2593
+ overflow: hidden;
2594
+ z-index: 10;
2595
+ }
2596
+ .legend__header {
2597
+ display: flex;
2598
+ align-items: center;
2599
+ justify-content: space-between;
2600
+ padding: 8px 12px;
2601
+ border-bottom: 1px solid var(--panel-border);
2602
+ }
2603
+ .legend__title {
2604
+ font-size: 12px;
2605
+ font-weight: 600;
2606
+ color: var(--editor-fg);
2607
+ text-transform: uppercase;
2608
+ letter-spacing: 0.5px;
2609
+ }
2610
+ .legend__close {
2611
+ display: flex;
2612
+ align-items: center;
2613
+ justify-content: center;
2614
+ width: 20px;
2615
+ height: 20px;
2616
+ border: none;
2617
+ border-radius: 3px;
2618
+ background: transparent;
2619
+ color: var(--editor-fg);
2620
+ font-size: 16px;
2621
+ cursor: pointer;
2622
+ opacity: 0.6;
2623
+ transition: opacity 0.1s ease, background 0.1s ease;
2624
+ }
2625
+ .legend__close:hover {
2626
+ opacity: 1;
2627
+ background: var(--button-bg);
2628
+ color: var(--button-fg);
2629
+ }
2630
+ .legend__content {
2631
+ padding: 8px 0;
2632
+ max-height: min(60vh, 520px);
2633
+ overflow-y: auto;
2634
+ overflow-x: hidden;
2635
+ }
2636
+ .legend__section {
2637
+ padding: 8px 12px;
2638
+ }
2639
+ .legend__section:not(:last-child) {
2640
+ border-bottom: 1px solid var(--panel-border);
2641
+ }
2642
+ .legend__section-title {
2643
+ margin: 0 0 8px 0;
2644
+ font-size: 10px;
2645
+ font-weight: 600;
2646
+ color: var(--editor-fg);
2647
+ text-transform: uppercase;
2648
+ letter-spacing: 0.5px;
2649
+ opacity: 0.7;
2650
+ }
2651
+ .legend__items {
2652
+ display: flex;
2653
+ flex-direction: column;
2654
+ gap: 8px;
2655
+ }
2656
+ .legend__items--cardinality {
2657
+ gap: 6px;
2658
+ }
2659
+ .legend__items--badges {
2660
+ flex-direction: row;
2661
+ flex-wrap: wrap;
2662
+ gap: 8px 14px;
2663
+ }
2664
+ .legend__item {
2665
+ display: flex;
2666
+ align-items: center;
2667
+ gap: 10px;
2668
+ }
2669
+ .legend__item-text {
2670
+ display: flex;
2671
+ flex-direction: column;
2672
+ gap: 1px;
2673
+ }
2674
+ .legend__item-label {
2675
+ font-size: 12px;
2676
+ font-weight: 500;
2677
+ color: var(--editor-fg);
2678
+ }
2679
+ .legend__item-desc {
2680
+ min-width: 0;
2681
+ font-size: 10px;
2682
+ color: var(--editor-fg);
2683
+ opacity: 0.6;
2684
+ }
2685
+ .legend__model-card {
2686
+ width: 36px;
2687
+ height: 24px;
2688
+ border-radius: 3px;
2689
+ border-width: 2px;
2690
+ border-style: solid;
2691
+ background: var(--panel-bg);
2692
+ position: relative;
2693
+ overflow: hidden;
2694
+ }
2695
+ .legend__model-card--logical {
2696
+ border-color: var(--stage-logical);
2697
+ }
2698
+ .legend__model-card--physical {
2699
+ border-color: var(--stage-physical);
2700
+ }
2701
+ .legend__model-card--ghost {
2702
+ border-color: var(--stage-ghost);
2703
+ border-style: dashed;
2704
+ opacity: 0.65;
2705
+ }
2706
+ .legend__model-card--ghost-disabled {
2707
+ border-style: dotted;
2708
+ }
2709
+ .legend__model-header {
2710
+ height: 8px;
2711
+ }
2712
+ .legend__model-header--logical {
2713
+ background: var(--stage-logical);
2714
+ }
2715
+ .legend__model-header--physical {
2716
+ background: var(--stage-physical);
2717
+ }
2718
+ .legend__model-header--ghost {
2719
+ background: var(--stage-ghost);
2720
+ }
2721
+ .legend__edge-sample {
2722
+ width: 48px;
2723
+ height: 16px;
2724
+ flex-shrink: 0;
2725
+ }
2726
+ .legend__edge {
2727
+ stroke-width: 2;
2728
+ }
2729
+ .legend__edge--logical {
2730
+ stroke: var(--stage-logical);
2731
+ }
2732
+ .legend__edge--physical {
2733
+ stroke: var(--stage-physical);
2734
+ }
2735
+ .legend__edge--disc-extra {
2736
+ stroke: var(--discrepancy-extra);
2737
+ stroke-dasharray: 5 3;
2738
+ }
2739
+ .legend__edge--disc-missing {
2740
+ stroke: var(--stage-ghost);
2741
+ stroke-dasharray: 5 3;
2742
+ }
2743
+ .legend__edge--disc-mismatch {
2744
+ stroke: var(--discrepancy-mismatch);
2745
+ }
2746
+ .legend__edge--annotation {
2747
+ stroke: var(--vscode-descriptionForeground, #999);
2748
+ stroke-dasharray: 6 4;
2749
+ stroke-opacity: 0.5;
2750
+ }
2751
+ .legend__annotation-card {
2752
+ width: 36px;
2753
+ height: 24px;
2754
+ border-radius: 3px;
2755
+ border-left: 3px solid #f59e0b;
2756
+ background: #fef3c7;
2757
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
2758
+ }
2759
+ body[data-vscode-theme-kind=vscode-dark] .legend__annotation-card,
2760
+ body[data-vscode-theme-kind=vscode-high-contrast] .legend__annotation-card {
2761
+ background: #422006;
2762
+ }
2763
+ .legend__cardinality {
2764
+ display: flex;
2765
+ align-items: center;
2766
+ gap: 4px;
2767
+ min-width: 56px;
2768
+ }
2769
+ .legend__cardinality-line {
2770
+ width: 28px;
2771
+ height: 8px;
2772
+ }
2773
+ .legend__cardinality-label {
2774
+ font-size: 12px;
2775
+ font-weight: 700;
2776
+ color: var(--stage-logical);
2777
+ min-width: 10px;
2778
+ text-align: center;
2779
+ }
2780
+ .legend__cardinality-label--many {
2781
+ font-size: 16px;
2782
+ }
2783
+ .legend__badge {
2784
+ display: inline-flex;
2785
+ align-items: center;
2786
+ justify-content: center;
2787
+ padding: 2px 5px;
2788
+ border-radius: 3px;
2789
+ font-size: 9px;
2790
+ font-weight: 600;
2791
+ text-transform: uppercase;
2792
+ }
2793
+ .legend__badge--pk {
2794
+ background: rgba(234, 179, 8, 0.2);
2795
+ color: #ca8a04;
2796
+ }
2797
+ .legend__badge--fk {
2798
+ background: rgba(59, 130, 246, 0.2);
2799
+ color: #3b82f6;
2800
+ }
2801
+ .legend__badge--nk {
2802
+ background: rgba(168, 85, 247, 0.2);
2803
+ color: #a855f7;
2804
+ }
2805
+ .legend__subsection-title {
2806
+ margin: 10px 0 6px 0;
2807
+ font-size: 9px;
2808
+ font-weight: 600;
2809
+ color: var(--editor-fg);
2810
+ text-transform: uppercase;
2811
+ letter-spacing: 0.4px;
2812
+ opacity: 0.5;
2813
+ }
2814
+ .legend__items--sources,
2815
+ .legend__items--disc-edges,
2816
+ .legend__items--symbols {
2817
+ gap: 6px;
2818
+ }
2819
+ .legend__items--symbols {
2820
+ margin-top: 10px;
2821
+ }
2822
+ .legend__badge--schema,
2823
+ .legend__badge--source {
2824
+ flex-shrink: 0;
2825
+ min-width: 26px;
2826
+ }
2827
+ .legend__badge--schema {
2828
+ background: rgba(96, 165, 250, 0.2);
2829
+ color: var(--stage-logical);
2830
+ }
2831
+ .legend__badge--source {
2832
+ background: var(--dim-fg);
2833
+ color: var(--editor-bg);
2834
+ }
2835
+ .legend__badge--source-catalog {
2836
+ background: var(--ok-bg);
2837
+ color: var(--ok-fg);
2838
+ }
2839
+ .legend__item-desc code {
2840
+ font-family: var(--vscode-editor-font-family, monospace);
2841
+ font-size: 9px;
2842
+ }
2843
+ .legend__symbols {
2844
+ display: inline-flex;
2845
+ flex-shrink: 0;
2846
+ gap: 4px;
2847
+ min-width: 42px;
2848
+ font-size: 12px;
2849
+ font-weight: 600;
2850
+ color: var(--editor-fg);
2851
+ opacity: 0.8;
2852
+ }
2853
+ .legend__symbols > span {
2854
+ cursor: help;
2855
+ }
2856
+ .legend__note {
2857
+ margin: 8px 0 0 0;
2858
+ font-size: 10px;
2859
+ font-style: italic;
2860
+ color: var(--editor-fg);
2861
+ opacity: 0.5;
2862
+ }
2863
+ .legend__note--lead {
2864
+ margin: -2px 0 8px 0;
2865
+ }
2866
+ .legend__swatch {
2867
+ flex-shrink: 0;
2868
+ width: 14px;
2869
+ height: 14px;
2870
+ border-radius: 2px;
2871
+ border-left-width: 4px;
2872
+ border-left-style: solid;
2873
+ background: var(--panel-bg);
2874
+ }
2875
+ .legend__swatch--extra {
2876
+ border-left-color: var(--discrepancy-extra);
2877
+ background: rgba(245, 158, 11, 0.12);
2878
+ }
2879
+ .legend__swatch--mismatch {
2880
+ border-left-color: var(--discrepancy-mismatch);
2881
+ background: rgba(239, 68, 68, 0.12);
2882
+ }
2883
+ .legend__swatch--missing {
2884
+ border-left-color: var(--stage-ghost);
2885
+ background: rgba(156, 163, 175, 0.12);
2886
+ }
2887
+
2888
+ /* src/styles/theme.css */
2889
+ *,
2890
+ *::before,
2891
+ *::after {
2892
+ box-sizing: border-box;
2893
+ }
2894
+ body {
2895
+ background-color: var(--vscode-editor-background);
2896
+ color: var(--vscode-editor-foreground);
2897
+ font-family: var(--vscode-font-family, "Segoe UI", Tahoma, Geneva, Verdana, sans-serif);
2898
+ font-size: var(--vscode-font-size, 13px);
2899
+ font-weight: var(--vscode-font-weight, 400);
2900
+ }
2901
+ :root {
2902
+ --editor-bg: var(--vscode-editor-background);
2903
+ --editor-fg: var(--vscode-editor-foreground);
2904
+ --panel-bg: var(--vscode-sideBar-background, var(--vscode-editor-background));
2905
+ --panel-border: var(--vscode-panel-border, var(--vscode-editorGroup-border, #444));
2906
+ --button-bg: var(--vscode-button-background);
2907
+ --button-fg: var(--vscode-button-foreground);
2908
+ --button-hover-bg: var(--vscode-button-hoverBackground);
2909
+ --input-bg: var(--vscode-input-background);
2910
+ --input-fg: var(--vscode-input-foreground);
2911
+ --input-border: var(--vscode-input-border, transparent);
2912
+ --focus-border: var(--vscode-focusBorder);
2913
+ --selection-bg: var(--vscode-editor-selectionBackground);
2914
+ --error-fg: var(--vscode-errorForeground);
2915
+ --warning-fg: var(--vscode-editorWarning-foreground, #cca700);
2916
+ --ok-fg: var(--vscode-charts-green, #2f8a48);
2917
+ --ok-bg: rgba(47, 138, 72, 0.12);
2918
+ --ai-fg: var(--vscode-charts-purple, #b48ce8);
2919
+ --ai-bg: rgba(180, 140, 232, 0.10);
2920
+ --dim-fg: var(--vscode-descriptionForeground, #8a94a3);
2921
+ --error-bg: rgba(239, 68, 68, 0.12);
2922
+ --warning-bg: rgba(224, 167, 43, 0.12);
2923
+ --stage-logical: #60a5fa;
2924
+ --stage-logical-bg: rgba(96, 165, 250, 0.08);
2925
+ --stage-logical-hover: rgba(96, 165, 250, 0.12);
2926
+ --stage-logical-ring: rgba(96, 165, 250, 0.3);
2927
+ --stage-physical: #22c55e;
2928
+ --stage-physical-bg: rgba(34, 197, 94, 0.08);
2929
+ --stage-physical-hover: rgba(34, 197, 94, 0.12);
2930
+ --stage-physical-ring: rgba(34, 197, 94, 0.3);
2931
+ --stage-physical-border: rgba(34, 197, 94, 0.2);
2932
+ --stage-ghost: #9ca3af;
2933
+ --stage-ghost-bg: rgba(156, 163, 175, 0.08);
2934
+ --discrepancy-extra: #f59e0b;
2935
+ --discrepancy-mismatch: #ef4444;
2936
+ --model-built: var(--stage-physical);
2937
+ --model-built-bg: var(--stage-physical-bg);
2938
+ --model-built-text: #ffffff;
2939
+ --model-approved: #14b8a6;
2940
+ --model-approved-bg: rgba(20, 184, 166, 0.08);
2941
+ --model-approved-text: #ffffff;
2942
+ --model-design: var(--stage-logical);
2943
+ --model-design-bg: var(--stage-logical-bg);
2944
+ --model-design-text: #ffffff;
2945
+ --model-missing: var(--stage-ghost);
2946
+ --model-missing-bg: var(--stage-ghost-bg);
2947
+ --edge-built: var(--stage-logical);
2948
+ --edge-design: var(--stage-logical);
2949
+ --layer-bronze: #cd7f32;
2950
+ --layer-bronze-bg: rgba(205, 127, 50, 0.2);
2951
+ --layer-silver: #a0a0a0;
2952
+ --layer-silver-bg: rgba(192, 192, 192, 0.2);
2953
+ --layer-gold: #d4a800;
2954
+ --layer-gold-bg: rgba(255, 215, 0, 0.2);
2955
+ }
2956
+ .react-flow {
2957
+ background-color: var(--editor-bg);
2958
+ }
2959
+ .react-flow__attribution {
2960
+ display: none;
2961
+ }
2962
+
2963
+ /* src/styles.css */