pg_insights 0.3.1 → 0.4.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/pg_insights/application.js +91 -24
  3. data/app/assets/javascripts/pg_insights/plan_performance.js +53 -0
  4. data/app/assets/javascripts/pg_insights/query_comparison.js +1129 -0
  5. data/app/assets/javascripts/pg_insights/results/view_toggles.js +26 -5
  6. data/app/assets/javascripts/pg_insights/results.js +231 -2
  7. data/app/assets/stylesheets/pg_insights/analysis.css +2628 -0
  8. data/app/assets/stylesheets/pg_insights/application.css +51 -1
  9. data/app/assets/stylesheets/pg_insights/results.css +12 -1
  10. data/app/controllers/pg_insights/insights_controller.rb +486 -9
  11. data/app/helpers/pg_insights/application_helper.rb +339 -0
  12. data/app/helpers/pg_insights/insights_helper.rb +567 -0
  13. data/app/jobs/pg_insights/query_analysis_job.rb +142 -0
  14. data/app/models/pg_insights/query_execution.rb +198 -0
  15. data/app/services/pg_insights/query_analysis_service.rb +269 -0
  16. data/app/views/layouts/pg_insights/application.html.erb +8 -1
  17. data/app/views/pg_insights/insights/_compare_view.html.erb +264 -0
  18. data/app/views/pg_insights/insights/_empty_state.html.erb +9 -0
  19. data/app/views/pg_insights/insights/_execution_table_view.html.erb +86 -0
  20. data/app/views/pg_insights/insights/_history_bar.html.erb +33 -0
  21. data/app/views/pg_insights/insights/_perf_view.html.erb +244 -0
  22. data/app/views/pg_insights/insights/_plan_nodes.html.erb +12 -0
  23. data/app/views/pg_insights/insights/_plan_tree.html.erb +30 -0
  24. data/app/views/pg_insights/insights/_plan_tree_modern.html.erb +12 -0
  25. data/app/views/pg_insights/insights/_plan_view.html.erb +159 -0
  26. data/app/views/pg_insights/insights/_query_panel.html.erb +3 -2
  27. data/app/views/pg_insights/insights/_result.html.erb +19 -4
  28. data/app/views/pg_insights/insights/_results_info.html.erb +33 -9
  29. data/app/views/pg_insights/insights/_results_info_empty.html.erb +10 -0
  30. data/app/views/pg_insights/insights/_results_panel.html.erb +7 -9
  31. data/app/views/pg_insights/insights/_results_table.html.erb +0 -5
  32. data/app/views/pg_insights/insights/_visual_view.html.erb +212 -0
  33. data/app/views/pg_insights/insights/index.html.erb +4 -1
  34. data/app/views/pg_insights/timeline/compare.html.erb +3 -3
  35. data/config/routes.rb +6 -0
  36. data/lib/generators/pg_insights/install_generator.rb +20 -14
  37. data/lib/generators/pg_insights/templates/db/migrate/create_pg_insights_query_executions.rb +45 -0
  38. data/lib/pg_insights/version.rb +1 -1
  39. data/lib/pg_insights.rb +30 -2
  40. metadata +20 -2
@@ -0,0 +1,2628 @@
1
+ /* ===========================================
2
+ QUERY ANALYSIS STYLES - CONFLICT-FREE
3
+ =========================================== */
4
+
5
+ /* Ensure analysis view content is visible */
6
+ #plan-view, #perf-view, #visual-view {
7
+ width: 100%;
8
+ min-height: 200px;
9
+ background: white;
10
+ overflow-y: auto;
11
+ }
12
+
13
+ /* ===========================================
14
+ SHARED ANALYSIS DASHBOARD STYLES
15
+ =========================================== */
16
+ .analysis-dashboard {
17
+ padding: 16px;
18
+ font-size: 13px;
19
+ line-height: 1.4;
20
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
21
+ }
22
+
23
+ .analysis-header {
24
+ margin-bottom: 20px;
25
+ padding-bottom: 16px;
26
+ border-bottom: 1px solid #e2e8f0;
27
+ }
28
+
29
+ .section-title {
30
+ font-size: 14px;
31
+ font-weight: 600;
32
+ color: #1f2937;
33
+ margin: 0 0 12px 0;
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 6px;
37
+ }
38
+
39
+ .metrics-section {
40
+ margin-bottom: 20px;
41
+ }
42
+
43
+ .metrics-section:last-child {
44
+ margin-bottom: 0;
45
+ }
46
+
47
+ /* ===========================================
48
+ PLAN VIEW SPECIFIC STYLES
49
+ =========================================== */
50
+
51
+ /* Metric Chips */
52
+ .metric-chips {
53
+ display: flex;
54
+ gap: 12px;
55
+ margin-bottom: 12px;
56
+ flex-wrap: wrap;
57
+ }
58
+
59
+ .chip {
60
+ display: inline-flex;
61
+ align-items: center;
62
+ gap: 6px;
63
+ padding: 6px 12px;
64
+ border-radius: 16px;
65
+ font-size: 12px;
66
+ font-weight: 500;
67
+ }
68
+
69
+ .chip.primary {
70
+ background: #dbeafe;
71
+ color: #1e40af;
72
+ }
73
+
74
+ .chip.success {
75
+ background: #dcfce7;
76
+ color: #166534;
77
+ }
78
+
79
+ .chip.info {
80
+ background: #fef3c7;
81
+ color: #92400e;
82
+ }
83
+
84
+ .chip-label {
85
+ font-weight: 500;
86
+ opacity: 0.8;
87
+ }
88
+
89
+ .chip-value {
90
+ font-weight: 600;
91
+ }
92
+
93
+ .execution-summary {
94
+ margin-top: 8px;
95
+ }
96
+
97
+ .summary-text {
98
+ font-size: 12px;
99
+ color: #6b7280;
100
+ font-weight: 500;
101
+ font-family: 'SF Mono', Monaco, Consolas, monospace;
102
+ }
103
+
104
+ /* Plan Visualization */
105
+ .plan-visualization {
106
+ background: #f8fafc;
107
+ border-radius: 6px;
108
+ padding: 16px;
109
+ }
110
+
111
+ .plan-flow {
112
+ font-family: 'SF Mono', Monaco, Consolas, monospace;
113
+ font-size: 12px;
114
+ }
115
+
116
+ .plan-nodes-container {
117
+ display: flex;
118
+ flex-direction: column;
119
+ gap: 8px;
120
+ }
121
+
122
+ .plan-node-compact {
123
+ display: flex;
124
+ align-items: flex-start;
125
+ gap: 8px;
126
+ margin-bottom: 6px;
127
+ }
128
+
129
+ .flow-connector {
130
+ color: #9ca3af;
131
+ font-family: monospace;
132
+ font-size: 12px;
133
+ line-height: 20px;
134
+ min-width: 20px;
135
+ margin-top: 2px;
136
+ }
137
+
138
+ .node-content {
139
+ flex: 1;
140
+ background: white;
141
+ border: 1px solid #e5e7eb;
142
+ border-radius: 6px;
143
+ padding: 10px 12px;
144
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
145
+ }
146
+
147
+ .node-header {
148
+ display: flex;
149
+ align-items: center;
150
+ gap: 8px;
151
+ margin-bottom: 4px;
152
+ }
153
+
154
+ .node-icon {
155
+ font-size: 14px;
156
+ }
157
+
158
+ .node-title {
159
+ font-weight: 600;
160
+ color: #1f2937;
161
+ flex: 1;
162
+ }
163
+
164
+ .node-metrics {
165
+ font-size: 11px;
166
+ color: #6b7280;
167
+ margin-bottom: 4px;
168
+ font-weight: 500;
169
+ }
170
+
171
+ .node-details-compact {
172
+ font-size: 10px;
173
+ color: #9ca3af;
174
+ font-style: italic;
175
+ line-height: 1.3;
176
+ }
177
+
178
+ /* Node Type Colors */
179
+ .node-scan-seq .node-content {
180
+ border-left: 3px solid #ef4444;
181
+ }
182
+
183
+ .node-scan-index .node-content {
184
+ border-left: 3px solid #22c55e;
185
+ }
186
+
187
+ .node-join .node-content {
188
+ border-left: 3px solid #3b82f6;
189
+ }
190
+
191
+ .node-sort .node-content {
192
+ border-left: 3px solid #8b5cf6;
193
+ }
194
+
195
+ .node-aggregate .node-content {
196
+ border-left: 3px solid #f59e0b;
197
+ }
198
+
199
+ .node-limit .node-content {
200
+ border-left: 3px solid #06b6d4;
201
+ }
202
+
203
+ .node-other .node-content {
204
+ border-left: 3px solid #6b7280;
205
+ }
206
+
207
+ /* Empty States */
208
+ .analysis-empty {
209
+ text-align: center;
210
+ padding: 40px 20px;
211
+ color: #6b7280;
212
+ }
213
+
214
+ .empty-icon {
215
+ font-size: 32px;
216
+ margin-bottom: 12px;
217
+ opacity: 0.5;
218
+ }
219
+
220
+ .empty-message {
221
+ font-size: 14px;
222
+ color: #9ca3af;
223
+ }
224
+
225
+ .plan-parse-error {
226
+ display: flex;
227
+ align-items: center;
228
+ gap: 8px;
229
+ padding: 12px;
230
+ background: #fef2f2;
231
+ border: 1px solid #fecaca;
232
+ border-radius: 6px;
233
+ color: #dc2626;
234
+ font-size: 13px;
235
+ }
236
+
237
+ .error-indicator {
238
+ font-size: 16px;
239
+ }
240
+
241
+ /* ===========================================
242
+ PERF VIEW SPECIFIC STYLES
243
+ =========================================== */
244
+
245
+ /* Timing Breakdown */
246
+ .timing-breakdown {
247
+ background: white;
248
+ border: 1px solid #e5e7eb;
249
+ border-radius: 6px;
250
+ padding: 14px;
251
+ }
252
+
253
+ .timing-item {
254
+ display: flex;
255
+ align-items: center;
256
+ gap: 12px;
257
+ margin-bottom: 10px;
258
+ padding: 6px 0;
259
+ }
260
+
261
+ .timing-item:last-of-type {
262
+ margin-bottom: 0;
263
+ }
264
+
265
+ .timing-label {
266
+ font-weight: 500;
267
+ color: #374151;
268
+ min-width: 80px;
269
+ font-size: 12px;
270
+ }
271
+
272
+ .timing-bar-container {
273
+ flex: 1;
274
+ height: 6px;
275
+ background: #f3f4f6;
276
+ border-radius: 3px;
277
+ overflow: hidden;
278
+ position: relative;
279
+ }
280
+
281
+ .timing-bar {
282
+ height: 100%;
283
+ border-radius: 3px;
284
+ transition: width 0.8s ease;
285
+ }
286
+
287
+ .planning-bar {
288
+ background: linear-gradient(90deg, #f59e0b, #d97706);
289
+ }
290
+
291
+ .execution-bar {
292
+ background: linear-gradient(90deg, #22c55e, #16a34a);
293
+ }
294
+
295
+ .timing-value {
296
+ font-weight: 600;
297
+ color: #1f2937;
298
+ font-size: 12px;
299
+ min-width: 60px;
300
+ text-align: right;
301
+ }
302
+
303
+ .timing-total {
304
+ display: flex;
305
+ align-items: center;
306
+ gap: 12px;
307
+ padding-top: 12px;
308
+ border-top: 1px solid #e5e7eb;
309
+ margin-top: 8px;
310
+ }
311
+
312
+ .total-label {
313
+ color: #1f2937;
314
+ font-weight: 600;
315
+ }
316
+
317
+ .total-value {
318
+ font-size: 14px;
319
+ font-weight: 700;
320
+ color: #059669;
321
+ }
322
+
323
+ /* KPI Grid */
324
+ .kpi-grid {
325
+ display: grid;
326
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
327
+ gap: 12px;
328
+ }
329
+
330
+ .kpi-card {
331
+ background: white;
332
+ border: 1px solid #e5e7eb;
333
+ border-radius: 6px;
334
+ padding: 12px;
335
+ display: flex;
336
+ align-items: center;
337
+ justify-content: center;
338
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
339
+ }
340
+
341
+ .kpi-card:hover {
342
+ transform: translateY(-1px);
343
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
344
+ }
345
+
346
+ .kpi-content {
347
+ flex: 1;
348
+ text-align: center;
349
+ }
350
+
351
+ .kpi-value {
352
+ font-size: 16px;
353
+ font-weight: 700;
354
+ color: #1f2937;
355
+ margin-bottom: 2px;
356
+ line-height: 1.2;
357
+ }
358
+
359
+ .kpi-label {
360
+ font-size: 11px;
361
+ color: #6b7280;
362
+ font-weight: 500;
363
+ text-transform: uppercase;
364
+ letter-spacing: 0.3px;
365
+ margin-bottom: 2px;
366
+ }
367
+
368
+ .kpi-hint {
369
+ font-size: 10px;
370
+ color: #9ca3af;
371
+ line-height: 1.2;
372
+ }
373
+
374
+ .cost-card {
375
+ border-left: 4px solid #f59e0b;
376
+ }
377
+
378
+ .rows-card {
379
+ border-left: 4px solid #3b82f6;
380
+ }
381
+
382
+ .efficiency-card {
383
+ border-left: 4px solid #8b5cf6;
384
+ }
385
+
386
+ /* Recommendations */
387
+ .recommendations-list {
388
+ display: flex;
389
+ flex-direction: column;
390
+ gap: 12px;
391
+ }
392
+
393
+ .recommendation-item {
394
+ display: flex;
395
+ align-items: flex-start;
396
+ gap: 12px;
397
+ padding: 12px 16px;
398
+ background: #fffbeb;
399
+ border: 1px solid #fed7aa;
400
+ border-radius: 6px;
401
+ }
402
+
403
+ .rec-number {
404
+ background: #f59e0b;
405
+ color: white;
406
+ width: 20px;
407
+ height: 20px;
408
+ border-radius: 50%;
409
+ display: flex;
410
+ align-items: center;
411
+ justify-content: center;
412
+ font-size: 11px;
413
+ font-weight: 600;
414
+ flex-shrink: 0;
415
+ }
416
+
417
+ .rec-content {
418
+ flex: 1;
419
+ }
420
+
421
+ .rec-text {
422
+ font-size: 13px;
423
+ color: #92400e;
424
+ line-height: 1.4;
425
+ }
426
+
427
+ /* Optimization Success */
428
+ .optimization-success {
429
+ background: white;
430
+ border: 1px solid #d1fae5;
431
+ border-radius: 8px;
432
+ padding: 20px;
433
+ }
434
+
435
+ .success-visual {
436
+ display: flex;
437
+ align-items: center;
438
+ gap: 16px;
439
+ margin-bottom: 16px;
440
+ }
441
+
442
+ .success-checkmark {
443
+ width: 40px;
444
+ height: 40px;
445
+ background: linear-gradient(135deg, #22c55e, #16a34a);
446
+ color: white;
447
+ border-radius: 50%;
448
+ display: flex;
449
+ align-items: center;
450
+ justify-content: center;
451
+ font-size: 20px;
452
+ font-weight: 700;
453
+ flex-shrink: 0;
454
+ }
455
+
456
+ .success-message {
457
+ flex: 1;
458
+ }
459
+
460
+ .success-primary {
461
+ font-size: 16px;
462
+ font-weight: 600;
463
+ color: #166534;
464
+ margin-bottom: 4px;
465
+ }
466
+
467
+ .success-secondary {
468
+ font-size: 14px;
469
+ color: #16a34a;
470
+ opacity: 0.8;
471
+ }
472
+
473
+ .performance-highlights {
474
+ display: grid;
475
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
476
+ gap: 12px;
477
+ }
478
+
479
+ .highlight-item {
480
+ display: flex;
481
+ align-items: center;
482
+ gap: 8px;
483
+ padding: 8px 12px;
484
+ background: #f0fdf4;
485
+ border-radius: 6px;
486
+ font-size: 12px;
487
+ color: #166534;
488
+ font-weight: 500;
489
+ }
490
+
491
+ .highlight-icon {
492
+ font-size: 14px;
493
+ }
494
+
495
+ /* ===========================================
496
+ HISTORY BAR & COMPARISON STYLES
497
+ =========================================== */
498
+
499
+ /* Results section wrapper */
500
+ .results-section-wrapper {
501
+ flex: 1;
502
+ min-width: 0;
503
+ display: flex;
504
+ flex-direction: column;
505
+ overflow-y: auto;
506
+ max-height: calc(100vh - 100px);
507
+ }
508
+
509
+ /* History Bar - Clean & Compact */
510
+ .history-bar {
511
+ background: #fafafa;
512
+ border: 1px solid #d4d4d8;
513
+ border-radius: 4px;
514
+ margin-bottom: 12px;
515
+ font-size: 13px;
516
+ }
517
+
518
+ .history-bar.collapsed .history-content {
519
+ display: none;
520
+ }
521
+
522
+ .history-bar.expanded .expand-arrow {
523
+ transform: rotate(90deg);
524
+ }
525
+
526
+ .history-header {
527
+ display: flex;
528
+ justify-content: space-between;
529
+ align-items: center;
530
+ padding: 8px 12px;
531
+ cursor: pointer;
532
+ user-select: none;
533
+ background: #f4f4f5;
534
+ border-bottom: 1px solid #d4d4d8;
535
+ }
536
+
537
+ .history-header:hover {
538
+ background: #e4e4e7;
539
+ }
540
+
541
+ .history-title {
542
+ display: flex;
543
+ align-items: center;
544
+ gap: 6px;
545
+ font-size: 13px;
546
+ font-weight: 500;
547
+ color: #18181b;
548
+ }
549
+
550
+ .history-icon {
551
+ font-size: 14px;
552
+ color: #71717a;
553
+ }
554
+
555
+ .history-count {
556
+ font-size: 11px;
557
+ color: #71717a;
558
+ font-weight: 400;
559
+ }
560
+
561
+ .history-controls {
562
+ display: flex;
563
+ align-items: center;
564
+ gap: 8px;
565
+ }
566
+
567
+ .selected-count {
568
+ font-size: 11px;
569
+ color: #059669;
570
+ font-weight: 500;
571
+ }
572
+
573
+ .btn-compare {
574
+ padding: 3px 8px;
575
+ background: #059669;
576
+ color: white;
577
+ border: none;
578
+ border-radius: 3px;
579
+ font-size: 11px;
580
+ font-weight: 500;
581
+ cursor: pointer;
582
+ }
583
+
584
+ .btn-compare:hover {
585
+ background: #047857;
586
+ }
587
+
588
+ .expand-arrow {
589
+ font-size: 10px;
590
+ color: #71717a;
591
+ transform: rotate(0deg);
592
+ transition: transform 0.15s ease;
593
+ }
594
+
595
+ .history-content {
596
+ padding: 12px;
597
+ background: white;
598
+ }
599
+
600
+ .history-loading {
601
+ display: flex;
602
+ align-items: center;
603
+ justify-content: center;
604
+ gap: 8px;
605
+ padding: 16px;
606
+ color: #71717a;
607
+ font-size: 13px;
608
+ }
609
+
610
+ .history-loading .loading-spinner {
611
+ width: 14px;
612
+ height: 14px;
613
+ border: 1px solid #e4e4e7;
614
+ border-left: 1px solid #3b82f6;
615
+ border-radius: 50%;
616
+ animation: spin 1s linear infinite;
617
+ }
618
+
619
+ .history-items {
620
+ display: grid;
621
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
622
+ gap: 8px;
623
+ }
624
+
625
+ .history-item {
626
+ display: flex;
627
+ align-items: center;
628
+ gap: 8px;
629
+ padding: 8px 10px;
630
+ background: white;
631
+ border: 1px solid #e4e4e7;
632
+ border-radius: 3px;
633
+ cursor: pointer;
634
+ font-size: 12px;
635
+ }
636
+
637
+ .history-item:hover {
638
+ background: #fafafa;
639
+ border-color: #d4d4d8;
640
+ }
641
+
642
+ .history-item.selected {
643
+ background: #eff6ff;
644
+ border-color: #3b82f6;
645
+ }
646
+
647
+ .history-checkbox {
648
+ flex-shrink: 0;
649
+ }
650
+
651
+ .history-details {
652
+ flex: 1;
653
+ min-width: 0;
654
+ }
655
+
656
+ .history-title-text {
657
+ font-size: 12px;
658
+ font-weight: 500;
659
+ color: #18181b;
660
+ white-space: nowrap;
661
+ overflow: hidden;
662
+ text-overflow: ellipsis;
663
+ margin-bottom: 2px;
664
+ }
665
+
666
+ .history-meta {
667
+ font-size: 10px;
668
+ color: #71717a;
669
+ display: flex;
670
+ gap: 6px;
671
+ }
672
+
673
+ .history-performance {
674
+ width: 6px;
675
+ height: 6px;
676
+ border-radius: 50%;
677
+ flex-shrink: 0;
678
+ align-self: center;
679
+ }
680
+
681
+ .performance-excellent { background: #22c55e; }
682
+ .performance-good { background: #f59e0b; }
683
+ .performance-fair { background: #ef4444; }
684
+ .performance-poor { background: #dc2626; }
685
+ .performance-unknown { background: #71717a; }
686
+
687
+ .history-empty {
688
+ text-align: center;
689
+ padding: 24px 16px;
690
+ color: #71717a;
691
+ font-size: 13px;
692
+ }
693
+
694
+ .empty-icon {
695
+ font-size: 24px;
696
+ margin-bottom: 8px;
697
+ opacity: 0.7;
698
+ }
699
+
700
+ /* Compare View - Professional & Compact */
701
+ .compare-container {
702
+ padding: 16px;
703
+ background: #fafafa;
704
+ border-radius: 4px;
705
+ border: 1px solid #d4d4d8;
706
+ }
707
+
708
+ #compare-view {
709
+ overflow-y: auto;
710
+ max-height: none;
711
+ }
712
+
713
+ .compare-header {
714
+ margin-bottom: 16px;
715
+ padding-bottom: 12px;
716
+ border-bottom: 1px solid #d4d4d8;
717
+ display: none;
718
+ }
719
+
720
+ .compare-header.active {
721
+ display: block;
722
+ }
723
+
724
+ .query-selector {
725
+ display: flex;
726
+ align-items: center;
727
+ gap: 16px;
728
+ margin-bottom: 12px;
729
+ }
730
+
731
+ .query-card {
732
+ flex: 1;
733
+ background: white;
734
+ border: 1px solid #e4e4e7;
735
+ border-radius: 4px;
736
+ padding: 12px;
737
+ text-align: left;
738
+ min-height: 80px;
739
+ display: flex;
740
+ flex-direction: column;
741
+ justify-content: center;
742
+ font-size: 13px;
743
+ }
744
+
745
+ .query-card.selected {
746
+ background: #eff6ff;
747
+ border-color: #3b82f6;
748
+ }
749
+
750
+ .query-label {
751
+ font-size: 10px;
752
+ font-weight: 600;
753
+ color: #71717a;
754
+ text-transform: uppercase;
755
+ letter-spacing: 0.5px;
756
+ margin-bottom: 4px;
757
+ }
758
+
759
+ .query-card.selected .query-label {
760
+ color: #3b82f6;
761
+ }
762
+
763
+ .query-title {
764
+ font-size: 13px;
765
+ font-weight: 600;
766
+ color: #18181b;
767
+ margin-bottom: 4px;
768
+ line-height: 1.3;
769
+ overflow: hidden;
770
+ text-overflow: ellipsis;
771
+ display: -webkit-box;
772
+ -webkit-line-clamp: 2;
773
+ -webkit-box-orient: vertical;
774
+ }
775
+
776
+ .query-summary {
777
+ font-size: 11px;
778
+ color: #059669;
779
+ font-weight: 500;
780
+ }
781
+
782
+ .vs-indicator {
783
+ display: flex;
784
+ flex-direction: column;
785
+ align-items: center;
786
+ gap: 6px;
787
+ flex-shrink: 0;
788
+ padding: 8px 0;
789
+ }
790
+
791
+ .vs-text {
792
+ font-size: 14px;
793
+ font-weight: 600;
794
+ color: #71717a;
795
+ background: white;
796
+ border: 1px solid #e4e4e7;
797
+ border-radius: 3px;
798
+ width: 32px;
799
+ height: 32px;
800
+ display: flex;
801
+ align-items: center;
802
+ justify-content: center;
803
+ }
804
+
805
+ .swap-btn {
806
+ background: #f4f4f5;
807
+ color: #71717a;
808
+ border: 1px solid #e4e4e7;
809
+ border-radius: 3px;
810
+ padding: 4px;
811
+ font-size: 12px;
812
+ cursor: pointer;
813
+ width: 24px;
814
+ height: 24px;
815
+ display: flex;
816
+ align-items: center;
817
+ justify-content: center;
818
+ }
819
+
820
+ .swap-btn:hover {
821
+ background: #e4e4e7;
822
+ }
823
+
824
+ .compare-actions {
825
+ text-align: center;
826
+ margin-top: 8px;
827
+ }
828
+
829
+ .btn-analyze {
830
+ padding: 8px 16px;
831
+ background: #059669;
832
+ color: white;
833
+ border: none;
834
+ border-radius: 3px;
835
+ font-size: 13px;
836
+ font-weight: 500;
837
+ cursor: pointer;
838
+ }
839
+
840
+ .btn-analyze:hover {
841
+ background: #047857;
842
+ }
843
+
844
+ .btn-analyze:disabled {
845
+ background: #a1a1aa;
846
+ cursor: not-allowed;
847
+ }
848
+
849
+ /* Phase 2: Enhanced Comparison Results */
850
+ .comparison-results {
851
+ margin-top: 16px;
852
+ }
853
+
854
+ /* Enhanced Metrics Overview */
855
+ .metrics-overview {
856
+ display: grid;
857
+ grid-template-columns: repeat(4, 1fr);
858
+ gap: 12px;
859
+ margin-bottom: 16px;
860
+ }
861
+
862
+ .metric-card {
863
+ background: white;
864
+ border: 1px solid #e4e4e7;
865
+ border-radius: 4px;
866
+ padding: 12px;
867
+ text-align: center;
868
+ }
869
+
870
+ .metric-label {
871
+ font-size: 11px;
872
+ color: #71717a;
873
+ font-weight: 600;
874
+ text-transform: uppercase;
875
+ margin-bottom: 8px;
876
+ }
877
+
878
+ .metric-values {
879
+ display: flex;
880
+ align-items: center;
881
+ justify-content: center;
882
+ gap: 8px;
883
+ margin-bottom: 4px;
884
+ }
885
+
886
+ .value-a, .value-b {
887
+ font-size: 15px;
888
+ font-weight: 600;
889
+ color: #18181b;
890
+ }
891
+
892
+ .vs-divider {
893
+ font-size: 11px;
894
+ color: #71717a;
895
+ font-weight: 400;
896
+ }
897
+
898
+ .metric-difference {
899
+ font-size: 11px;
900
+ font-weight: 600;
901
+ }
902
+
903
+ .metric-difference.better { color: #059669; }
904
+ .metric-difference.worse { color: #dc2626; }
905
+ .metric-difference.same { color: #71717a; }
906
+
907
+ /* Detailed Metrics */
908
+ .detailed-metrics h5 {
909
+ font-size: 13px;
910
+ font-weight: 600;
911
+ color: #18181b;
912
+ margin: 16px 0 8px 0;
913
+ }
914
+
915
+ .performance-comparison,
916
+ .plans-comparison,
917
+ .insights-comparison {
918
+ margin-bottom: 16px;
919
+ background: white;
920
+ border: 1px solid #e4e4e7;
921
+ border-radius: 4px;
922
+ }
923
+
924
+ .performance-comparison h4,
925
+ .plans-comparison h4,
926
+ .insights-comparison h4 {
927
+ font-size: 14px;
928
+ font-weight: 600;
929
+ color: #18181b;
930
+ margin: 0;
931
+ padding: 10px 12px;
932
+ background: #f4f4f5;
933
+ border-bottom: 1px solid #e4e4e7;
934
+ display: flex;
935
+ align-items: center;
936
+ gap: 6px;
937
+ }
938
+
939
+ /* ===========================================
940
+ METRICS TABLE STYLES - PROPERLY SCOPED
941
+ =========================================== */
942
+
943
+ /* Traditional Metrics Table (for comparison views) */
944
+ .metrics-table-wrapper {
945
+ overflow-x: auto;
946
+ }
947
+
948
+ table.metrics-table {
949
+ width: 100%;
950
+ border-collapse: collapse;
951
+ background: white;
952
+ font-size: 13px;
953
+ border-radius: 8px;
954
+ overflow: hidden;
955
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
956
+ }
957
+
958
+ table.metrics-table th {
959
+ background: linear-gradient(135deg, #f8fafc, #f1f5f9);
960
+ color: #1e293b;
961
+ padding: 10px 14px;
962
+ text-align: left;
963
+ font-weight: 600;
964
+ font-size: 12px;
965
+ border-bottom: 1px solid #e2e8f0;
966
+ text-transform: uppercase;
967
+ letter-spacing: 0.3px;
968
+ }
969
+
970
+ table.metrics-table td {
971
+ padding: 10px 14px;
972
+ border-bottom: 1px solid #f1f5f9;
973
+ font-size: 12px;
974
+ font-weight: 500;
975
+ vertical-align: middle;
976
+ color: #374151;
977
+ }
978
+
979
+ table.metrics-table tr:last-child td {
980
+ border-bottom: none;
981
+ }
982
+
983
+ table.metrics-table tr:hover {
984
+ background: rgba(59, 130, 246, 0.02);
985
+ }
986
+
987
+ /* Performance Metrics Table (Flexbox Layout for Perf Tab) */
988
+ .perf-metrics-table {
989
+ display: flex;
990
+ flex-direction: column;
991
+ gap: 6px;
992
+ }
993
+
994
+ .perf-metrics-table .metric-row {
995
+ display: flex;
996
+ justify-content: space-between;
997
+ align-items: center;
998
+ padding: 8px 0;
999
+ font-size: 12px;
1000
+ transition: background-color 0.2s ease;
1001
+ }
1002
+
1003
+ .perf-metrics-table .metric-row:hover {
1004
+ background: rgba(59, 130, 246, 0.03);
1005
+ margin: 0 -8px;
1006
+ padding: 8px 8px;
1007
+ border-radius: 4px;
1008
+ }
1009
+
1010
+ .perf-metrics-table .metric-row:not(:last-child) {
1011
+ border-bottom: 1px solid rgba(59, 130, 246, 0.08);
1012
+ }
1013
+
1014
+ .perf-metrics-table .metric-label {
1015
+ color: #64748b;
1016
+ font-weight: 600;
1017
+ text-transform: uppercase;
1018
+ font-size: 11px;
1019
+ letter-spacing: 0.3px;
1020
+ }
1021
+
1022
+ .perf-metrics-table .metric-value {
1023
+ font-weight: 700;
1024
+ color: #1e293b;
1025
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
1026
+ background: linear-gradient(135deg, #f8fafc, #f1f5f9);
1027
+ padding: 3px 8px;
1028
+ border-radius: 4px;
1029
+ border: 1px solid #e2e8f0;
1030
+ }
1031
+
1032
+ /* Timeline Metrics Table (Flexbox Layout for Timeline Compare) */
1033
+ .timeline-metrics-table {
1034
+ padding: 16px;
1035
+ }
1036
+
1037
+ .timeline-metrics-table .metric-row {
1038
+ display: flex;
1039
+ align-items: center;
1040
+ gap: 16px;
1041
+ padding: 8px 0;
1042
+ border-bottom: 1px solid #e5e7eb;
1043
+ }
1044
+
1045
+ .timeline-metrics-table .metric-row:last-child {
1046
+ border-bottom: none;
1047
+ }
1048
+
1049
+ .timeline-metrics-table .metric-name {
1050
+ flex: 1;
1051
+ font-size: 13px;
1052
+ font-weight: 600;
1053
+ color: #374151;
1054
+ }
1055
+
1056
+ .timeline-metrics-table .metric-values {
1057
+ display: flex;
1058
+ align-items: center;
1059
+ gap: 8px;
1060
+ font-size: 13px;
1061
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
1062
+ }
1063
+
1064
+ .timeline-metrics-table .arrow {
1065
+ color: #6b7280;
1066
+ }
1067
+
1068
+ .timeline-metrics-table .metric-change {
1069
+ font-size: 13px;
1070
+ font-weight: 600;
1071
+ min-width: 60px;
1072
+ text-align: right;
1073
+ }
1074
+
1075
+ .timeline-metrics-table .metric-change.positive {
1076
+ color: #059669;
1077
+ }
1078
+
1079
+ .timeline-metrics-table .metric-change.negative {
1080
+ color: #dc2626;
1081
+ }
1082
+
1083
+ /* ===========================================
1084
+ END METRICS TABLE STYLES
1085
+ =========================================== */
1086
+
1087
+ .metric-better {
1088
+ color: #059669;
1089
+ font-weight: 600;
1090
+ }
1091
+
1092
+ .metric-worse {
1093
+ color: #dc2626;
1094
+ font-weight: 600;
1095
+ }
1096
+
1097
+ .metric-same {
1098
+ color: #71717a;
1099
+ font-weight: 400;
1100
+ }
1101
+
1102
+ .winner-summary {
1103
+ background: #f0fdf4;
1104
+ border: 1px solid #bbf7d0;
1105
+ border-radius: 4px;
1106
+ padding: 12px;
1107
+ margin: 16px 0;
1108
+ text-align: center;
1109
+ font-size: 13px;
1110
+ }
1111
+
1112
+ .winner-badge {
1113
+ display: flex;
1114
+ align-items: center;
1115
+ justify-content: center;
1116
+ gap: 6px;
1117
+ font-size: 13px;
1118
+ font-weight: 600;
1119
+ color: #166534;
1120
+ }
1121
+
1122
+ .winner-icon {
1123
+ font-size: 16px;
1124
+ }
1125
+
1126
+ /* Enhanced Plan Comparison */
1127
+ .plan-overview {
1128
+ display: flex;
1129
+ justify-content: space-between;
1130
+ align-items: center;
1131
+ padding: 12px;
1132
+ background: #fafafa;
1133
+ border: 1px solid #e4e4e7;
1134
+ border-radius: 4px;
1135
+ margin-bottom: 12px;
1136
+ font-size: 12px;
1137
+ }
1138
+
1139
+ .plan-stats {
1140
+ display: flex;
1141
+ gap: 24px;
1142
+ }
1143
+
1144
+ .stat-item {
1145
+ display: flex;
1146
+ flex-direction: column;
1147
+ gap: 2px;
1148
+ }
1149
+
1150
+ .stat-label {
1151
+ font-size: 11px;
1152
+ color: #71717a;
1153
+ font-weight: 600;
1154
+ }
1155
+
1156
+ .stat-values {
1157
+ font-size: 12px;
1158
+ color: #18181b;
1159
+ font-weight: 600;
1160
+ }
1161
+
1162
+ .plan-controls {
1163
+ display: flex;
1164
+ gap: 4px;
1165
+ }
1166
+
1167
+ .plan-toggle {
1168
+ padding: 4px 8px;
1169
+ background: white;
1170
+ border: 1px solid #e4e4e7;
1171
+ border-radius: 3px;
1172
+ font-size: 11px;
1173
+ font-weight: 500;
1174
+ cursor: pointer;
1175
+ color: #71717a;
1176
+ }
1177
+
1178
+ .plan-toggle.active,
1179
+ .plan-toggle:hover {
1180
+ background: #059669;
1181
+ color: white;
1182
+ border-color: #059669;
1183
+ }
1184
+
1185
+ .plans-grid {
1186
+ display: grid;
1187
+ grid-template-columns: 1fr 1fr;
1188
+ gap: 12px;
1189
+ padding: 12px;
1190
+ }
1191
+
1192
+ .plan-column {
1193
+ background: white;
1194
+ border: 1px solid #e4e4e7;
1195
+ border-radius: 4px;
1196
+ overflow: hidden;
1197
+ }
1198
+
1199
+ .plan-header {
1200
+ display: flex;
1201
+ justify-content: space-between;
1202
+ align-items: center;
1203
+ padding: 8px 12px;
1204
+ background: #f4f4f5;
1205
+ border-bottom: 1px solid #e4e4e7;
1206
+ }
1207
+
1208
+ .plan-header h5 {
1209
+ font-size: 13px;
1210
+ font-weight: 600;
1211
+ color: #18181b;
1212
+ margin: 0;
1213
+ }
1214
+
1215
+ .plan-meta {
1216
+ display: flex;
1217
+ gap: 8px;
1218
+ font-size: 11px;
1219
+ }
1220
+
1221
+ .plan-efficiency,
1222
+ .plan-bottleneck {
1223
+ padding: 2px 6px;
1224
+ border-radius: 2px;
1225
+ font-weight: 500;
1226
+ }
1227
+
1228
+ .plan-efficiency {
1229
+ background: #dcfce7;
1230
+ color: #166534;
1231
+ }
1232
+
1233
+ .plan-bottleneck {
1234
+ background: #fef2f2;
1235
+ color: #991b1b;
1236
+ }
1237
+
1238
+ /* Plan Overlay View */
1239
+ .plan-overlay {
1240
+ background: white;
1241
+ border: 1px solid #e4e4e7;
1242
+ border-radius: 4px;
1243
+ padding: 12px;
1244
+ }
1245
+
1246
+ .overlay-controls {
1247
+ display: flex;
1248
+ justify-content: space-between;
1249
+ align-items: center;
1250
+ padding: 8px 12px;
1251
+ background: #fafafa;
1252
+ border: 1px solid #e4e4e7;
1253
+ border-radius: 4px;
1254
+ margin-bottom: 12px;
1255
+ font-size: 12px;
1256
+ }
1257
+
1258
+ .overlay-legend {
1259
+ display: flex;
1260
+ gap: 16px;
1261
+ }
1262
+
1263
+ .legend-item {
1264
+ display: flex;
1265
+ align-items: center;
1266
+ gap: 6px;
1267
+ font-weight: 500;
1268
+ }
1269
+
1270
+ .legend-color {
1271
+ width: 12px;
1272
+ height: 12px;
1273
+ border-radius: 2px;
1274
+ border: 1px solid #d4d4d8;
1275
+ }
1276
+
1277
+ .query-a-color { background: #3b82f6; }
1278
+ .query-b-color { background: #059669; }
1279
+ .common-color { background: #71717a; }
1280
+
1281
+ .overlay-options {
1282
+ display: flex;
1283
+ gap: 12px;
1284
+ }
1285
+
1286
+ .overlay-options label {
1287
+ display: flex;
1288
+ align-items: center;
1289
+ gap: 4px;
1290
+ font-size: 11px;
1291
+ color: #71717a;
1292
+ cursor: pointer;
1293
+ }
1294
+
1295
+ .overlay-options input[type="checkbox"] {
1296
+ width: 12px;
1297
+ height: 12px;
1298
+ }
1299
+
1300
+ .overlay-content {
1301
+ background: white;
1302
+ border: 1px solid #e4e4e7;
1303
+ border-radius: 4px;
1304
+ padding: 16px;
1305
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
1306
+ font-size: 12px;
1307
+ line-height: 1.6;
1308
+ max-height: 400px;
1309
+ overflow-y: auto;
1310
+ position: relative;
1311
+ }
1312
+
1313
+ .overlay-node {
1314
+ padding: 4px 8px;
1315
+ margin: 2px 0;
1316
+ border-radius: 2px;
1317
+ position: relative;
1318
+ }
1319
+
1320
+ .overlay-node.query-a {
1321
+ background: rgba(59, 130, 246, 0.1);
1322
+ border-left: 3px solid #3b82f6;
1323
+ }
1324
+
1325
+ .overlay-node.query-b {
1326
+ background: rgba(5, 150, 105, 0.1);
1327
+ border-left: 3px solid #059669;
1328
+ }
1329
+
1330
+ .overlay-node.common {
1331
+ background: rgba(113, 113, 122, 0.05);
1332
+ border-left: 3px solid #71717a;
1333
+ }
1334
+
1335
+ .overlay-node.different {
1336
+ background: rgba(239, 68, 68, 0.1);
1337
+ border-left: 3px solid #ef4444;
1338
+ border-right: 3px solid #ef4444;
1339
+ }
1340
+
1341
+ .overlay-metrics {
1342
+ position: absolute;
1343
+ right: 8px;
1344
+ top: 4px;
1345
+ font-size: 10px;
1346
+ color: #71717a;
1347
+ background: rgba(255, 255, 255, 0.9);
1348
+ padding: 2px 4px;
1349
+ border-radius: 2px;
1350
+ }
1351
+
1352
+ /* Plan Differences View */
1353
+ .plan-differences {
1354
+ padding: 12px;
1355
+ background: white;
1356
+ border: 1px solid #e4e4e7;
1357
+ border-radius: 4px;
1358
+ }
1359
+
1360
+ .diff-summary {
1361
+ background: #fffbeb;
1362
+ border: 1px solid #fed7aa;
1363
+ border-radius: 4px;
1364
+ padding: 12px;
1365
+ margin-bottom: 12px;
1366
+ font-size: 13px;
1367
+ }
1368
+
1369
+ .diff-details {
1370
+ display: grid;
1371
+ gap: 8px;
1372
+ }
1373
+
1374
+ .plan-content {
1375
+ background: white;
1376
+ padding: 12px;
1377
+ font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
1378
+ font-size: 12px;
1379
+ line-height: 1.4;
1380
+ max-height: 300px;
1381
+ overflow-y: auto;
1382
+ color: #18181b;
1383
+ }
1384
+
1385
+ .plan-content::-webkit-scrollbar {
1386
+ width: 4px;
1387
+ }
1388
+
1389
+ .plan-content::-webkit-scrollbar-track {
1390
+ background: #f4f4f5;
1391
+ }
1392
+
1393
+ .plan-content::-webkit-scrollbar-thumb {
1394
+ background: #d4d4d8;
1395
+ border-radius: 2px;
1396
+ }
1397
+
1398
+ /* Advanced Optimization Insights */
1399
+ .optimization-score {
1400
+ display: grid;
1401
+ grid-template-columns: 1fr auto 1fr;
1402
+ gap: 16px;
1403
+ align-items: center;
1404
+ padding: 16px;
1405
+ background: white;
1406
+ border: 1px solid #e4e4e7;
1407
+ border-radius: 4px;
1408
+ margin-bottom: 16px;
1409
+ }
1410
+
1411
+ .score-card {
1412
+ text-align: center;
1413
+ padding: 12px;
1414
+ background: #fafafa;
1415
+ border: 1px solid #e4e4e7;
1416
+ border-radius: 4px;
1417
+ }
1418
+
1419
+ .score-header {
1420
+ font-size: 11px;
1421
+ color: #71717a;
1422
+ font-weight: 600;
1423
+ text-transform: uppercase;
1424
+ margin-bottom: 8px;
1425
+ }
1426
+
1427
+ .score-value {
1428
+ font-size: 24px;
1429
+ font-weight: 700;
1430
+ color: #18181b;
1431
+ margin-bottom: 4px;
1432
+ }
1433
+
1434
+ .score-grade {
1435
+ font-size: 12px;
1436
+ font-weight: 600;
1437
+ padding: 2px 8px;
1438
+ border-radius: 2px;
1439
+ }
1440
+
1441
+ .grade-a { background: #dcfce7; color: #166534; }
1442
+ .grade-b { background: #fef3c7; color: #92400e; }
1443
+ .grade-c { background: #fed7aa; color: #9a3412; }
1444
+ .grade-d { background: #fecaca; color: #991b1b; }
1445
+
1446
+ .score-comparison {
1447
+ text-align: center;
1448
+ font-size: 12px;
1449
+ color: #71717a;
1450
+ }
1451
+
1452
+ .score-arrow {
1453
+ font-size: 20px;
1454
+ margin-bottom: 4px;
1455
+ }
1456
+
1457
+ .score-improvement {
1458
+ font-weight: 600;
1459
+ }
1460
+
1461
+ .score-improvement.better { color: #059669; }
1462
+ .score-improvement.worse { color: #dc2626; }
1463
+
1464
+ /* Key Findings */
1465
+ .findings-section {
1466
+ margin-bottom: 16px;
1467
+ }
1468
+
1469
+ .findings-section h5 {
1470
+ font-size: 14px;
1471
+ font-weight: 600;
1472
+ color: #18181b;
1473
+ margin: 0 0 12px 0;
1474
+ }
1475
+
1476
+ .findings-grid {
1477
+ display: grid;
1478
+ grid-template-columns: repeat(3, 1fr);
1479
+ gap: 12px;
1480
+ }
1481
+
1482
+ .finding-category {
1483
+ background: white;
1484
+ border: 1px solid #e4e4e7;
1485
+ border-radius: 4px;
1486
+ padding: 12px;
1487
+ }
1488
+
1489
+ .finding-category h6 {
1490
+ font-size: 12px;
1491
+ font-weight: 600;
1492
+ color: #18181b;
1493
+ margin: 0 0 8px 0;
1494
+ }
1495
+
1496
+ .finding-category ul {
1497
+ margin: 0;
1498
+ padding: 0;
1499
+ list-style: none;
1500
+ }
1501
+
1502
+ .finding-category li {
1503
+ font-size: 12px;
1504
+ color: #71717a;
1505
+ padding: 4px 0;
1506
+ border-bottom: 1px solid #f4f4f5;
1507
+ }
1508
+
1509
+ .finding-category li:last-child {
1510
+ border-bottom: none;
1511
+ }
1512
+
1513
+ /* Recommendations */
1514
+ .recommendations-section {
1515
+ margin-bottom: 16px;
1516
+ }
1517
+
1518
+ .recommendations-section h5 {
1519
+ font-size: 14px;
1520
+ font-weight: 600;
1521
+ color: #18181b;
1522
+ margin: 0 0 12px 0;
1523
+ }
1524
+
1525
+ .recommendation-item {
1526
+ display: flex;
1527
+ align-items: flex-start;
1528
+ gap: 8px;
1529
+ padding: 12px;
1530
+ background: #f0fdf4;
1531
+ border: 1px solid #bbf7d0;
1532
+ border-radius: 4px;
1533
+ margin-bottom: 8px;
1534
+ font-size: 13px;
1535
+ }
1536
+
1537
+ .recommendation-priority {
1538
+ font-size: 10px;
1539
+ font-weight: 600;
1540
+ text-transform: uppercase;
1541
+ padding: 2px 6px;
1542
+ border-radius: 2px;
1543
+ flex-shrink: 0;
1544
+ }
1545
+
1546
+ .priority-high { background: #fecaca; color: #991b1b; }
1547
+ .priority-medium { background: #fef3c7; color: #92400e; }
1548
+ .priority-low { background: #e0e7ff; color: #3730a3; }
1549
+
1550
+ .recommendation-text {
1551
+ flex: 1;
1552
+ color: #166534;
1553
+ line-height: 1.4;
1554
+ font-weight: 500;
1555
+ }
1556
+
1557
+ /* Traditional Insights */
1558
+ .insights-list {
1559
+ padding: 12px;
1560
+ }
1561
+
1562
+ .insight-item {
1563
+ display: flex;
1564
+ align-items: flex-start;
1565
+ gap: 8px;
1566
+ padding: 12px;
1567
+ background: #fffbeb;
1568
+ border: 1px solid #fed7aa;
1569
+ border-radius: 4px;
1570
+ margin-bottom: 8px;
1571
+ font-size: 13px;
1572
+ }
1573
+
1574
+ .insight-icon {
1575
+ font-size: 14px;
1576
+ color: #d97706;
1577
+ margin-top: 1px;
1578
+ flex-shrink: 0;
1579
+ }
1580
+
1581
+ .insight-text {
1582
+ flex: 1;
1583
+ color: #92400e;
1584
+ line-height: 1.4;
1585
+ font-weight: 400;
1586
+ }
1587
+
1588
+ .comparison-loading {
1589
+ display: flex;
1590
+ flex-direction: column;
1591
+ align-items: center;
1592
+ justify-content: center;
1593
+ padding: 32px 16px;
1594
+ color: #71717a;
1595
+ background: white;
1596
+ border: 1px solid #e4e4e7;
1597
+ border-radius: 4px;
1598
+ margin: 16px 0;
1599
+ font-size: 13px;
1600
+ }
1601
+
1602
+ .comparison-loading .loading-spinner {
1603
+ width: 20px;
1604
+ height: 20px;
1605
+ border: 2px solid #f4f4f5;
1606
+ border-left: 2px solid #3b82f6;
1607
+ border-radius: 50%;
1608
+ animation: spin 1s linear infinite;
1609
+ margin-bottom: 12px;
1610
+ }
1611
+
1612
+ .comparison-loading p {
1613
+ font-size: 13px;
1614
+ font-weight: 400;
1615
+ color: #71717a;
1616
+ }
1617
+
1618
+ .comparison-empty {
1619
+ text-align: center;
1620
+ padding: 40px 16px;
1621
+ color: #71717a;
1622
+ background: white;
1623
+ border: 1px solid #e4e4e7;
1624
+ border-radius: 4px;
1625
+ margin: 16px 0;
1626
+ font-size: 13px;
1627
+ }
1628
+
1629
+ .comparison-empty .empty-icon {
1630
+ font-size: 32px;
1631
+ margin-bottom: 12px;
1632
+ opacity: 0.5;
1633
+ }
1634
+
1635
+ .comparison-empty h3 {
1636
+ font-size: 15px;
1637
+ font-weight: 600;
1638
+ color: #18181b;
1639
+ margin-bottom: 8px;
1640
+ }
1641
+
1642
+ .comparison-empty p {
1643
+ font-size: 13px;
1644
+ line-height: 1.4;
1645
+ max-width: 300px;
1646
+ margin: 0 auto;
1647
+ color: #71717a;
1648
+ }
1649
+
1650
+ /* ===========================================
1651
+ RESPONSIVE DESIGN
1652
+ =========================================== */
1653
+ @media (max-width: 768px) {
1654
+ .analysis-dashboard {
1655
+ padding: 12px;
1656
+ }
1657
+
1658
+ .metric-chips {
1659
+ flex-direction: column;
1660
+ }
1661
+
1662
+ .chip {
1663
+ justify-content: center;
1664
+ }
1665
+
1666
+ .perf-status-banner {
1667
+ flex-direction: column;
1668
+ text-align: center;
1669
+ gap: 12px;
1670
+ }
1671
+
1672
+ .timing-item {
1673
+ flex-direction: column;
1674
+ align-items: stretch;
1675
+ gap: 6px;
1676
+ }
1677
+
1678
+ .timing-label {
1679
+ min-width: auto;
1680
+ }
1681
+
1682
+ .timing-value {
1683
+ text-align: left;
1684
+ }
1685
+
1686
+ .kpi-grid {
1687
+ grid-template-columns: 1fr;
1688
+ }
1689
+
1690
+ .performance-highlights {
1691
+ grid-template-columns: 1fr;
1692
+ }
1693
+
1694
+
1695
+ }
1696
+
1697
+ @media (max-width: 480px) {
1698
+ .analysis-dashboard {
1699
+ padding: 8px;
1700
+ }
1701
+
1702
+ .metrics-section {
1703
+ margin-bottom: 16px;
1704
+ }
1705
+
1706
+ .node-content {
1707
+ padding: 8px 10px;
1708
+ }
1709
+
1710
+ .kpi-card {
1711
+ padding: 12px;
1712
+ }
1713
+
1714
+ .success-visual {
1715
+ flex-direction: column;
1716
+ text-align: center;
1717
+ }
1718
+ }
1719
+
1720
+ /* Enhanced Plan View Styles */
1721
+ .plan-analysis-section, .plan-breakdown-section, .plan-insights-section {
1722
+ margin: 16px 0;
1723
+ padding: 16px;
1724
+ background: white;
1725
+ border-radius: 8px;
1726
+ border: 1px solid #e5e7eb;
1727
+ }
1728
+
1729
+ .plan-stats-grid {
1730
+ display: grid;
1731
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
1732
+ gap: 12px;
1733
+ margin-top: 12px;
1734
+ }
1735
+
1736
+ .stat-card {
1737
+ display: flex;
1738
+ align-items: center;
1739
+ padding: 12px;
1740
+ background: #f8fafc;
1741
+ border: 1px solid #e2e8f0;
1742
+ border-radius: 6px;
1743
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
1744
+ }
1745
+
1746
+ .stat-card:hover {
1747
+ transform: translateY(-1px);
1748
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
1749
+ }
1750
+
1751
+ .stat-content {
1752
+ flex: 1;
1753
+ text-align: center;
1754
+ }
1755
+
1756
+ .stat-value {
1757
+ font-size: 16px;
1758
+ font-weight: 600;
1759
+ color: #1f2937;
1760
+ margin-bottom: 2px;
1761
+ line-height: 1.2;
1762
+ }
1763
+
1764
+ .stat-label {
1765
+ font-size: 11px;
1766
+ color: #6b7280;
1767
+ text-transform: uppercase;
1768
+ letter-spacing: 0.5px;
1769
+ line-height: 1.2;
1770
+ }
1771
+
1772
+ .details-grid {
1773
+ display: grid;
1774
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
1775
+ gap: 10px;
1776
+ margin-top: 12px;
1777
+ }
1778
+
1779
+ .detail-item {
1780
+ display: flex;
1781
+ align-items: center;
1782
+ justify-content: space-between;
1783
+ padding: 10px 12px;
1784
+ background: #f1f5f9;
1785
+ border-radius: 6px;
1786
+ }
1787
+
1788
+ .detail-label {
1789
+ font-size: 12px;
1790
+ color: #475569;
1791
+ font-weight: 500;
1792
+ }
1793
+
1794
+ .detail-value {
1795
+ font-weight: 600;
1796
+ color: #1e293b;
1797
+ font-size: 12px;
1798
+ }
1799
+
1800
+ .plan-insights-grid {
1801
+ display: grid;
1802
+ grid-template-columns: 1fr 1fr;
1803
+ gap: 24px;
1804
+ margin-top: 16px;
1805
+ }
1806
+
1807
+ .insights-column h5 {
1808
+ font-size: 14px;
1809
+ font-weight: 600;
1810
+ color: #374151;
1811
+ margin-bottom: 12px;
1812
+ display: flex;
1813
+ align-items: center;
1814
+ gap: 8px;
1815
+ }
1816
+
1817
+ .insight-list {
1818
+ list-style: none;
1819
+ padding: 0;
1820
+ margin: 0;
1821
+ }
1822
+
1823
+ .insight-list li {
1824
+ padding: 8px 12px;
1825
+ margin-bottom: 6px;
1826
+ background: #f9fafb;
1827
+ border-left: 3px solid #d1d5db;
1828
+ border-radius: 0 4px 4px 0;
1829
+ font-size: 13px;
1830
+ color: #374151;
1831
+ }
1832
+
1833
+ /* Enhanced Performance View Styles - REMOVED CONFLICTING RULES */
1834
+ .advanced-metrics-table {
1835
+ margin-top: 16px;
1836
+ }
1837
+
1838
+ .metric-score {
1839
+ display: inline-block;
1840
+ padding: 4px 8px;
1841
+ border-radius: 4px;
1842
+ font-weight: 600;
1843
+ font-size: 12px;
1844
+ text-transform: uppercase;
1845
+ }
1846
+
1847
+ /* Compact Performance Dashboard */
1848
+ .perf-dashboard {
1849
+ background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
1850
+ min-height: 100%;
1851
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
1852
+ }
1853
+
1854
+ .perf-header {
1855
+ background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
1856
+ border-bottom: 1px solid #e2e8f0;
1857
+ padding: 14px 18px;
1858
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
1859
+ }
1860
+
1861
+ .perf-status {
1862
+ display: flex;
1863
+ align-items: center;
1864
+ gap: 14px;
1865
+ font-size: 14px;
1866
+ }
1867
+
1868
+ .perf-status.status-warning {
1869
+ color: #d97706;
1870
+ }
1871
+
1872
+ .status-warning-header {
1873
+ background: linear-gradient(135deg, #fefce8 0%, #fef3c7 20%, #ffffff 100%) !important;
1874
+ border-left: 3px solid #f59e0b !important;
1875
+ }
1876
+
1877
+ .perf-status.status-success {
1878
+ color: #059669;
1879
+ }
1880
+
1881
+ .status-success-header {
1882
+ background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 20%, #ffffff 100%) !important;
1883
+ border-left: 3px solid #22c55e !important;
1884
+ }
1885
+
1886
+ .status-icon {
1887
+ font-weight: bold;
1888
+ font-size: 16px;
1889
+ width: 24px;
1890
+ height: 24px;
1891
+ border-radius: 50%;
1892
+ display: flex;
1893
+ align-items: center;
1894
+ justify-content: center;
1895
+ background: rgba(255, 255, 255, 0.8);
1896
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
1897
+ }
1898
+
1899
+ .perf-status.status-warning .status-icon {
1900
+ background: linear-gradient(135deg, #fbbf24, #f59e0b);
1901
+ color: white;
1902
+ }
1903
+
1904
+ .perf-status.status-success .status-icon {
1905
+ background: linear-gradient(135deg, #34d399, #10b981);
1906
+ color: white;
1907
+ }
1908
+
1909
+ .status-text {
1910
+ font-weight: 600;
1911
+ flex: 1;
1912
+ letter-spacing: -0.01em;
1913
+ }
1914
+
1915
+ .perf-rating {
1916
+ font-size: 11px;
1917
+ font-weight: 700;
1918
+ padding: 6px 10px;
1919
+ background: linear-gradient(135deg, #e2e8f0, #cbd5e1);
1920
+ border-radius: 16px;
1921
+ color: #475569;
1922
+ text-transform: uppercase;
1923
+ letter-spacing: 0.5px;
1924
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.05);
1925
+ transition: all 0.2s ease;
1926
+ }
1927
+
1928
+ .perf-rating:hover {
1929
+ transform: translateY(-1px);
1930
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.1);
1931
+ }
1932
+
1933
+ /* Compact Metrics Grid */
1934
+ .perf-metrics-grid {
1935
+ display: grid;
1936
+ grid-template-columns: 1fr 1fr 1fr;
1937
+ gap: 1px;
1938
+ background: linear-gradient(45deg, #e2e8f0, #cbd5e1);
1939
+ margin: 0;
1940
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
1941
+ }
1942
+
1943
+ .metrics-group {
1944
+ background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
1945
+ padding: 18px;
1946
+ position: relative;
1947
+ transition: all 0.3s ease;
1948
+ }
1949
+
1950
+ .metrics-group:hover {
1951
+ transform: translateY(-1px);
1952
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
1953
+ }
1954
+
1955
+ .metrics-group.timing-group {
1956
+ background: linear-gradient(135deg, #fef7ff 0%, #faf5ff 50%, #ffffff 100%);
1957
+ border-top: 2px solid #a855f7;
1958
+ }
1959
+
1960
+ .metrics-group:nth-child(2) {
1961
+ background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 50%, #ffffff 100%);
1962
+ border-top: 2px solid #0ea5e9;
1963
+ }
1964
+
1965
+ .metrics-group.analysis-group {
1966
+ background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 50%, #ffffff 100%);
1967
+ border-top: 2px solid #22c55e;
1968
+ }
1969
+
1970
+ .group-header {
1971
+ font-size: 13px;
1972
+ font-weight: 700;
1973
+ color: #1e293b;
1974
+ margin-bottom: 14px;
1975
+ padding-bottom: 8px;
1976
+ border-bottom: 1px solid rgba(0, 0, 0, 0.06);
1977
+ text-transform: uppercase;
1978
+ letter-spacing: 0.5px;
1979
+ position: relative;
1980
+ }
1981
+
1982
+ .timing-group .group-header {
1983
+ color: #7c3aed;
1984
+ }
1985
+
1986
+ .metrics-group:nth-child(2) .group-header {
1987
+ color: #0369a1;
1988
+ }
1989
+
1990
+ .analysis-group .group-header {
1991
+ color: #166534;
1992
+ }
1993
+
1994
+ /* Timing Bars */
1995
+ .timing-bars {
1996
+ display: flex;
1997
+ flex-direction: column;
1998
+ gap: 8px;
1999
+ }
2000
+
2001
+ .timing-row {
2002
+ display: flex;
2003
+ align-items: center;
2004
+ gap: 8px;
2005
+ font-size: 12px;
2006
+ }
2007
+
2008
+ .timing-row.total-row {
2009
+ margin-top: 4px;
2010
+ padding-top: 8px;
2011
+ border-top: 1px solid #f1f5f9;
2012
+ font-weight: 600;
2013
+ }
2014
+
2015
+ .timing-label {
2016
+ width: 60px;
2017
+ color: #6b7280;
2018
+ font-size: 11px;
2019
+ text-transform: uppercase;
2020
+ letter-spacing: 0.5px;
2021
+ }
2022
+
2023
+ .timing-bar-container {
2024
+ flex: 1;
2025
+ height: 6px;
2026
+ background: linear-gradient(90deg, #f1f5f9, #e2e8f0);
2027
+ border-radius: 3px;
2028
+ overflow: hidden;
2029
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
2030
+ }
2031
+
2032
+ .timing-bar {
2033
+ height: 100%;
2034
+ border-radius: 3px;
2035
+ transition: all 0.3s ease;
2036
+ animation: progressFill 0.8s ease-out;
2037
+ }
2038
+
2039
+ @keyframes progressFill {
2040
+ from {
2041
+ width: 0 !important;
2042
+ }
2043
+ to {
2044
+ width: inherit;
2045
+ }
2046
+ }
2047
+
2048
+ .planning-bar {
2049
+ background: linear-gradient(90deg, #8b5cf6, #7c3aed);
2050
+ box-shadow: 0 1px 3px rgba(139, 92, 246, 0.3);
2051
+ }
2052
+
2053
+ .execution-bar {
2054
+ background: linear-gradient(90deg, #10b981, #059669);
2055
+ box-shadow: 0 1px 3px rgba(16, 185, 129, 0.3);
2056
+ }
2057
+
2058
+ .timing-value, .timing-total {
2059
+ width: 60px;
2060
+ text-align: right;
2061
+ font-weight: 600;
2062
+ color: #1e293b;
2063
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
2064
+ font-size: 11px;
2065
+ }
2066
+
2067
+ .timing-total {
2068
+ color: #7c3aed;
2069
+ font-weight: 700;
2070
+ }
2071
+
2072
+ /* DUPLICATE STYLES REMOVED - NOW PROPERLY ORGANIZED ABOVE */
2073
+
2074
+ /* Analysis Table */
2075
+ .analysis-table {
2076
+ display: flex;
2077
+ flex-direction: column;
2078
+ gap: 8px;
2079
+ }
2080
+
2081
+ .analysis-row {
2082
+ display: flex;
2083
+ align-items: center;
2084
+ gap: 10px;
2085
+ padding: 10px 0;
2086
+ font-size: 12px;
2087
+ transition: background-color 0.2s ease;
2088
+ }
2089
+
2090
+ .analysis-row:hover {
2091
+ background: rgba(34, 197, 94, 0.03);
2092
+ margin: 0 -8px;
2093
+ padding: 10px 8px;
2094
+ border-radius: 6px;
2095
+ }
2096
+
2097
+ .analysis-row:not(:last-child) {
2098
+ border-bottom: 1px solid rgba(34, 197, 94, 0.08);
2099
+ }
2100
+
2101
+ .analysis-metric {
2102
+ flex: 1;
2103
+ font-weight: 600;
2104
+ color: #166534;
2105
+ text-transform: uppercase;
2106
+ font-size: 11px;
2107
+ letter-spacing: 0.3px;
2108
+ }
2109
+
2110
+ .analysis-score {
2111
+ font-weight: 700;
2112
+ font-size: 10px;
2113
+ text-transform: uppercase;
2114
+ padding: 4px 8px;
2115
+ border-radius: 12px;
2116
+ min-width: 65px;
2117
+ text-align: center;
2118
+ letter-spacing: 0.5px;
2119
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
2120
+ border: 1px solid rgba(255, 255, 255, 0.2);
2121
+ }
2122
+
2123
+ .analysis-desc {
2124
+ flex: 1;
2125
+ color: #6b7280;
2126
+ font-size: 10px;
2127
+ text-align: right;
2128
+ font-style: italic;
2129
+ }
2130
+
2131
+ /* Recommendations */
2132
+ .recommendations-section {
2133
+ background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 20%, #ffffff 100%);
2134
+ border-top: 1px solid #f59e0b;
2135
+ padding: 18px;
2136
+ box-shadow: inset 0 1px 0 rgba(251, 191, 36, 0.1);
2137
+ }
2138
+
2139
+ .recommendations-section .group-header {
2140
+ color: #92400e;
2141
+ border-bottom-color: rgba(251, 191, 36, 0.2);
2142
+ }
2143
+
2144
+ .recommendations-list {
2145
+ display: flex;
2146
+ flex-direction: column;
2147
+ gap: 8px;
2148
+ }
2149
+
2150
+ .recommendation {
2151
+ display: flex;
2152
+ align-items: flex-start;
2153
+ gap: 10px;
2154
+ font-size: 12px;
2155
+ color: #92400e;
2156
+ padding: 8px 12px;
2157
+ background: rgba(255, 255, 255, 0.6);
2158
+ border-radius: 6px;
2159
+ border-left: 3px solid #f59e0b;
2160
+ transition: all 0.2s ease;
2161
+ line-height: 1.4;
2162
+ }
2163
+
2164
+ .recommendation:hover {
2165
+ background: rgba(255, 255, 255, 0.8);
2166
+ transform: translateX(2px);
2167
+ box-shadow: 0 2px 4px rgba(245, 158, 11, 0.1);
2168
+ }
2169
+
2170
+ .rec-icon {
2171
+ color: #f59e0b;
2172
+ font-weight: bold;
2173
+ margin-top: 1px;
2174
+ font-size: 14px;
2175
+ }
2176
+
2177
+ /* Responsive adjustments for desktop tools */
2178
+ @media (min-width: 1200px) {
2179
+ .perf-metrics-grid {
2180
+ grid-template-columns: 1fr 1fr 1.2fr;
2181
+ }
2182
+
2183
+ .analysis-group {
2184
+ grid-column: span 1;
2185
+ }
2186
+ }
2187
+
2188
+ @media (max-width: 1024px) {
2189
+ .perf-metrics-grid {
2190
+ grid-template-columns: 1fr 1fr;
2191
+ }
2192
+
2193
+ .analysis-group {
2194
+ grid-column: span 2;
2195
+ }
2196
+ }
2197
+
2198
+ @media (max-width: 768px) {
2199
+ .perf-metrics-grid {
2200
+ grid-template-columns: 1fr;
2201
+ gap: 1px;
2202
+ }
2203
+
2204
+ .timing-row {
2205
+ gap: 6px;
2206
+ }
2207
+
2208
+ .timing-label {
2209
+ width: 50px;
2210
+ }
2211
+
2212
+ .timing-value, .timing-total {
2213
+ width: 50px;
2214
+ }
2215
+ }
2216
+
2217
+ /* Enhanced chip styles */
2218
+ .chip.secondary {
2219
+ background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);
2220
+ color: white;
2221
+ }
2222
+
2223
+ .chip.accent {
2224
+ background: linear-gradient(135deg, #06b6d4 0%, #0891b2 100%);
2225
+ color: white;
2226
+ }
2227
+
2228
+ .chip.warning {
2229
+ background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
2230
+ color: white;
2231
+ }
2232
+
2233
+ /* Metric score coloring */
2234
+ .metric-score {
2235
+ color: #374151;
2236
+ }
2237
+
2238
+ .score-excellent {
2239
+ background: linear-gradient(135deg, #22c55e, #16a34a) !important;
2240
+ color: white !important;
2241
+ font-weight: 700;
2242
+ }
2243
+
2244
+ .score-good {
2245
+ background: linear-gradient(135deg, #3b82f6, #2563eb) !important;
2246
+ color: white !important;
2247
+ font-weight: 700;
2248
+ }
2249
+
2250
+ .score-fair {
2251
+ background: linear-gradient(135deg, #f59e0b, #d97706) !important;
2252
+ color: white !important;
2253
+ font-weight: 700;
2254
+ }
2255
+
2256
+ .score-poor {
2257
+ background: linear-gradient(135deg, #ef4444, #dc2626) !important;
2258
+ color: white !important;
2259
+ font-weight: 700;
2260
+ }
2261
+
2262
+ .score-none {
2263
+ background: linear-gradient(135deg, #9ca3af, #6b7280) !important;
2264
+ color: white !important;
2265
+ font-weight: 700;
2266
+ }
2267
+
2268
+ /* Enhanced Performance Header */
2269
+ .status-details {
2270
+ flex: 1;
2271
+ display: flex;
2272
+ flex-direction: column;
2273
+ gap: 2px;
2274
+ }
2275
+
2276
+ .status-context {
2277
+ font-size: 11px;
2278
+ font-weight: 400;
2279
+ opacity: 0.85;
2280
+ letter-spacing: 0.01em;
2281
+ }
2282
+
2283
+ .perf-rating-group {
2284
+ display: flex;
2285
+ flex-direction: column;
2286
+ align-items: flex-end;
2287
+ gap: 4px;
2288
+ }
2289
+
2290
+ .perf-score {
2291
+ font-size: 10px;
2292
+ font-weight: 600;
2293
+ color: #64748b;
2294
+ padding: 2px 6px;
2295
+ background: rgba(255, 255, 255, 0.7);
2296
+ border-radius: 8px;
2297
+ border: 1px solid rgba(0, 0, 0, 0.1);
2298
+ }
2299
+
2300
+ /* Enhanced Group Headers */
2301
+ .group-header {
2302
+ display: flex;
2303
+ align-items: center;
2304
+ justify-content: space-between;
2305
+ font-size: 13px;
2306
+ font-weight: 700;
2307
+ color: #1e293b;
2308
+ margin-bottom: 14px;
2309
+ padding-bottom: 8px;
2310
+ border-bottom: 1px solid rgba(0, 0, 0, 0.06);
2311
+ text-transform: uppercase;
2312
+ letter-spacing: 0.5px;
2313
+ position: relative;
2314
+ }
2315
+
2316
+ .header-title {
2317
+ font-size: 12px;
2318
+ font-weight: 700;
2319
+ }
2320
+
2321
+ .header-insight {
2322
+ font-size: 10px;
2323
+ font-weight: 500;
2324
+ opacity: 0.7;
2325
+ text-transform: capitalize;
2326
+ letter-spacing: 0.02em;
2327
+ }
2328
+
2329
+ /* Enhanced Timing Section */
2330
+ .timing-value-group {
2331
+ display: flex;
2332
+ flex-direction: column;
2333
+ align-items: flex-end;
2334
+ min-width: 75px;
2335
+ }
2336
+
2337
+ .timing-percentage {
2338
+ font-size: 9px;
2339
+ color: #64748b;
2340
+ font-weight: 500;
2341
+ margin-top: 1px;
2342
+ }
2343
+
2344
+ .timing-total-value {
2345
+ display: flex;
2346
+ flex-direction: column;
2347
+ align-items: flex-end;
2348
+ font-weight: 700;
2349
+ color: #7c3aed;
2350
+ }
2351
+
2352
+ .timing-benchmark {
2353
+ font-size: 9px;
2354
+ font-weight: 500;
2355
+ color: #64748b;
2356
+ margin-top: 2px;
2357
+ text-transform: uppercase;
2358
+ letter-spacing: 0.5px;
2359
+ }
2360
+
2361
+ /* Enhanced Metrics Section */
2362
+ .metric-row.primary-metric {
2363
+ border: 1px solid rgba(59, 130, 246, 0.15);
2364
+ background: rgba(59, 130, 246, 0.02);
2365
+ border-radius: 6px;
2366
+ padding: 10px 8px;
2367
+ margin: 0 -8px 8px -8px;
2368
+ }
2369
+
2370
+ .metric-value-group {
2371
+ display: flex;
2372
+ flex-direction: column;
2373
+ align-items: flex-end;
2374
+ gap: 2px;
2375
+ }
2376
+
2377
+ .metric-threshold {
2378
+ font-size: 9px;
2379
+ font-weight: 600;
2380
+ padding: 2px 5px;
2381
+ border-radius: 8px;
2382
+ text-transform: uppercase;
2383
+ letter-spacing: 0.3px;
2384
+ }
2385
+
2386
+ .metric-threshold:contains("✓") {
2387
+ background: #dcfce7;
2388
+ color: #166534;
2389
+ }
2390
+
2391
+ .metric-threshold:contains("⚠") {
2392
+ background: #fef3c7;
2393
+ color: #92400e;
2394
+ }
2395
+
2396
+ .metric-context {
2397
+ font-size: 9px;
2398
+ color: #64748b;
2399
+ font-weight: 500;
2400
+ font-style: italic;
2401
+ }
2402
+
2403
+ /* Enhanced Analysis Section */
2404
+ .analysis-details {
2405
+ display: flex;
2406
+ flex-direction: column;
2407
+ align-items: flex-end;
2408
+ gap: 2px;
2409
+ flex: 1;
2410
+ }
2411
+
2412
+ .analysis-impact {
2413
+ font-size: 9px;
2414
+ color: #059669;
2415
+ font-weight: 600;
2416
+ text-transform: uppercase;
2417
+ letter-spacing: 0.3px;
2418
+ }
2419
+
2420
+ /* Smart Recommendations Section */
2421
+ .recommendations-header {
2422
+ margin-bottom: 16px;
2423
+ }
2424
+
2425
+ .recommendations-grid {
2426
+ display: flex;
2427
+ flex-direction: column;
2428
+ gap: 12px;
2429
+ }
2430
+
2431
+ .recommendation-card {
2432
+ background: rgba(255, 255, 255, 0.8);
2433
+ border: 1px solid rgba(245, 158, 11, 0.2);
2434
+ border-radius: 8px;
2435
+ padding: 14px;
2436
+ transition: all 0.3s ease;
2437
+ position: relative;
2438
+ overflow: hidden;
2439
+ }
2440
+
2441
+ .recommendation-card::before {
2442
+ content: '';
2443
+ position: absolute;
2444
+ left: 0;
2445
+ top: 0;
2446
+ bottom: 0;
2447
+ width: 4px;
2448
+ background: linear-gradient(180deg, #f59e0b, #d97706);
2449
+ }
2450
+
2451
+ .recommendation-card:hover {
2452
+ background: rgba(255, 255, 255, 0.95);
2453
+ transform: translateY(-2px);
2454
+ box-shadow: 0 4px 12px rgba(245, 158, 11, 0.15);
2455
+ border-color: rgba(245, 158, 11, 0.3);
2456
+ }
2457
+
2458
+ .rec-priority {
2459
+ display: flex;
2460
+ align-items: center;
2461
+ justify-content: space-between;
2462
+ margin-bottom: 8px;
2463
+ }
2464
+
2465
+ .priority-indicator {
2466
+ font-size: 9px;
2467
+ font-weight: 700;
2468
+ padding: 3px 8px;
2469
+ border-radius: 10px;
2470
+ text-transform: uppercase;
2471
+ letter-spacing: 0.5px;
2472
+ }
2473
+
2474
+ .priority-high {
2475
+ background: linear-gradient(135deg, #ef4444, #dc2626);
2476
+ color: white;
2477
+ }
2478
+
2479
+ .priority-medium {
2480
+ background: linear-gradient(135deg, #f59e0b, #d97706);
2481
+ color: white;
2482
+ }
2483
+
2484
+ .priority-low {
2485
+ background: linear-gradient(135deg, #6b7280, #4b5563);
2486
+ color: white;
2487
+ }
2488
+
2489
+ .rec-impact {
2490
+ font-size: 10px;
2491
+ font-weight: 600;
2492
+ color: #059669;
2493
+ padding: 2px 6px;
2494
+ background: #dcfce7;
2495
+ border-radius: 6px;
2496
+ }
2497
+
2498
+ .rec-text {
2499
+ font-size: 12px;
2500
+ color: #92400e;
2501
+ line-height: 1.4;
2502
+ font-weight: 500;
2503
+ }
2504
+
2505
+ .rec-actions {
2506
+ margin-top: 6px;
2507
+ padding-top: 6px;
2508
+ border-top: 1px solid rgba(245, 158, 11, 0.1);
2509
+ }
2510
+
2511
+ .rec-hint {
2512
+ font-size: 10px;
2513
+ color: #6b7280;
2514
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
2515
+ font-style: italic;
2516
+ padding: 2px 6px;
2517
+ background: #f8fafc;
2518
+ border-radius: 4px;
2519
+ }
2520
+
2521
+ /* No Recommendations Section */
2522
+ .no-recommendations-section {
2523
+ background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 20%, #ffffff 100%);
2524
+ border-top: 1px solid #22c55e;
2525
+ padding: 20px;
2526
+ box-shadow: inset 0 1px 0 rgba(34, 197, 94, 0.1);
2527
+ }
2528
+
2529
+ .no-recommendations-section .group-header {
2530
+ color: #166534;
2531
+ border-bottom-color: rgba(34, 197, 94, 0.2);
2532
+ }
2533
+
2534
+ .no-recommendations-content {
2535
+ display: flex;
2536
+ flex-direction: column;
2537
+ gap: 12px;
2538
+ }
2539
+
2540
+ .performance-badges {
2541
+ display: flex;
2542
+ gap: 8px;
2543
+ flex-wrap: wrap;
2544
+ }
2545
+
2546
+ .perf-badge {
2547
+ font-size: 10px;
2548
+ font-weight: 600;
2549
+ padding: 4px 10px;
2550
+ border-radius: 12px;
2551
+ text-transform: uppercase;
2552
+ letter-spacing: 0.5px;
2553
+ }
2554
+
2555
+ .perf-badge.excellent {
2556
+ background: linear-gradient(135deg, #22c55e, #16a34a);
2557
+ color: white;
2558
+ }
2559
+
2560
+ .perf-badge.good {
2561
+ background: linear-gradient(135deg, #3b82f6, #2563eb);
2562
+ color: white;
2563
+ }
2564
+
2565
+ .optimization-summary {
2566
+ font-size: 12px;
2567
+ color: #166534;
2568
+ line-height: 1.5;
2569
+ margin: 0;
2570
+ font-style: italic;
2571
+ }
2572
+
2573
+ /* Enhanced Responsive Design */
2574
+ @media (min-width: 1400px) {
2575
+ .perf-metrics-grid {
2576
+ grid-template-columns: 1fr 1.2fr 1.3fr;
2577
+ }
2578
+
2579
+ .recommendations-grid {
2580
+ display: grid;
2581
+ grid-template-columns: 1fr 1fr;
2582
+ gap: 16px;
2583
+ }
2584
+ }
2585
+
2586
+ @media (max-width: 1200px) {
2587
+ .perf-metrics-grid {
2588
+ grid-template-columns: 1fr 1fr;
2589
+ }
2590
+
2591
+ .analysis-group {
2592
+ grid-column: span 2;
2593
+ }
2594
+
2595
+ .metric-value-group {
2596
+ align-items: flex-start;
2597
+ }
2598
+
2599
+ .timing-value-group {
2600
+ align-items: flex-start;
2601
+ }
2602
+ }
2603
+
2604
+ @media (max-width: 900px) {
2605
+ .perf-header {
2606
+ padding: 12px 14px;
2607
+ }
2608
+
2609
+ .perf-status {
2610
+ gap: 10px;
2611
+ }
2612
+
2613
+ .status-details {
2614
+ gap: 1px;
2615
+ }
2616
+
2617
+ .perf-rating-group {
2618
+ align-items: flex-start;
2619
+ }
2620
+
2621
+ .metrics-group {
2622
+ padding: 14px;
2623
+ }
2624
+
2625
+ .recommendation-card {
2626
+ padding: 12px;
2627
+ }
2628
+ }