@memberjunction/ng-core-entity-forms 5.34.0 → 5.35.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 (106) hide show
  1. package/dist/lib/custom/Tests/test-form.component.d.ts +25 -1
  2. package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
  3. package/dist/lib/custom/Tests/test-form.component.js +898 -547
  4. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  5. package/dist/lib/custom/Tests/test-suite-form.component.d.ts +56 -1
  6. package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
  7. package/dist/lib/custom/Tests/test-suite-form.component.js +1647 -788
  8. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  9. package/dist/lib/custom/custom-forms.module.d.ts +25 -24
  10. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  11. package/dist/lib/custom/custom-forms.module.js +4 -0
  12. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  13. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +215 -213
  14. package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
  15. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +23 -23
  16. package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
  17. package/dist/lib/generated/Entities/MJAIConfiguration/mjaiconfiguration.form.component.js +12 -12
  18. package/dist/lib/generated/Entities/MJAIConfiguration/mjaiconfiguration.form.component.js.map +1 -1
  19. package/dist/lib/generated/Entities/MJAIModality/mjaimodality.form.component.js +17 -17
  20. package/dist/lib/generated/Entities/MJAIModality/mjaimodality.form.component.js.map +1 -1
  21. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js +51 -51
  22. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js.map +1 -1
  23. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +31 -31
  24. package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
  25. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +9 -9
  26. package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
  27. package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js +25 -25
  28. package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js.map +1 -1
  29. package/dist/lib/generated/Entities/MJAPIKey/mjapikey.form.component.js +13 -13
  30. package/dist/lib/generated/Entities/MJAPIKey/mjapikey.form.component.js.map +1 -1
  31. package/dist/lib/generated/Entities/MJAPIScope/mjapiscope.form.component.js +9 -9
  32. package/dist/lib/generated/Entities/MJAPIScope/mjapiscope.form.component.js.map +1 -1
  33. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js +19 -19
  34. package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js.map +1 -1
  35. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js +17 -17
  36. package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js.map +1 -1
  37. package/dist/lib/generated/Entities/MJArtifactType/mjartifacttype.form.component.js +53 -47
  38. package/dist/lib/generated/Entities/MJArtifactType/mjartifacttype.form.component.js.map +1 -1
  39. package/dist/lib/generated/Entities/MJArtifactVersion/mjartifactversion.form.component.d.ts.map +1 -1
  40. package/dist/lib/generated/Entities/MJArtifactVersion/mjartifactversion.form.component.js +53 -33
  41. package/dist/lib/generated/Entities/MJArtifactVersion/mjartifactversion.form.component.js.map +1 -1
  42. package/dist/lib/generated/Entities/MJAuditLogType/mjauditlogtype.form.component.js +10 -10
  43. package/dist/lib/generated/Entities/MJAuditLogType/mjauditlogtype.form.component.js.map +1 -1
  44. package/dist/lib/generated/Entities/MJAuthorization/mjauthorization.form.component.js +20 -20
  45. package/dist/lib/generated/Entities/MJAuthorization/mjauthorization.form.component.js.map +1 -1
  46. package/dist/lib/generated/Entities/MJCommunicationProvider/mjcommunicationprovider.form.component.js +19 -19
  47. package/dist/lib/generated/Entities/MJCommunicationProvider/mjcommunicationprovider.form.component.js.map +1 -1
  48. package/dist/lib/generated/Entities/MJCompany/mjcompany.form.component.js +9 -9
  49. package/dist/lib/generated/Entities/MJCompany/mjcompany.form.component.js.map +1 -1
  50. package/dist/lib/generated/Entities/MJCompanyIntegration/mjcompanyintegration.form.component.js +17 -17
  51. package/dist/lib/generated/Entities/MJCompanyIntegration/mjcompanyintegration.form.component.js.map +1 -1
  52. package/dist/lib/generated/Entities/MJCompanyIntegrationRun/mjcompanyintegrationrun.form.component.js +10 -10
  53. package/dist/lib/generated/Entities/MJCompanyIntegrationRun/mjcompanyintegrationrun.form.component.js.map +1 -1
  54. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +9 -9
  55. package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
  56. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js +10 -10
  57. package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js.map +1 -1
  58. package/dist/lib/generated/Entities/MJConversationDetailAttachment/mjconversationdetailattachment.form.component.js +7 -5
  59. package/dist/lib/generated/Entities/MJConversationDetailAttachment/mjconversationdetailattachment.form.component.js.map +1 -1
  60. package/dist/lib/generated/Entities/MJDashboard/mjdashboard.form.component.js +17 -17
  61. package/dist/lib/generated/Entities/MJDashboard/mjdashboard.form.component.js.map +1 -1
  62. package/dist/lib/generated/Entities/MJDashboardCategory/mjdashboardcategory.form.component.js +9 -9
  63. package/dist/lib/generated/Entities/MJDashboardCategory/mjdashboardcategory.form.component.js.map +1 -1
  64. package/dist/lib/generated/Entities/MJEmployee/mjemployee.form.component.js +15 -15
  65. package/dist/lib/generated/Entities/MJEmployee/mjemployee.form.component.js.map +1 -1
  66. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +208 -208
  67. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  68. package/dist/lib/generated/Entities/MJEntityAction/mjentityaction.form.component.js +9 -9
  69. package/dist/lib/generated/Entities/MJEntityAction/mjentityaction.form.component.js.map +1 -1
  70. package/dist/lib/generated/Entities/MJFileCategory/mjfilecategory.form.component.js +10 -10
  71. package/dist/lib/generated/Entities/MJFileCategory/mjfilecategory.form.component.js.map +1 -1
  72. package/dist/lib/generated/Entities/MJFileStorageAccount/mjfilestorageaccount.form.component.js +9 -9
  73. package/dist/lib/generated/Entities/MJFileStorageAccount/mjfilestorageaccount.form.component.js.map +1 -1
  74. package/dist/lib/generated/Entities/MJIntegration/mjintegration.form.component.js +9 -9
  75. package/dist/lib/generated/Entities/MJIntegration/mjintegration.form.component.js.map +1 -1
  76. package/dist/lib/generated/Entities/MJList/mjlist.form.component.js +17 -17
  77. package/dist/lib/generated/Entities/MJList/mjlist.form.component.js.map +1 -1
  78. package/dist/lib/generated/Entities/MJMCPServerConnection/mjmcpserverconnection.form.component.js +12 -12
  79. package/dist/lib/generated/Entities/MJMCPServerConnection/mjmcpserverconnection.form.component.js.map +1 -1
  80. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js +30 -30
  81. package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js.map +1 -1
  82. package/dist/lib/generated/Entities/MJQueryCategory/mjquerycategory.form.component.js +10 -10
  83. package/dist/lib/generated/Entities/MJQueryCategory/mjquerycategory.form.component.js.map +1 -1
  84. package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.js +10 -10
  85. package/dist/lib/generated/Entities/MJRecordChange/mjrecordchange.form.component.js.map +1 -1
  86. package/dist/lib/generated/Entities/MJRecordMergeLog/mjrecordmergelog.form.component.js +10 -10
  87. package/dist/lib/generated/Entities/MJRecordMergeLog/mjrecordmergelog.form.component.js.map +1 -1
  88. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js +34 -34
  89. package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js.map +1 -1
  90. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.js +19 -19
  91. package/dist/lib/generated/Entities/MJSearchScope/mjsearchscope.form.component.js.map +1 -1
  92. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js +16 -16
  93. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js.map +1 -1
  94. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.js +16 -16
  95. package/dist/lib/generated/Entities/MJTemplate/mjtemplate.form.component.js.map +1 -1
  96. package/dist/lib/generated/Entities/MJTemplateCategory/mjtemplatecategory.form.component.js +10 -10
  97. package/dist/lib/generated/Entities/MJTemplateCategory/mjtemplatecategory.form.component.js.map +1 -1
  98. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +330 -330
  99. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  100. package/dist/lib/generated/Entities/MJUserView/mjuserview.form.component.js +13 -13
  101. package/dist/lib/generated/Entities/MJUserView/mjuserview.form.component.js.map +1 -1
  102. package/dist/lib/generated/Entities/MJVectorDatabase/mjvectordatabase.form.component.js +10 -10
  103. package/dist/lib/generated/Entities/MJVectorDatabase/mjvectordatabase.form.component.js.map +1 -1
  104. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js +9 -9
  105. package/dist/lib/generated/Entities/MJVectorIndex/mjvectorindex.form.component.js.map +1 -1
  106. package/package.json +37 -36
@@ -9,6 +9,7 @@ import * as d3 from 'd3';
9
9
  import { Subject } from 'rxjs';
10
10
  import { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';
11
11
  import { CompositeKey, RunView } from '@memberjunction/core';
12
+ import { moveItemInArray } from '@angular/cdk/drag-drop';
12
13
  import { UserInfoEngine } from '@memberjunction/core-entities';
13
14
  import { BaseFormComponent } from '@memberjunction/ng-base-forms';
14
15
  import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
@@ -19,10 +20,11 @@ import { TestingDialogService, TagsHelper, EvaluationPreferencesService } from '
19
20
  import * as i0 from "@angular/core";
20
21
  import * as i1 from "@angular/common";
21
22
  import * as i2 from "@angular/forms";
22
- import * as i3 from "@memberjunction/ng-ui-components";
23
- import * as i4 from "@memberjunction/ng-testing";
24
- import * as i5 from "@memberjunction/ng-shared-generic";
25
- import * as i6 from "@memberjunction/ng-versions";
23
+ import * as i3 from "@angular/cdk/drag-drop";
24
+ import * as i4 from "@memberjunction/ng-ui-components";
25
+ import * as i5 from "@memberjunction/ng-testing";
26
+ import * as i6 from "@memberjunction/ng-shared-generic";
27
+ import * as i7 from "@memberjunction/ng-versions";
26
28
  const _c0 = ["chartContainer"];
27
29
  const _c1 = () => [1, 2, 3, 4, 5];
28
30
  const _c2 = () => [1, 2, 3];
@@ -32,9 +34,15 @@ const _c5 = (a0, a1, a2) => ({ "high": a0, "medium": a1, "low": a2 });
32
34
  const _c6 = (a0, a1) => ({ "positive": a0, "negative": a1 });
33
35
  const _c7 = (a0, a1, a2) => ({ "fa-arrow-down": a0, "fa-arrow-up": a1, "fa-minus": a2 });
34
36
  const _c8 = (a0, a1) => ({ "improved": a0, "regressed": a1 });
35
- function MJTestSuiteFormComponentExtended_Conditional_25_Template(rf, ctx) { if (rf & 1) {
36
- i0.ɵɵelementStart(0, "span", 17);
37
- i0.ɵɵelement(1, "i", 29);
37
+ const _forTrack0 = ($index, $item) => $item.ID;
38
+ function MJTestSuiteFormComponentExtended_Conditional_21_Template(rf, ctx) { if (rf & 1) {
39
+ i0.ɵɵelementStart(0, "span", 16);
40
+ i0.ɵɵtext(1, "\u25CF");
41
+ i0.ɵɵelementEnd();
42
+ } }
43
+ function MJTestSuiteFormComponentExtended_Conditional_26_Template(rf, ctx) { if (rf & 1) {
44
+ i0.ɵɵelementStart(0, "span", 20);
45
+ i0.ɵɵelement(1, "i", 33);
38
46
  i0.ɵɵtext(2);
39
47
  i0.ɵɵelementEnd();
40
48
  } if (rf & 2) {
@@ -42,8 +50,14 @@ function MJTestSuiteFormComponentExtended_Conditional_25_Template(rf, ctx) { if
42
50
  i0.ɵɵadvance(2);
43
51
  i0.ɵɵtextInterpolate1(" ", ctx_r0.suiteTests.length, " tests ");
44
52
  } }
45
- function MJTestSuiteFormComponentExtended_Conditional_37_Template(rf, ctx) { if (rf & 1) {
46
- i0.ɵɵelementStart(0, "div", 24)(1, "p");
53
+ function MJTestSuiteFormComponentExtended_Conditional_27_Template(rf, ctx) { if (rf & 1) {
54
+ i0.ɵɵelementStart(0, "span", 21);
55
+ i0.ɵɵelement(1, "i", 57);
56
+ i0.ɵɵtext(2, " Unsaved ");
57
+ i0.ɵɵelementEnd();
58
+ } }
59
+ function MJTestSuiteFormComponentExtended_Conditional_39_Template(rf, ctx) { if (rf & 1) {
60
+ i0.ɵɵelementStart(0, "div", 28)(1, "p");
47
61
  i0.ɵɵtext(2);
48
62
  i0.ɵɵelementEnd()();
49
63
  } if (rf & 2) {
@@ -51,8 +65,8 @@ function MJTestSuiteFormComponentExtended_Conditional_37_Template(rf, ctx) { if
51
65
  i0.ɵɵadvance(2);
52
66
  i0.ɵɵtextInterpolate(ctx_r0.record.Description);
53
67
  } }
54
- function MJTestSuiteFormComponentExtended_Conditional_46_Template(rf, ctx) { if (rf & 1) {
55
- i0.ɵɵelementStart(0, "span", 30);
68
+ function MJTestSuiteFormComponentExtended_Conditional_48_Template(rf, ctx) { if (rf & 1) {
69
+ i0.ɵɵelementStart(0, "span", 34);
56
70
  i0.ɵɵtext(1);
57
71
  i0.ɵɵelementEnd();
58
72
  } if (rf & 2) {
@@ -60,8 +74,8 @@ function MJTestSuiteFormComponentExtended_Conditional_46_Template(rf, ctx) { if
60
74
  i0.ɵɵadvance();
61
75
  i0.ɵɵtextInterpolate(ctx_r0.suiteTests.length);
62
76
  } }
63
- function MJTestSuiteFormComponentExtended_Conditional_50_Template(rf, ctx) { if (rf & 1) {
64
- i0.ɵɵelementStart(0, "span", 30);
77
+ function MJTestSuiteFormComponentExtended_Conditional_52_Template(rf, ctx) { if (rf & 1) {
78
+ i0.ɵɵelementStart(0, "span", 34);
65
79
  i0.ɵɵtext(1);
66
80
  i0.ɵɵelementEnd();
67
81
  } if (rf & 2) {
@@ -69,303 +83,468 @@ function MJTestSuiteFormComponentExtended_Conditional_50_Template(rf, ctx) { if
69
83
  i0.ɵɵadvance();
70
84
  i0.ɵɵtextInterpolate(ctx_r0.suiteRuns.length);
71
85
  } }
72
- function MJTestSuiteFormComponentExtended_Conditional_58_Template(rf, ctx) { if (rf & 1) {
86
+ function MJTestSuiteFormComponentExtended_Conditional_60_For_25_Template(rf, ctx) { if (rf & 1) {
87
+ i0.ɵɵelementStart(0, "option", 73);
88
+ i0.ɵɵtext(1);
89
+ i0.ɵɵelementEnd();
90
+ } if (rf & 2) {
91
+ const opt_r3 = ctx.$implicit;
92
+ i0.ɵɵproperty("ngValue", opt_r3);
93
+ i0.ɵɵadvance();
94
+ i0.ɵɵtextInterpolate(opt_r3);
95
+ } }
96
+ function MJTestSuiteFormComponentExtended_Conditional_60_For_33_Template(rf, ctx) { if (rf & 1) {
97
+ i0.ɵɵelementStart(0, "option", 73);
98
+ i0.ɵɵtext(1);
99
+ i0.ɵɵelementEnd();
100
+ } if (rf & 2) {
101
+ const s_r4 = ctx.$implicit;
102
+ i0.ɵɵproperty("ngValue", s_r4.ID);
103
+ i0.ɵɵadvance();
104
+ i0.ɵɵtextInterpolate(s_r4.Name);
105
+ } }
106
+ function MJTestSuiteFormComponentExtended_Conditional_60_For_39_Template(rf, ctx) { if (rf & 1) {
107
+ const _r6 = i0.ɵɵgetCurrentView();
108
+ i0.ɵɵelementStart(0, "span", 78);
109
+ i0.ɵɵtext(1);
110
+ i0.ɵɵelementStart(2, "button", 90);
111
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_For_39_Template_button_click_2_listener($event) { const tag_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.removeTag(tag_r7); return i0.ɵɵresetView($event.stopPropagation()); });
112
+ i0.ɵɵelement(3, "i", 91);
113
+ i0.ɵɵelementEnd()();
114
+ } if (rf & 2) {
115
+ const tag_r7 = ctx.$implicit;
116
+ i0.ɵɵadvance();
117
+ i0.ɵɵtextInterpolate1(" ", tag_r7, " ");
118
+ i0.ɵɵadvance();
119
+ i0.ɵɵattribute("aria-label", "Remove tag " + tag_r7);
120
+ } }
121
+ function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if (rf & 1) {
73
122
  const _r2 = i0.ɵɵgetCurrentView();
74
- i0.ɵɵelementStart(0, "div", 35)(1, "div", 44)(2, "h3");
75
- i0.ɵɵelement(3, "i", 45);
76
- i0.ɵɵtext(4, " Suite Information");
123
+ i0.ɵɵelementStart(0, "div", 39)(1, "section", 58)(2, "header", 59)(3, "h3");
124
+ i0.ɵɵelement(4, "i", 60);
125
+ i0.ɵɵtext(5, " Details");
77
126
  i0.ɵɵelementEnd();
78
- i0.ɵɵelementStart(5, "div", 46)(6, "div", 47)(7, "div", 48);
79
- i0.ɵɵtext(8, "Name");
127
+ i0.ɵɵelementStart(6, "p", 61);
128
+ i0.ɵɵtext(7, "Edit any field \u2014 changes are saved with the bar at the bottom.");
129
+ i0.ɵɵelementEnd()();
130
+ i0.ɵɵelementStart(8, "div", 62)(9, "div", 63)(10, "label", 64);
131
+ i0.ɵɵtext(11, "Name ");
132
+ i0.ɵɵelementStart(12, "span", 65);
133
+ i0.ɵɵtext(13, "*");
134
+ i0.ɵɵelementEnd()();
135
+ i0.ɵɵelementStart(14, "input", 66);
136
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.Name, $event) || (ctx_r0.record.Name = $event); return i0.ɵɵresetView($event); });
137
+ i0.ɵɵelementEnd()();
138
+ i0.ɵɵelementStart(15, "div", 63)(16, "label", 67);
139
+ i0.ɵɵtext(17, "Description");
80
140
  i0.ɵɵelementEnd();
81
- i0.ɵɵelementStart(9, "div", 49);
82
- i0.ɵɵtext(10);
141
+ i0.ɵɵelementStart(18, "textarea", 68);
142
+ i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_textarea_ngModelChange_18_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Description = $event || null); });
83
143
  i0.ɵɵelementEnd()();
84
- i0.ɵɵelementStart(11, "div", 47)(12, "div", 48);
85
- i0.ɵɵtext(13, "Status");
144
+ i0.ɵɵelementStart(19, "div", 69)(20, "label", 70);
145
+ i0.ɵɵtext(21, "Status");
86
146
  i0.ɵɵelementEnd();
87
- i0.ɵɵelementStart(14, "div", 49)(15, "span", 50);
88
- i0.ɵɵtext(16);
147
+ i0.ɵɵelementStart(22, "div", 71)(23, "select", 72);
148
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_select_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.Status, $event) || (ctx_r0.record.Status = $event); return i0.ɵɵresetView($event); });
149
+ i0.ɵɵrepeaterCreate(24, MJTestSuiteFormComponentExtended_Conditional_60_For_25_Template, 2, 2, "option", 73, i0.ɵɵrepeaterTrackByIdentity);
89
150
  i0.ɵɵelementEnd()()();
90
- i0.ɵɵelementStart(17, "div", 47)(18, "div", 48);
91
- i0.ɵɵtext(19, "Created");
151
+ i0.ɵɵelementStart(26, "div", 69)(27, "label", 74);
152
+ i0.ɵɵtext(28, "Parent Suite");
92
153
  i0.ɵɵelementEnd();
93
- i0.ɵɵelementStart(20, "div", 49);
94
- i0.ɵɵtext(21);
95
- i0.ɵɵpipe(22, "date");
96
- i0.ɵɵelementEnd()();
97
- i0.ɵɵelementStart(23, "div", 47)(24, "div", 48);
98
- i0.ɵɵtext(25, "Updated");
154
+ i0.ɵɵelementStart(29, "select", 75);
155
+ i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_select_ngModelChange_29_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.ParentID = $event || null); });
156
+ i0.ɵɵelementStart(30, "option", 73);
157
+ i0.ɵɵtext(31, "\u2014 None (top-level) \u2014");
99
158
  i0.ɵɵelementEnd();
100
- i0.ɵɵelementStart(26, "div", 49);
101
- i0.ɵɵtext(27);
102
- i0.ɵɵpipe(28, "date");
159
+ i0.ɵɵrepeaterCreate(32, MJTestSuiteFormComponentExtended_Conditional_60_For_33_Template, 2, 2, "option", 73, _forTrack0);
103
160
  i0.ɵɵelementEnd()();
104
- i0.ɵɵelementStart(29, "div", 47)(30, "div", 48);
105
- i0.ɵɵtext(31, "Max Execution Time");
161
+ i0.ɵɵelementStart(34, "div", 63)(35, "label", 76);
162
+ i0.ɵɵtext(36, "Tags");
163
+ i0.ɵɵelementEnd();
164
+ i0.ɵɵelementStart(37, "div", 77);
165
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_Template_div_click_37_listener() { i0.ɵɵrestoreView(_r2); const tagInput_r5 = i0.ɵɵreference(41); return i0.ɵɵresetView(tagInput_r5.focus()); });
166
+ i0.ɵɵrepeaterCreate(38, MJTestSuiteFormComponentExtended_Conditional_60_For_39_Template, 4, 2, "span", 78, i0.ɵɵrepeaterTrackByIdentity);
167
+ i0.ɵɵelementStart(40, "input", 79, 0);
168
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_ngModelChange_40_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.tagDraft, $event) || (ctx_r0.tagDraft = $event); return i0.ɵɵresetView($event); });
169
+ i0.ɵɵlistener("keydown", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_keydown_40_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onTagInputKeydown($event)); })("blur", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_blur_40_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.addTagFromDraft()); });
170
+ i0.ɵɵelementEnd()();
171
+ i0.ɵɵelementStart(42, "span", 80);
172
+ i0.ɵɵtext(43, "Press Enter or comma to add a tag. Backspace on empty input removes the last tag.");
173
+ i0.ɵɵelementEnd()()()();
174
+ i0.ɵɵelementStart(44, "section", 58)(45, "header", 59)(46, "h3");
175
+ i0.ɵɵelement(47, "i", 81);
176
+ i0.ɵɵtext(48, " Execution Settings");
177
+ i0.ɵɵelementEnd()();
178
+ i0.ɵɵelementStart(49, "div", 62)(50, "div", 69)(51, "label", 82);
179
+ i0.ɵɵtext(52, "Max Execution Time (ms)");
106
180
  i0.ɵɵelementEnd();
107
- i0.ɵɵelementStart(32, "div", 49);
108
- i0.ɵɵtext(33);
181
+ i0.ɵɵelementStart(53, "input", 83);
182
+ i0.ɵɵlistener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_60_Template_input_ngModelChange_53_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.MaxExecutionTimeMS = $event === "" || $event === null ? null : +$event); });
183
+ i0.ɵɵelementEnd();
184
+ i0.ɵɵelementStart(54, "span", 80);
185
+ i0.ɵɵtext(55);
109
186
  i0.ɵɵelementEnd()()()();
110
- i0.ɵɵelementStart(34, "div", 51)(35, "h3");
111
- i0.ɵɵelement(36, "i", 52);
112
- i0.ɵɵtext(37, " Execution Settings");
187
+ i0.ɵɵelementStart(56, "section", 84)(57, "div", 85)(58, "div", 86)(59, "div", 87);
188
+ i0.ɵɵtext(60, "Created");
113
189
  i0.ɵɵelementEnd();
114
- i0.ɵɵelementStart(38, "div", 53)(39, "div", 54)(40, "label");
115
- i0.ɵɵtext(41, "Max Execution Time (ms)");
190
+ i0.ɵɵelementStart(61, "div", 88);
191
+ i0.ɵɵtext(62);
192
+ i0.ɵɵpipe(63, "date");
193
+ i0.ɵɵelementEnd()();
194
+ i0.ɵɵelementStart(64, "div", 86)(65, "div", 87);
195
+ i0.ɵɵtext(66, "Last updated");
116
196
  i0.ɵɵelementEnd();
117
- i0.ɵɵelementStart(42, "input", 55);
118
- i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_58_Template_input_ngModelChange_42_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.MaxExecutionTimeMS, $event) || (ctx_r0.record.MaxExecutionTimeMS = $event); return i0.ɵɵresetView($event); });
197
+ i0.ɵɵelementStart(67, "div", 88);
198
+ i0.ɵɵtext(68);
199
+ i0.ɵɵpipe(69, "date");
200
+ i0.ɵɵelementEnd()();
201
+ i0.ɵɵelementStart(70, "div", 86)(71, "div", 87);
202
+ i0.ɵɵtext(72, "Suite ID");
119
203
  i0.ɵɵelementEnd();
120
- i0.ɵɵelementStart(43, "span", 56);
121
- i0.ɵɵtext(44, "Default timeout for tests in this suite");
204
+ i0.ɵɵelementStart(73, "div", 89);
205
+ i0.ɵɵtext(74);
122
206
  i0.ɵɵelementEnd()()()()();
123
207
  } if (rf & 2) {
124
208
  const ctx_r0 = i0.ɵɵnextContext();
125
- i0.ɵɵadvance(10);
126
- i0.ɵɵtextInterpolate(ctx_r0.record.Name);
209
+ i0.ɵɵadvance(14);
210
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.Name);
211
+ i0.ɵɵadvance(4);
212
+ i0.ɵɵproperty("ngModel", ctx_r0.record.Description);
127
213
  i0.ɵɵadvance(5);
128
- i0.ɵɵproperty("ngClass", ctx_r0.getStatusClass());
214
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.Status);
129
215
  i0.ɵɵadvance();
130
- i0.ɵɵtextInterpolate(ctx_r0.record.Status);
216
+ i0.ɵɵrepeater(ctx_r0.statusOptions);
131
217
  i0.ɵɵadvance(5);
132
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(22, 7, ctx_r0.record.__mj_CreatedAt, "medium"));
218
+ i0.ɵɵproperty("ngModel", ctx_r0.record.ParentID);
219
+ i0.ɵɵadvance();
220
+ i0.ɵɵproperty("ngValue", null);
221
+ i0.ɵɵadvance(2);
222
+ i0.ɵɵrepeater(ctx_r0.parentSuiteOptions);
133
223
  i0.ɵɵadvance(6);
134
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(28, 10, ctx_r0.record.__mj_UpdatedAt, "medium"));
224
+ i0.ɵɵrepeater(ctx_r0.tags);
225
+ i0.ɵɵadvance(2);
226
+ i0.ɵɵproperty("placeholder", ctx_r0.tags.length === 0 ? "Add tags, press Enter or comma..." : "");
227
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.tagDraft);
228
+ i0.ɵɵadvance(13);
229
+ i0.ɵɵproperty("ngModel", ctx_r0.record.MaxExecutionTimeMS);
230
+ i0.ɵɵadvance(2);
231
+ i0.ɵɵtextInterpolate1("Default timeout for tests in this suite. Currently: ", ctx_r0.formatTimeout(ctx_r0.record.MaxExecutionTimeMS));
232
+ i0.ɵɵadvance(7);
233
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(63, 12, ctx_r0.record.__mj_CreatedAt, "medium"));
135
234
  i0.ɵɵadvance(6);
136
- i0.ɵɵtextInterpolate(ctx_r0.formatTimeout(ctx_r0.record.MaxExecutionTimeMS));
137
- i0.ɵɵadvance(9);
138
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.MaxExecutionTimeMS);
235
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(69, 15, ctx_r0.record.__mj_UpdatedAt, "medium"));
236
+ i0.ɵɵadvance(6);
237
+ i0.ɵɵtextInterpolate(ctx_r0.record.ID);
238
+ } }
239
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template(rf, ctx) { if (rf & 1) {
240
+ i0.ɵɵelementStart(0, "span", 94);
241
+ i0.ɵɵtext(1);
242
+ i0.ɵɵelementEnd();
243
+ } if (rf & 2) {
244
+ const ctx_r0 = i0.ɵɵnextContext(2);
245
+ i0.ɵɵadvance();
246
+ i0.ɵɵtextInterpolate(ctx_r0.suiteTests.length);
139
247
  } }
140
- function MJTestSuiteFormComponentExtended_Conditional_59_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
141
- i0.ɵɵelementStart(0, "div", 61);
142
- i0.ɵɵelement(1, "div", 62)(2, "div", 63);
143
- i0.ɵɵelementStart(3, "div", 64);
144
- i0.ɵɵelement(4, "div", 65)(5, "div", 66);
248
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_For_3_Template(rf, ctx) { if (rf & 1) {
249
+ i0.ɵɵelementStart(0, "div", 103);
250
+ i0.ɵɵelement(1, "div", 104)(2, "div", 105);
251
+ i0.ɵɵelementStart(3, "div", 106);
252
+ i0.ɵɵelement(4, "div", 107)(5, "div", 108);
145
253
  i0.ɵɵelementEnd()();
146
254
  } }
147
- function MJTestSuiteFormComponentExtended_Conditional_59_Conditional_1_Template(rf, ctx) { if (rf & 1) {
148
- i0.ɵɵelementStart(0, "div", 57)(1, "div", 60);
149
- i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_59_Conditional_1_For_3_Template, 6, 0, "div", 61, i0.ɵɵrepeaterTrackByIdentity);
255
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template(rf, ctx) { if (rf & 1) {
256
+ i0.ɵɵelementStart(0, "div", 99)(1, "div", 102);
257
+ i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_For_3_Template, 6, 0, "div", 103, i0.ɵɵrepeaterTrackByIdentity);
150
258
  i0.ɵɵelementEnd()();
151
259
  } if (rf & 2) {
152
260
  i0.ɵɵadvance(2);
153
261
  i0.ɵɵrepeater(i0.ɵɵpureFunction0(0, _c1));
154
262
  } }
155
- function MJTestSuiteFormComponentExtended_Conditional_59_Conditional_2_For_2_Conditional_9_Template(rf, ctx) { if (rf & 1) {
263
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_11_Template(rf, ctx) { if (rf & 1) {
156
264
  i0.ɵɵelementStart(0, "span");
157
- i0.ɵɵelement(1, "i", 45);
265
+ i0.ɵɵelement(1, "i", 119);
158
266
  i0.ɵɵtext(2);
159
267
  i0.ɵɵelementEnd();
160
268
  } if (rf & 2) {
161
- const test_r4 = i0.ɵɵnextContext().$implicit;
269
+ const test_r11 = i0.ɵɵnextContext().$implicit;
162
270
  i0.ɵɵadvance(2);
163
- i0.ɵɵtextInterpolate1(" ", test_r4.Status);
271
+ i0.ɵɵtextInterpolate1(" ", test_r11.Status);
164
272
  } }
165
- function MJTestSuiteFormComponentExtended_Conditional_59_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
166
- const _r3 = i0.ɵɵgetCurrentView();
167
- i0.ɵɵelementStart(0, "div", 68);
168
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_59_Conditional_2_For_2_Template_div_click_0_listener() { const test_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r4.TestID)); });
169
- i0.ɵɵelementStart(1, "div", 69);
170
- i0.ɵɵtext(2);
273
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_4_Template(rf, ctx) { if (rf & 1) {
274
+ i0.ɵɵelement(0, "i", 123);
275
+ } }
276
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_5_Template(rf, ctx) { if (rf & 1) {
277
+ i0.ɵɵtext(0, " Remove ");
278
+ } }
279
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template(rf, ctx) { if (rf & 1) {
280
+ const _r12 = i0.ɵɵgetCurrentView();
281
+ i0.ɵɵelementStart(0, "div", 120);
282
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r12); return i0.ɵɵresetView($event.stopPropagation()); });
283
+ i0.ɵɵelementStart(1, "span", 121);
284
+ i0.ɵɵtext(2, "Remove from suite?");
285
+ i0.ɵɵelementEnd();
286
+ i0.ɵɵelementStart(3, "button", 122);
287
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_3_listener($event) { i0.ɵɵrestoreView(_r12); const test_r11 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.confirmRemoveTest(test_r11, $event)); });
288
+ i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_4_Template, 1, 0, "i", 123)(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Conditional_5_Template, 1, 0);
289
+ i0.ɵɵelementEnd();
290
+ i0.ɵɵelementStart(6, "button", 124);
291
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.cancelRemoveTest($event)); });
292
+ i0.ɵɵtext(7, " Cancel ");
293
+ i0.ɵɵelementEnd()();
294
+ } if (rf & 2) {
295
+ const ctx_r0 = i0.ɵɵnextContext(4);
296
+ i0.ɵɵadvance(3);
297
+ i0.ɵɵproperty("disabled", ctx_r0.isRemovingTest);
298
+ i0.ɵɵadvance();
299
+ i0.ɵɵconditional(ctx_r0.isRemovingTest ? 4 : 5);
300
+ i0.ɵɵadvance(2);
301
+ i0.ɵɵproperty("disabled", ctx_r0.isRemovingTest);
302
+ } }
303
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
304
+ const _r13 = i0.ɵɵgetCurrentView();
305
+ i0.ɵɵelementStart(0, "button", 125);
306
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r13); const test_r11 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.requestRemoveTest(test_r11, $event)); });
307
+ i0.ɵɵelement(1, "i", 91);
171
308
  i0.ɵɵelementEnd();
172
- i0.ɵɵelementStart(3, "div", 70);
173
- i0.ɵɵelement(4, "i", 29);
309
+ i0.ɵɵelementStart(2, "i", 126);
310
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template_i_click_2_listener() { i0.ɵɵrestoreView(_r13); const test_r11 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r11.TestID)); });
174
311
  i0.ɵɵelementEnd();
175
- i0.ɵɵelementStart(5, "div", 71)(6, "div", 72);
176
- i0.ɵɵtext(7);
312
+ } }
313
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
314
+ const _r10 = i0.ɵɵgetCurrentView();
315
+ i0.ɵɵelementStart(0, "div", 110)(1, "span", 111);
316
+ i0.ɵɵelement(2, "i", 112);
177
317
  i0.ɵɵelementEnd();
178
- i0.ɵɵelementStart(8, "div", 73);
179
- i0.ɵɵconditionalCreate(9, MJTestSuiteFormComponentExtended_Conditional_59_Conditional_2_For_2_Conditional_9_Template, 3, 1, "span");
318
+ i0.ɵɵelementStart(3, "div", 113);
319
+ i0.ɵɵtext(4);
320
+ i0.ɵɵelementEnd();
321
+ i0.ɵɵelementStart(5, "div", 114);
322
+ i0.ɵɵelement(6, "i", 33);
323
+ i0.ɵɵelementEnd();
324
+ i0.ɵɵelementStart(7, "div", 115);
325
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template_div_click_7_listener() { const test_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r11.TestID)); });
326
+ i0.ɵɵelementStart(8, "div", 116);
327
+ i0.ɵɵtext(9);
328
+ i0.ɵɵelementEnd();
329
+ i0.ɵɵelementStart(10, "div", 117);
330
+ i0.ɵɵconditionalCreate(11, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_11_Template, 3, 1, "span");
180
331
  i0.ɵɵelementEnd()();
181
- i0.ɵɵelement(10, "i", 74);
332
+ i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_12_Template, 8, 3, "div", 118)(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Conditional_13_Template, 3, 0);
182
333
  i0.ɵɵelementEnd();
183
334
  } if (rf & 2) {
184
- const test_r4 = ctx.$implicit;
185
- i0.ɵɵadvance(2);
186
- i0.ɵɵtextInterpolate(test_r4.Sequence);
335
+ const test_r11 = ctx.$implicit;
336
+ const ctx_r0 = i0.ɵɵnextContext(3);
337
+ i0.ɵɵproperty("cdkDragDisabled", ctx_r0.isReorderingTests || ctx_r0.isRemovingTest);
338
+ i0.ɵɵadvance(4);
339
+ i0.ɵɵtextInterpolate(test_r11.Sequence);
187
340
  i0.ɵɵadvance(5);
188
- i0.ɵɵtextInterpolate(test_r4.Test);
341
+ i0.ɵɵtextInterpolate(test_r11.Test);
189
342
  i0.ɵɵadvance(2);
190
- i0.ɵɵconditional(test_r4.Status ? 9 : -1);
343
+ i0.ɵɵconditional(test_r11.Status ? 11 : -1);
344
+ i0.ɵɵadvance();
345
+ i0.ɵɵconditional(ctx_r0.confirmingRemoveSuiteTestId === test_r11.ID ? 12 : 13);
191
346
  } }
192
- function MJTestSuiteFormComponentExtended_Conditional_59_Conditional_2_Template(rf, ctx) { if (rf & 1) {
193
- i0.ɵɵelementStart(0, "div", 58);
194
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_59_Conditional_2_For_2_Template, 11, 3, "div", 67, i0.ɵɵrepeaterTrackByIdentity);
347
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template(rf, ctx) { if (rf & 1) {
348
+ const _r9 = i0.ɵɵgetCurrentView();
349
+ i0.ɵɵelementStart(0, "div", 109);
350
+ i0.ɵɵlistener("cdkDropListDropped", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template_div_cdkDropListDropped_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.onTestDrop($event)); });
351
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_For_2_Template, 14, 5, "div", 110, _forTrack0);
195
352
  i0.ɵɵelementEnd();
196
353
  } if (rf & 2) {
197
354
  const ctx_r0 = i0.ɵɵnextContext(2);
198
355
  i0.ɵɵadvance();
199
356
  i0.ɵɵrepeater(ctx_r0.suiteTests);
200
357
  } }
201
- function MJTestSuiteFormComponentExtended_Conditional_59_Conditional_3_Template(rf, ctx) { if (rf & 1) {
202
- i0.ɵɵelementStart(0, "div", 59)(1, "div", 75);
203
- i0.ɵɵelement(2, "i", 29);
358
+ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template(rf, ctx) { if (rf & 1) {
359
+ const _r14 = i0.ɵɵgetCurrentView();
360
+ i0.ɵɵelementStart(0, "div", 101)(1, "div", 127);
361
+ i0.ɵɵelement(2, "i", 33);
204
362
  i0.ɵɵelementEnd();
205
363
  i0.ɵɵelementStart(3, "h4");
206
364
  i0.ɵɵtext(4, "No Tests in Suite");
207
365
  i0.ɵɵelementEnd();
208
366
  i0.ɵɵelementStart(5, "p");
209
367
  i0.ɵɵtext(6, "Add tests to this suite to start running them together.");
368
+ i0.ɵɵelementEnd();
369
+ i0.ɵɵelementStart(7, "button", 25);
370
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r14); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.openAddTestsDialog()); });
371
+ i0.ɵɵelement(8, "i", 98);
372
+ i0.ɵɵtext(9, " Add tests ");
210
373
  i0.ɵɵelementEnd()();
211
374
  } }
212
- function MJTestSuiteFormComponentExtended_Conditional_59_Template(rf, ctx) { if (rf & 1) {
213
- i0.ɵɵelementStart(0, "div", 36);
214
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_59_Conditional_1_Template, 4, 1, "div", 57);
215
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_59_Conditional_2_Template, 3, 0, "div", 58);
216
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_59_Conditional_3_Template, 7, 0, "div", 59);
375
+ function MJTestSuiteFormComponentExtended_Conditional_61_Template(rf, ctx) { if (rf & 1) {
376
+ const _r8 = i0.ɵɵgetCurrentView();
377
+ i0.ɵɵelementStart(0, "div", 40)(1, "div", 92)(2, "div", 93)(3, "strong");
378
+ i0.ɵɵtext(4, "Suite tests");
379
+ i0.ɵɵelementEnd();
380
+ i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_5_Template, 2, 1, "span", 94);
381
+ i0.ɵɵelementStart(6, "span", 95);
382
+ i0.ɵɵtext(7, "Drag to reorder \u00B7 Hover a row to remove");
383
+ i0.ɵɵelementEnd()();
384
+ i0.ɵɵelementStart(8, "div", 96)(9, "button", 97);
385
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.openAddTestsDialog()); });
386
+ i0.ɵɵelement(10, "i", 98);
387
+ i0.ɵɵtext(11, " Add tests ");
388
+ i0.ɵɵelementEnd()()();
389
+ i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_12_Template, 4, 1, "div", 99);
390
+ i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_13_Template, 3, 0, "div", 100);
391
+ i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_14_Template, 10, 0, "div", 101);
217
392
  i0.ɵɵelementEnd();
218
393
  } if (rf & 2) {
219
394
  const ctx_r0 = i0.ɵɵnextContext();
395
+ i0.ɵɵadvance(5);
396
+ i0.ɵɵconditional(ctx_r0.testsLoaded ? 5 : -1);
397
+ i0.ɵɵadvance(4);
398
+ i0.ɵɵproperty("disabled", ctx_r0.isReorderingTests);
399
+ i0.ɵɵadvance(3);
400
+ i0.ɵɵconditional(ctx_r0.loadingTests ? 12 : -1);
220
401
  i0.ɵɵadvance();
221
- i0.ɵɵconditional(ctx_r0.loadingTests ? 1 : -1);
222
- i0.ɵɵadvance();
223
- i0.ɵɵconditional(!ctx_r0.loadingTests && ctx_r0.suiteTests.length > 0 ? 2 : -1);
402
+ i0.ɵɵconditional(!ctx_r0.loadingTests && ctx_r0.suiteTests.length > 0 ? 13 : -1);
224
403
  i0.ɵɵadvance();
225
- i0.ɵɵconditional(ctx_r0.testsLoaded && !ctx_r0.loadingTests && ctx_r0.suiteTests.length === 0 ? 3 : -1);
404
+ i0.ɵɵconditional(ctx_r0.testsLoaded && !ctx_r0.loadingTests && ctx_r0.suiteTests.length === 0 ? 14 : -1);
226
405
  } }
227
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
228
- i0.ɵɵelementStart(0, "div", 61);
229
- i0.ɵɵelement(1, "div", 63);
230
- i0.ɵɵelementStart(2, "div", 64);
231
- i0.ɵɵelement(3, "div", 65)(4, "div", 66);
406
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_For_3_Template(rf, ctx) { if (rf & 1) {
407
+ i0.ɵɵelementStart(0, "div", 103);
408
+ i0.ɵɵelement(1, "div", 105);
409
+ i0.ɵɵelementStart(2, "div", 106);
410
+ i0.ɵɵelement(3, "div", 107)(4, "div", 108);
232
411
  i0.ɵɵelementEnd()();
233
412
  } }
234
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_1_Template(rf, ctx) { if (rf & 1) {
235
- i0.ɵɵelementStart(0, "div", 57)(1, "div", 60);
236
- i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_1_For_3_Template, 5, 0, "div", 61, i0.ɵɵrepeaterTrackByIdentity);
413
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template(rf, ctx) { if (rf & 1) {
414
+ i0.ɵɵelementStart(0, "div", 99)(1, "div", 102);
415
+ i0.ɵɵrepeaterCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_For_3_Template, 5, 0, "div", 103, i0.ɵɵrepeaterTrackByIdentity);
237
416
  i0.ɵɵelementEnd()();
238
417
  } if (rf & 2) {
239
418
  i0.ɵɵadvance(2);
240
419
  i0.ɵɵrepeater(i0.ɵɵpureFunction0(0, _c2));
241
420
  } }
242
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
421
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
243
422
  i0.ɵɵelementStart(0, "span");
244
- i0.ɵɵelement(1, "i", 92);
423
+ i0.ɵɵelement(1, "i", 145);
245
424
  i0.ɵɵtext(2);
246
425
  i0.ɵɵelementEnd();
247
426
  } if (rf & 2) {
248
- const run_r6 = i0.ɵɵnextContext().$implicit;
427
+ const run_r16 = i0.ɵɵnextContext().$implicit;
249
428
  const ctx_r0 = i0.ɵɵnextContext(3);
250
429
  i0.ɵɵadvance(2);
251
- i0.ɵɵtextInterpolate3(" ", run_r6.PassedTests, "/", run_r6.TotalTests, " (", ctx_r0.getPassRate(run_r6).toFixed(0), "%) ");
430
+ i0.ɵɵtextInterpolate3(" ", run_r16.PassedTests, "/", run_r16.TotalTests, " (", ctx_r0.getPassRate(run_r16).toFixed(0), "%) ");
252
431
  } }
253
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
254
- i0.ɵɵelementStart(0, "span", 93);
255
- i0.ɵɵelement(1, "i", 80);
432
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
433
+ i0.ɵɵelementStart(0, "span", 146);
434
+ i0.ɵɵelement(1, "i", 132);
256
435
  i0.ɵɵelementEnd();
257
436
  } if (rf & 2) {
258
- const run_r6 = i0.ɵɵnextContext().$implicit;
259
- i0.ɵɵclassMap("status-" + run_r6.Status.toLowerCase());
437
+ const run_r16 = i0.ɵɵnextContext().$implicit;
438
+ i0.ɵɵclassMap("status-" + run_r16.Status.toLowerCase());
260
439
  i0.ɵɵadvance();
261
- i0.ɵɵclassProp("fa-circle-check", run_r6.Status === "Completed")("fa-circle-xmark", run_r6.Status === "Failed")("fa-spinner", run_r6.Status === "Running")("fa-clock", run_r6.Status === "Pending")("fa-ban", run_r6.Status === "Cancelled");
440
+ i0.ɵɵclassProp("fa-circle-check", run_r16.Status === "Completed")("fa-circle-xmark", run_r16.Status === "Failed")("fa-spinner", run_r16.Status === "Running")("fa-clock", run_r16.Status === "Pending")("fa-ban", run_r16.Status === "Cancelled");
262
441
  } }
263
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_16_Template(rf, ctx) { if (rf & 1) {
264
- i0.ɵɵelementStart(0, "span", 89);
265
- i0.ɵɵelement(1, "i", 94);
266
- i0.ɵɵelementStart(2, "span", 95);
267
- i0.ɵɵelement(3, "i", 96);
442
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_16_Template(rf, ctx) { if (rf & 1) {
443
+ i0.ɵɵelementStart(0, "span", 141);
444
+ i0.ɵɵelement(1, "i", 147);
445
+ i0.ɵɵelementStart(2, "span", 148);
446
+ i0.ɵɵelement(3, "i", 149);
268
447
  i0.ɵɵelementEnd()();
269
448
  } }
270
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
271
- i0.ɵɵelementStart(0, "span", 97);
272
- i0.ɵɵelement(1, "i", 98);
449
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_17_Template(rf, ctx) { if (rf & 1) {
450
+ i0.ɵɵelementStart(0, "span", 150);
451
+ i0.ɵɵelement(1, "i", 151);
273
452
  i0.ɵɵelementStart(2, "span");
274
453
  i0.ɵɵtext(3);
275
454
  i0.ɵɵelementEnd()();
276
455
  } if (rf & 2) {
277
- const run_r6 = i0.ɵɵnextContext().$implicit;
456
+ const run_r16 = i0.ɵɵnextContext().$implicit;
278
457
  const ctx_r0 = i0.ɵɵnextContext(3);
279
- i0.ɵɵclassProp("high", ctx_r0.getPassRate(run_r6) >= 80)("medium", ctx_r0.getPassRate(run_r6) >= 50 && ctx_r0.getPassRate(run_r6) < 80)("low", ctx_r0.getPassRate(run_r6) < 50);
458
+ i0.ɵɵclassProp("high", ctx_r0.getPassRate(run_r16) >= 80)("medium", ctx_r0.getPassRate(run_r16) >= 50 && ctx_r0.getPassRate(run_r16) < 80)("low", ctx_r0.getPassRate(run_r16) < 50);
280
459
  i0.ɵɵadvance(3);
281
- i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r6).toFixed(0), "%");
460
+ i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r16).toFixed(0), "%");
282
461
  } }
283
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
284
- i0.ɵɵelementStart(0, "span", 99);
462
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
463
+ i0.ɵɵelementStart(0, "span", 152);
285
464
  i0.ɵɵtext(1);
286
465
  i0.ɵɵelementEnd();
287
466
  } if (rf & 2) {
288
- const tag_r7 = ctx.$implicit;
467
+ const tag_r17 = ctx.$implicit;
289
468
  i0.ɵɵadvance();
290
- i0.ɵɵtextInterpolate(tag_r7);
469
+ i0.ɵɵtextInterpolate(tag_r17);
291
470
  } }
292
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
293
- i0.ɵɵelementStart(0, "div", 91);
294
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_18_For_2_Template, 2, 1, "span", 99, i0.ɵɵrepeaterTrackByIdentity);
471
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
472
+ i0.ɵɵelementStart(0, "div", 143);
473
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_For_2_Template, 2, 1, "span", 152, i0.ɵɵrepeaterTrackByIdentity);
295
474
  i0.ɵɵelementEnd();
296
475
  } if (rf & 2) {
297
- const run_r6 = i0.ɵɵnextContext().$implicit;
476
+ const run_r16 = i0.ɵɵnextContext().$implicit;
298
477
  const ctx_r0 = i0.ɵɵnextContext(3);
299
478
  i0.ɵɵadvance();
300
- i0.ɵɵrepeater(ctx_r0.getRunTags(run_r6));
479
+ i0.ɵɵrepeater(ctx_r0.getRunTags(run_r16));
301
480
  } }
302
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
303
- const _r5 = i0.ɵɵgetCurrentView();
304
- i0.ɵɵelementStart(0, "div", 78);
305
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Template_div_click_0_listener() { const run_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r6.ID)); });
306
- i0.ɵɵelementStart(1, "div", 79);
307
- i0.ɵɵelement(2, "i", 80);
308
- i0.ɵɵelementEnd();
309
- i0.ɵɵelementStart(3, "div", 81)(4, "div", 82)(5, "span", 83);
481
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
482
+ const _r15 = i0.ɵɵgetCurrentView();
483
+ i0.ɵɵelementStart(0, "div", 130);
484
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template_div_click_0_listener() { const run_r16 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r16.ID)); });
485
+ i0.ɵɵelementStart(1, "div", 131);
486
+ i0.ɵɵelement(2, "i", 132);
487
+ i0.ɵɵelementEnd();
488
+ i0.ɵɵelementStart(3, "div", 133)(4, "div", 134)(5, "span", 135);
310
489
  i0.ɵɵtext(6);
311
490
  i0.ɵɵelementEnd();
312
- i0.ɵɵelementStart(7, "span", 84);
491
+ i0.ɵɵelementStart(7, "span", 136);
313
492
  i0.ɵɵtext(8);
314
493
  i0.ɵɵelementEnd()();
315
- i0.ɵɵelementStart(9, "div", 85)(10, "span");
316
- i0.ɵɵelement(11, "i", 86);
494
+ i0.ɵɵelementStart(9, "div", 137)(10, "span");
495
+ i0.ɵɵelement(11, "i", 138);
317
496
  i0.ɵɵtext(12);
318
497
  i0.ɵɵelementEnd();
319
- i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_13_Template, 3, 3, "span");
498
+ i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_13_Template, 3, 3, "span");
320
499
  i0.ɵɵelementEnd();
321
- i0.ɵɵelementStart(14, "div", 87);
322
- i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_15_Template, 2, 12, "span", 88);
323
- i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_16_Template, 4, 0, "span", 89);
324
- i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_17_Template, 4, 7, "span", 90);
500
+ i0.ɵɵelementStart(14, "div", 139);
501
+ i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_15_Template, 2, 12, "span", 140);
502
+ i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_16_Template, 4, 0, "span", 141);
503
+ i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_17_Template, 4, 7, "span", 142);
325
504
  i0.ɵɵelementEnd();
326
- i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Conditional_18_Template, 3, 0, "div", 91);
505
+ i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Conditional_18_Template, 3, 0, "div", 143);
327
506
  i0.ɵɵelementEnd();
328
- i0.ɵɵelement(19, "i", 74);
507
+ i0.ɵɵelement(19, "i", 144);
329
508
  i0.ɵɵelementEnd();
330
509
  } if (rf & 2) {
331
- const run_r6 = ctx.$implicit;
510
+ const run_r16 = ctx.$implicit;
332
511
  const ctx_r0 = i0.ɵɵnextContext(3);
333
512
  i0.ɵɵadvance();
334
- i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r6.Status));
513
+ i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r16.Status));
335
514
  i0.ɵɵadvance();
336
- i0.ɵɵclassProp("fa-check", run_r6.Status === "Completed")("fa-times", run_r6.Status === "Failed")("fa-spinner", run_r6.Status === "Running")("fa-clock", run_r6.Status === "Pending")("fa-ban", run_r6.Status === "Cancelled");
515
+ i0.ɵɵclassProp("fa-check", run_r16.Status === "Completed")("fa-times", run_r16.Status === "Failed")("fa-spinner", run_r16.Status === "Running")("fa-clock", run_r16.Status === "Pending")("fa-ban", run_r16.Status === "Cancelled");
337
516
  i0.ɵɵadvance(4);
338
- i0.ɵɵtextInterpolate1("Run #", run_r6.ID.substring(0, 8));
517
+ i0.ɵɵtextInterpolate1("Run #", run_r16.ID.substring(0, 8));
339
518
  i0.ɵɵadvance();
340
- i0.ɵɵstyleProp("color", ctx_r0.getRunStatusColor(run_r6.Status));
519
+ i0.ɵɵstyleProp("color", ctx_r0.getRunStatusColor(run_r16.Status));
341
520
  i0.ɵɵadvance();
342
- i0.ɵɵtextInterpolate(run_r6.Status);
521
+ i0.ɵɵtextInterpolate(run_r16.Status);
343
522
  i0.ɵɵadvance(4);
344
- i0.ɵɵtextInterpolate1(" ", ctx_r0.getRelativeTime(run_r6.StartedAt));
523
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.getRelativeTime(run_r16.StartedAt));
345
524
  i0.ɵɵadvance();
346
- i0.ɵɵconditional(run_r6.TotalTests ? 13 : -1);
525
+ i0.ɵɵconditional(run_r16.TotalTests ? 13 : -1);
347
526
  i0.ɵɵadvance(2);
348
527
  i0.ɵɵconditional(ctx_r0.evalPreferences.showExecution ? 15 : -1);
349
528
  i0.ɵɵadvance();
350
529
  i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman ? 16 : -1);
351
530
  i0.ɵɵadvance();
352
- i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && run_r6.TotalTests ? 17 : -1);
531
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && run_r16.TotalTests ? 17 : -1);
353
532
  i0.ɵɵadvance();
354
- i0.ɵɵconditional(ctx_r0.getRunTags(run_r6).length > 0 ? 18 : -1);
533
+ i0.ɵɵconditional(ctx_r0.getRunTags(run_r16).length > 0 ? 18 : -1);
355
534
  } }
356
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_Template(rf, ctx) { if (rf & 1) {
357
- i0.ɵɵelementStart(0, "div", 76);
358
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_For_2_Template, 20, 22, "div", 77, i0.ɵɵrepeaterTrackByIdentity);
535
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template(rf, ctx) { if (rf & 1) {
536
+ i0.ɵɵelementStart(0, "div", 128);
537
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_For_2_Template, 20, 22, "div", 129, i0.ɵɵrepeaterTrackByIdentity);
359
538
  i0.ɵɵelementEnd();
360
539
  } if (rf & 2) {
361
540
  const ctx_r0 = i0.ɵɵnextContext(2);
362
541
  i0.ɵɵadvance();
363
542
  i0.ɵɵrepeater(ctx_r0.suiteRuns);
364
543
  } }
365
- function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_3_Template(rf, ctx) { if (rf & 1) {
366
- const _r8 = i0.ɵɵgetCurrentView();
367
- i0.ɵɵelementStart(0, "div", 59)(1, "div", 75);
368
- i0.ɵɵelement(2, "i", 100);
544
+ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template(rf, ctx) { if (rf & 1) {
545
+ const _r18 = i0.ɵɵgetCurrentView();
546
+ i0.ɵɵelementStart(0, "div", 101)(1, "div", 127);
547
+ i0.ɵɵelement(2, "i", 153);
369
548
  i0.ɵɵelementEnd();
370
549
  i0.ɵɵelementStart(3, "h4");
371
550
  i0.ɵɵtext(4, "No Suite Runs Yet");
@@ -373,17 +552,17 @@ function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_3_Template(
373
552
  i0.ɵɵelementStart(5, "p");
374
553
  i0.ɵɵtext(6, "Run this suite to see execution history and results here.");
375
554
  i0.ɵɵelementEnd();
376
- i0.ɵɵelementStart(7, "button", 21);
377
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_60_Conditional_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
378
- i0.ɵɵelement(8, "i", 22);
555
+ i0.ɵɵelementStart(7, "button", 25);
556
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r18); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
557
+ i0.ɵɵelement(8, "i", 26);
379
558
  i0.ɵɵtext(9, " Run Suite Now ");
380
559
  i0.ɵɵelementEnd()();
381
560
  } }
382
- function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if (rf & 1) {
383
- i0.ɵɵelementStart(0, "div", 37);
384
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_1_Template, 4, 1, "div", 57);
385
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_2_Template, 3, 0, "div", 76);
386
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_60_Conditional_3_Template, 10, 0, "div", 59);
561
+ function MJTestSuiteFormComponentExtended_Conditional_62_Template(rf, ctx) { if (rf & 1) {
562
+ i0.ɵɵelementStart(0, "div", 41);
563
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_1_Template, 4, 1, "div", 99);
564
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_2_Template, 3, 0, "div", 128);
565
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_3_Template, 10, 0, "div", 101);
387
566
  i0.ɵɵelementEnd();
388
567
  } if (rf & 2) {
389
568
  const ctx_r0 = i0.ɵɵnextContext();
@@ -394,12 +573,12 @@ function MJTestSuiteFormComponentExtended_Conditional_60_Template(rf, ctx) { if
394
573
  i0.ɵɵadvance();
395
574
  i0.ɵɵconditional(ctx_r0.runsLoaded && !ctx_r0.loadingRuns && ctx_r0.suiteRuns.length === 0 ? 3 : -1);
396
575
  } }
397
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_1_Template(rf, ctx) { if (rf & 1) {
398
- i0.ɵɵelementStart(0, "div", 57);
399
- i0.ɵɵelement(1, "mj-loading", 101);
576
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_1_Template(rf, ctx) { if (rf & 1) {
577
+ i0.ɵɵelementStart(0, "div", 99);
578
+ i0.ɵɵelement(1, "mj-loading", 154);
400
579
  i0.ɵɵelementEnd();
401
580
  } }
402
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
581
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
403
582
  i0.ɵɵelementStart(0, "span");
404
583
  i0.ɵɵtext(1);
405
584
  i0.ɵɵelementEnd();
@@ -408,10 +587,10 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
408
587
  i0.ɵɵadvance();
409
588
  i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r0.selectedTags.length, " tags");
410
589
  } }
411
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
412
- i0.ɵɵelementStart(0, "span", 112);
590
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Template(rf, ctx) { if (rf & 1) {
591
+ i0.ɵɵelementStart(0, "span", 165);
413
592
  i0.ɵɵtext(1);
414
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_19_Conditional_2_Template, 2, 1, "span");
593
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Conditional_2_Template, 2, 1, "span");
415
594
  i0.ɵɵelementEnd();
416
595
  } if (rf & 2) {
417
596
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -420,8 +599,8 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
420
599
  i0.ɵɵadvance();
421
600
  i0.ɵɵconditional(ctx_r0.selectedTags.length > 0 ? 2 : -1);
422
601
  } }
423
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
424
- i0.ɵɵelementStart(0, "span", 117);
602
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_Conditional_3_Template(rf, ctx) { if (rf & 1) {
603
+ i0.ɵɵelementStart(0, "span", 170);
425
604
  i0.ɵɵtext(1);
426
605
  i0.ɵɵelementEnd();
427
606
  } if (rf & 2) {
@@ -429,37 +608,37 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
429
608
  i0.ɵɵadvance();
430
609
  i0.ɵɵtextInterpolate1("(", ctx_r0.selectedTags.length, " selected)");
431
610
  } }
432
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_For_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
433
- i0.ɵɵelement(0, "i", 122);
611
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_For_9_Conditional_1_Template(rf, ctx) { if (rf & 1) {
612
+ i0.ɵɵelement(0, "i", 175);
434
613
  } }
435
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_For_9_Template(rf, ctx) { if (rf & 1) {
436
- const _r12 = i0.ɵɵgetCurrentView();
437
- i0.ɵɵelementStart(0, "button", 121);
438
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_For_9_Template_button_click_0_listener() { const tag_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(tag_r13)); });
439
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_For_9_Conditional_1_Template, 1, 0, "i", 122);
614
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_For_9_Template(rf, ctx) { if (rf & 1) {
615
+ const _r22 = i0.ɵɵgetCurrentView();
616
+ i0.ɵɵelementStart(0, "button", 174);
617
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_For_9_Template_button_click_0_listener() { const tag_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(tag_r23)); });
618
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_For_9_Conditional_1_Template, 1, 0, "i", 175);
440
619
  i0.ɵɵtext(2);
441
620
  i0.ɵɵelementEnd();
442
621
  } if (rf & 2) {
443
- const tag_r13 = ctx.$implicit;
622
+ const tag_r23 = ctx.$implicit;
444
623
  const ctx_r0 = i0.ɵɵnextContext(5);
445
- i0.ɵɵclassProp("active", ctx_r0.isTagSelected(tag_r13));
624
+ i0.ɵɵclassProp("active", ctx_r0.isTagSelected(tag_r23));
446
625
  i0.ɵɵadvance();
447
- i0.ɵɵconditional(ctx_r0.isTagSelected(tag_r13) ? 1 : -1);
626
+ i0.ɵɵconditional(ctx_r0.isTagSelected(tag_r23) ? 1 : -1);
448
627
  i0.ɵɵadvance();
449
- i0.ɵɵtextInterpolate1(" ", tag_r13, " ");
628
+ i0.ɵɵtextInterpolate1(" ", tag_r23, " ");
450
629
  } }
451
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_Template(rf, ctx) { if (rf & 1) {
452
- const _r11 = i0.ɵɵgetCurrentView();
453
- i0.ɵɵelementStart(0, "div", 114)(1, "label");
630
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_Template(rf, ctx) { if (rf & 1) {
631
+ const _r21 = i0.ɵɵgetCurrentView();
632
+ i0.ɵɵelementStart(0, "div", 167)(1, "label");
454
633
  i0.ɵɵtext(2, "Filter by Tag ");
455
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_Conditional_3_Template, 2, 1, "span", 117);
634
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_Conditional_3_Template, 2, 1, "span", 170);
456
635
  i0.ɵɵelementEnd();
457
- i0.ɵɵelementStart(4, "div", 118)(5, "button", 119);
458
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(null)); });
459
- i0.ɵɵelement(6, "i", 9);
636
+ i0.ɵɵelementStart(4, "div", 171)(5, "button", 172);
637
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r21); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(null)); });
638
+ i0.ɵɵelement(6, "i", 11);
460
639
  i0.ɵɵtext(7, " All Tags ");
461
640
  i0.ɵɵelementEnd();
462
- i0.ɵɵrepeaterCreate(8, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_For_9_Template, 3, 4, "button", 120, i0.ɵɵrepeaterTrackByIdentity);
641
+ i0.ɵɵrepeaterCreate(8, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_For_9_Template, 3, 4, "button", 173, i0.ɵɵrepeaterTrackByIdentity);
463
642
  i0.ɵɵelementEnd()();
464
643
  } if (rf & 2) {
465
644
  const ctx_r0 = i0.ɵɵnextContext(4);
@@ -470,28 +649,28 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
470
649
  i0.ɵɵadvance(3);
471
650
  i0.ɵɵrepeater(ctx_r0.uniqueTags);
472
651
  } }
473
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
474
- const _r10 = i0.ɵɵgetCurrentView();
475
- i0.ɵɵelementStart(0, "div", 113)(1, "div", 114)(2, "label");
652
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
653
+ const _r20 = i0.ɵɵgetCurrentView();
654
+ i0.ɵɵelementStart(0, "div", 166)(1, "div", 167)(2, "label");
476
655
  i0.ɵɵtext(3, "Time Range");
477
656
  i0.ɵɵelementEnd();
478
- i0.ɵɵelementStart(4, "div", 115)(5, "button", 116);
479
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("7d")); });
657
+ i0.ɵɵelementStart(4, "div", 168)(5, "button", 169);
658
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("7d")); });
480
659
  i0.ɵɵtext(6, "7 Days");
481
660
  i0.ɵɵelementEnd();
482
- i0.ɵɵelementStart(7, "button", 116);
483
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("30d")); });
661
+ i0.ɵɵelementStart(7, "button", 169);
662
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("30d")); });
484
663
  i0.ɵɵtext(8, "30 Days");
485
664
  i0.ɵɵelementEnd();
486
- i0.ɵɵelementStart(9, "button", 116);
487
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("90d")); });
665
+ i0.ɵɵelementStart(9, "button", 169);
666
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("90d")); });
488
667
  i0.ɵɵtext(10, "90 Days");
489
668
  i0.ɵɵelementEnd();
490
- i0.ɵɵelementStart(11, "button", 116);
491
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("all")); });
669
+ i0.ɵɵelementStart(11, "button", 169);
670
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r20); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("all")); });
492
671
  i0.ɵɵtext(12, "All Time");
493
672
  i0.ɵɵelementEnd()()();
494
- i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Conditional_13_Template, 10, 3, "div", 114);
673
+ i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Conditional_13_Template, 10, 3, "div", 167);
495
674
  i0.ɵɵelementEnd();
496
675
  } if (rf & 2) {
497
676
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -506,37 +685,37 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
506
685
  i0.ɵɵadvance(2);
507
686
  i0.ɵɵconditional(ctx_r0.uniqueTags.length > 0 ? 13 : -1);
508
687
  } }
509
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_For_60_For_21_Template(rf, ctx) { if (rf & 1) {
510
- i0.ɵɵelementStart(0, "span", 145);
688
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_For_60_For_21_Template(rf, ctx) { if (rf & 1) {
689
+ i0.ɵɵelementStart(0, "span", 198);
511
690
  i0.ɵɵtext(1);
512
691
  i0.ɵɵelementEnd();
513
692
  } if (rf & 2) {
514
- const tag_r16 = ctx.$implicit;
693
+ const tag_r26 = ctx.$implicit;
515
694
  i0.ɵɵadvance();
516
- i0.ɵɵtextInterpolate(tag_r16);
695
+ i0.ɵɵtextInterpolate(tag_r26);
517
696
  } }
518
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_For_60_Conditional_22_Template(rf, ctx) { if (rf & 1) {
519
- i0.ɵɵelementStart(0, "span", 146);
697
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_For_60_Conditional_22_Template(rf, ctx) { if (rf & 1) {
698
+ i0.ɵɵelementStart(0, "span", 199);
520
699
  i0.ɵɵtext(1);
521
700
  i0.ɵɵelementEnd();
522
701
  } if (rf & 2) {
523
- const dp_r15 = i0.ɵɵnextContext().$implicit;
702
+ const dp_r25 = i0.ɵɵnextContext().$implicit;
524
703
  i0.ɵɵadvance();
525
- i0.ɵɵtextInterpolate1("+", dp_r15.tags.length - 2);
704
+ i0.ɵɵtextInterpolate1("+", dp_r25.tags.length - 2);
526
705
  } }
527
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_For_60_Template(rf, ctx) { if (rf & 1) {
528
- const _r14 = i0.ɵɵgetCurrentView();
529
- i0.ɵɵelementStart(0, "tr", 140);
530
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_For_60_Template_tr_click_0_listener() { const dp_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteRun(dp_r15.runId)); });
706
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_For_60_Template(rf, ctx) { if (rf & 1) {
707
+ const _r24 = i0.ɵɵgetCurrentView();
708
+ i0.ɵɵelementStart(0, "tr", 193);
709
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_For_60_Template_tr_click_0_listener() { const dp_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteRun(dp_r25.runId)); });
531
710
  i0.ɵɵelementStart(1, "td");
532
711
  i0.ɵɵtext(2);
533
712
  i0.ɵɵpipe(3, "date");
534
713
  i0.ɵɵelementEnd();
535
- i0.ɵɵelementStart(4, "td")(5, "span", 141);
714
+ i0.ɵɵelementStart(4, "td")(5, "span", 194);
536
715
  i0.ɵɵtext(6);
537
716
  i0.ɵɵelementEnd()();
538
- i0.ɵɵelementStart(7, "td")(8, "div", 142);
539
- i0.ɵɵelement(9, "div", 143);
717
+ i0.ɵɵelementStart(7, "td")(8, "div", 195);
718
+ i0.ɵɵelement(9, "div", 196);
540
719
  i0.ɵɵelementStart(10, "span");
541
720
  i0.ɵɵtext(11);
542
721
  i0.ɵɵelementEnd()()();
@@ -549,86 +728,86 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
549
728
  i0.ɵɵelementStart(16, "td");
550
729
  i0.ɵɵtext(17);
551
730
  i0.ɵɵelementEnd();
552
- i0.ɵɵelementStart(18, "td")(19, "div", 144);
553
- i0.ɵɵrepeaterCreate(20, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_For_60_For_21_Template, 2, 1, "span", 145, i0.ɵɵrepeaterTrackByIdentity);
554
- i0.ɵɵconditionalCreate(22, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_For_60_Conditional_22_Template, 2, 1, "span", 146);
731
+ i0.ɵɵelementStart(18, "td")(19, "div", 197);
732
+ i0.ɵɵrepeaterCreate(20, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_For_60_For_21_Template, 2, 1, "span", 198, i0.ɵɵrepeaterTrackByIdentity);
733
+ i0.ɵɵconditionalCreate(22, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_For_60_Conditional_22_Template, 2, 1, "span", 199);
555
734
  i0.ɵɵelementEnd()()();
556
735
  } if (rf & 2) {
557
- const dp_r15 = ctx.$implicit;
736
+ const dp_r25 = ctx.$implicit;
558
737
  const ctx_r0 = i0.ɵɵnextContext(4);
559
738
  i0.ɵɵadvance(2);
560
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 12, dp_r15.date, "short"));
739
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(3, 12, dp_r25.date, "short"));
561
740
  i0.ɵɵadvance(3);
562
- i0.ɵɵproperty("ngClass", "status-" + dp_r15.status.toLowerCase());
741
+ i0.ɵɵproperty("ngClass", "status-" + dp_r25.status.toLowerCase());
563
742
  i0.ɵɵadvance();
564
- i0.ɵɵtextInterpolate(dp_r15.status);
743
+ i0.ɵɵtextInterpolate(dp_r25.status);
565
744
  i0.ɵɵadvance(3);
566
- i0.ɵɵstyleProp("width", dp_r15.passRate, "%");
567
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(15, _c5, dp_r15.passRate >= 80, dp_r15.passRate >= 50 && dp_r15.passRate < 80, dp_r15.passRate < 50));
745
+ i0.ɵɵstyleProp("width", dp_r25.passRate, "%");
746
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(15, _c5, dp_r25.passRate >= 80, dp_r25.passRate >= 50 && dp_r25.passRate < 80, dp_r25.passRate < 50));
568
747
  i0.ɵɵadvance(2);
569
- i0.ɵɵtextInterpolate1("", dp_r15.passRate.toFixed(0), "%");
748
+ i0.ɵɵtextInterpolate1("", dp_r25.passRate.toFixed(0), "%");
570
749
  i0.ɵɵadvance(2);
571
- i0.ɵɵtextInterpolate2("", dp_r15.passedTests, "/", dp_r15.totalTests);
750
+ i0.ɵɵtextInterpolate2("", dp_r25.passedTests, "/", dp_r25.totalTests);
572
751
  i0.ɵɵadvance(2);
573
- i0.ɵɵtextInterpolate(ctx_r0.formatDuration(dp_r15.duration));
752
+ i0.ɵɵtextInterpolate(ctx_r0.formatDuration(dp_r25.duration));
574
753
  i0.ɵɵadvance(2);
575
- i0.ɵɵtextInterpolate(ctx_r0.formatCost(dp_r15.cost));
754
+ i0.ɵɵtextInterpolate(ctx_r0.formatCost(dp_r25.cost));
576
755
  i0.ɵɵadvance(3);
577
- i0.ɵɵrepeater(dp_r15.tags.slice(0, 2));
756
+ i0.ɵɵrepeater(dp_r25.tags.slice(0, 2));
578
757
  i0.ɵɵadvance(2);
579
- i0.ɵɵconditional(dp_r15.tags.length > 2 ? 22 : -1);
758
+ i0.ɵɵconditional(dp_r25.tags.length > 2 ? 22 : -1);
580
759
  } }
581
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_Conditional_61_Template(rf, ctx) { if (rf & 1) {
582
- i0.ɵɵelementStart(0, "div", 139)(1, "p");
760
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_Conditional_61_Template(rf, ctx) { if (rf & 1) {
761
+ i0.ɵɵelementStart(0, "div", 192)(1, "p");
583
762
  i0.ɵɵtext(2, "No runs match the current filters.");
584
763
  i0.ɵɵelementEnd()();
585
764
  } }
586
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_Template(rf, ctx) { if (rf & 1) {
587
- i0.ɵɵelementStart(0, "div", 123)(1, "div", 124)(2, "div", 125);
588
- i0.ɵɵelement(3, "i", 100);
765
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_Template(rf, ctx) { if (rf & 1) {
766
+ i0.ɵɵelementStart(0, "div", 176)(1, "div", 177)(2, "div", 178);
767
+ i0.ɵɵelement(3, "i", 153);
589
768
  i0.ɵɵelementEnd();
590
- i0.ɵɵelementStart(4, "div", 126)(5, "div", 127);
769
+ i0.ɵɵelementStart(4, "div", 179)(5, "div", 180);
591
770
  i0.ɵɵtext(6);
592
771
  i0.ɵɵelementEnd();
593
- i0.ɵɵelementStart(7, "div", 128);
772
+ i0.ɵɵelementStart(7, "div", 181);
594
773
  i0.ɵɵtext(8, "Total Runs");
595
774
  i0.ɵɵelementEnd()()();
596
- i0.ɵɵelementStart(9, "div", 124)(10, "div", 129);
597
- i0.ɵɵelement(11, "i", 92);
775
+ i0.ɵɵelementStart(9, "div", 177)(10, "div", 182);
776
+ i0.ɵɵelement(11, "i", 145);
598
777
  i0.ɵɵelementEnd();
599
- i0.ɵɵelementStart(12, "div", 126)(13, "div", 127);
778
+ i0.ɵɵelementStart(12, "div", 179)(13, "div", 180);
600
779
  i0.ɵɵtext(14);
601
780
  i0.ɵɵelementEnd();
602
- i0.ɵɵelementStart(15, "div", 128);
781
+ i0.ɵɵelementStart(15, "div", 181);
603
782
  i0.ɵɵtext(16, "Avg Pass Rate");
604
783
  i0.ɵɵelementEnd();
605
- i0.ɵɵelementStart(17, "div", 130);
606
- i0.ɵɵelement(18, "i", 16);
784
+ i0.ɵɵelementStart(17, "div", 183);
785
+ i0.ɵɵelement(18, "i", 19);
607
786
  i0.ɵɵtext(19);
608
787
  i0.ɵɵelementEnd()()();
609
- i0.ɵɵelementStart(20, "div", 124)(21, "div", 131);
610
- i0.ɵɵelement(22, "i", 96);
788
+ i0.ɵɵelementStart(20, "div", 177)(21, "div", 184);
789
+ i0.ɵɵelement(22, "i", 149);
611
790
  i0.ɵɵelementEnd();
612
- i0.ɵɵelementStart(23, "div", 126)(24, "div", 127);
791
+ i0.ɵɵelementStart(23, "div", 179)(24, "div", 180);
613
792
  i0.ɵɵtext(25);
614
793
  i0.ɵɵelementEnd();
615
- i0.ɵɵelementStart(26, "div", 128);
794
+ i0.ɵɵelementStart(26, "div", 181);
616
795
  i0.ɵɵtext(27, "Avg Duration");
617
796
  i0.ɵɵelementEnd()()();
618
- i0.ɵɵelementStart(28, "div", 124)(29, "div", 132);
619
- i0.ɵɵelement(30, "i", 133);
797
+ i0.ɵɵelementStart(28, "div", 177)(29, "div", 185);
798
+ i0.ɵɵelement(30, "i", 186);
620
799
  i0.ɵɵelementEnd();
621
- i0.ɵɵelementStart(31, "div", 126)(32, "div", 127);
800
+ i0.ɵɵelementStart(31, "div", 179)(32, "div", 180);
622
801
  i0.ɵɵtext(33);
623
802
  i0.ɵɵelementEnd();
624
- i0.ɵɵelementStart(34, "div", 128);
803
+ i0.ɵɵelementStart(34, "div", 181);
625
804
  i0.ɵɵtext(35, "Total Cost");
626
805
  i0.ɵɵelementEnd()()()();
627
- i0.ɵɵelementStart(36, "div", 134)(37, "h3");
628
- i0.ɵɵelement(38, "i", 135);
806
+ i0.ɵɵelementStart(36, "div", 187)(37, "h3");
807
+ i0.ɵɵelement(38, "i", 188);
629
808
  i0.ɵɵtext(39, " Run History");
630
809
  i0.ɵɵelementEnd();
631
- i0.ɵɵelementStart(40, "div", 136)(41, "table", 137)(42, "thead")(43, "tr")(44, "th");
810
+ i0.ɵɵelementStart(40, "div", 189)(41, "table", 190)(42, "thead")(43, "tr")(44, "th");
632
811
  i0.ɵɵtext(45, "Date");
633
812
  i0.ɵɵelementEnd();
634
813
  i0.ɵɵelementStart(46, "th");
@@ -650,9 +829,9 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
650
829
  i0.ɵɵtext(57, "Tags");
651
830
  i0.ɵɵelementEnd()()();
652
831
  i0.ɵɵelementStart(58, "tbody");
653
- i0.ɵɵrepeaterCreate(59, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_For_60_Template, 23, 19, "tr", 138, i0.ɵɵrepeaterTrackByIdentity);
832
+ i0.ɵɵrepeaterCreate(59, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_For_60_Template, 23, 19, "tr", 191, i0.ɵɵrepeaterTrackByIdentity);
654
833
  i0.ɵɵelementEnd()()();
655
- i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_Conditional_61_Template, 3, 0, "div", 139);
834
+ i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_Conditional_61_Template, 3, 0, "div", 192);
656
835
  i0.ɵɵelementEnd();
657
836
  } if (rf & 2) {
658
837
  const ctx_r0 = i0.ɵɵnextContext(3);
@@ -675,260 +854,260 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
675
854
  i0.ɵɵadvance(2);
676
855
  i0.ɵɵconditional(ctx_r0.getFilteredAnalyticsData().length === 0 ? 61 : -1);
677
856
  } }
678
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_0_Template(rf, ctx) { if (rf & 1) {
679
- i0.ɵɵelementStart(0, "div", 57);
680
- i0.ɵɵelement(1, "mj-loading", 148);
857
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_0_Template(rf, ctx) { if (rf & 1) {
858
+ i0.ɵɵelementStart(0, "div", 99);
859
+ i0.ɵɵelement(1, "mj-loading", 201);
681
860
  i0.ɵɵelementEnd();
682
861
  } }
683
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
684
- const _r18 = i0.ɵɵgetCurrentView();
685
- i0.ɵɵelementStart(0, "button", 170);
686
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.clearMatrixFilter()); });
687
- i0.ɵɵelement(1, "i", 171);
862
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
863
+ const _r28 = i0.ɵɵgetCurrentView();
864
+ i0.ɵɵelementStart(0, "button", 223);
865
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.clearMatrixFilter()); });
866
+ i0.ɵɵelement(1, "i", 91);
688
867
  i0.ɵɵelementEnd();
689
868
  } }
690
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
691
- i0.ɵɵelementStart(0, "span", 177);
869
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
870
+ i0.ɵɵelementStart(0, "span", 229);
692
871
  i0.ɵɵtext(1);
693
872
  i0.ɵɵelementEnd();
694
873
  } if (rf & 2) {
695
- const tag_r21 = ctx.$implicit;
874
+ const tag_r31 = ctx.$implicit;
696
875
  i0.ɵɵadvance();
697
- i0.ɵɵtextInterpolate(tag_r21);
876
+ i0.ɵɵtextInterpolate(tag_r31);
698
877
  } }
699
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
700
- i0.ɵɵelementStart(0, "span", 178);
878
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_Conditional_3_Template(rf, ctx) { if (rf & 1) {
879
+ i0.ɵɵelementStart(0, "span", 230);
701
880
  i0.ɵɵtext(1);
702
881
  i0.ɵɵelementEnd();
703
882
  } if (rf & 2) {
704
- const run_r20 = i0.ɵɵnextContext(2).$implicit;
883
+ const run_r30 = i0.ɵɵnextContext(2).$implicit;
705
884
  i0.ɵɵadvance();
706
- i0.ɵɵtextInterpolate1("+", run_r20.tags.length - 2);
885
+ i0.ɵɵtextInterpolate1("+", run_r30.tags.length - 2);
707
886
  } }
708
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_Template(rf, ctx) { if (rf & 1) {
709
- i0.ɵɵelementStart(0, "div", 174);
710
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_For_2_Template, 2, 1, "span", 177, i0.ɵɵrepeaterTrackByIdentity);
711
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_Conditional_3_Template, 2, 1, "span", 178);
887
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_Template(rf, ctx) { if (rf & 1) {
888
+ i0.ɵɵelementStart(0, "div", 226);
889
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_For_2_Template, 2, 1, "span", 229, i0.ɵɵrepeaterTrackByIdentity);
890
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_Conditional_3_Template, 2, 1, "span", 230);
712
891
  i0.ɵɵelementEnd();
713
892
  } if (rf & 2) {
714
- const run_r20 = i0.ɵɵnextContext().$implicit;
893
+ const run_r30 = i0.ɵɵnextContext().$implicit;
715
894
  i0.ɵɵadvance();
716
- i0.ɵɵrepeater(run_r20.tags.slice(0, 2));
895
+ i0.ɵɵrepeater(run_r30.tags.slice(0, 2));
717
896
  i0.ɵɵadvance(2);
718
- i0.ɵɵconditional(run_r20.tags.length > 2 ? 3 : -1);
897
+ i0.ɵɵconditional(run_r30.tags.length > 2 ? 3 : -1);
719
898
  } }
720
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_26_Template(rf, ctx) { if (rf & 1) {
721
- const _r19 = i0.ɵɵgetCurrentView();
722
- i0.ɵɵelementStart(0, "th", 172);
899
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_26_Template(rf, ctx) { if (rf & 1) {
900
+ const _r29 = i0.ɵɵgetCurrentView();
901
+ i0.ɵɵelementStart(0, "th", 224);
723
902
  i0.ɵɵpipe(1, "date");
724
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_26_Template_th_click_0_listener() { const run_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r20.runId)); });
725
- i0.ɵɵelementStart(2, "div", 173);
726
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_Template, 4, 1, "div", 174);
727
- i0.ɵɵelementStart(4, "div", 175);
903
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_26_Template_th_click_0_listener() { const run_r30 = i0.ɵɵrestoreView(_r29).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r30.runId)); });
904
+ i0.ɵɵelementStart(2, "div", 225);
905
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_26_Conditional_3_Template, 4, 1, "div", 226);
906
+ i0.ɵɵelementStart(4, "div", 227);
728
907
  i0.ɵɵtext(5);
729
908
  i0.ɵɵelementEnd();
730
- i0.ɵɵelementStart(6, "div", 176);
909
+ i0.ɵɵelementStart(6, "div", 228);
731
910
  i0.ɵɵtext(7);
732
911
  i0.ɵɵelementEnd()()();
733
912
  } if (rf & 2) {
734
- const run_r20 = ctx.$implicit;
913
+ const run_r30 = ctx.$implicit;
735
914
  const ctx_r0 = i0.ɵɵnextContext(5);
736
- i0.ɵɵproperty("title", "Click to view suite run - " + i0.ɵɵpipeBind2(1, 5, run_r20.date, "medium"));
915
+ i0.ɵɵproperty("title", "Click to view suite run - " + i0.ɵɵpipeBind2(1, 5, run_r30.date, "medium"));
737
916
  i0.ɵɵadvance(3);
738
- i0.ɵɵconditional(run_r20.tags.length > 0 ? 3 : -1);
917
+ i0.ɵɵconditional(run_r30.tags.length > 0 ? 3 : -1);
739
918
  i0.ɵɵadvance(2);
740
- i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(run_r20.date));
919
+ i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(run_r30.date));
741
920
  i0.ɵɵadvance();
742
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(8, _c5, run_r20.passRate >= 80, run_r20.passRate >= 50 && run_r20.passRate < 80, run_r20.passRate < 50));
921
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction3(8, _c5, run_r30.passRate >= 80, run_r30.passRate >= 50 && run_r30.passRate < 80, run_r30.passRate < 50));
743
922
  i0.ɵɵadvance();
744
- i0.ɵɵtextInterpolate1(" ", run_r20.passRate.toFixed(0), "% ");
923
+ i0.ɵɵtextInterpolate1(" ", run_r30.passRate.toFixed(0), "% ");
745
924
  } }
746
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
747
- i0.ɵɵelementStart(0, "span", 192);
748
- i0.ɵɵelement(1, "i", 80);
925
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
926
+ i0.ɵɵelementStart(0, "span", 244);
927
+ i0.ɵɵelement(1, "i", 132);
749
928
  i0.ɵɵelementEnd();
750
929
  } if (rf & 2) {
751
- const result_r26 = i0.ɵɵnextContext();
930
+ const result_r36 = i0.ɵɵnextContext();
752
931
  const ctx_r0 = i0.ɵɵnextContext(7);
753
- i0.ɵɵclassProp("cell-skipped-status", result_r26.status === "Skipped" || result_r26.status === "Pending");
754
- i0.ɵɵproperty("ngClass", "status-" + result_r26.status.toLowerCase())("title", ctx_r0.getStatusTooltip(result_r26.status));
932
+ i0.ɵɵclassProp("cell-skipped-status", result_r36.status === "Skipped" || result_r36.status === "Pending");
933
+ i0.ɵɵproperty("ngClass", "status-" + result_r36.status.toLowerCase())("title", ctx_r0.getStatusTooltip(result_r36.status));
755
934
  i0.ɵɵadvance();
756
- i0.ɵɵclassProp("fa-check", result_r26.status === "Passed")("fa-times", result_r26.status === "Failed")("fa-exclamation", result_r26.status === "Error")("fa-hourglass-end", result_r26.status === "Timeout")("fa-forward", result_r26.status === "Skipped")("fa-spinner", result_r26.status === "Running")("fa-clock", result_r26.status === "Pending");
935
+ i0.ɵɵclassProp("fa-check", result_r36.status === "Passed")("fa-times", result_r36.status === "Failed")("fa-exclamation", result_r36.status === "Error")("fa-hourglass-end", result_r36.status === "Timeout")("fa-forward", result_r36.status === "Skipped")("fa-spinner", result_r36.status === "Running")("fa-clock", result_r36.status === "Pending");
757
936
  } }
758
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
759
- i0.ɵɵelementStart(0, "span", 188);
760
- i0.ɵɵelement(1, "i", 193);
937
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
938
+ i0.ɵɵelementStart(0, "span", 240);
939
+ i0.ɵɵelement(1, "i", 245);
761
940
  i0.ɵɵelementEnd();
762
941
  } }
763
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
764
- i0.ɵɵelementStart(0, "span", 194);
765
- i0.ɵɵelement(1, "i", 94);
766
- i0.ɵɵelementStart(2, "span", 195);
942
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
943
+ i0.ɵɵelementStart(0, "span", 246);
944
+ i0.ɵɵelement(1, "i", 147);
945
+ i0.ɵɵelementStart(2, "span", 247);
767
946
  i0.ɵɵtext(3);
768
947
  i0.ɵɵelementEnd()();
769
948
  } if (rf & 2) {
770
- const result_r26 = i0.ɵɵnextContext();
949
+ const result_r36 = i0.ɵɵnextContext();
771
950
  const ctx_r0 = i0.ɵɵnextContext(7);
772
- i0.ɵɵclassProp("rating-low", result_r26.humanRating <= 4)("rating-medium", result_r26.humanRating >= 5 && result_r26.humanRating <= 6)("rating-good", result_r26.humanRating >= 7 && result_r26.humanRating <= 8)("rating-excellent", result_r26.humanRating >= 9);
773
- i0.ɵɵproperty("title", ctx_r0.getHumanTooltip(result_r26.humanRating, result_r26.humanComments));
951
+ i0.ɵɵclassProp("rating-low", result_r36.humanRating <= 4)("rating-medium", result_r36.humanRating >= 5 && result_r36.humanRating <= 6)("rating-good", result_r36.humanRating >= 7 && result_r36.humanRating <= 8)("rating-excellent", result_r36.humanRating >= 9);
952
+ i0.ɵɵproperty("title", ctx_r0.getHumanTooltip(result_r36.humanRating, result_r36.humanComments));
774
953
  i0.ɵɵadvance(3);
775
- i0.ɵɵtextInterpolate(result_r26.humanRating);
954
+ i0.ɵɵtextInterpolate(result_r36.humanRating);
776
955
  } }
777
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
778
- i0.ɵɵelementStart(0, "span", 196);
779
- i0.ɵɵelement(1, "i", 98);
780
- i0.ɵɵelementStart(2, "span", 197);
956
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
957
+ i0.ɵɵelementStart(0, "span", 248);
958
+ i0.ɵɵelement(1, "i", 151);
959
+ i0.ɵɵelementStart(2, "span", 249);
781
960
  i0.ɵɵtext(3);
782
961
  i0.ɵɵelementEnd()();
783
962
  } if (rf & 2) {
784
- const result_r26 = i0.ɵɵnextContext();
785
- i0.ɵɵclassProp("score-low", result_r26.score < 0.5)("score-medium", result_r26.score >= 0.5 && result_r26.score < 0.7)("score-good", result_r26.score >= 0.7 && result_r26.score < 0.85)("score-excellent", result_r26.score >= 0.85);
786
- i0.ɵɵproperty("title", "Auto Score: " + (result_r26.score * 100).toFixed(0) + "% automated evaluation");
963
+ const result_r36 = i0.ɵɵnextContext();
964
+ i0.ɵɵclassProp("score-low", result_r36.score < 0.5)("score-medium", result_r36.score >= 0.5 && result_r36.score < 0.7)("score-good", result_r36.score >= 0.7 && result_r36.score < 0.85)("score-excellent", result_r36.score >= 0.85);
965
+ i0.ɵɵproperty("title", "Auto Score: " + (result_r36.score * 100).toFixed(0) + "% automated evaluation");
787
966
  i0.ɵɵadvance(3);
788
- i0.ɵɵtextInterpolate((result_r26.score * 100).toFixed(0));
967
+ i0.ɵɵtextInterpolate((result_r36.score * 100).toFixed(0));
789
968
  } }
790
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
791
- i0.ɵɵelementStart(0, "span", 191);
792
- i0.ɵɵelement(1, "i", 98);
969
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
970
+ i0.ɵɵelementStart(0, "span", 243);
971
+ i0.ɵɵelement(1, "i", 151);
793
972
  i0.ɵɵelementEnd();
794
973
  } }
795
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
796
- i0.ɵɵelementStart(0, "div", 185);
797
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template, 2, 18, "span", 187);
798
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template, 2, 0, "span", 188);
799
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template, 4, 10, "span", 189);
800
- i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template, 4, 10, "span", 190);
801
- i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template, 2, 0, "span", 191);
974
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Template(rf, ctx) { if (rf & 1) {
975
+ i0.ɵɵelementStart(0, "div", 237);
976
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_1_Template, 2, 18, "span", 239);
977
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_2_Template, 2, 0, "span", 240);
978
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_3_Template, 4, 10, "span", 241);
979
+ i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_4_Template, 4, 10, "span", 242);
980
+ i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Conditional_5_Template, 2, 0, "span", 243);
802
981
  i0.ɵɵelementEnd();
803
982
  } if (rf & 2) {
804
- const result_r26 = ctx;
983
+ const result_r36 = ctx;
805
984
  const ctx_r0 = i0.ɵɵnextContext(7);
806
985
  i0.ɵɵadvance();
807
986
  i0.ɵɵconditional(ctx_r0.evalPreferences.showExecution ? 1 : -1);
808
987
  i0.ɵɵadvance();
809
- i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && !result_r26.humanRating ? 2 : -1);
988
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && !result_r36.humanRating ? 2 : -1);
810
989
  i0.ɵɵadvance();
811
- i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && result_r26.humanRating ? 3 : -1);
990
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showHuman && result_r36.humanRating ? 3 : -1);
812
991
  i0.ɵɵadvance();
813
- i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r26.score != null ? 4 : -1);
992
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r36.score != null ? 4 : -1);
814
993
  i0.ɵɵadvance();
815
- i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r26.score == null ? 5 : -1);
994
+ i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto && result_r36.score == null ? 5 : -1);
816
995
  } }
817
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
818
- i0.ɵɵelementStart(0, "span", 186);
819
- i0.ɵɵelement(1, "i", 198);
996
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_2_Template(rf, ctx) { if (rf & 1) {
997
+ i0.ɵɵelementStart(0, "span", 238);
998
+ i0.ɵɵelement(1, "i", 250);
820
999
  i0.ɵɵelementEnd();
821
1000
  } }
822
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Template(rf, ctx) { if (rf & 1) {
823
- const _r24 = i0.ɵɵgetCurrentView();
824
- i0.ɵɵelementStart(0, "td", 184);
825
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Template_td_click_0_listener($event) { const run_r25 = i0.ɵɵrestoreView(_r24).$implicit; const test_r23 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.onMatrixCellClick(ctx_r0.getTestResultForRun(run_r25.runId, test_r23.testId), $event)); });
826
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Template, 6, 5, "div", 185);
827
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_2_Template, 2, 0, "span", 186);
1001
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Template(rf, ctx) { if (rf & 1) {
1002
+ const _r34 = i0.ɵɵgetCurrentView();
1003
+ i0.ɵɵelementStart(0, "td", 236);
1004
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Template_td_click_0_listener($event) { const run_r35 = i0.ɵɵrestoreView(_r34).$implicit; const test_r33 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.onMatrixCellClick(ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId), $event)); });
1005
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_1_Template, 6, 5, "div", 237);
1006
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Conditional_2_Template, 2, 0, "span", 238);
828
1007
  i0.ɵɵelementEnd();
829
1008
  } if (rf & 2) {
830
1009
  let tmp_27_0;
831
1010
  let tmp_28_0;
832
- const run_r25 = ctx.$implicit;
833
- const test_r23 = i0.ɵɵnextContext().$implicit;
1011
+ const run_r35 = ctx.$implicit;
1012
+ const test_r33 = i0.ɵɵnextContext().$implicit;
834
1013
  const ctx_r0 = i0.ɵɵnextContext(5);
835
- i0.ɵɵclassProp("clickable", ctx_r0.getTestResultForRun(run_r25.runId, test_r23.testId))("cell-not-run", !ctx_r0.getTestResultForRun(run_r25.runId, test_r23.testId));
836
- i0.ɵɵproperty("ngClass", ctx_r0.getMatrixCellClass(ctx_r0.getTestResultForRun(run_r25.runId, test_r23.testId)))("title", ((tmp_27_0 = ctx_r0.getTestResultForRun(run_r25.runId, test_r23.testId)) == null ? null : tmp_27_0.status) + " - Click to view test run" || "Not Run");
1014
+ i0.ɵɵclassProp("clickable", ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId))("cell-not-run", !ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId));
1015
+ i0.ɵɵproperty("ngClass", ctx_r0.getMatrixCellClass(ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId)))("title", ((tmp_27_0 = ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId)) == null ? null : tmp_27_0.status) + " - Click to view test run" || "Not Run");
837
1016
  i0.ɵɵadvance();
838
- i0.ɵɵconditional((tmp_28_0 = ctx_r0.getTestResultForRun(run_r25.runId, test_r23.testId)) ? 1 : -1, tmp_28_0);
1017
+ i0.ɵɵconditional((tmp_28_0 = ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId)) ? 1 : -1, tmp_28_0);
839
1018
  i0.ɵɵadvance();
840
- i0.ɵɵconditional(!ctx_r0.getTestResultForRun(run_r25.runId, test_r23.testId) ? 2 : -1);
1019
+ i0.ɵɵconditional(!ctx_r0.getTestResultForRun(run_r35.runId, test_r33.testId) ? 2 : -1);
841
1020
  } }
842
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_Template(rf, ctx) { if (rf & 1) {
843
- const _r22 = i0.ɵɵgetCurrentView();
844
- i0.ɵɵelementStart(0, "tr", 179);
845
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_Template_tr_click_0_listener() { const test_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.selectMatrixRow(test_r23.testId)); });
846
- i0.ɵɵelementStart(1, "td", 180);
1021
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_Template(rf, ctx) { if (rf & 1) {
1022
+ const _r32 = i0.ɵɵgetCurrentView();
1023
+ i0.ɵɵelementStart(0, "tr", 231);
1024
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_Template_tr_click_0_listener() { const test_r33 = i0.ɵɵrestoreView(_r32).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.selectMatrixRow(test_r33.testId)); });
1025
+ i0.ɵɵelementStart(1, "td", 232);
847
1026
  i0.ɵɵtext(2);
848
1027
  i0.ɵɵelementEnd();
849
- i0.ɵɵelementStart(3, "td", 181)(4, "span", 182);
1028
+ i0.ɵɵelementStart(3, "td", 233)(4, "span", 234);
850
1029
  i0.ɵɵtext(5);
851
1030
  i0.ɵɵelementEnd()();
852
- i0.ɵɵrepeaterCreate(6, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Template, 3, 8, "td", 183, i0.ɵɵrepeaterTrackByIdentity);
853
- i0.ɵɵelement(8, "td", 169);
1031
+ i0.ɵɵrepeaterCreate(6, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_For_7_Template, 3, 8, "td", 235, i0.ɵɵrepeaterTrackByIdentity);
1032
+ i0.ɵɵelement(8, "td", 222);
854
1033
  i0.ɵɵelementEnd();
855
1034
  } if (rf & 2) {
856
- const test_r23 = ctx.$implicit;
1035
+ const test_r33 = ctx.$implicit;
857
1036
  const ctx_r0 = i0.ɵɵnextContext(5);
858
- i0.ɵɵclassProp("row-selected", ctx_r0.selectedMatrixTestId === test_r23.testId);
1037
+ i0.ɵɵclassProp("row-selected", ctx_r0.selectedMatrixTestId === test_r33.testId);
859
1038
  i0.ɵɵadvance(2);
860
- i0.ɵɵtextInterpolate(test_r23.sequence);
1039
+ i0.ɵɵtextInterpolate(test_r33.sequence);
861
1040
  i0.ɵɵadvance(2);
862
- i0.ɵɵproperty("title", test_r23.testName);
1041
+ i0.ɵɵproperty("title", test_r33.testName);
863
1042
  i0.ɵɵadvance();
864
- i0.ɵɵtextInterpolate(test_r23.testName);
1043
+ i0.ɵɵtextInterpolate(test_r33.testName);
865
1044
  i0.ɵɵadvance();
866
1045
  i0.ɵɵrepeater(ctx_r0.matrixData);
867
1046
  } }
868
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_2_Template(rf, ctx) { if (rf & 1) {
869
- i0.ɵɵelementStart(0, "span", 200)(1, "span", 203);
1047
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1048
+ i0.ɵɵelementStart(0, "span", 252)(1, "span", 255);
870
1049
  i0.ɵɵtext(2);
871
1050
  i0.ɵɵelementEnd()();
872
1051
  } if (rf & 2) {
873
- const run_r27 = i0.ɵɵnextContext().$implicit;
1052
+ const run_r37 = i0.ɵɵnextContext().$implicit;
874
1053
  const ctx_r0 = i0.ɵɵnextContext(5);
875
1054
  i0.ɵɵadvance(2);
876
- i0.ɵɵtextInterpolate2("", ctx_r0.getRunPassedCount(run_r27), "/", ctx_r0.getRunTotalCount(run_r27));
1055
+ i0.ɵɵtextInterpolate2("", ctx_r0.getRunPassedCount(run_r37), "/", ctx_r0.getRunTotalCount(run_r37));
877
1056
  } }
878
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
879
- i0.ɵɵelementStart(0, "span", 204);
1057
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1058
+ i0.ɵɵelementStart(0, "span", 256);
880
1059
  i0.ɵɵtext(1);
881
1060
  i0.ɵɵelementEnd();
882
1061
  } if (rf & 2) {
883
1062
  let tmp_16_0;
884
- const run_r27 = i0.ɵɵnextContext(2).$implicit;
1063
+ const run_r37 = i0.ɵɵnextContext(2).$implicit;
885
1064
  const ctx_r0 = i0.ɵɵnextContext(5);
886
1065
  i0.ɵɵadvance();
887
- i0.ɵɵtextInterpolate((tmp_16_0 = ctx_r0.getRunHumanAvg(run_r27)) == null ? null : tmp_16_0.toFixed(1));
1066
+ i0.ɵɵtextInterpolate((tmp_16_0 = ctx_r0.getRunHumanAvg(run_r37)) == null ? null : tmp_16_0.toFixed(1));
888
1067
  } }
889
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_3_Template(rf, ctx) { if (rf & 1) {
890
- i0.ɵɵelementStart(0, "span", 201);
891
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_3_Conditional_1_Template, 2, 1, "span", 204);
892
- i0.ɵɵelementStart(2, "span", 205);
1068
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1069
+ i0.ɵɵelementStart(0, "span", 253);
1070
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_3_Conditional_1_Template, 2, 1, "span", 256);
1071
+ i0.ɵɵelementStart(2, "span", 257);
893
1072
  i0.ɵɵtext(3);
894
1073
  i0.ɵɵelementEnd()();
895
1074
  } if (rf & 2) {
896
- const run_r27 = i0.ɵɵnextContext().$implicit;
1075
+ const run_r37 = i0.ɵɵnextContext().$implicit;
897
1076
  const ctx_r0 = i0.ɵɵnextContext(5);
898
1077
  i0.ɵɵadvance();
899
- i0.ɵɵconditional(ctx_r0.getRunHumanAvg(run_r27) != null ? 1 : -1);
1078
+ i0.ɵɵconditional(ctx_r0.getRunHumanAvg(run_r37) != null ? 1 : -1);
900
1079
  i0.ɵɵadvance(2);
901
- i0.ɵɵtextInterpolate1("(", ctx_r0.getRunHumanCount(run_r27), ")");
1080
+ i0.ɵɵtextInterpolate1("(", ctx_r0.getRunHumanCount(run_r37), ")");
902
1081
  } }
903
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
904
- i0.ɵɵelementStart(0, "span", 204);
1082
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_4_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1083
+ i0.ɵɵelementStart(0, "span", 256);
905
1084
  i0.ɵɵtext(1);
906
1085
  i0.ɵɵelementEnd();
907
1086
  } if (rf & 2) {
908
- const run_r27 = i0.ɵɵnextContext(2).$implicit;
1087
+ const run_r37 = i0.ɵɵnextContext(2).$implicit;
909
1088
  const ctx_r0 = i0.ɵɵnextContext(5);
910
1089
  i0.ɵɵadvance();
911
- i0.ɵɵtextInterpolate1("", (ctx_r0.getRunAutoAvg(run_r27) * 100).toFixed(0), "%");
1090
+ i0.ɵɵtextInterpolate1("", (ctx_r0.getRunAutoAvg(run_r37) * 100).toFixed(0), "%");
912
1091
  } }
913
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_4_Template(rf, ctx) { if (rf & 1) {
914
- i0.ɵɵelementStart(0, "span", 202);
915
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_4_Conditional_1_Template, 2, 1, "span", 204);
916
- i0.ɵɵelementStart(2, "span", 205);
1092
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1093
+ i0.ɵɵelementStart(0, "span", 254);
1094
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_4_Conditional_1_Template, 2, 1, "span", 256);
1095
+ i0.ɵɵelementStart(2, "span", 257);
917
1096
  i0.ɵɵtext(3);
918
1097
  i0.ɵɵelementEnd()();
919
1098
  } if (rf & 2) {
920
- const run_r27 = i0.ɵɵnextContext().$implicit;
1099
+ const run_r37 = i0.ɵɵnextContext().$implicit;
921
1100
  const ctx_r0 = i0.ɵɵnextContext(5);
922
1101
  i0.ɵɵadvance();
923
- i0.ɵɵconditional(ctx_r0.getRunAutoAvg(run_r27) != null ? 1 : -1);
1102
+ i0.ɵɵconditional(ctx_r0.getRunAutoAvg(run_r37) != null ? 1 : -1);
924
1103
  i0.ɵɵadvance(2);
925
- i0.ɵɵtextInterpolate1("(", ctx_r0.getRunAutoCount(run_r27), ")");
1104
+ i0.ɵɵtextInterpolate1("(", ctx_r0.getRunAutoCount(run_r37), ")");
926
1105
  } }
927
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Template(rf, ctx) { if (rf & 1) {
928
- i0.ɵɵelementStart(0, "td", 168)(1, "div", 199);
929
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_2_Template, 3, 2, "span", 200);
930
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_3_Template, 4, 2, "span", 201);
931
- i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_4_Template, 4, 2, "span", 202);
1106
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Template(rf, ctx) { if (rf & 1) {
1107
+ i0.ɵɵelementStart(0, "td", 221)(1, "div", 251);
1108
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_2_Template, 3, 2, "span", 252);
1109
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_3_Template, 4, 2, "span", 253);
1110
+ i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Conditional_4_Template, 4, 2, "span", 254);
932
1111
  i0.ɵɵelementEnd()();
933
1112
  } if (rf & 2) {
934
1113
  const ctx_r0 = i0.ɵɵnextContext(5);
@@ -939,50 +1118,50 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
939
1118
  i0.ɵɵadvance();
940
1119
  i0.ɵɵconditional(ctx_r0.evalPreferences.showAuto ? 4 : -1);
941
1120
  } }
942
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_Template(rf, ctx) { if (rf & 1) {
943
- const _r17 = i0.ɵɵgetCurrentView();
944
- i0.ɵɵelementStart(0, "div", 147)(1, "div", 149)(2, "h3");
945
- i0.ɵɵelement(3, "i", 106);
1121
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1122
+ const _r27 = i0.ɵɵgetCurrentView();
1123
+ i0.ɵɵelementStart(0, "div", 200)(1, "div", 202)(2, "h3");
1124
+ i0.ɵɵelement(3, "i", 159);
946
1125
  i0.ɵɵtext(4, " Test Results Matrix");
947
1126
  i0.ɵɵelementEnd();
948
- i0.ɵɵelementStart(5, "div", 150)(6, "div", 151);
949
- i0.ɵɵelement(7, "i", 152);
950
- i0.ɵɵelementStart(8, "input", 153);
951
- i0.ɵɵlistener("input", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onMatrixFilterInput($event)); });
1127
+ i0.ɵɵelementStart(5, "div", 203)(6, "div", 204);
1128
+ i0.ɵɵelement(7, "i", 205);
1129
+ i0.ɵɵelementStart(8, "input", 206);
1130
+ i0.ɵɵlistener("input", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onMatrixFilterInput($event)); });
952
1131
  i0.ɵɵelementEnd();
953
- i0.ɵɵconditionalCreate(9, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_Conditional_9_Template, 2, 0, "button", 154);
1132
+ i0.ɵɵconditionalCreate(9, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_Conditional_9_Template, 2, 0, "button", 207);
954
1133
  i0.ɵɵelementEnd();
955
- i0.ɵɵelementStart(10, "span", 155);
1134
+ i0.ɵɵelementStart(10, "span", 208);
956
1135
  i0.ɵɵtext(11);
957
1136
  i0.ɵɵelementEnd();
958
- i0.ɵɵelementStart(12, "button", 156);
959
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.exportMatrixToCSV()); });
960
- i0.ɵɵelement(13, "i", 157);
1137
+ i0.ɵɵelementStart(12, "button", 209);
1138
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.exportMatrixToCSV()); });
1139
+ i0.ɵɵelement(13, "i", 210);
961
1140
  i0.ɵɵtext(14, " Export ");
962
1141
  i0.ɵɵelementEnd()()();
963
- i0.ɵɵelementStart(15, "div", 158)(16, "table", 159)(17, "thead")(18, "tr")(19, "th", 160);
964
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_Template_th_click_19_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("sequence")); });
1142
+ i0.ɵɵelementStart(15, "div", 211)(16, "table", 212)(17, "thead")(18, "tr")(19, "th", 213);
1143
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_Template_th_click_19_listener() { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("sequence")); });
965
1144
  i0.ɵɵtext(20, " # ");
966
- i0.ɵɵelement(21, "i", 16);
1145
+ i0.ɵɵelement(21, "i", 19);
967
1146
  i0.ɵɵelementEnd();
968
- i0.ɵɵelementStart(22, "th", 161);
969
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_Template_th_click_22_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("name")); });
1147
+ i0.ɵɵelementStart(22, "th", 214);
1148
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_Template_th_click_22_listener() { i0.ɵɵrestoreView(_r27); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("name")); });
970
1149
  i0.ɵɵtext(23, " Test ");
971
- i0.ɵɵelement(24, "i", 16);
1150
+ i0.ɵɵelement(24, "i", 19);
972
1151
  i0.ɵɵelementEnd();
973
- i0.ɵɵrepeaterCreate(25, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_26_Template, 8, 12, "th", 162, i0.ɵɵrepeaterTrackByIdentity);
974
- i0.ɵɵelement(27, "th", 163);
1152
+ i0.ɵɵrepeaterCreate(25, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_26_Template, 8, 12, "th", 215, i0.ɵɵrepeaterTrackByIdentity);
1153
+ i0.ɵɵelement(27, "th", 216);
975
1154
  i0.ɵɵelementEnd()();
976
1155
  i0.ɵɵelementStart(28, "tbody");
977
- i0.ɵɵrepeaterCreate(29, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_30_Template, 9, 5, "tr", 164, i0.ɵɵrepeaterTrackByIdentity);
1156
+ i0.ɵɵrepeaterCreate(29, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_30_Template, 9, 5, "tr", 217, i0.ɵɵrepeaterTrackByIdentity);
978
1157
  i0.ɵɵelementEnd();
979
- i0.ɵɵelementStart(31, "tfoot")(32, "tr", 165);
980
- i0.ɵɵelement(33, "td", 166);
981
- i0.ɵɵelementStart(34, "td", 167)(35, "strong");
1158
+ i0.ɵɵelementStart(31, "tfoot")(32, "tr", 218);
1159
+ i0.ɵɵelement(33, "td", 219);
1160
+ i0.ɵɵelementStart(34, "td", 220)(35, "strong");
982
1161
  i0.ɵɵtext(36, "Totals");
983
1162
  i0.ɵɵelementEnd()();
984
- i0.ɵɵrepeaterCreate(37, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_For_38_Template, 5, 3, "td", 168, i0.ɵɵrepeaterTrackByIdentity);
985
- i0.ɵɵelement(39, "td", 169);
1163
+ i0.ɵɵrepeaterCreate(37, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_For_38_Template, 5, 3, "td", 221, i0.ɵɵrepeaterTrackByIdentity);
1164
+ i0.ɵɵelement(39, "td", 222);
986
1165
  i0.ɵɵelementEnd()()()()();
987
1166
  } if (rf & 2) {
988
1167
  const ctx_r0 = i0.ɵɵnextContext(4);
@@ -1005,9 +1184,9 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
1005
1184
  i0.ɵɵadvance(8);
1006
1185
  i0.ɵɵrepeater(ctx_r0.matrixData);
1007
1186
  } }
1008
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1009
- i0.ɵɵelementStart(0, "div", 59)(1, "div", 75);
1010
- i0.ɵɵelement(2, "i", 106);
1187
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1188
+ i0.ɵɵelementStart(0, "div", 101)(1, "div", 127);
1189
+ i0.ɵɵelement(2, "i", 159);
1011
1190
  i0.ɵɵelementEnd();
1012
1191
  i0.ɵɵelementStart(3, "h4");
1013
1192
  i0.ɵɵtext(4, "No Matrix Data");
@@ -1016,10 +1195,10 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
1016
1195
  i0.ɵɵtext(6, "No suite runs match the current filters.");
1017
1196
  i0.ɵɵelementEnd()();
1018
1197
  } }
1019
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Template(rf, ctx) { if (rf & 1) {
1020
- i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_0_Template, 2, 0, "div", 57);
1021
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_1_Template, 40, 7, "div", 147);
1022
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Conditional_2_Template, 7, 0, "div", 59);
1198
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Template(rf, ctx) { if (rf & 1) {
1199
+ i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_0_Template, 2, 0, "div", 99);
1200
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_1_Template, 40, 7, "div", 200);
1201
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Conditional_2_Template, 7, 0, "div", 101);
1023
1202
  } if (rf & 2) {
1024
1203
  const ctx_r0 = i0.ɵɵnextContext(3);
1025
1204
  i0.ɵɵconditional(ctx_r0.loadingMatrix ? 0 : -1);
@@ -1028,37 +1207,37 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
1028
1207
  i0.ɵɵadvance();
1029
1208
  i0.ɵɵconditional(!ctx_r0.loadingMatrix && ctx_r0.matrixLoaded && ctx_r0.matrixData.length === 0 ? 2 : -1);
1030
1209
  } }
1031
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_24_Conditional_0_Template(rf, ctx) { if (rf & 1) {
1032
- i0.ɵɵelementStart(0, "div", 57);
1033
- i0.ɵɵelement(1, "mj-loading", 207);
1210
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_24_Conditional_0_Template(rf, ctx) { if (rf & 1) {
1211
+ i0.ɵɵelementStart(0, "div", 99);
1212
+ i0.ɵɵelement(1, "mj-loading", 259);
1034
1213
  i0.ɵɵelementEnd();
1035
1214
  } }
1036
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_24_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1037
- i0.ɵɵelementStart(0, "div", 206)(1, "div", 208)(2, "h3");
1038
- i0.ɵɵelement(3, "i", 107);
1215
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_24_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1216
+ i0.ɵɵelementStart(0, "div", 258)(1, "div", 260)(2, "h3");
1217
+ i0.ɵɵelement(3, "i", 160);
1039
1218
  i0.ɵɵtext(4, " Test Results Flow");
1040
1219
  i0.ɵɵelementEnd();
1041
- i0.ɵɵelementStart(5, "div", 209)(6, "span", 210);
1042
- i0.ɵɵelement(7, "i", 122);
1220
+ i0.ɵɵelementStart(5, "div", 261)(6, "span", 262);
1221
+ i0.ɵɵelement(7, "i", 175);
1043
1222
  i0.ɵɵtext(8, " Passed");
1044
1223
  i0.ɵɵelementEnd();
1045
- i0.ɵɵelementStart(9, "span", 211);
1046
- i0.ɵɵelement(10, "i", 171);
1224
+ i0.ɵɵelementStart(9, "span", 263);
1225
+ i0.ɵɵelement(10, "i", 91);
1047
1226
  i0.ɵɵtext(11, " Failed");
1048
1227
  i0.ɵɵelementEnd();
1049
- i0.ɵɵelementStart(12, "span", 212);
1050
- i0.ɵɵelement(13, "i", 213);
1228
+ i0.ɵɵelementStart(12, "span", 264);
1229
+ i0.ɵɵelement(13, "i", 265);
1051
1230
  i0.ɵɵtext(14, " Error");
1052
1231
  i0.ɵɵelementEnd();
1053
- i0.ɵɵelementStart(15, "span", 214);
1054
- i0.ɵɵelement(16, "i", 215);
1232
+ i0.ɵɵelementStart(15, "span", 266);
1233
+ i0.ɵɵelement(16, "i", 267);
1055
1234
  i0.ɵɵtext(17, " Skipped");
1056
1235
  i0.ɵɵelementEnd()()();
1057
- i0.ɵɵelementStart(18, "div", 216);
1058
- i0.ɵɵelement(19, "div", 217, 0);
1236
+ i0.ɵɵelementStart(18, "div", 268);
1237
+ i0.ɵɵelement(19, "div", 269, 1);
1059
1238
  i0.ɵɵelementEnd();
1060
- i0.ɵɵelementStart(21, "div", 218);
1061
- i0.ɵɵelement(22, "i", 45);
1239
+ i0.ɵɵelementStart(21, "div", 270);
1240
+ i0.ɵɵelement(22, "i", 119);
1062
1241
  i0.ɵɵtext(23);
1063
1242
  i0.ɵɵelementEnd()();
1064
1243
  } if (rf & 2) {
@@ -1066,9 +1245,9 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
1066
1245
  i0.ɵɵadvance(23);
1067
1246
  i0.ɵɵtextInterpolate1(" Interactive visualization showing test results across ", ctx_r0.matrixData.length, " runs. Hover over elements for details, click nodes to navigate. ");
1068
1247
  } }
1069
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_24_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1070
- i0.ɵɵelementStart(0, "div", 59)(1, "div", 75);
1071
- i0.ɵɵelement(2, "i", 107);
1248
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_24_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1249
+ i0.ɵɵelementStart(0, "div", 101)(1, "div", 127);
1250
+ i0.ɵɵelement(2, "i", 160);
1072
1251
  i0.ɵɵelementEnd();
1073
1252
  i0.ɵɵelementStart(3, "h4");
1074
1253
  i0.ɵɵtext(4, "No Chart Data");
@@ -1077,10 +1256,10 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
1077
1256
  i0.ɵɵtext(6, "No suite runs match the current filters.");
1078
1257
  i0.ɵɵelementEnd()();
1079
1258
  } }
1080
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_24_Template(rf, ctx) { if (rf & 1) {
1081
- i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_24_Conditional_0_Template, 2, 0, "div", 57);
1082
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_24_Conditional_1_Template, 24, 1, "div", 206);
1083
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_24_Conditional_2_Template, 7, 0, "div", 59);
1259
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_24_Template(rf, ctx) { if (rf & 1) {
1260
+ i0.ɵɵconditionalCreate(0, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_24_Conditional_0_Template, 2, 0, "div", 99);
1261
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_24_Conditional_1_Template, 24, 1, "div", 258);
1262
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_24_Conditional_2_Template, 7, 0, "div", 101);
1084
1263
  } if (rf & 2) {
1085
1264
  const ctx_r0 = i0.ɵɵnextContext(3);
1086
1265
  i0.ɵɵconditional(ctx_r0.loadingMatrix ? 0 : -1);
@@ -1089,40 +1268,40 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Condition
1089
1268
  i0.ɵɵadvance();
1090
1269
  i0.ɵɵconditional(!ctx_r0.loadingMatrix && ctx_r0.matrixLoaded && ctx_r0.matrixData.length === 0 ? 2 : -1);
1091
1270
  } }
1092
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1093
- const _r9 = i0.ɵɵgetCurrentView();
1094
- i0.ɵɵelementStart(0, "div", 102)(1, "div", 103)(2, "button", 104);
1095
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("summary")); });
1096
- i0.ɵɵelement(3, "i", 105);
1271
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1272
+ const _r19 = i0.ɵɵgetCurrentView();
1273
+ i0.ɵɵelementStart(0, "div", 155)(1, "div", 156)(2, "button", 157);
1274
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("summary")); });
1275
+ i0.ɵɵelement(3, "i", 158);
1097
1276
  i0.ɵɵelementStart(4, "span");
1098
1277
  i0.ɵɵtext(5, "Summary");
1099
1278
  i0.ɵɵelementEnd()();
1100
- i0.ɵɵelementStart(6, "button", 104);
1101
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("matrix")); });
1102
- i0.ɵɵelement(7, "i", 106);
1279
+ i0.ɵɵelementStart(6, "button", 157);
1280
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("matrix")); });
1281
+ i0.ɵɵelement(7, "i", 159);
1103
1282
  i0.ɵɵelementStart(8, "span");
1104
1283
  i0.ɵɵtext(9, "Matrix");
1105
1284
  i0.ɵɵelementEnd()();
1106
- i0.ɵɵelementStart(10, "button", 104);
1107
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("chart")); });
1108
- i0.ɵɵelement(11, "i", 107);
1285
+ i0.ɵɵelementStart(10, "button", 157);
1286
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("chart")); });
1287
+ i0.ɵɵelement(11, "i", 160);
1109
1288
  i0.ɵɵelementStart(12, "span");
1110
1289
  i0.ɵɵtext(13, "Chart");
1111
1290
  i0.ɵɵelementEnd()()()();
1112
- i0.ɵɵelementStart(14, "div", 108)(15, "div", 109);
1113
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Template_div_click_15_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleFilters()); });
1114
- i0.ɵɵelementStart(16, "span", 110);
1115
- i0.ɵɵelement(17, "i", 111);
1291
+ i0.ɵɵelementStart(14, "div", 161)(15, "div", 162);
1292
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template_div_click_15_listener() { i0.ɵɵrestoreView(_r19); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleFilters()); });
1293
+ i0.ɵɵelementStart(16, "span", 163);
1294
+ i0.ɵɵelement(17, "i", 164);
1116
1295
  i0.ɵɵtext(18, " Filters ");
1117
- i0.ɵɵconditionalCreate(19, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_19_Template, 3, 2, "span", 112);
1296
+ i0.ɵɵconditionalCreate(19, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_19_Template, 3, 2, "span", 165);
1118
1297
  i0.ɵɵelementEnd();
1119
- i0.ɵɵelement(20, "i", 16);
1298
+ i0.ɵɵelement(20, "i", 19);
1120
1299
  i0.ɵɵelementEnd();
1121
- i0.ɵɵconditionalCreate(21, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_21_Template, 14, 9, "div", 113);
1300
+ i0.ɵɵconditionalCreate(21, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_21_Template, 14, 9, "div", 166);
1122
1301
  i0.ɵɵelementEnd();
1123
- i0.ɵɵconditionalCreate(22, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_22_Template, 62, 15);
1124
- i0.ɵɵconditionalCreate(23, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_23_Template, 3, 3);
1125
- i0.ɵɵconditionalCreate(24, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Conditional_24_Template, 3, 3);
1302
+ i0.ɵɵconditionalCreate(22, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_22_Template, 62, 15);
1303
+ i0.ɵɵconditionalCreate(23, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_23_Template, 3, 3);
1304
+ i0.ɵɵconditionalCreate(24, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Conditional_24_Template, 3, 3);
1126
1305
  } if (rf & 2) {
1127
1306
  const ctx_r0 = i0.ɵɵnextContext(2);
1128
1307
  i0.ɵɵadvance(2);
@@ -1146,10 +1325,10 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Template(
1146
1325
  i0.ɵɵadvance();
1147
1326
  i0.ɵɵconditional(ctx_r0.analyticsView === "chart" ? 24 : -1);
1148
1327
  } }
1149
- function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1150
- const _r28 = i0.ɵɵgetCurrentView();
1151
- i0.ɵɵelementStart(0, "div", 59)(1, "div", 75);
1152
- i0.ɵɵelement(2, "i", 32);
1328
+ function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1329
+ const _r38 = i0.ɵɵgetCurrentView();
1330
+ i0.ɵɵelementStart(0, "div", 101)(1, "div", 127);
1331
+ i0.ɵɵelement(2, "i", 36);
1153
1332
  i0.ɵɵelementEnd();
1154
1333
  i0.ɵɵelementStart(3, "h4");
1155
1334
  i0.ɵɵtext(4, "No Analytics Data");
@@ -1157,17 +1336,17 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_3_Template(
1157
1336
  i0.ɵɵelementStart(5, "p");
1158
1337
  i0.ɵɵtext(6, "Run this suite to start collecting analytics data.");
1159
1338
  i0.ɵɵelementEnd();
1160
- i0.ɵɵelementStart(7, "button", 21);
1161
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_61_Conditional_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
1162
- i0.ɵɵelement(8, "i", 22);
1339
+ i0.ɵɵelementStart(7, "button", 25);
1340
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r38); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
1341
+ i0.ɵɵelement(8, "i", 26);
1163
1342
  i0.ɵɵtext(9, " Run Suite Now ");
1164
1343
  i0.ɵɵelementEnd()();
1165
1344
  } }
1166
- function MJTestSuiteFormComponentExtended_Conditional_61_Template(rf, ctx) { if (rf & 1) {
1167
- i0.ɵɵelementStart(0, "div", 38);
1168
- i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_1_Template, 2, 0, "div", 57);
1169
- i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_2_Template, 25, 14);
1170
- i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_61_Conditional_3_Template, 10, 0, "div", 59);
1345
+ function MJTestSuiteFormComponentExtended_Conditional_63_Template(rf, ctx) { if (rf & 1) {
1346
+ i0.ɵɵelementStart(0, "div", 42);
1347
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_1_Template, 2, 0, "div", 99);
1348
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_2_Template, 25, 14);
1349
+ i0.ɵɵconditionalCreate(3, MJTestSuiteFormComponentExtended_Conditional_63_Conditional_3_Template, 10, 0, "div", 101);
1171
1350
  i0.ɵɵelementEnd();
1172
1351
  } if (rf & 2) {
1173
1352
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1178,75 +1357,75 @@ function MJTestSuiteFormComponentExtended_Conditional_61_Template(rf, ctx) { if
1178
1357
  i0.ɵɵadvance();
1179
1358
  i0.ɵɵconditional(!ctx_r0.loadingAnalytics && ctx_r0.analyticsLoaded && ctx_r0.analyticsData.length === 0 ? 3 : -1);
1180
1359
  } }
1181
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_5_For_2_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
1182
- i0.ɵɵelementStart(0, "span", 234);
1360
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
1361
+ i0.ɵɵelementStart(0, "span", 286);
1183
1362
  i0.ɵɵtext(1);
1184
1363
  i0.ɵɵelementEnd();
1185
1364
  } if (rf & 2) {
1186
- const tag_r31 = ctx.$implicit;
1365
+ const tag_r41 = ctx.$implicit;
1187
1366
  i0.ɵɵadvance();
1188
- i0.ɵɵtextInterpolate(tag_r31);
1367
+ i0.ɵɵtextInterpolate(tag_r41);
1189
1368
  } }
1190
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_5_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1191
- i0.ɵɵelementStart(0, "div", 233);
1192
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_5_For_2_Conditional_8_For_2_Template, 2, 1, "span", 234, i0.ɵɵrepeaterTrackByIdentity);
1369
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1370
+ i0.ɵɵelementStart(0, "div", 285);
1371
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_For_2_Template, 2, 1, "span", 286, i0.ɵɵrepeaterTrackByIdentity);
1193
1372
  i0.ɵɵelementEnd();
1194
1373
  } if (rf & 2) {
1195
- const run_r30 = i0.ɵɵnextContext().$implicit;
1374
+ const run_r40 = i0.ɵɵnextContext().$implicit;
1196
1375
  const ctx_r0 = i0.ɵɵnextContext(3);
1197
1376
  i0.ɵɵadvance();
1198
- i0.ɵɵrepeater(ctx_r0.getRunTags(run_r30).slice(0, 2));
1377
+ i0.ɵɵrepeater(ctx_r0.getRunTags(run_r40).slice(0, 2));
1199
1378
  } }
1200
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
1201
- const _r29 = i0.ɵɵgetCurrentView();
1202
- i0.ɵɵelementStart(0, "div", 228);
1203
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_5_For_2_Template_div_click_0_listener() { const run_r30 = i0.ɵɵrestoreView(_r29).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.selectCompareRunA(run_r30)); });
1204
- i0.ɵɵelement(1, "div", 229);
1205
- i0.ɵɵelementStart(2, "div", 230)(3, "div", 231);
1379
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
1380
+ const _r39 = i0.ɵɵgetCurrentView();
1381
+ i0.ɵɵelementStart(0, "div", 280);
1382
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template_div_click_0_listener() { const run_r40 = i0.ɵɵrestoreView(_r39).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.selectCompareRunA(run_r40)); });
1383
+ i0.ɵɵelement(1, "div", 281);
1384
+ i0.ɵɵelementStart(2, "div", 282)(3, "div", 283);
1206
1385
  i0.ɵɵtext(4);
1207
1386
  i0.ɵɵpipe(5, "date");
1208
1387
  i0.ɵɵelementEnd();
1209
- i0.ɵɵelementStart(6, "div", 232);
1388
+ i0.ɵɵelementStart(6, "div", 284);
1210
1389
  i0.ɵɵtext(7);
1211
1390
  i0.ɵɵelementEnd()();
1212
- i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_5_For_2_Conditional_8_Template, 3, 0, "div", 233);
1391
+ i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Conditional_8_Template, 3, 0, "div", 285);
1213
1392
  i0.ɵɵelementEnd();
1214
1393
  } if (rf & 2) {
1215
- const run_r30 = ctx.$implicit;
1394
+ const run_r40 = ctx.$implicit;
1216
1395
  const ctx_r0 = i0.ɵɵnextContext(3);
1217
- i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunA(run_r30));
1396
+ i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunA(run_r40));
1218
1397
  i0.ɵɵadvance();
1219
- i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r30.Status));
1398
+ i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r40.Status));
1220
1399
  i0.ɵɵadvance(3);
1221
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 7, run_r30.StartedAt, "short"));
1400
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 7, run_r40.StartedAt, "short"));
1222
1401
  i0.ɵɵadvance(3);
1223
- i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r30).toFixed(0), "% pass");
1402
+ i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r40).toFixed(0), "% pass");
1224
1403
  i0.ɵɵadvance();
1225
- i0.ɵɵconditional(ctx_r0.getRunTags(run_r30).length > 0 ? 8 : -1);
1404
+ i0.ɵɵconditional(ctx_r0.getRunTags(run_r40).length > 0 ? 8 : -1);
1226
1405
  } }
1227
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1228
- i0.ɵɵelementStart(0, "div", 221);
1229
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_5_For_2_Template, 9, 10, "div", 227, i0.ɵɵrepeaterTrackByIdentity);
1406
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1407
+ i0.ɵɵelementStart(0, "div", 273);
1408
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_For_2_Template, 9, 10, "div", 279, i0.ɵɵrepeaterTrackByIdentity);
1230
1409
  i0.ɵɵelementEnd();
1231
1410
  } if (rf & 2) {
1232
1411
  const ctx_r0 = i0.ɵɵnextContext(2);
1233
1412
  i0.ɵɵadvance();
1234
1413
  i0.ɵɵrepeater(ctx_r0.suiteRuns);
1235
1414
  } }
1236
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_6_Template(rf, ctx) { if (rf & 1) {
1237
- const _r32 = i0.ɵɵgetCurrentView();
1238
- i0.ɵɵelementStart(0, "div", 222)(1, "div", 235)(2, "span", 236);
1415
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template(rf, ctx) { if (rf & 1) {
1416
+ const _r42 = i0.ɵɵgetCurrentView();
1417
+ i0.ɵɵelementStart(0, "div", 274)(1, "div", 287)(2, "span", 288);
1239
1418
  i0.ɵɵtext(3, "Selected:");
1240
1419
  i0.ɵɵelementEnd();
1241
- i0.ɵɵelementStart(4, "button", 237);
1242
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r32); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunA = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
1420
+ i0.ɵɵelementStart(4, "button", 289);
1421
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r42); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunA = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
1243
1422
  i0.ɵɵtext(5, "Clear");
1244
1423
  i0.ɵɵelementEnd()();
1245
- i0.ɵɵelementStart(6, "div", 238)(7, "span");
1424
+ i0.ɵɵelementStart(6, "div", 290)(7, "span");
1246
1425
  i0.ɵɵtext(8);
1247
1426
  i0.ɵɵpipe(9, "date");
1248
1427
  i0.ɵɵelementEnd();
1249
- i0.ɵɵelementStart(10, "span", 239);
1428
+ i0.ɵɵelementStart(10, "span", 291);
1250
1429
  i0.ɵɵtext(11);
1251
1430
  i0.ɵɵelementEnd()()();
1252
1431
  } if (rf & 2) {
@@ -1256,75 +1435,75 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_6_Template(
1256
1435
  i0.ɵɵadvance(3);
1257
1436
  i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(ctx_r0.compareRunA).toFixed(1), "%");
1258
1437
  } }
1259
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_12_For_2_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
1260
- i0.ɵɵelementStart(0, "span", 234);
1438
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
1439
+ i0.ɵɵelementStart(0, "span", 286);
1261
1440
  i0.ɵɵtext(1);
1262
1441
  i0.ɵɵelementEnd();
1263
1442
  } if (rf & 2) {
1264
- const tag_r35 = ctx.$implicit;
1443
+ const tag_r45 = ctx.$implicit;
1265
1444
  i0.ɵɵadvance();
1266
- i0.ɵɵtextInterpolate(tag_r35);
1445
+ i0.ɵɵtextInterpolate(tag_r45);
1267
1446
  } }
1268
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_12_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1269
- i0.ɵɵelementStart(0, "div", 233);
1270
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_12_For_2_Conditional_8_For_2_Template, 2, 1, "span", 234, i0.ɵɵrepeaterTrackByIdentity);
1447
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1448
+ i0.ɵɵelementStart(0, "div", 285);
1449
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_For_2_Template, 2, 1, "span", 286, i0.ɵɵrepeaterTrackByIdentity);
1271
1450
  i0.ɵɵelementEnd();
1272
1451
  } if (rf & 2) {
1273
- const run_r34 = i0.ɵɵnextContext().$implicit;
1452
+ const run_r44 = i0.ɵɵnextContext().$implicit;
1274
1453
  const ctx_r0 = i0.ɵɵnextContext(3);
1275
1454
  i0.ɵɵadvance();
1276
- i0.ɵɵrepeater(ctx_r0.getRunTags(run_r34).slice(0, 2));
1455
+ i0.ɵɵrepeater(ctx_r0.getRunTags(run_r44).slice(0, 2));
1277
1456
  } }
1278
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
1279
- const _r33 = i0.ɵɵgetCurrentView();
1280
- i0.ɵɵelementStart(0, "div", 228);
1281
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_12_For_2_Template_div_click_0_listener() { const run_r34 = i0.ɵɵrestoreView(_r33).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(!ctx_r0.IsCompareRunA(run_r34) && ctx_r0.selectCompareRunB(run_r34)); });
1282
- i0.ɵɵelement(1, "div", 229);
1283
- i0.ɵɵelementStart(2, "div", 230)(3, "div", 231);
1457
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template(rf, ctx) { if (rf & 1) {
1458
+ const _r43 = i0.ɵɵgetCurrentView();
1459
+ i0.ɵɵelementStart(0, "div", 280);
1460
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template_div_click_0_listener() { const run_r44 = i0.ɵɵrestoreView(_r43).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(!ctx_r0.IsCompareRunA(run_r44) && ctx_r0.selectCompareRunB(run_r44)); });
1461
+ i0.ɵɵelement(1, "div", 281);
1462
+ i0.ɵɵelementStart(2, "div", 282)(3, "div", 283);
1284
1463
  i0.ɵɵtext(4);
1285
1464
  i0.ɵɵpipe(5, "date");
1286
1465
  i0.ɵɵelementEnd();
1287
- i0.ɵɵelementStart(6, "div", 232);
1466
+ i0.ɵɵelementStart(6, "div", 284);
1288
1467
  i0.ɵɵtext(7);
1289
1468
  i0.ɵɵelementEnd()();
1290
- i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_12_For_2_Conditional_8_Template, 3, 0, "div", 233);
1469
+ i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Conditional_8_Template, 3, 0, "div", 285);
1291
1470
  i0.ɵɵelementEnd();
1292
1471
  } if (rf & 2) {
1293
- const run_r34 = ctx.$implicit;
1472
+ const run_r44 = ctx.$implicit;
1294
1473
  const ctx_r0 = i0.ɵɵnextContext(3);
1295
- i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunB(run_r34))("disabled", ctx_r0.IsCompareRunA(run_r34));
1474
+ i0.ɵɵclassProp("selected", ctx_r0.IsCompareRunB(run_r44))("disabled", ctx_r0.IsCompareRunA(run_r44));
1296
1475
  i0.ɵɵadvance();
1297
- i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r34.Status));
1476
+ i0.ɵɵstyleProp("background-color", ctx_r0.getRunStatusColor(run_r44.Status));
1298
1477
  i0.ɵɵadvance(3);
1299
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 9, run_r34.StartedAt, "short"));
1478
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(5, 9, run_r44.StartedAt, "short"));
1300
1479
  i0.ɵɵadvance(3);
1301
- i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r34).toFixed(0), "% pass");
1480
+ i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r44).toFixed(0), "% pass");
1302
1481
  i0.ɵɵadvance();
1303
- i0.ɵɵconditional(ctx_r0.getRunTags(run_r34).length > 0 ? 8 : -1);
1482
+ i0.ɵɵconditional(ctx_r0.getRunTags(run_r44).length > 0 ? 8 : -1);
1304
1483
  } }
1305
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_12_Template(rf, ctx) { if (rf & 1) {
1306
- i0.ɵɵelementStart(0, "div", 221);
1307
- i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_12_For_2_Template, 9, 12, "div", 240, i0.ɵɵrepeaterTrackByIdentity);
1484
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template(rf, ctx) { if (rf & 1) {
1485
+ i0.ɵɵelementStart(0, "div", 273);
1486
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_For_2_Template, 9, 12, "div", 292, i0.ɵɵrepeaterTrackByIdentity);
1308
1487
  i0.ɵɵelementEnd();
1309
1488
  } if (rf & 2) {
1310
1489
  const ctx_r0 = i0.ɵɵnextContext(2);
1311
1490
  i0.ɵɵadvance();
1312
1491
  i0.ɵɵrepeater(ctx_r0.suiteRuns);
1313
1492
  } }
1314
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_13_Template(rf, ctx) { if (rf & 1) {
1315
- const _r36 = i0.ɵɵgetCurrentView();
1316
- i0.ɵɵelementStart(0, "div", 222)(1, "div", 235)(2, "span", 236);
1493
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template(rf, ctx) { if (rf & 1) {
1494
+ const _r46 = i0.ɵɵgetCurrentView();
1495
+ i0.ɵɵelementStart(0, "div", 274)(1, "div", 287)(2, "span", 288);
1317
1496
  i0.ɵɵtext(3, "Selected:");
1318
1497
  i0.ɵɵelementEnd();
1319
- i0.ɵɵelementStart(4, "button", 237);
1320
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_13_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r36); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunB = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
1498
+ i0.ɵɵelementStart(4, "button", 289);
1499
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r46); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunB = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
1321
1500
  i0.ɵɵtext(5, "Clear");
1322
1501
  i0.ɵɵelementEnd()();
1323
- i0.ɵɵelementStart(6, "div", 238)(7, "span");
1502
+ i0.ɵɵelementStart(6, "div", 290)(7, "span");
1324
1503
  i0.ɵɵtext(8);
1325
1504
  i0.ɵɵpipe(9, "date");
1326
1505
  i0.ɵɵelementEnd();
1327
- i0.ɵɵelementStart(10, "span", 239);
1506
+ i0.ɵɵelementStart(10, "span", 291);
1328
1507
  i0.ɵɵtext(11);
1329
1508
  i0.ɵɵelementEnd()()();
1330
1509
  } if (rf & 2) {
@@ -1334,168 +1513,168 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_13_Template
1334
1513
  i0.ɵɵadvance(3);
1335
1514
  i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(ctx_r0.compareRunB).toFixed(1), "%");
1336
1515
  } }
1337
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1338
- i0.ɵɵelementStart(0, "span", 141);
1516
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_4_Template(rf, ctx) { if (rf & 1) {
1517
+ i0.ɵɵelementStart(0, "span", 194);
1339
1518
  i0.ɵɵtext(1);
1340
1519
  i0.ɵɵelementEnd();
1341
1520
  } if (rf & 2) {
1342
- const result_r37 = i0.ɵɵnextContext().$implicit;
1343
- i0.ɵɵproperty("ngClass", "status-" + result_r37.runA.status.toLowerCase());
1521
+ const result_r47 = i0.ɵɵnextContext().$implicit;
1522
+ i0.ɵɵproperty("ngClass", "status-" + result_r47.runA.status.toLowerCase());
1344
1523
  i0.ɵɵadvance();
1345
- i0.ɵɵtextInterpolate(result_r37.runA.status);
1524
+ i0.ɵɵtextInterpolate(result_r47.runA.status);
1346
1525
  } }
1347
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1348
- i0.ɵɵelementStart(0, "span", 253);
1526
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_5_Template(rf, ctx) { if (rf & 1) {
1527
+ i0.ɵɵelementStart(0, "span", 305);
1349
1528
  i0.ɵɵtext(1, "N/A");
1350
1529
  i0.ɵɵelementEnd();
1351
1530
  } }
1352
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_7_Template(rf, ctx) { if (rf & 1) {
1353
- i0.ɵɵelementStart(0, "span", 141);
1531
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_7_Template(rf, ctx) { if (rf & 1) {
1532
+ i0.ɵɵelementStart(0, "span", 194);
1354
1533
  i0.ɵɵtext(1);
1355
1534
  i0.ɵɵelementEnd();
1356
1535
  } if (rf & 2) {
1357
- const result_r37 = i0.ɵɵnextContext().$implicit;
1358
- i0.ɵɵproperty("ngClass", "status-" + result_r37.runB.status.toLowerCase());
1536
+ const result_r47 = i0.ɵɵnextContext().$implicit;
1537
+ i0.ɵɵproperty("ngClass", "status-" + result_r47.runB.status.toLowerCase());
1359
1538
  i0.ɵɵadvance();
1360
- i0.ɵɵtextInterpolate(result_r37.runB.status);
1539
+ i0.ɵɵtextInterpolate(result_r47.runB.status);
1361
1540
  } }
1362
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1363
- i0.ɵɵelementStart(0, "span", 253);
1541
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1542
+ i0.ɵɵelementStart(0, "span", 305);
1364
1543
  i0.ɵɵtext(1, "N/A");
1365
1544
  i0.ɵɵelementEnd();
1366
1545
  } }
1367
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_10_Template(rf, ctx) { if (rf & 1) {
1368
- i0.ɵɵelementStart(0, "span", 252);
1546
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_10_Template(rf, ctx) { if (rf & 1) {
1547
+ i0.ɵɵelementStart(0, "span", 304);
1369
1548
  i0.ɵɵtext(1);
1370
1549
  i0.ɵɵelementEnd();
1371
1550
  } if (rf & 2) {
1372
- const result_r37 = i0.ɵɵnextContext().$implicit;
1373
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r37.scoreDiff > 0, result_r37.scoreDiff < 0));
1551
+ const result_r47 = i0.ɵɵnextContext().$implicit;
1552
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r47.scoreDiff > 0, result_r47.scoreDiff < 0));
1374
1553
  i0.ɵɵadvance();
1375
- i0.ɵɵtextInterpolate2(" ", result_r37.scoreDiff > 0 ? "+" : "", "", (result_r37.scoreDiff * 100).toFixed(1), "% ");
1554
+ i0.ɵɵtextInterpolate2(" ", result_r47.scoreDiff > 0 ? "+" : "", "", (result_r47.scoreDiff * 100).toFixed(1), "% ");
1376
1555
  } }
1377
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_11_Template(rf, ctx) { if (rf & 1) {
1378
- i0.ɵɵelementStart(0, "span", 254);
1556
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_11_Template(rf, ctx) { if (rf & 1) {
1557
+ i0.ɵɵelementStart(0, "span", 306);
1379
1558
  i0.ɵɵtext(1, "-");
1380
1559
  i0.ɵɵelementEnd();
1381
1560
  } }
1382
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_13_Template(rf, ctx) { if (rf & 1) {
1383
- i0.ɵɵelementStart(0, "span", 252);
1561
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_13_Template(rf, ctx) { if (rf & 1) {
1562
+ i0.ɵɵelementStart(0, "span", 304);
1384
1563
  i0.ɵɵtext(1);
1385
1564
  i0.ɵɵelementEnd();
1386
1565
  } if (rf & 2) {
1387
- const result_r37 = i0.ɵɵnextContext().$implicit;
1388
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r37.durationDiff < 0, result_r37.durationDiff > 0));
1566
+ const result_r47 = i0.ɵɵnextContext().$implicit;
1567
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(3, _c6, result_r47.durationDiff < 0, result_r47.durationDiff > 0));
1389
1568
  i0.ɵɵadvance();
1390
- i0.ɵɵtextInterpolate2(" ", result_r37.durationDiff > 0 ? "+" : "", "", result_r37.durationDiff.toFixed(1), "s ");
1569
+ i0.ɵɵtextInterpolate2(" ", result_r47.durationDiff > 0 ? "+" : "", "", result_r47.durationDiff.toFixed(1), "s ");
1391
1570
  } }
1392
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_14_Template(rf, ctx) { if (rf & 1) {
1393
- i0.ɵɵelementStart(0, "span", 254);
1571
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_14_Template(rf, ctx) { if (rf & 1) {
1572
+ i0.ɵɵelementStart(0, "span", 306);
1394
1573
  i0.ɵɵtext(1, "-");
1395
1574
  i0.ɵɵelementEnd();
1396
1575
  } }
1397
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_16_Template(rf, ctx) { if (rf & 1) {
1398
- i0.ɵɵelementStart(0, "span", 255);
1399
- i0.ɵɵelement(1, "i", 258);
1576
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_16_Template(rf, ctx) { if (rf & 1) {
1577
+ i0.ɵɵelementStart(0, "span", 307);
1578
+ i0.ɵɵelement(1, "i", 310);
1400
1579
  i0.ɵɵtext(2, " Fixed ");
1401
1580
  i0.ɵɵelementEnd();
1402
1581
  } }
1403
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_17_Template(rf, ctx) { if (rf & 1) {
1404
- i0.ɵɵelementStart(0, "span", 256);
1405
- i0.ɵɵelement(1, "i", 259);
1582
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_17_Template(rf, ctx) { if (rf & 1) {
1583
+ i0.ɵɵelementStart(0, "span", 308);
1584
+ i0.ɵɵelement(1, "i", 311);
1406
1585
  i0.ɵɵtext(2, " Broke ");
1407
1586
  i0.ɵɵelementEnd();
1408
1587
  } }
1409
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_18_Template(rf, ctx) { if (rf & 1) {
1410
- i0.ɵɵelementStart(0, "span", 257);
1411
- i0.ɵɵelement(1, "i", 198);
1588
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_18_Template(rf, ctx) { if (rf & 1) {
1589
+ i0.ɵɵelementStart(0, "span", 309);
1590
+ i0.ɵɵelement(1, "i", 250);
1412
1591
  i0.ɵɵelementEnd();
1413
1592
  } }
1414
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Template(rf, ctx) { if (rf & 1) {
1415
- i0.ɵɵelementStart(0, "tr", 252)(1, "td", 181);
1593
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Template(rf, ctx) { if (rf & 1) {
1594
+ i0.ɵɵelementStart(0, "tr", 304)(1, "td", 233);
1416
1595
  i0.ɵɵtext(2);
1417
1596
  i0.ɵɵelementEnd();
1418
1597
  i0.ɵɵelementStart(3, "td");
1419
- i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_4_Template, 2, 2, "span", 141);
1420
- i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_5_Template, 2, 0, "span", 253);
1598
+ i0.ɵɵconditionalCreate(4, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_4_Template, 2, 2, "span", 194);
1599
+ i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_5_Template, 2, 0, "span", 305);
1421
1600
  i0.ɵɵelementEnd();
1422
1601
  i0.ɵɵelementStart(6, "td");
1423
- i0.ɵɵconditionalCreate(7, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_7_Template, 2, 2, "span", 141);
1424
- i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_8_Template, 2, 0, "span", 253);
1602
+ i0.ɵɵconditionalCreate(7, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_7_Template, 2, 2, "span", 194);
1603
+ i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_8_Template, 2, 0, "span", 305);
1425
1604
  i0.ɵɵelementEnd();
1426
1605
  i0.ɵɵelementStart(9, "td");
1427
- i0.ɵɵconditionalCreate(10, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_10_Template, 2, 6, "span", 252);
1428
- i0.ɵɵconditionalCreate(11, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_11_Template, 2, 0, "span", 254);
1606
+ i0.ɵɵconditionalCreate(10, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_10_Template, 2, 6, "span", 304);
1607
+ i0.ɵɵconditionalCreate(11, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_11_Template, 2, 0, "span", 306);
1429
1608
  i0.ɵɵelementEnd();
1430
1609
  i0.ɵɵelementStart(12, "td");
1431
- i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_13_Template, 2, 6, "span", 252);
1432
- i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_14_Template, 2, 0, "span", 254);
1610
+ i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_13_Template, 2, 6, "span", 304);
1611
+ i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_14_Template, 2, 0, "span", 306);
1433
1612
  i0.ɵɵelementEnd();
1434
1613
  i0.ɵɵelementStart(15, "td");
1435
- i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_16_Template, 3, 0, "span", 255);
1436
- i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_17_Template, 3, 0, "span", 256);
1437
- i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Conditional_18_Template, 2, 0, "span", 257);
1614
+ i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_16_Template, 3, 0, "span", 307);
1615
+ i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_17_Template, 3, 0, "span", 308);
1616
+ i0.ɵɵconditionalCreate(18, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Conditional_18_Template, 2, 0, "span", 309);
1438
1617
  i0.ɵɵelementEnd()();
1439
1618
  } if (rf & 2) {
1440
- const result_r37 = ctx.$implicit;
1441
- i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(13, _c8, result_r37.runA && result_r37.runB && result_r37.runA.status !== "Passed" && result_r37.runB.status === "Passed", result_r37.runA && result_r37.runB && result_r37.runA.status === "Passed" && result_r37.runB.status !== "Passed"));
1619
+ const result_r47 = ctx.$implicit;
1620
+ i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(13, _c8, result_r47.runA && result_r47.runB && result_r47.runA.status !== "Passed" && result_r47.runB.status === "Passed", result_r47.runA && result_r47.runB && result_r47.runA.status === "Passed" && result_r47.runB.status !== "Passed"));
1442
1621
  i0.ɵɵadvance(2);
1443
- i0.ɵɵtextInterpolate(result_r37.testName);
1622
+ i0.ɵɵtextInterpolate(result_r47.testName);
1444
1623
  i0.ɵɵadvance(2);
1445
- i0.ɵɵconditional(result_r37.runA ? 4 : -1);
1624
+ i0.ɵɵconditional(result_r47.runA ? 4 : -1);
1446
1625
  i0.ɵɵadvance();
1447
- i0.ɵɵconditional(!result_r37.runA ? 5 : -1);
1626
+ i0.ɵɵconditional(!result_r47.runA ? 5 : -1);
1448
1627
  i0.ɵɵadvance(2);
1449
- i0.ɵɵconditional(result_r37.runB ? 7 : -1);
1628
+ i0.ɵɵconditional(result_r47.runB ? 7 : -1);
1450
1629
  i0.ɵɵadvance();
1451
- i0.ɵɵconditional(!result_r37.runB ? 8 : -1);
1630
+ i0.ɵɵconditional(!result_r47.runB ? 8 : -1);
1452
1631
  i0.ɵɵadvance(2);
1453
- i0.ɵɵconditional(result_r37.scoreDiff != null ? 10 : -1);
1632
+ i0.ɵɵconditional(result_r47.scoreDiff != null ? 10 : -1);
1454
1633
  i0.ɵɵadvance();
1455
- i0.ɵɵconditional(result_r37.scoreDiff == null ? 11 : -1);
1634
+ i0.ɵɵconditional(result_r47.scoreDiff == null ? 11 : -1);
1456
1635
  i0.ɵɵadvance(2);
1457
- i0.ɵɵconditional(result_r37.durationDiff != null ? 13 : -1);
1636
+ i0.ɵɵconditional(result_r47.durationDiff != null ? 13 : -1);
1458
1637
  i0.ɵɵadvance();
1459
- i0.ɵɵconditional(result_r37.durationDiff == null ? 14 : -1);
1638
+ i0.ɵɵconditional(result_r47.durationDiff == null ? 14 : -1);
1460
1639
  i0.ɵɵadvance(2);
1461
- i0.ɵɵconditional(result_r37.runA && result_r37.runB && result_r37.runA.status !== "Passed" && result_r37.runB.status === "Passed" ? 16 : -1);
1640
+ i0.ɵɵconditional(result_r47.runA && result_r47.runB && result_r47.runA.status !== "Passed" && result_r47.runB.status === "Passed" ? 16 : -1);
1462
1641
  i0.ɵɵadvance();
1463
- i0.ɵɵconditional(result_r37.runA && result_r37.runB && result_r37.runA.status === "Passed" && result_r37.runB.status !== "Passed" ? 17 : -1);
1642
+ i0.ɵɵconditional(result_r47.runA && result_r47.runB && result_r47.runA.status === "Passed" && result_r47.runB.status !== "Passed" ? 17 : -1);
1464
1643
  i0.ɵɵadvance();
1465
- i0.ɵɵconditional(!result_r37.statusChanged ? 18 : -1);
1644
+ i0.ɵɵconditional(!result_r47.statusChanged ? 18 : -1);
1466
1645
  } }
1467
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_Template(rf, ctx) { if (rf & 1) {
1468
- i0.ɵɵelementStart(0, "div", 225)(1, "div", 241)(2, "div", 242)(3, "div", 243);
1646
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template(rf, ctx) { if (rf & 1) {
1647
+ i0.ɵɵelementStart(0, "div", 277)(1, "div", 293)(2, "div", 294)(3, "div", 295);
1469
1648
  i0.ɵɵtext(4, "Pass Rate Change");
1470
1649
  i0.ɵɵelementEnd();
1471
- i0.ɵɵelementStart(5, "div", 244);
1472
- i0.ɵɵelement(6, "i", 16);
1650
+ i0.ɵɵelementStart(5, "div", 296);
1651
+ i0.ɵɵelement(6, "i", 19);
1473
1652
  i0.ɵɵtext(7);
1474
1653
  i0.ɵɵelementEnd()();
1475
- i0.ɵɵelementStart(8, "div", 242)(9, "div", 243);
1654
+ i0.ɵɵelementStart(8, "div", 294)(9, "div", 295);
1476
1655
  i0.ɵɵtext(10, "Duration Change");
1477
1656
  i0.ɵɵelementEnd();
1478
- i0.ɵɵelementStart(11, "div", 244);
1479
- i0.ɵɵelement(12, "i", 16);
1657
+ i0.ɵɵelementStart(11, "div", 296);
1658
+ i0.ɵɵelement(12, "i", 19);
1480
1659
  i0.ɵɵtext(13);
1481
1660
  i0.ɵɵelementEnd()();
1482
- i0.ɵɵelementStart(14, "div", 245)(15, "div", 243);
1661
+ i0.ɵɵelementStart(14, "div", 297)(15, "div", 295);
1483
1662
  i0.ɵɵtext(16, "Improved");
1484
1663
  i0.ɵɵelementEnd();
1485
- i0.ɵɵelementStart(17, "div", 246);
1664
+ i0.ɵɵelementStart(17, "div", 298);
1486
1665
  i0.ɵɵtext(18);
1487
1666
  i0.ɵɵelementEnd()();
1488
- i0.ɵɵelementStart(19, "div", 247)(20, "div", 243);
1667
+ i0.ɵɵelementStart(19, "div", 299)(20, "div", 295);
1489
1668
  i0.ɵɵtext(21, "Regressed");
1490
1669
  i0.ɵɵelementEnd();
1491
- i0.ɵɵelementStart(22, "div", 246);
1670
+ i0.ɵɵelementStart(22, "div", 298);
1492
1671
  i0.ɵɵtext(23);
1493
1672
  i0.ɵɵelementEnd()()();
1494
- i0.ɵɵelementStart(24, "div", 248)(25, "h3");
1495
- i0.ɵɵelement(26, "i", 249);
1673
+ i0.ɵɵelementStart(24, "div", 300)(25, "h3");
1674
+ i0.ɵɵelement(26, "i", 301);
1496
1675
  i0.ɵɵtext(27, " Test-by-Test Comparison");
1497
1676
  i0.ɵɵelementEnd();
1498
- i0.ɵɵelementStart(28, "div", 250)(29, "table", 251)(30, "thead")(31, "tr")(32, "th");
1677
+ i0.ɵɵelementStart(28, "div", 302)(29, "table", 303)(30, "thead")(31, "tr")(32, "th");
1499
1678
  i0.ɵɵtext(33, "Test");
1500
1679
  i0.ɵɵelementEnd();
1501
1680
  i0.ɵɵelementStart(34, "th");
@@ -1514,7 +1693,7 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_Template
1514
1693
  i0.ɵɵtext(43, "Change");
1515
1694
  i0.ɵɵelementEnd()()();
1516
1695
  i0.ɵɵelementStart(44, "tbody");
1517
- i0.ɵɵrepeaterCreate(45, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_For_46_Template, 19, 16, "tr", 252, i0.ɵɵrepeaterTrackByIdentity);
1696
+ i0.ɵɵrepeaterCreate(45, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_For_46_Template, 19, 16, "tr", 304, i0.ɵɵrepeaterTrackByIdentity);
1518
1697
  i0.ɵɵelementEnd()()()()();
1519
1698
  } if (rf & 2) {
1520
1699
  let tmp_4_0;
@@ -1538,14 +1717,14 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_Template
1538
1717
  i0.ɵɵadvance(22);
1539
1718
  i0.ɵɵrepeater(ctx_r0.compareResults);
1540
1719
  } }
1541
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_15_Template(rf, ctx) { if (rf & 1) {
1542
- i0.ɵɵelementStart(0, "div", 57);
1543
- i0.ɵɵelement(1, "mj-loading", 260);
1720
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_15_Template(rf, ctx) { if (rf & 1) {
1721
+ i0.ɵɵelementStart(0, "div", 99);
1722
+ i0.ɵɵelement(1, "mj-loading", 312);
1544
1723
  i0.ɵɵelementEnd();
1545
1724
  } }
1546
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_16_Template(rf, ctx) { if (rf & 1) {
1547
- i0.ɵɵelementStart(0, "div", 226)(1, "div", 261);
1548
- i0.ɵɵelement(2, "i", 33);
1725
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_16_Template(rf, ctx) { if (rf & 1) {
1726
+ i0.ɵɵelementStart(0, "div", 278)(1, "div", 313);
1727
+ i0.ɵɵelement(2, "i", 37);
1549
1728
  i0.ɵɵelementEnd();
1550
1729
  i0.ɵɵelementStart(3, "h4");
1551
1730
  i0.ɵɵtext(4, "Select Two Runs to Compare");
@@ -1554,10 +1733,10 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_16_Template
1554
1733
  i0.ɵɵtext(6, "Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.");
1555
1734
  i0.ɵɵelementEnd()();
1556
1735
  } }
1557
- function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_17_Template(rf, ctx) { if (rf & 1) {
1558
- const _r38 = i0.ɵɵgetCurrentView();
1559
- i0.ɵɵelementStart(0, "div", 59)(1, "div", 75);
1560
- i0.ɵɵelement(2, "i", 33);
1736
+ function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template(rf, ctx) { if (rf & 1) {
1737
+ const _r48 = i0.ɵɵgetCurrentView();
1738
+ i0.ɵɵelementStart(0, "div", 101)(1, "div", 127);
1739
+ i0.ɵɵelement(2, "i", 37);
1561
1740
  i0.ɵɵelementEnd();
1562
1741
  i0.ɵɵelementStart(3, "h4");
1563
1742
  i0.ɵɵtext(4, "Not Enough Runs to Compare");
@@ -1565,32 +1744,32 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_17_Template
1565
1744
  i0.ɵɵelementStart(5, "p");
1566
1745
  i0.ɵɵtext(6, "You need at least 2 suite runs to use the comparison feature.");
1567
1746
  i0.ɵɵelementEnd();
1568
- i0.ɵɵelementStart(7, "button", 21);
1569
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_62_Conditional_17_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r38); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
1570
- i0.ɵɵelement(8, "i", 22);
1747
+ i0.ɵɵelementStart(7, "button", 25);
1748
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r48); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
1749
+ i0.ɵɵelement(8, "i", 26);
1571
1750
  i0.ɵɵtext(9, " Run Suite Now ");
1572
1751
  i0.ɵɵelementEnd()();
1573
1752
  } }
1574
- function MJTestSuiteFormComponentExtended_Conditional_62_Template(rf, ctx) { if (rf & 1) {
1575
- i0.ɵɵelementStart(0, "div", 39)(1, "div", 219)(2, "div", 220)(3, "h4");
1753
+ function MJTestSuiteFormComponentExtended_Conditional_64_Template(rf, ctx) { if (rf & 1) {
1754
+ i0.ɵɵelementStart(0, "div", 43)(1, "div", 271)(2, "div", 272)(3, "h4");
1576
1755
  i0.ɵɵtext(4, "Run A (Baseline)");
1577
1756
  i0.ɵɵelementEnd();
1578
- i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_5_Template, 3, 0, "div", 221);
1579
- i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_6_Template, 12, 5, "div", 222);
1757
+ i0.ɵɵconditionalCreate(5, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_5_Template, 3, 0, "div", 273);
1758
+ i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_6_Template, 12, 5, "div", 274);
1580
1759
  i0.ɵɵelementEnd();
1581
- i0.ɵɵelementStart(7, "div", 223);
1582
- i0.ɵɵelement(8, "i", 224);
1760
+ i0.ɵɵelementStart(7, "div", 275);
1761
+ i0.ɵɵelement(8, "i", 276);
1583
1762
  i0.ɵɵelementEnd();
1584
- i0.ɵɵelementStart(9, "div", 220)(10, "h4");
1763
+ i0.ɵɵelementStart(9, "div", 272)(10, "h4");
1585
1764
  i0.ɵɵtext(11, "Run B (Compare)");
1586
1765
  i0.ɵɵelementEnd();
1587
- i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_12_Template, 3, 0, "div", 221);
1588
- i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_13_Template, 12, 5, "div", 222);
1766
+ i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_12_Template, 3, 0, "div", 273);
1767
+ i0.ɵɵconditionalCreate(13, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_13_Template, 12, 5, "div", 274);
1589
1768
  i0.ɵɵelementEnd()();
1590
- i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_14_Template, 47, 23, "div", 225);
1591
- i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_15_Template, 2, 0, "div", 57);
1592
- i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_16_Template, 7, 0, "div", 226);
1593
- i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_62_Conditional_17_Template, 10, 0, "div", 59);
1769
+ i0.ɵɵconditionalCreate(14, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_14_Template, 47, 23, "div", 277);
1770
+ i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_15_Template, 2, 0, "div", 99);
1771
+ i0.ɵɵconditionalCreate(16, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_16_Template, 7, 0, "div", 278);
1772
+ i0.ɵɵconditionalCreate(17, MJTestSuiteFormComponentExtended_Conditional_64_Conditional_17_Template, 10, 0, "div", 101);
1594
1773
  i0.ɵɵelementEnd();
1595
1774
  } if (rf & 2) {
1596
1775
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1611,50 +1790,59 @@ function MJTestSuiteFormComponentExtended_Conditional_62_Template(rf, ctx) { if
1611
1790
  i0.ɵɵadvance();
1612
1791
  i0.ɵɵconditional(ctx_r0.runsLoaded && ctx_r0.suiteRuns.length < 2 ? 17 : -1);
1613
1792
  } }
1614
- function MJTestSuiteFormComponentExtended_Conditional_65_Template(rf, ctx) { if (rf & 1) {
1615
- const _r39 = i0.ɵɵgetCurrentView();
1616
- i0.ɵɵelementStart(0, "div", 42)(1, "div", 262);
1617
- i0.ɵɵelement(2, "i", 41);
1793
+ function MJTestSuiteFormComponentExtended_Conditional_67_Template(rf, ctx) { if (rf & 1) {
1794
+ const _r49 = i0.ɵɵgetCurrentView();
1795
+ i0.ɵɵelementStart(0, "div", 46)(1, "div", 314);
1796
+ i0.ɵɵelement(2, "i", 45);
1618
1797
  i0.ɵɵtext(3, " Shortcuts ");
1619
- i0.ɵɵelementStart(4, "button", 263);
1620
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_65_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r39); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
1621
- i0.ɵɵelement(5, "i", 171);
1798
+ i0.ɵɵelementStart(4, "button", 315);
1799
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_67_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r49); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
1800
+ i0.ɵɵelement(5, "i", 91);
1622
1801
  i0.ɵɵelementEnd()();
1623
- i0.ɵɵelementStart(6, "div", 264)(7, "div", 265)(8, "span");
1624
- i0.ɵɵtext(9, "Refresh");
1802
+ i0.ɵɵelementStart(6, "div", 316)(7, "div", 317)(8, "span");
1803
+ i0.ɵɵtext(9, "Save changes");
1625
1804
  i0.ɵɵelementEnd();
1626
- i0.ɵɵelementStart(10, "span", 266)(11, "kbd");
1805
+ i0.ɵɵelementStart(10, "span", 318)(11, "kbd");
1627
1806
  i0.ɵɵtext(12, "Cmd");
1628
1807
  i0.ɵɵelementEnd();
1629
1808
  i0.ɵɵelementStart(13, "kbd");
1630
- i0.ɵɵtext(14, "R");
1809
+ i0.ɵɵtext(14, "S");
1631
1810
  i0.ɵɵelementEnd()()();
1632
- i0.ɵɵelementStart(15, "div", 265)(16, "span");
1633
- i0.ɵɵtext(17, "Run Suite");
1811
+ i0.ɵɵelementStart(15, "div", 317)(16, "span");
1812
+ i0.ɵɵtext(17, "Refresh");
1634
1813
  i0.ɵɵelementEnd();
1635
- i0.ɵɵelementStart(18, "span", 266)(19, "kbd");
1814
+ i0.ɵɵelementStart(18, "span", 318)(19, "kbd");
1636
1815
  i0.ɵɵtext(20, "Cmd");
1637
1816
  i0.ɵɵelementEnd();
1638
1817
  i0.ɵɵelementStart(21, "kbd");
1639
- i0.ɵɵtext(22, "Enter");
1818
+ i0.ɵɵtext(22, "R");
1819
+ i0.ɵɵelementEnd()()();
1820
+ i0.ɵɵelementStart(23, "div", 317)(24, "span");
1821
+ i0.ɵɵtext(25, "Run Suite");
1822
+ i0.ɵɵelementEnd();
1823
+ i0.ɵɵelementStart(26, "span", 318)(27, "kbd");
1824
+ i0.ɵɵtext(28, "Cmd");
1825
+ i0.ɵɵelementEnd();
1826
+ i0.ɵɵelementStart(29, "kbd");
1827
+ i0.ɵɵtext(30, "Enter");
1640
1828
  i0.ɵɵelementEnd()()();
1641
- i0.ɵɵelementStart(23, "div", 265)(24, "span");
1642
- i0.ɵɵtext(25, "Switch Tabs");
1829
+ i0.ɵɵelementStart(31, "div", 317)(32, "span");
1830
+ i0.ɵɵtext(33, "Switch Tabs");
1643
1831
  i0.ɵɵelementEnd();
1644
- i0.ɵɵelementStart(26, "span", 266)(27, "kbd");
1645
- i0.ɵɵtext(28, "1");
1832
+ i0.ɵɵelementStart(34, "span", 318)(35, "kbd");
1833
+ i0.ɵɵtext(36, "1");
1646
1834
  i0.ɵɵelementEnd();
1647
- i0.ɵɵtext(29, "-");
1648
- i0.ɵɵelementStart(30, "kbd");
1649
- i0.ɵɵtext(31, "5");
1835
+ i0.ɵɵtext(37, "-");
1836
+ i0.ɵɵelementStart(38, "kbd");
1837
+ i0.ɵɵtext(39, "5");
1650
1838
  i0.ɵɵelementEnd()()()()();
1651
1839
  } }
1652
- function MJTestSuiteFormComponentExtended_Conditional_66_Template(rf, ctx) { if (rf & 1) {
1653
- const _r40 = i0.ɵɵgetCurrentView();
1654
- i0.ɵɵelementStart(0, "mj-slide-panel", 267);
1655
- i0.ɵɵlistener("Closed", function MJTestSuiteFormComponentExtended_Conditional_66_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r40); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1656
- i0.ɵɵelementStart(1, "app-test-run-dialog", 268);
1657
- i0.ɵɵlistener("PanelClose", function MJTestSuiteFormComponentExtended_Conditional_66_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(_r40); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1840
+ function MJTestSuiteFormComponentExtended_Conditional_68_Template(rf, ctx) { if (rf & 1) {
1841
+ const _r50 = i0.ɵɵgetCurrentView();
1842
+ i0.ɵɵelementStart(0, "mj-slide-panel", 319);
1843
+ i0.ɵɵlistener("Closed", function MJTestSuiteFormComponentExtended_Conditional_68_Template_mj_slide_panel_Closed_0_listener() { i0.ɵɵrestoreView(_r50); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1844
+ i0.ɵɵelementStart(1, "app-test-run-dialog", 320);
1845
+ i0.ɵɵlistener("PanelClose", function MJTestSuiteFormComponentExtended_Conditional_68_Template_app_test_run_dialog_PanelClose_1_listener() { i0.ɵɵrestoreView(_r50); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnPanelClosed()); });
1658
1846
  i0.ɵɵelementEnd()();
1659
1847
  } if (rf & 2) {
1660
1848
  const ctx_r0 = i0.ɵɵnextContext();
@@ -1662,6 +1850,247 @@ function MJTestSuiteFormComponentExtended_Conditional_66_Template(rf, ctx) { if
1662
1850
  i0.ɵɵadvance();
1663
1851
  i0.ɵɵproperty("PanelMode", true)("selectedTestId", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.testId) ?? null)("selectedSuiteId", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.suiteId) ?? null)("runMode", (ctx_r0.testingDialogService.PanelOptions == null ? null : ctx_r0.testingDialogService.PanelOptions.mode) ?? "suite");
1664
1852
  } }
1853
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template(rf, ctx) { if (rf & 1) {
1854
+ const _r52 = i0.ɵɵgetCurrentView();
1855
+ i0.ɵɵelementStart(0, "button", 342);
1856
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r52); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.addTestsSearch = ""); });
1857
+ i0.ɵɵelement(1, "i", 91);
1858
+ i0.ɵɵelementEnd();
1859
+ } }
1860
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_15_Template(rf, ctx) { if (rf & 1) {
1861
+ i0.ɵɵelementStart(0, "strong");
1862
+ i0.ɵɵtext(1);
1863
+ i0.ɵɵelementEnd();
1864
+ i0.ɵɵtext(2, " selected ");
1865
+ } if (rf & 2) {
1866
+ const ctx_r0 = i0.ɵɵnextContext(2);
1867
+ i0.ɵɵadvance();
1868
+ i0.ɵɵtextInterpolate(ctx_r0.selectedTestIdsToAdd.size);
1869
+ } }
1870
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_16_Template(rf, ctx) { if (rf & 1) {
1871
+ i0.ɵɵtext(0);
1872
+ } if (rf & 2) {
1873
+ const ctx_r0 = i0.ɵɵnextContext(2);
1874
+ i0.ɵɵtextInterpolate2(" ", ctx_r0.filteredAvailableTests.length, " test", ctx_r0.filteredAvailableTests.length === 1 ? "" : "s", " available ");
1875
+ } }
1876
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_23_Template(rf, ctx) { if (rf & 1) {
1877
+ i0.ɵɵelementStart(0, "div", 336);
1878
+ i0.ɵɵelement(1, "mj-loading", 343);
1879
+ i0.ɵɵelementEnd();
1880
+ } }
1881
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1882
+ i0.ɵɵelement(0, "i", 145);
1883
+ i0.ɵɵelementStart(1, "h4");
1884
+ i0.ɵɵtext(2, "Everything's already in the suite");
1885
+ i0.ɵɵelementEnd();
1886
+ i0.ɵɵelementStart(3, "p");
1887
+ i0.ɵɵtext(4, "This suite contains every available test. Create a new test first to add more.");
1888
+ i0.ɵɵelementEnd();
1889
+ } }
1890
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1891
+ i0.ɵɵelement(0, "i", 205);
1892
+ i0.ɵɵelementStart(1, "h4");
1893
+ i0.ɵɵtext(2, "No matches");
1894
+ i0.ɵɵelementEnd();
1895
+ i0.ɵɵelementStart(3, "p");
1896
+ i0.ɵɵtext(4);
1897
+ i0.ɵɵelementEnd();
1898
+ } if (rf & 2) {
1899
+ const ctx_r0 = i0.ɵɵnextContext(3);
1900
+ i0.ɵɵadvance(4);
1901
+ i0.ɵɵtextInterpolate1("No tests match \"", ctx_r0.addTestsSearch, "\".");
1902
+ } }
1903
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Template(rf, ctx) { if (rf & 1) {
1904
+ i0.ɵɵelementStart(0, "div", 337);
1905
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_1_Template, 5, 0)(2, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Conditional_2_Template, 5, 1);
1906
+ i0.ɵɵelementEnd();
1907
+ } if (rf & 2) {
1908
+ const ctx_r0 = i0.ɵɵnextContext(2);
1909
+ i0.ɵɵadvance();
1910
+ i0.ɵɵconditional(ctx_r0.availableTests.length === 0 ? 1 : 2);
1911
+ } }
1912
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1913
+ i0.ɵɵelement(0, "i", 175);
1914
+ } }
1915
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
1916
+ i0.ɵɵelementStart(0, "div", 349);
1917
+ i0.ɵɵtext(1);
1918
+ i0.ɵɵelementEnd();
1919
+ } if (rf & 2) {
1920
+ const t_r54 = i0.ɵɵnextContext().$implicit;
1921
+ i0.ɵɵadvance();
1922
+ i0.ɵɵtextInterpolate(t_r54.Description);
1923
+ } }
1924
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
1925
+ i0.ɵɵelementStart(0, "span", 351);
1926
+ i0.ɵɵtext(1);
1927
+ i0.ɵɵelementEnd();
1928
+ } if (rf & 2) {
1929
+ const t_r54 = i0.ɵɵnextContext().$implicit;
1930
+ i0.ɵɵadvance();
1931
+ i0.ɵɵtextInterpolate(t_r54.Type);
1932
+ } }
1933
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template(rf, ctx) { if (rf & 1) {
1934
+ const _r53 = i0.ɵɵgetCurrentView();
1935
+ i0.ɵɵelementStart(0, "li", 345);
1936
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template_li_click_0_listener() { const t_r54 = i0.ɵɵrestoreView(_r53).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.toggleAddSelection(t_r54.ID)); });
1937
+ i0.ɵɵelementStart(1, "span", 346);
1938
+ i0.ɵɵconditionalCreate(2, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_2_Template, 1, 0, "i", 175);
1939
+ i0.ɵɵelementEnd();
1940
+ i0.ɵɵelementStart(3, "div", 347)(4, "div", 348);
1941
+ i0.ɵɵtext(5);
1942
+ i0.ɵɵelementEnd();
1943
+ i0.ɵɵconditionalCreate(6, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_6_Template, 2, 1, "div", 349);
1944
+ i0.ɵɵelementEnd();
1945
+ i0.ɵɵelementStart(7, "div", 350);
1946
+ i0.ɵɵconditionalCreate(8, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Conditional_8_Template, 2, 1, "span", 351);
1947
+ i0.ɵɵelementStart(9, "span", 352);
1948
+ i0.ɵɵtext(10);
1949
+ i0.ɵɵelementEnd()()();
1950
+ } if (rf & 2) {
1951
+ const t_r54 = ctx.$implicit;
1952
+ const ctx_r0 = i0.ɵɵnextContext(3);
1953
+ i0.ɵɵclassProp("picker-row--selected", ctx_r0.isAddSelected(t_r54.ID));
1954
+ i0.ɵɵattribute("aria-checked", ctx_r0.isAddSelected(t_r54.ID));
1955
+ i0.ɵɵadvance(2);
1956
+ i0.ɵɵconditional(ctx_r0.isAddSelected(t_r54.ID) ? 2 : -1);
1957
+ i0.ɵɵadvance(3);
1958
+ i0.ɵɵtextInterpolate(t_r54.Name);
1959
+ i0.ɵɵadvance();
1960
+ i0.ɵɵconditional(t_r54.Description ? 6 : -1);
1961
+ i0.ɵɵadvance(2);
1962
+ i0.ɵɵconditional(t_r54.Type ? 8 : -1);
1963
+ i0.ɵɵadvance();
1964
+ i0.ɵɵattribute("data-status", t_r54.Status == null ? null : t_r54.Status.toLowerCase());
1965
+ i0.ɵɵadvance();
1966
+ i0.ɵɵtextInterpolate(t_r54.Status);
1967
+ } }
1968
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_Template(rf, ctx) { if (rf & 1) {
1969
+ i0.ɵɵelementStart(0, "ul", 338);
1970
+ i0.ɵɵrepeaterCreate(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_For_2_Template, 11, 9, "li", 344, _forTrack0);
1971
+ i0.ɵɵelementEnd();
1972
+ } if (rf & 2) {
1973
+ const ctx_r0 = i0.ɵɵnextContext(2);
1974
+ i0.ɵɵadvance();
1975
+ i0.ɵɵrepeater(ctx_r0.filteredAvailableTests);
1976
+ } }
1977
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_28_Template(rf, ctx) { if (rf & 1) {
1978
+ i0.ɵɵelement(0, "i", 123);
1979
+ i0.ɵɵtext(1, " Adding\u2026 ");
1980
+ } }
1981
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_1_Template(rf, ctx) { if (rf & 1) {
1982
+ i0.ɵɵtext(0, " Add tests ");
1983
+ } }
1984
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_2_Template(rf, ctx) { if (rf & 1) {
1985
+ i0.ɵɵtext(0, " Add 1 test ");
1986
+ } }
1987
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_3_Template(rf, ctx) { if (rf & 1) {
1988
+ i0.ɵɵtext(0);
1989
+ } if (rf & 2) {
1990
+ const ctx_r0 = i0.ɵɵnextContext(3);
1991
+ i0.ɵɵtextInterpolate1(" Add ", ctx_r0.selectedTestIdsToAdd.size, " tests ");
1992
+ } }
1993
+ function MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Template(rf, ctx) { if (rf & 1) {
1994
+ i0.ɵɵelement(0, "i", 175);
1995
+ i0.ɵɵconditionalCreate(1, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_1_Template, 1, 0)(2, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_2_Template, 1, 0)(3, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Conditional_3_Template, 1, 1);
1996
+ } if (rf & 2) {
1997
+ const ctx_r0 = i0.ɵɵnextContext(2);
1998
+ i0.ɵɵadvance();
1999
+ i0.ɵɵconditional(ctx_r0.selectedTestIdsToAdd.size === 0 ? 1 : ctx_r0.selectedTestIdsToAdd.size === 1 ? 2 : 3);
2000
+ } }
2001
+ function MJTestSuiteFormComponentExtended_Conditional_69_Template(rf, ctx) { if (rf & 1) {
2002
+ const _r51 = i0.ɵɵgetCurrentView();
2003
+ i0.ɵɵelementStart(0, "div", 321);
2004
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
2005
+ i0.ɵɵelementEnd();
2006
+ i0.ɵɵelementStart(1, "div", 322);
2007
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r51); return i0.ɵɵresetView($event.stopPropagation()); });
2008
+ i0.ɵɵelementStart(2, "div", 323)(3, "h2", 324);
2009
+ i0.ɵɵelement(4, "i", 325);
2010
+ i0.ɵɵtext(5, " Add tests to suite ");
2011
+ i0.ɵɵelementEnd();
2012
+ i0.ɵɵelementStart(6, "button", 326);
2013
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
2014
+ i0.ɵɵelement(7, "i", 91);
2015
+ i0.ɵɵelementEnd()();
2016
+ i0.ɵɵelementStart(8, "div", 327);
2017
+ i0.ɵɵelement(9, "i", 328);
2018
+ i0.ɵɵelementStart(10, "input", 329, 2);
2019
+ i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteFormComponentExtended_Conditional_69_Template_input_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.addTestsSearch, $event) || (ctx_r0.addTestsSearch = $event); return i0.ɵɵresetView($event); });
2020
+ i0.ɵɵelementEnd();
2021
+ i0.ɵɵconditionalCreate(12, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_12_Template, 2, 0, "button", 330);
2022
+ i0.ɵɵelementEnd();
2023
+ i0.ɵɵelementStart(13, "div", 331)(14, "span", 332);
2024
+ i0.ɵɵconditionalCreate(15, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_15_Template, 3, 1)(16, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_16_Template, 1, 2);
2025
+ i0.ɵɵelementEnd();
2026
+ i0.ɵɵelementStart(17, "div", 333)(18, "button", 334);
2027
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.selectAllFiltered()); });
2028
+ i0.ɵɵtext(19, " Select all ");
2029
+ i0.ɵɵelementEnd();
2030
+ i0.ɵɵelementStart(20, "button", 334);
2031
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.clearAddSelection()); });
2032
+ i0.ɵɵtext(21, " Clear ");
2033
+ i0.ɵɵelementEnd()()();
2034
+ i0.ɵɵelementStart(22, "div", 335);
2035
+ i0.ɵɵconditionalCreate(23, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_23_Template, 2, 0, "div", 336)(24, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_24_Template, 3, 1, "div", 337)(25, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_25_Template, 3, 0, "ul", 338);
2036
+ i0.ɵɵelementEnd();
2037
+ i0.ɵɵelementStart(26, "div", 339)(27, "button", 340);
2038
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.confirmAddTests()); });
2039
+ i0.ɵɵconditionalCreate(28, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_28_Template, 2, 0)(29, MJTestSuiteFormComponentExtended_Conditional_69_Conditional_29_Template, 4, 1);
2040
+ i0.ɵɵelementEnd();
2041
+ i0.ɵɵelementStart(30, "button", 341);
2042
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Conditional_69_Template_button_click_30_listener() { i0.ɵɵrestoreView(_r51); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.closeAddTestsDialog()); });
2043
+ i0.ɵɵtext(31, " Cancel ");
2044
+ i0.ɵɵelementEnd()()();
2045
+ } if (rf & 2) {
2046
+ const ctx_r0 = i0.ɵɵnextContext();
2047
+ i0.ɵɵadvance(6);
2048
+ i0.ɵɵproperty("disabled", ctx_r0.isAddingTests);
2049
+ i0.ɵɵadvance(4);
2050
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.addTestsSearch);
2051
+ i0.ɵɵadvance(2);
2052
+ i0.ɵɵconditional(ctx_r0.addTestsSearch ? 12 : -1);
2053
+ i0.ɵɵadvance(3);
2054
+ i0.ɵɵconditional(ctx_r0.selectedTestIdsToAdd.size > 0 ? 15 : !ctx_r0.loadingAvailableTests ? 16 : -1);
2055
+ i0.ɵɵadvance(3);
2056
+ i0.ɵɵproperty("disabled", ctx_r0.loadingAvailableTests || ctx_r0.filteredAvailableTests.length === 0);
2057
+ i0.ɵɵadvance(2);
2058
+ i0.ɵɵproperty("disabled", ctx_r0.selectedTestIdsToAdd.size === 0);
2059
+ i0.ɵɵadvance(3);
2060
+ i0.ɵɵconditional(ctx_r0.loadingAvailableTests ? 23 : ctx_r0.filteredAvailableTests.length === 0 ? 24 : 25);
2061
+ i0.ɵɵadvance(4);
2062
+ i0.ɵɵproperty("disabled", ctx_r0.selectedTestIdsToAdd.size === 0 || ctx_r0.isAddingTests);
2063
+ i0.ɵɵadvance();
2064
+ i0.ɵɵconditional(ctx_r0.isAddingTests ? 28 : 29);
2065
+ i0.ɵɵadvance(2);
2066
+ i0.ɵɵproperty("disabled", ctx_r0.isAddingTests);
2067
+ } }
2068
+ function MJTestSuiteFormComponentExtended_Conditional_78_Template(rf, ctx) { if (rf & 1) {
2069
+ i0.ɵɵtext(0);
2070
+ } if (rf & 2) {
2071
+ const ctx_r0 = i0.ɵɵnextContext();
2072
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.dirtyFieldNames[0], " edited ");
2073
+ } }
2074
+ function MJTestSuiteFormComponentExtended_Conditional_79_Template(rf, ctx) { if (rf & 1) {
2075
+ i0.ɵɵtext(0);
2076
+ } if (rf & 2) {
2077
+ const ctx_r0 = i0.ɵɵnextContext();
2078
+ i0.ɵɵtextInterpolate1(" ", ctx_r0.dirtyFieldNames.length, " fields edited ");
2079
+ } }
2080
+ function MJTestSuiteFormComponentExtended_Conditional_82_Template(rf, ctx) { if (rf & 1) {
2081
+ i0.ɵɵelement(0, "i", 123);
2082
+ i0.ɵɵtext(1, " Saving\u2026 ");
2083
+ } }
2084
+ function MJTestSuiteFormComponentExtended_Conditional_83_Template(rf, ctx) { if (rf & 1) {
2085
+ i0.ɵɵelement(0, "i", 175);
2086
+ i0.ɵɵtext(1, " Save changes ");
2087
+ i0.ɵɵelementStart(2, "span", 353)(3, "kbd");
2088
+ i0.ɵɵtext(4, "\u2318");
2089
+ i0.ɵɵelementEnd();
2090
+ i0.ɵɵelementStart(5, "kbd");
2091
+ i0.ɵɵtext(6, "S");
2092
+ i0.ɵɵelementEnd()();
2093
+ } }
1665
2094
  /** Settings key for keyboard shortcuts visibility */
1666
2095
  const SHORTCUTS_SETTINGS_KEY = '__mj.Testing.ShowKeyboardShortcuts';
1667
2096
  let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended extends MJTestSuiteFormComponent {
@@ -1715,6 +2144,23 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
1715
2144
  // Matrix test name filter
1716
2145
  this.matrixTestFilter = '';
1717
2146
  this.matrixFilterSubject$ = new Subject();
2147
+ // Edit state
2148
+ this.isSaving = false;
2149
+ this.parentSuiteOptions = [];
2150
+ this.tagDraft = '';
2151
+ this.statusOptions = ['Active', 'Pending', 'Disabled'];
2152
+ // Add Tests picker state
2153
+ this.showAddTestsDialog = false;
2154
+ this.availableTests = [];
2155
+ this.loadingAvailableTests = false;
2156
+ this.selectedTestIdsToAdd = new Set();
2157
+ this.addTestsSearch = '';
2158
+ this.isAddingTests = false;
2159
+ // Remove-confirm state (per-row inline confirm)
2160
+ this.confirmingRemoveSuiteTestId = null;
2161
+ this.isRemovingTest = false;
2162
+ // Reorder state
2163
+ this.isReorderingTests = false;
1718
2164
  // Service injections
1719
2165
  this.navigationService = inject(NavigationService);
1720
2166
  this.testingDialogService = inject(TestingDialogService);
@@ -1726,6 +2172,8 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
1726
2172
  async ngOnInit() {
1727
2173
  await super.ngOnInit();
1728
2174
  this.loadShortcutsSetting();
2175
+ // Fire-and-forget: parent suite list for the edit form
2176
+ this.loadParentSuiteOptions();
1729
2177
  // Subscribe to evaluation preferences
1730
2178
  this.evalPrefsService.preferences$
1731
2179
  .pipe(takeUntil(this.destroy$))
@@ -1762,6 +2210,14 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
1762
2210
  handleKeyboardShortcut(event) {
1763
2211
  if (!this.keyboardShortcutsEnabled)
1764
2212
  return;
2213
+ // Cmd/Ctrl + S: Save (if dirty)
2214
+ if ((event.metaKey || event.ctrlKey) && event.key === 's' && !event.shiftKey) {
2215
+ if (this.isDirty) {
2216
+ event.preventDefault();
2217
+ this.saveChanges();
2218
+ }
2219
+ return;
2220
+ }
1765
2221
  // Cmd/Ctrl + R: Refresh
1766
2222
  if ((event.metaKey || event.ctrlKey) && event.key === 'r' && !event.shiftKey) {
1767
2223
  event.preventDefault();
@@ -1774,8 +2230,8 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
1774
2230
  this.runSuite();
1775
2231
  return;
1776
2232
  }
1777
- // Number keys for tabs (1-5)
1778
- if (!event.metaKey && !event.ctrlKey && !event.altKey) {
2233
+ // Number keys for tabs (1-5) — skip when typing into form inputs
2234
+ if (!event.metaKey && !event.ctrlKey && !event.altKey && !this.isTextInputFocused()) {
1779
2235
  switch (event.key) {
1780
2236
  case '1':
1781
2237
  this.changeTab('overview');
@@ -1795,6 +2251,20 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
1795
2251
  }
1796
2252
  }
1797
2253
  }
2254
+ // Warn before tab close / hard navigation when there are unsaved changes
2255
+ handleBeforeUnload(event) {
2256
+ if (this.isDirty) {
2257
+ event.preventDefault();
2258
+ event.returnValue = '';
2259
+ }
2260
+ }
2261
+ isTextInputFocused() {
2262
+ const el = document.activeElement;
2263
+ if (!el)
2264
+ return false;
2265
+ const tag = el.tagName;
2266
+ return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || el.isContentEditable;
2267
+ }
1798
2268
  changeTab(tab) {
1799
2269
  this.activeTab = tab;
1800
2270
  if (tab === 'tests' && !this.testsLoaded)
@@ -3376,6 +3846,351 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
3376
3846
  IsCompareRunB(run) {
3377
3847
  return UUIDsEqual(this.compareRunB?.ID, run.ID);
3378
3848
  }
3849
+ // ==========================================
3850
+ // Edit / Save Methods
3851
+ // ==========================================
3852
+ /** True if the suite record has any unsaved field changes. */
3853
+ get isDirty() {
3854
+ return this.record?.Dirty === true;
3855
+ }
3856
+ /** Names of fields with pending edits, used by the save bar. */
3857
+ get dirtyFieldNames() {
3858
+ if (!this.record?.Fields)
3859
+ return [];
3860
+ return this.record.Fields.filter(f => f.Dirty).map(f => f.Name);
3861
+ }
3862
+ /** Parsed tags as a plain array — derived from record.Tags JSON. */
3863
+ get tags() {
3864
+ return TagsHelper.parseTags(this.record?.Tags);
3865
+ }
3866
+ /**
3867
+ * Load all suites for the Parent Suite dropdown. Excludes the current
3868
+ * suite (a suite cannot be its own parent).
3869
+ */
3870
+ async loadParentSuiteOptions() {
3871
+ try {
3872
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
3873
+ const result = await rv.RunView({
3874
+ EntityName: 'MJ: Test Suites',
3875
+ ExtraFilter: this.record?.ID ? `ID <> '${this.record.ID}'` : '',
3876
+ OrderBy: 'Name',
3877
+ ResultType: 'entity_object'
3878
+ });
3879
+ if (result.Success) {
3880
+ this.parentSuiteOptions = result.Results || [];
3881
+ this.cdr.markForCheck();
3882
+ }
3883
+ }
3884
+ catch (error) {
3885
+ console.warn('Failed to load parent suite options:', error);
3886
+ }
3887
+ }
3888
+ /** Save all pending changes on the suite record. */
3889
+ async saveChanges() {
3890
+ if (!this.isDirty || this.isSaving)
3891
+ return;
3892
+ this.isSaving = true;
3893
+ this.cdr.markForCheck();
3894
+ try {
3895
+ const ok = await this.SaveRecord(false);
3896
+ if (ok) {
3897
+ SharedService.Instance.CreateSimpleNotification('Suite saved', 'success', 2000);
3898
+ }
3899
+ else {
3900
+ const detail = this.record?.LatestResult?.CompleteMessage || this.record?.LatestResult?.Message || 'Save failed';
3901
+ SharedService.Instance.CreateSimpleNotification(detail, 'error', 4000);
3902
+ }
3903
+ }
3904
+ catch (err) {
3905
+ const msg = err instanceof Error ? err.message : 'Save failed';
3906
+ SharedService.Instance.CreateSimpleNotification(msg, 'error', 4000);
3907
+ }
3908
+ finally {
3909
+ this.isSaving = false;
3910
+ this.cdr.markForCheck();
3911
+ }
3912
+ }
3913
+ /** Discard all pending field changes on the suite. */
3914
+ discardChanges() {
3915
+ if (!this.isDirty)
3916
+ return;
3917
+ if (!confirm('Discard your unsaved changes?'))
3918
+ return;
3919
+ this.record.Revert();
3920
+ this.tagDraft = '';
3921
+ this.cdr.markForCheck();
3922
+ }
3923
+ /** Add a tag from tagDraft (called on Enter / comma / blur). */
3924
+ addTagFromDraft() {
3925
+ const raw = this.tagDraft.trim();
3926
+ if (!raw)
3927
+ return;
3928
+ // Allow comma-separated entry: "alpha, beta" → two tags
3929
+ const incoming = raw.split(',').map(t => t.trim()).filter(t => t.length > 0);
3930
+ const existing = this.tags;
3931
+ const merged = [...existing];
3932
+ for (const t of incoming) {
3933
+ if (!merged.includes(t))
3934
+ merged.push(t);
3935
+ }
3936
+ this.record.Tags = TagsHelper.toJson(merged);
3937
+ this.tagDraft = '';
3938
+ this.cdr.markForCheck();
3939
+ }
3940
+ /** Remove a single tag. */
3941
+ removeTag(tag) {
3942
+ this.record.Tags = TagsHelper.removeTag(this.record.Tags, tag);
3943
+ this.cdr.markForCheck();
3944
+ }
3945
+ /** Handle Enter / comma in the tag input to commit the draft tag. */
3946
+ onTagInputKeydown(event) {
3947
+ if (event.key === 'Enter' || event.key === ',') {
3948
+ event.preventDefault();
3949
+ this.addTagFromDraft();
3950
+ return;
3951
+ }
3952
+ // Backspace on an empty draft pops the last chip
3953
+ if (event.key === 'Backspace' && !this.tagDraft) {
3954
+ const all = this.tags;
3955
+ if (all.length > 0) {
3956
+ event.preventDefault();
3957
+ this.removeTag(all[all.length - 1]);
3958
+ }
3959
+ }
3960
+ }
3961
+ // ==========================================
3962
+ // Suite Membership: Add / Remove / Reorder Tests
3963
+ // ==========================================
3964
+ /** Open the picker dialog and load tests not yet in this suite. */
3965
+ async openAddTestsDialog() {
3966
+ this.showAddTestsDialog = true;
3967
+ this.selectedTestIdsToAdd = new Set();
3968
+ this.addTestsSearch = '';
3969
+ this.loadingAvailableTests = true;
3970
+ this.cdr.markForCheck();
3971
+ try {
3972
+ if (!this.testsLoaded) {
3973
+ await this.loadTests();
3974
+ }
3975
+ const existingTestIds = new Set(this.suiteTests.map(st => st.TestID));
3976
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
3977
+ const result = await rv.RunView({
3978
+ EntityName: 'MJ: Tests',
3979
+ OrderBy: 'Name',
3980
+ ResultType: 'entity_object'
3981
+ });
3982
+ if (result.Success) {
3983
+ this.availableTests = (result.Results || []).filter(t => !existingTestIds.has(t.ID));
3984
+ }
3985
+ else {
3986
+ SharedService.Instance.CreateSimpleNotification('Failed to load tests', 'error', 3000);
3987
+ }
3988
+ }
3989
+ catch (err) {
3990
+ console.error('Error loading available tests:', err);
3991
+ SharedService.Instance.CreateSimpleNotification('Failed to load tests', 'error', 3000);
3992
+ }
3993
+ finally {
3994
+ this.loadingAvailableTests = false;
3995
+ this.cdr.markForCheck();
3996
+ }
3997
+ }
3998
+ closeAddTestsDialog() {
3999
+ if (this.isAddingTests)
4000
+ return;
4001
+ this.showAddTestsDialog = false;
4002
+ this.selectedTestIdsToAdd = new Set();
4003
+ this.addTestsSearch = '';
4004
+ this.cdr.markForCheck();
4005
+ }
4006
+ toggleAddSelection(testId) {
4007
+ if (this.selectedTestIdsToAdd.has(testId)) {
4008
+ this.selectedTestIdsToAdd.delete(testId);
4009
+ }
4010
+ else {
4011
+ this.selectedTestIdsToAdd.add(testId);
4012
+ }
4013
+ // Set mutation alone doesn't trigger OnPush — assign a new reference
4014
+ this.selectedTestIdsToAdd = new Set(this.selectedTestIdsToAdd);
4015
+ this.cdr.markForCheck();
4016
+ }
4017
+ isAddSelected(testId) {
4018
+ return this.selectedTestIdsToAdd.has(testId);
4019
+ }
4020
+ /** Tests that match the picker search filter. */
4021
+ get filteredAvailableTests() {
4022
+ const q = this.addTestsSearch.trim().toLowerCase();
4023
+ if (!q)
4024
+ return this.availableTests;
4025
+ return this.availableTests.filter(t => (t.Name || '').toLowerCase().includes(q) ||
4026
+ (t.Description || '').toLowerCase().includes(q) ||
4027
+ (t.Type || '').toLowerCase().includes(q));
4028
+ }
4029
+ selectAllFiltered() {
4030
+ for (const t of this.filteredAvailableTests) {
4031
+ this.selectedTestIdsToAdd.add(t.ID);
4032
+ }
4033
+ this.selectedTestIdsToAdd = new Set(this.selectedTestIdsToAdd);
4034
+ this.cdr.markForCheck();
4035
+ }
4036
+ clearAddSelection() {
4037
+ this.selectedTestIdsToAdd = new Set();
4038
+ this.cdr.markForCheck();
4039
+ }
4040
+ /** Create suite-test rows for every selected test, appended after existing ones. */
4041
+ async confirmAddTests() {
4042
+ if (this.selectedTestIdsToAdd.size === 0 || this.isAddingTests)
4043
+ return;
4044
+ this.isAddingTests = true;
4045
+ this.cdr.markForCheck();
4046
+ const provider = this.ProviderToUse;
4047
+ const startSequence = this.suiteTests.reduce((max, st) => Math.max(max, st.Sequence ?? 0), 0);
4048
+ const idsToAdd = Array.from(this.selectedTestIdsToAdd);
4049
+ // Snapshot test names from the picker so we can hydrate the joined "Test"
4050
+ // column on the optimistic rows (BaseEntity's joined view fields aren't
4051
+ // always populated through a TransactionGroup save).
4052
+ const testNameById = new Map(this.availableTests.map(t => [t.ID, t.Name]));
4053
+ try {
4054
+ const tg = await provider.CreateTransactionGroup();
4055
+ const newRows = [];
4056
+ for (let i = 0; i < idsToAdd.length; i++) {
4057
+ const row = await provider.GetEntityObject('MJ: Test Suite Tests', provider.CurrentUser);
4058
+ row.NewRecord();
4059
+ row.SuiteID = this.record.ID;
4060
+ row.TestID = idsToAdd[i];
4061
+ row.Sequence = startSequence + i + 1;
4062
+ row.Status = 'Active';
4063
+ row.TransactionGroup = tg;
4064
+ await row.Save();
4065
+ newRows.push(row);
4066
+ }
4067
+ const ok = await tg.Submit();
4068
+ if (ok) {
4069
+ // Optimistic UI update: append the saved rows immediately so the user
4070
+ // sees the new tests right away. If the joined "Test" name field
4071
+ // didn't come back from the save (TG quirk), hydrate it from the
4072
+ // picker snapshot.
4073
+ for (const row of newRows) {
4074
+ if (!row.Test) {
4075
+ const name = testNameById.get(row.TestID);
4076
+ if (name) {
4077
+ row.Set('Test', name);
4078
+ }
4079
+ }
4080
+ }
4081
+ this.suiteTests = [...this.suiteTests, ...newRows];
4082
+ this.cdr.markForCheck();
4083
+ SharedService.Instance.CreateSimpleNotification(idsToAdd.length === 1 ? 'Test added to suite' : `${idsToAdd.length} tests added to suite`, 'success', 2000);
4084
+ this.showAddTestsDialog = false;
4085
+ this.selectedTestIdsToAdd = new Set();
4086
+ this.addTestsSearch = '';
4087
+ }
4088
+ else {
4089
+ const failed = newRows.find(r => r.LatestResult && !r.LatestResult.Success);
4090
+ const detail = failed?.LatestResult?.CompleteMessage || 'Failed to add tests';
4091
+ SharedService.Instance.CreateSimpleNotification(detail, 'error', 4000);
4092
+ }
4093
+ }
4094
+ catch (err) {
4095
+ const msg = err instanceof Error ? err.message : 'Failed to add tests';
4096
+ SharedService.Instance.CreateSimpleNotification(msg, 'error', 4000);
4097
+ }
4098
+ finally {
4099
+ this.isAddingTests = false;
4100
+ this.cdr.markForCheck();
4101
+ }
4102
+ }
4103
+ /** Show the inline remove-confirm for one suite-test row. */
4104
+ requestRemoveTest(suiteTest, event) {
4105
+ if (event)
4106
+ event.stopPropagation();
4107
+ this.confirmingRemoveSuiteTestId = suiteTest.ID;
4108
+ this.cdr.markForCheck();
4109
+ }
4110
+ cancelRemoveTest(event) {
4111
+ if (event)
4112
+ event.stopPropagation();
4113
+ this.confirmingRemoveSuiteTestId = null;
4114
+ this.cdr.markForCheck();
4115
+ }
4116
+ /** Delete the suite-test join row and refresh the list. */
4117
+ async confirmRemoveTest(suiteTest, event) {
4118
+ if (event)
4119
+ event.stopPropagation();
4120
+ if (this.isRemovingTest)
4121
+ return;
4122
+ this.isRemovingTest = true;
4123
+ this.cdr.markForCheck();
4124
+ try {
4125
+ const ok = await suiteTest.Delete();
4126
+ if (ok) {
4127
+ this.suiteTests = this.suiteTests.filter(t => !UUIDsEqual(t.ID, suiteTest.ID));
4128
+ SharedService.Instance.CreateSimpleNotification('Test removed from suite', 'success', 2000);
4129
+ }
4130
+ else {
4131
+ const detail = suiteTest.LatestResult?.CompleteMessage || 'Failed to remove test';
4132
+ SharedService.Instance.CreateSimpleNotification(detail, 'error', 4000);
4133
+ }
4134
+ }
4135
+ catch (err) {
4136
+ const msg = err instanceof Error ? err.message : 'Failed to remove test';
4137
+ SharedService.Instance.CreateSimpleNotification(msg, 'error', 4000);
4138
+ }
4139
+ finally {
4140
+ this.isRemovingTest = false;
4141
+ this.confirmingRemoveSuiteTestId = null;
4142
+ this.cdr.markForCheck();
4143
+ }
4144
+ }
4145
+ /** Handle CDK drag-drop reordering — persists new Sequence values. */
4146
+ async onTestDrop(event) {
4147
+ if (event.previousIndex === event.currentIndex)
4148
+ return;
4149
+ // Optimistic reorder
4150
+ const reordered = [...this.suiteTests];
4151
+ moveItemInArray(reordered, event.previousIndex, event.currentIndex);
4152
+ this.suiteTests = reordered;
4153
+ this.cdr.markForCheck();
4154
+ // Compute which rows actually changed sequence (1-based contiguous numbering)
4155
+ const dirty = [];
4156
+ reordered.forEach((row, idx) => {
4157
+ const newSeq = idx + 1;
4158
+ if (row.Sequence !== newSeq) {
4159
+ row.Sequence = newSeq;
4160
+ dirty.push(row);
4161
+ }
4162
+ });
4163
+ if (dirty.length === 0)
4164
+ return;
4165
+ this.isReorderingTests = true;
4166
+ this.cdr.markForCheck();
4167
+ const provider = this.ProviderToUse;
4168
+ try {
4169
+ const tg = await provider.CreateTransactionGroup();
4170
+ for (const row of dirty) {
4171
+ row.TransactionGroup = tg;
4172
+ await row.Save();
4173
+ }
4174
+ const ok = await tg.Submit();
4175
+ if (!ok) {
4176
+ const failed = dirty.find(r => r.LatestResult && !r.LatestResult.Success);
4177
+ const detail = failed?.LatestResult?.CompleteMessage || 'Failed to save new order';
4178
+ SharedService.Instance.CreateSimpleNotification(detail, 'error', 4000);
4179
+ this.testsLoaded = false;
4180
+ await this.loadTests();
4181
+ }
4182
+ }
4183
+ catch (err) {
4184
+ const msg = err instanceof Error ? err.message : 'Failed to save new order';
4185
+ SharedService.Instance.CreateSimpleNotification(msg, 'error', 4000);
4186
+ this.testsLoaded = false;
4187
+ await this.loadTests();
4188
+ }
4189
+ finally {
4190
+ this.isReorderingTests = false;
4191
+ this.cdr.markForCheck();
4192
+ }
4193
+ }
3379
4194
  static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMJTestSuiteFormComponentExtended_BaseFactory; return function MJTestSuiteFormComponentExtended_Factory(__ngFactoryType__) { return (ɵMJTestSuiteFormComponentExtended_BaseFactory || (ɵMJTestSuiteFormComponentExtended_BaseFactory = i0.ɵɵgetInheritedFactory(MJTestSuiteFormComponentExtended)))(__ngFactoryType__ || MJTestSuiteFormComponentExtended); }; })(); }
3380
4195
  static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJTestSuiteFormComponentExtended, selectors: [["mj-test-suite-form"]], viewQuery: function MJTestSuiteFormComponentExtended_Query(rf, ctx) { if (rf & 1) {
3381
4196
  i0.ɵɵviewQuery(_c0, 5);
@@ -3383,98 +4198,120 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
3383
4198
  let _t;
3384
4199
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.chartContainer = _t.first);
3385
4200
  } }, hostBindings: function MJTestSuiteFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
3386
- i0.ɵɵlistener("keydown", function MJTestSuiteFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, i0.ɵɵresolveDocument);
3387
- } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 67, vars: 37, consts: [["chartContainer", ""], [1, "test-suite-form"], [1, "suite-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "fas", "fa-layer-group"], [1, "header-content"], [1, "header-left"], [1, "suite-icon"], [1, "suite-info"], [1, "suite-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], [1, "test-count"], [1, "header-actions"], ["mjButton", "", "title", "Export to CSV", 3, "click"], [1, "fas", "fa-file-excel"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], ["mjButton", "", 3, "click", "disabled"], [1, "suite-description"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-flask"], [1, "tab-badge"], [1, "fas", "fa-history"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-balance-scale"], [1, "tab-content"], [1, "overview-tab"], [1, "tests-tab"], [1, "runs-tab"], [1, "analytics-tab"], [1, "compare-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], ["Mode", "slide", 3, "Title", "Resizable"], [1, "info-section"], [1, "fas", "fa-info-circle"], [1, "info-grid"], [1, "info-item"], [1, "info-label"], [1, "info-value"], [1, "status-badge-inline", 3, "ngClass"], [1, "config-section"], [1, "fas", "fa-cogs"], [1, "config-grid"], [1, "config-item"], ["type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-hint"], [1, "loading-state"], [1, "tests-list"], [1, "empty-state"], [1, "skeleton-list"], [1, "skeleton-card"], [1, "skeleton-sequence"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], [1, "test-item"], [1, "test-item", 3, "click"], [1, "test-sequence"], [1, "test-icon"], [1, "test-content"], [1, "test-name"], [1, "test-status"], [1, "fas", "fa-chevron-right"], [1, "empty-icon"], [1, "runs-list"], [1, "run-item"], [1, "run-item", 3, "click"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-header"], [1, "run-id"], [1, "run-status"], [1, "run-meta"], [1, "fas", "fa-calendar"], [1, "run-eval-metrics"], [1, "eval-metric", "status", 3, "class"], ["title", "Human evaluation", 1, "eval-metric", "human"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto", 3, "high", "medium", "low"], [1, "run-tags"], [1, "fas", "fa-check-circle"], [1, "eval-metric", "status"], [1, "fas", "fa-user"], [1, "eval-pending"], [1, "fas", "fa-clock"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto"], [1, "fas", "fa-robot"], [1, "tag-chip"], [1, "fas", "fa-play-circle"], ["text", "Loading analytics data..."], [1, "analytics-subnav"], [1, "subnav-tabs"], [1, "subnav-tab", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "fas", "fa-th"], [1, "fas", "fa-project-diagram"], [1, "analytics-filters"], [1, "filters-header", 3, "click"], [1, "filters-title"], [1, "fas", "fa-filter"], [1, "filter-summary"], [1, "filters-content"], [1, "filter-group"], [1, "filter-buttons"], [1, "filter-btn", 3, "click"], [1, "filter-hint"], [1, "filter-buttons", "tag-filters"], [1, "filter-btn", "tag-btn", "all-tags-btn", 3, "click"], [1, "filter-btn", "tag-btn", 3, "active"], [1, "filter-btn", "tag-btn", 3, "click"], [1, "fas", "fa-check"], [1, "analytics-kpis"], [1, "kpi-card"], [1, "kpi-icon"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "success"], [1, "kpi-trend", 3, "ngClass"], [1, "kpi-icon", "info"], [1, "kpi-icon", "warning"], [1, "fas", "fa-dollar-sign"], [1, "analytics-table-section"], [1, "fas", "fa-table"], [1, "analytics-table-wrapper"], [1, "analytics-table"], [1, "clickable-row"], [1, "empty-state", "small"], [1, "clickable-row", 3, "click"], [1, "status-chip", 3, "ngClass"], [1, "pass-rate-cell"], [1, "pass-rate-bar", 3, "ngClass"], [1, "tag-cell"], [1, "tag-chip-table"], [1, "tag-more"], [1, "matrix-section"], ["text", "Loading test matrix..."], [1, "matrix-header"], [1, "matrix-header-right"], [1, "matrix-filter-input"], [1, "fas", "fa-search"], ["type", "text", "placeholder", "Filter tests...", 1, "filter-input", 3, "input", "value"], ["title", "Clear filter", 1, "clear-filter-btn"], [1, "matrix-run-count"], ["mjButton", "", "title", "Export matrix to CSV", 3, "click", "disabled"], [1, "fas", "fa-download"], [1, "matrix-scroll-container"], [1, "test-matrix"], ["title", "Sort by sequence", 1, "seq-header", 3, "click"], ["title", "Sort by name", 1, "test-name-header", 3, "click"], [1, "run-header", 3, "title"], [1, "spacer-header"], [3, "row-selected"], [1, "totals-row"], [1, "seq-cell", "totals-label"], [1, "test-name-cell", "totals-label"], [1, "result-cell", "totals-cell"], [1, "spacer-cell"], ["title", "Clear filter", 1, "clear-filter-btn", 3, "click"], [1, "fas", "fa-times"], [1, "run-header", 3, "click", "title"], [1, "run-header-content"], [1, "run-tags-header"], [1, "run-date"], [1, "run-pass-rate", 3, "ngClass"], [1, "tag-chip-header"], [1, "tag-more-header"], [3, "click"], [1, "seq-cell"], [1, "test-name-cell"], [1, "test-name", 3, "title"], [1, "result-cell", 3, "ngClass", "clickable", "cell-not-run", "title"], [1, "result-cell", 3, "click", "ngClass", "title"], [1, "cell-eval-stack"], [1, "cell-not-run-indicator"], [1, "cell-status", 3, "ngClass", "cell-skipped-status", "title"], ["title", "Human Review: No rating submitted yet", 1, "cell-human", "no-feedback"], [1, "cell-human", "has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title"], [1, "cell-auto", "has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title"], ["title", "Auto Score: No automated score available", 1, "cell-auto", "no-score"], [1, "cell-status", 3, "ngClass", "title"], [1, "fas", "fa-user-slash"], [1, "cell-human", "has-feedback", 3, "title"], [1, "rating-value"], [1, "cell-auto", "has-score", 3, "title"], [1, "score-value"], [1, "fas", "fa-minus"], [1, "cell-eval-stack", "totals-stack"], [1, "totals-status"], [1, "totals-human"], [1, "totals-auto"], [1, "pass-count"], [1, "avg-label"], [1, "count-label"], [1, "chart-section"], ["text", "Loading chart data..."], [1, "chart-header"], [1, "chart-legend"], [1, "legend-item", "chart-passed"], [1, "legend-item", "chart-failed"], [1, "legend-item", "chart-error"], [1, "fas", "fa-exclamation"], [1, "legend-item", "chart-skipped"], [1, "fas", "fa-forward"], [1, "chart-container"], [1, "d3-chart"], [1, "chart-info"], [1, "compare-selection"], [1, "compare-run-selector"], [1, "run-selector-list"], [1, "selected-run-preview"], [1, "compare-vs"], [1, "fas", "fa-exchange-alt"], [1, "compare-results"], [1, "compare-empty"], [1, "run-selector-item", 3, "selected"], [1, "run-selector-item", 3, "click"], [1, "selector-status"], [1, "selector-content"], [1, "selector-date"], [1, "selector-rate"], [1, "selector-tags"], [1, "tag-mini"], [1, "preview-header"], [1, "preview-label"], [1, "clear-btn", 3, "click"], [1, "preview-details"], [1, "preview-rate"], [1, "run-selector-item", 3, "selected", "disabled"], [1, "compare-summary"], [1, "compare-summary-card"], [1, "summary-label"], [1, "summary-value", 3, "ngClass"], [1, "compare-summary-card", "improved"], [1, "summary-value"], [1, "compare-summary-card", "regressed"], [1, "compare-table-section"], [1, "fas", "fa-list"], [1, "compare-table-wrapper"], [1, "compare-table"], [3, "ngClass"], [1, "status-chip", "status-missing"], [1, "muted"], [1, "change-indicator", "improved"], [1, "change-indicator", "regressed"], [1, "change-indicator", "unchanged"], [1, "fas", "fa-arrow-up"], [1, "fas", "fa-arrow-down"], ["text", "Loading comparison data..."], [1, "compare-empty-icon"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"], ["Mode", "slide", 3, "Closed", "Title", "Resizable"], [3, "PanelClose", "PanelMode", "selectedTestId", "selectedSuiteId", "runMode"]], template: function MJTestSuiteFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
3388
- i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "nav", 3)(3, "ol")(4, "li")(5, "a", 4);
4201
+ i0.ɵɵlistener("keydown", function MJTestSuiteFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, i0.ɵɵresolveDocument)("beforeunload", function MJTestSuiteFormComponentExtended_beforeunload_HostBindingHandler($event) { return ctx.handleBeforeUnload($event); }, i0.ɵɵresolveWindow);
4202
+ } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 87, vars: 51, consts: [["tagInput", ""], ["chartContainer", ""], ["pickerSearch", ""], [1, "test-suite-form"], [1, "suite-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "fas", "fa-layer-group"], [1, "header-content"], [1, "header-left"], [1, "suite-icon"], [1, "suite-info"], ["title", "You have unsaved changes", "aria-label", "Unsaved changes", 1, "dirty-indicator"], [1, "suite-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], [1, "test-count"], ["title", "You have unsaved changes", 1, "unsaved-pill"], [1, "header-actions"], ["mjButton", "", "title", "Export to CSV", 3, "click"], [1, "fas", "fa-file-excel"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], ["mjButton", "", 3, "click", "disabled"], [1, "suite-description"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-flask"], [1, "tab-badge"], [1, "fas", "fa-history"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-balance-scale"], [1, "tab-content"], [1, "overview-tab"], [1, "tests-tab"], [1, "runs-tab"], [1, "analytics-tab"], [1, "compare-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], ["Mode", "slide", 3, "Title", "Resizable"], ["role", "region", "aria-label", "Unsaved changes", 1, "save-bar"], [1, "save-bar-message"], ["aria-hidden", "true", 1, "save-bar-dot"], [1, "save-bar-text"], [1, "save-bar-fields"], [1, "save-bar-actions"], ["type", "button", "title", "Save changes (\u2318S)", 1, "save-bar-btn", "save-bar-btn--primary", 3, "click", "disabled"], ["type", "button", "title", "Discard changes", 1, "save-bar-btn", "save-bar-btn--ghost", 3, "click", "disabled"], [1, "fas", "fa-undo"], [1, "fas", "fa-circle"], [1, "edit-section"], [1, "edit-section-header"], [1, "fas", "fa-pen-to-square"], [1, "edit-section-sub"], [1, "edit-grid"], [1, "edit-field", "edit-field--full"], ["for", "suite-name"], [1, "required"], ["id", "suite-name", "type", "text", "placeholder", "e.g., Core Agent Test Suite", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-description"], ["id", "suite-description", "rows", "3", "placeholder", "What does this suite cover?", 1, "config-input", "config-textarea", 3, "ngModelChange", "ngModel"], [1, "edit-field"], ["for", "suite-status"], [1, "select-wrapper"], ["id", "suite-status", 1, "config-input", 3, "ngModelChange", "ngModel"], [3, "ngValue"], ["for", "suite-parent"], ["id", "suite-parent", 1, "config-input", 3, "ngModelChange", "ngModel"], ["for", "suite-tags"], [1, "tag-editor", 3, "click"], [1, "tag-chip-editable"], ["id", "suite-tags", "type", "text", 1, "tag-input-inline", 3, "ngModelChange", "keydown", "blur", "placeholder", "ngModel"], [1, "config-hint"], [1, "fas", "fa-cogs"], ["for", "suite-timeout"], ["id", "suite-timeout", "type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "meta-section"], [1, "meta-grid"], [1, "meta-item"], [1, "meta-label"], [1, "meta-value"], [1, "meta-value", "meta-mono"], ["type", "button", 1, "tag-remove", 3, "click"], [1, "fas", "fa-times"], [1, "tests-actionbar"], [1, "tests-actionbar-text"], [1, "tests-actionbar-count"], [1, "tests-actionbar-hint"], [1, "tests-actionbar-actions"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fas", "fa-plus"], [1, "loading-state"], ["cdkDropList", "", 1, "tests-list"], [1, "empty-state"], [1, "skeleton-list"], [1, "skeleton-card"], [1, "skeleton-sequence"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], ["cdkDropList", "", 1, "tests-list", 3, "cdkDropListDropped"], ["cdkDrag", "", 1, "test-item", 3, "cdkDragDisabled"], ["cdkDragHandle", "", "title", "Drag to reorder", "aria-label", "Drag to reorder", 1, "test-drag-handle"], [1, "fas", "fa-grip-vertical"], [1, "test-sequence"], [1, "test-icon"], [1, "test-content", 3, "click"], [1, "test-name"], [1, "test-status"], [1, "test-remove-confirm"], [1, "fas", "fa-info-circle"], [1, "test-remove-confirm", 3, "click"], [1, "test-remove-confirm-text"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--danger", 3, "click", "disabled"], [1, "fas", "fa-spinner", "fa-spin"], ["type", "button", 1, "test-remove-confirm-btn", "test-remove-confirm-btn--ghost", 3, "click", "disabled"], ["type", "button", "title", "Remove from suite", "aria-label", "Remove from suite", 1, "test-remove-btn", 3, "click"], [1, "fas", "fa-chevron-right", "test-chevron", 3, "click"], [1, "empty-icon"], [1, "runs-list"], [1, "run-item"], [1, "run-item", 3, "click"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-header"], [1, "run-id"], [1, "run-status"], [1, "run-meta"], [1, "fas", "fa-calendar"], [1, "run-eval-metrics"], [1, "eval-metric", "status", 3, "class"], ["title", "Human evaluation", 1, "eval-metric", "human"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto", 3, "high", "medium", "low"], [1, "run-tags"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-check-circle"], [1, "eval-metric", "status"], [1, "fas", "fa-user"], [1, "eval-pending"], [1, "fas", "fa-clock"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto"], [1, "fas", "fa-robot"], [1, "tag-chip"], [1, "fas", "fa-play-circle"], ["text", "Loading analytics data..."], [1, "analytics-subnav"], [1, "subnav-tabs"], [1, "subnav-tab", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "fas", "fa-th"], [1, "fas", "fa-project-diagram"], [1, "analytics-filters"], [1, "filters-header", 3, "click"], [1, "filters-title"], [1, "fas", "fa-filter"], [1, "filter-summary"], [1, "filters-content"], [1, "filter-group"], [1, "filter-buttons"], [1, "filter-btn", 3, "click"], [1, "filter-hint"], [1, "filter-buttons", "tag-filters"], [1, "filter-btn", "tag-btn", "all-tags-btn", 3, "click"], [1, "filter-btn", "tag-btn", 3, "active"], [1, "filter-btn", "tag-btn", 3, "click"], [1, "fas", "fa-check"], [1, "analytics-kpis"], [1, "kpi-card"], [1, "kpi-icon"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "success"], [1, "kpi-trend", 3, "ngClass"], [1, "kpi-icon", "info"], [1, "kpi-icon", "warning"], [1, "fas", "fa-dollar-sign"], [1, "analytics-table-section"], [1, "fas", "fa-table"], [1, "analytics-table-wrapper"], [1, "analytics-table"], [1, "clickable-row"], [1, "empty-state", "small"], [1, "clickable-row", 3, "click"], [1, "status-chip", 3, "ngClass"], [1, "pass-rate-cell"], [1, "pass-rate-bar", 3, "ngClass"], [1, "tag-cell"], [1, "tag-chip-table"], [1, "tag-more"], [1, "matrix-section"], ["text", "Loading test matrix..."], [1, "matrix-header"], [1, "matrix-header-right"], [1, "matrix-filter-input"], [1, "fas", "fa-search"], ["type", "text", "placeholder", "Filter tests...", 1, "filter-input", 3, "input", "value"], ["title", "Clear filter", 1, "clear-filter-btn"], [1, "matrix-run-count"], ["mjButton", "", "title", "Export matrix to CSV", 3, "click", "disabled"], [1, "fas", "fa-download"], [1, "matrix-scroll-container"], [1, "test-matrix"], ["title", "Sort by sequence", 1, "seq-header", 3, "click"], ["title", "Sort by name", 1, "test-name-header", 3, "click"], [1, "run-header", 3, "title"], [1, "spacer-header"], [3, "row-selected"], [1, "totals-row"], [1, "seq-cell", "totals-label"], [1, "test-name-cell", "totals-label"], [1, "result-cell", "totals-cell"], [1, "spacer-cell"], ["title", "Clear filter", 1, "clear-filter-btn", 3, "click"], [1, "run-header", 3, "click", "title"], [1, "run-header-content"], [1, "run-tags-header"], [1, "run-date"], [1, "run-pass-rate", 3, "ngClass"], [1, "tag-chip-header"], [1, "tag-more-header"], [3, "click"], [1, "seq-cell"], [1, "test-name-cell"], [1, "test-name", 3, "title"], [1, "result-cell", 3, "ngClass", "clickable", "cell-not-run", "title"], [1, "result-cell", 3, "click", "ngClass", "title"], [1, "cell-eval-stack"], [1, "cell-not-run-indicator"], [1, "cell-status", 3, "ngClass", "cell-skipped-status", "title"], ["title", "Human Review: No rating submitted yet", 1, "cell-human", "no-feedback"], [1, "cell-human", "has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title"], [1, "cell-auto", "has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title"], ["title", "Auto Score: No automated score available", 1, "cell-auto", "no-score"], [1, "cell-status", 3, "ngClass", "title"], [1, "fas", "fa-user-slash"], [1, "cell-human", "has-feedback", 3, "title"], [1, "rating-value"], [1, "cell-auto", "has-score", 3, "title"], [1, "score-value"], [1, "fas", "fa-minus"], [1, "cell-eval-stack", "totals-stack"], [1, "totals-status"], [1, "totals-human"], [1, "totals-auto"], [1, "pass-count"], [1, "avg-label"], [1, "count-label"], [1, "chart-section"], ["text", "Loading chart data..."], [1, "chart-header"], [1, "chart-legend"], [1, "legend-item", "chart-passed"], [1, "legend-item", "chart-failed"], [1, "legend-item", "chart-error"], [1, "fas", "fa-exclamation"], [1, "legend-item", "chart-skipped"], [1, "fas", "fa-forward"], [1, "chart-container"], [1, "d3-chart"], [1, "chart-info"], [1, "compare-selection"], [1, "compare-run-selector"], [1, "run-selector-list"], [1, "selected-run-preview"], [1, "compare-vs"], [1, "fas", "fa-exchange-alt"], [1, "compare-results"], [1, "compare-empty"], [1, "run-selector-item", 3, "selected"], [1, "run-selector-item", 3, "click"], [1, "selector-status"], [1, "selector-content"], [1, "selector-date"], [1, "selector-rate"], [1, "selector-tags"], [1, "tag-mini"], [1, "preview-header"], [1, "preview-label"], [1, "clear-btn", 3, "click"], [1, "preview-details"], [1, "preview-rate"], [1, "run-selector-item", 3, "selected", "disabled"], [1, "compare-summary"], [1, "compare-summary-card"], [1, "summary-label"], [1, "summary-value", 3, "ngClass"], [1, "compare-summary-card", "improved"], [1, "summary-value"], [1, "compare-summary-card", "regressed"], [1, "compare-table-section"], [1, "fas", "fa-list"], [1, "compare-table-wrapper"], [1, "compare-table"], [3, "ngClass"], [1, "status-chip", "status-missing"], [1, "muted"], [1, "change-indicator", "improved"], [1, "change-indicator", "regressed"], [1, "change-indicator", "unchanged"], [1, "fas", "fa-arrow-up"], [1, "fas", "fa-arrow-down"], ["text", "Loading comparison data..."], [1, "compare-empty-icon"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"], ["Mode", "slide", 3, "Closed", "Title", "Resizable"], [3, "PanelClose", "PanelMode", "selectedTestId", "selectedSuiteId", "runMode"], [1, "picker-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "add-tests-dialog-title", 1, "picker-dialog", 3, "click"], [1, "picker-header"], ["id", "add-tests-dialog-title", 1, "picker-title"], [1, "fas", "fa-plus-circle"], ["type", "button", "aria-label", "Close", 1, "picker-close", 3, "click", "disabled"], [1, "picker-search"], [1, "fas", "fa-search", "picker-search-icon"], ["type", "text", "placeholder", "Search tests by name, description, or type...", "autofocus", "", 1, "picker-search-input", 3, "ngModelChange", "ngModel"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear"], [1, "picker-toolbar"], [1, "picker-toolbar-status"], [1, "picker-toolbar-actions"], ["type", "button", 1, "picker-link-btn", 3, "click", "disabled"], [1, "picker-body"], [1, "picker-loading"], [1, "picker-empty"], [1, "picker-list"], [1, "picker-footer"], ["type", "button", 1, "picker-btn", "picker-btn--primary", 3, "click", "disabled"], ["type", "button", 1, "picker-btn", "picker-btn--ghost", 3, "click", "disabled"], ["type", "button", "aria-label", "Clear search", 1, "picker-search-clear", 3, "click"], ["text", "Loading tests..."], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "picker-row--selected"], ["role", "checkbox", "tabindex", "0", 1, "picker-row", 3, "click"], [1, "picker-check"], [1, "picker-row-main"], [1, "picker-row-name"], [1, "picker-row-desc"], [1, "picker-row-meta"], [1, "picker-row-pill"], [1, "picker-row-pill", "picker-row-pill--status"], [1, "save-bar-kbd"]], template: function MJTestSuiteFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
4203
+ i0.ɵɵelementStart(0, "div", 3)(1, "div", 4)(2, "nav", 5)(3, "ol")(4, "li")(5, "a", 6);
3389
4204
  i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_a_click_5_listener() { return ctx.navigateToTestingDashboard(); });
3390
- i0.ɵɵelement(6, "i", 5);
3391
- i0.ɵɵelementStart(7, "span", 6);
4205
+ i0.ɵɵelement(6, "i", 7);
4206
+ i0.ɵɵelementStart(7, "span", 8);
3392
4207
  i0.ɵɵtext(8, "Testing");
3393
4208
  i0.ɵɵelementEnd()()();
3394
- i0.ɵɵelementStart(9, "li", 7);
3395
- i0.ɵɵelement(10, "i", 8)(11, "i", 9);
4209
+ i0.ɵɵelementStart(9, "li", 9);
4210
+ i0.ɵɵelement(10, "i", 10)(11, "i", 11);
3396
4211
  i0.ɵɵelementStart(12, "span");
3397
4212
  i0.ɵɵtext(13);
3398
4213
  i0.ɵɵelementEnd()()()();
3399
- i0.ɵɵelementStart(14, "div", 10)(15, "div", 11)(16, "div", 12);
3400
- i0.ɵɵelement(17, "i", 9);
4214
+ i0.ɵɵelementStart(14, "div", 12)(15, "div", 13)(16, "div", 14);
4215
+ i0.ɵɵelement(17, "i", 11);
3401
4216
  i0.ɵɵelementEnd();
3402
- i0.ɵɵelementStart(18, "div", 13)(19, "h1");
4217
+ i0.ɵɵelementStart(18, "div", 15)(19, "h1");
3403
4218
  i0.ɵɵtext(20);
4219
+ i0.ɵɵconditionalCreate(21, MJTestSuiteFormComponentExtended_Conditional_21_Template, 2, 0, "span", 16);
3404
4220
  i0.ɵɵelementEnd();
3405
- i0.ɵɵelementStart(21, "div", 14)(22, "span", 15);
3406
- i0.ɵɵelement(23, "i", 16);
3407
- i0.ɵɵtext(24);
4221
+ i0.ɵɵelementStart(22, "div", 17)(23, "span", 18);
4222
+ i0.ɵɵelement(24, "i", 19);
4223
+ i0.ɵɵtext(25);
3408
4224
  i0.ɵɵelementEnd();
3409
- i0.ɵɵconditionalCreate(25, MJTestSuiteFormComponentExtended_Conditional_25_Template, 3, 1, "span", 17);
4225
+ i0.ɵɵconditionalCreate(26, MJTestSuiteFormComponentExtended_Conditional_26_Template, 3, 1, "span", 20);
4226
+ i0.ɵɵconditionalCreate(27, MJTestSuiteFormComponentExtended_Conditional_27_Template, 3, 0, "span", 21);
3410
4227
  i0.ɵɵelementEnd()()();
3411
- i0.ɵɵelementStart(26, "div", 18);
3412
- i0.ɵɵelement(27, "app-evaluation-mode-toggle");
3413
- i0.ɵɵelementStart(28, "button", 19);
3414
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_28_listener() { return ctx.exportToExcel(); });
3415
- i0.ɵɵelement(29, "i", 20);
3416
- i0.ɵɵtext(30, " Export ");
4228
+ i0.ɵɵelementStart(28, "div", 22);
4229
+ i0.ɵɵelement(29, "app-evaluation-mode-toggle");
4230
+ i0.ɵɵelementStart(30, "button", 23);
4231
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_30_listener() { return ctx.exportToExcel(); });
4232
+ i0.ɵɵelement(31, "i", 24);
4233
+ i0.ɵɵtext(32, " Export ");
3417
4234
  i0.ɵɵelementEnd();
3418
- i0.ɵɵelementStart(31, "button", 21);
3419
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_31_listener() { return ctx.runSuite(); });
3420
- i0.ɵɵelement(32, "i", 22);
3421
- i0.ɵɵtext(33, " Run Suite ");
4235
+ i0.ɵɵelementStart(33, "button", 25);
4236
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_33_listener() { return ctx.runSuite(); });
4237
+ i0.ɵɵelement(34, "i", 26);
4238
+ i0.ɵɵtext(35, " Run Suite ");
3422
4239
  i0.ɵɵelementEnd();
3423
- i0.ɵɵelementStart(34, "button", 23);
3424
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_34_listener() { return ctx.refresh(); });
3425
- i0.ɵɵelement(35, "i", 16);
3426
- i0.ɵɵtext(36);
4240
+ i0.ɵɵelementStart(36, "button", 27);
4241
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_36_listener() { return ctx.refresh(); });
4242
+ i0.ɵɵelement(37, "i", 19);
4243
+ i0.ɵɵtext(38);
3427
4244
  i0.ɵɵelementEnd()()();
3428
- i0.ɵɵconditionalCreate(37, MJTestSuiteFormComponentExtended_Conditional_37_Template, 3, 1, "div", 24);
4245
+ i0.ɵɵconditionalCreate(39, MJTestSuiteFormComponentExtended_Conditional_39_Template, 3, 1, "div", 28);
3429
4246
  i0.ɵɵelementEnd();
3430
- i0.ɵɵelementStart(38, "div", 25)(39, "div", 26)(40, "button", 27);
3431
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_40_listener() { return ctx.changeTab("overview"); });
3432
- i0.ɵɵelement(41, "i", 28);
3433
- i0.ɵɵtext(42, " Overview ");
4247
+ i0.ɵɵelementStart(40, "div", 29)(41, "div", 30)(42, "button", 31);
4248
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_42_listener() { return ctx.changeTab("overview"); });
4249
+ i0.ɵɵelement(43, "i", 32);
4250
+ i0.ɵɵtext(44, " Overview ");
3434
4251
  i0.ɵɵelementEnd();
3435
- i0.ɵɵelementStart(43, "button", 27);
3436
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_43_listener() { return ctx.changeTab("tests"); });
3437
- i0.ɵɵelement(44, "i", 29);
3438
- i0.ɵɵtext(45, " Tests ");
3439
- i0.ɵɵconditionalCreate(46, MJTestSuiteFormComponentExtended_Conditional_46_Template, 2, 1, "span", 30);
4252
+ i0.ɵɵelementStart(45, "button", 31);
4253
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_45_listener() { return ctx.changeTab("tests"); });
4254
+ i0.ɵɵelement(46, "i", 33);
4255
+ i0.ɵɵtext(47, " Tests ");
4256
+ i0.ɵɵconditionalCreate(48, MJTestSuiteFormComponentExtended_Conditional_48_Template, 2, 1, "span", 34);
3440
4257
  i0.ɵɵelementEnd();
3441
- i0.ɵɵelementStart(47, "button", 27);
3442
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_47_listener() { return ctx.changeTab("runs"); });
3443
- i0.ɵɵelement(48, "i", 31);
3444
- i0.ɵɵtext(49, " Runs ");
3445
- i0.ɵɵconditionalCreate(50, MJTestSuiteFormComponentExtended_Conditional_50_Template, 2, 1, "span", 30);
4258
+ i0.ɵɵelementStart(49, "button", 31);
4259
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_49_listener() { return ctx.changeTab("runs"); });
4260
+ i0.ɵɵelement(50, "i", 35);
4261
+ i0.ɵɵtext(51, " Runs ");
4262
+ i0.ɵɵconditionalCreate(52, MJTestSuiteFormComponentExtended_Conditional_52_Template, 2, 1, "span", 34);
3446
4263
  i0.ɵɵelementEnd();
3447
- i0.ɵɵelementStart(51, "button", 27);
3448
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_51_listener() { return ctx.changeTab("analytics"); });
3449
- i0.ɵɵelement(52, "i", 32);
3450
- i0.ɵɵtext(53, " Analytics ");
4264
+ i0.ɵɵelementStart(53, "button", 31);
4265
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_53_listener() { return ctx.changeTab("analytics"); });
4266
+ i0.ɵɵelement(54, "i", 36);
4267
+ i0.ɵɵtext(55, " Analytics ");
3451
4268
  i0.ɵɵelementEnd();
3452
- i0.ɵɵelementStart(54, "button", 27);
3453
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_54_listener() { return ctx.changeTab("compare"); });
3454
- i0.ɵɵelement(55, "i", 33);
3455
- i0.ɵɵtext(56, " Compare ");
4269
+ i0.ɵɵelementStart(56, "button", 31);
4270
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_56_listener() { return ctx.changeTab("compare"); });
4271
+ i0.ɵɵelement(57, "i", 37);
4272
+ i0.ɵɵtext(58, " Compare ");
3456
4273
  i0.ɵɵelementEnd()()();
3457
- i0.ɵɵelementStart(57, "div", 34);
3458
- i0.ɵɵconditionalCreate(58, MJTestSuiteFormComponentExtended_Conditional_58_Template, 45, 13, "div", 35);
3459
- i0.ɵɵconditionalCreate(59, MJTestSuiteFormComponentExtended_Conditional_59_Template, 4, 3, "div", 36);
3460
- i0.ɵɵconditionalCreate(60, MJTestSuiteFormComponentExtended_Conditional_60_Template, 4, 3, "div", 37);
3461
- i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_61_Template, 4, 3, "div", 38);
3462
- i0.ɵɵconditionalCreate(62, MJTestSuiteFormComponentExtended_Conditional_62_Template, 18, 8, "div", 39);
4274
+ i0.ɵɵelementStart(59, "div", 38);
4275
+ i0.ɵɵconditionalCreate(60, MJTestSuiteFormComponentExtended_Conditional_60_Template, 75, 18, "div", 39);
4276
+ i0.ɵɵconditionalCreate(61, MJTestSuiteFormComponentExtended_Conditional_61_Template, 15, 5, "div", 40);
4277
+ i0.ɵɵconditionalCreate(62, MJTestSuiteFormComponentExtended_Conditional_62_Template, 4, 3, "div", 41);
4278
+ i0.ɵɵconditionalCreate(63, MJTestSuiteFormComponentExtended_Conditional_63_Template, 4, 3, "div", 42);
4279
+ i0.ɵɵconditionalCreate(64, MJTestSuiteFormComponentExtended_Conditional_64_Template, 18, 8, "div", 43);
4280
+ i0.ɵɵelementEnd();
4281
+ i0.ɵɵelementStart(65, "button", 44);
4282
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_65_listener() { return ctx.toggleShortcuts(); });
4283
+ i0.ɵɵelement(66, "i", 45);
3463
4284
  i0.ɵɵelementEnd();
3464
- i0.ɵɵelementStart(63, "button", 40);
3465
- i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_63_listener() { return ctx.toggleShortcuts(); });
3466
- i0.ɵɵelement(64, "i", 41);
4285
+ i0.ɵɵconditionalCreate(67, MJTestSuiteFormComponentExtended_Conditional_67_Template, 40, 0, "div", 46);
4286
+ i0.ɵɵconditionalCreate(68, MJTestSuiteFormComponentExtended_Conditional_68_Template, 2, 6, "mj-slide-panel", 47);
4287
+ i0.ɵɵconditionalCreate(69, MJTestSuiteFormComponentExtended_Conditional_69_Template, 32, 10);
4288
+ i0.ɵɵelementStart(70, "div", 48)(71, "div", 49)(72, "span", 50);
4289
+ i0.ɵɵtext(73, "\u25CF");
3467
4290
  i0.ɵɵelementEnd();
3468
- i0.ɵɵconditionalCreate(65, MJTestSuiteFormComponentExtended_Conditional_65_Template, 32, 0, "div", 42);
3469
- i0.ɵɵconditionalCreate(66, MJTestSuiteFormComponentExtended_Conditional_66_Template, 2, 6, "mj-slide-panel", 43);
4291
+ i0.ɵɵelementStart(74, "span", 51)(75, "strong");
4292
+ i0.ɵɵtext(76, "Unsaved changes");
3470
4293
  i0.ɵɵelementEnd();
4294
+ i0.ɵɵelementStart(77, "span", 52);
4295
+ i0.ɵɵconditionalCreate(78, MJTestSuiteFormComponentExtended_Conditional_78_Template, 1, 1)(79, MJTestSuiteFormComponentExtended_Conditional_79_Template, 1, 1);
4296
+ i0.ɵɵelementEnd()()();
4297
+ i0.ɵɵelementStart(80, "div", 53)(81, "button", 54);
4298
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_81_listener() { return ctx.saveChanges(); });
4299
+ i0.ɵɵconditionalCreate(82, MJTestSuiteFormComponentExtended_Conditional_82_Template, 2, 0)(83, MJTestSuiteFormComponentExtended_Conditional_83_Template, 7, 0);
4300
+ i0.ɵɵelementEnd();
4301
+ i0.ɵɵelementStart(84, "button", 55);
4302
+ i0.ɵɵlistener("click", function MJTestSuiteFormComponentExtended_Template_button_click_84_listener() { return ctx.discardChanges(); });
4303
+ i0.ɵɵelement(85, "i", 56);
4304
+ i0.ɵɵtext(86, " Discard ");
4305
+ i0.ɵɵelementEnd()()()();
3471
4306
  } if (rf & 2) {
3472
4307
  i0.ɵɵadvance(13);
3473
4308
  i0.ɵɵtextInterpolate(ctx.record.Name);
3474
4309
  i0.ɵɵadvance(3);
3475
4310
  i0.ɵɵstyleProp("background-color", ctx.getStatusColor());
3476
4311
  i0.ɵɵadvance(4);
3477
- i0.ɵɵtextInterpolate(ctx.record.Name);
4312
+ i0.ɵɵtextInterpolate1(" ", ctx.record.Name, " ");
4313
+ i0.ɵɵadvance();
4314
+ i0.ɵɵconditional(ctx.isDirty ? 21 : -1);
3478
4315
  i0.ɵɵadvance(2);
3479
4316
  i0.ɵɵproperty("ngClass", ctx.getStatusClass());
3480
4317
  i0.ɵɵadvance();
@@ -3482,7 +4319,9 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
3482
4319
  i0.ɵɵadvance();
3483
4320
  i0.ɵɵtextInterpolate1(" ", ctx.record.Status, " ");
3484
4321
  i0.ɵɵadvance();
3485
- i0.ɵɵconditional(ctx.testsLoaded ? 25 : -1);
4322
+ i0.ɵɵconditional(ctx.testsLoaded ? 26 : -1);
4323
+ i0.ɵɵadvance();
4324
+ i0.ɵɵconditional(ctx.isDirty ? 27 : -1);
3486
4325
  i0.ɵɵadvance(9);
3487
4326
  i0.ɵɵproperty("disabled", ctx.isRefreshing);
3488
4327
  i0.ɵɵadvance();
@@ -3490,7 +4329,7 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
3490
4329
  i0.ɵɵadvance();
3491
4330
  i0.ɵɵtextInterpolate1(" ", ctx.isRefreshing ? "Refreshing..." : "Refresh", " ");
3492
4331
  i0.ɵɵadvance();
3493
- i0.ɵɵconditional(ctx.record.Description ? 37 : -1);
4332
+ i0.ɵɵconditional(ctx.record.Description ? 39 : -1);
3494
4333
  i0.ɵɵadvance(3);
3495
4334
  i0.ɵɵclassProp("active", ctx.activeTab === "overview");
3496
4335
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "overview");
@@ -3498,35 +4337,52 @@ let MJTestSuiteFormComponentExtended = class MJTestSuiteFormComponentExtended ex
3498
4337
  i0.ɵɵclassProp("active", ctx.activeTab === "tests");
3499
4338
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "tests");
3500
4339
  i0.ɵɵadvance(3);
3501
- i0.ɵɵconditional(ctx.testsLoaded ? 46 : -1);
4340
+ i0.ɵɵconditional(ctx.testsLoaded ? 48 : -1);
3502
4341
  i0.ɵɵadvance();
3503
4342
  i0.ɵɵclassProp("active", ctx.activeTab === "runs");
3504
4343
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "runs");
3505
4344
  i0.ɵɵadvance(3);
3506
- i0.ɵɵconditional(ctx.runsLoaded ? 50 : -1);
4345
+ i0.ɵɵconditional(ctx.runsLoaded ? 52 : -1);
3507
4346
  i0.ɵɵadvance();
3508
4347
  i0.ɵɵclassProp("active", ctx.activeTab === "analytics");
3509
4348
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "analytics");
3510
4349
  i0.ɵɵadvance(3);
3511
4350
  i0.ɵɵclassProp("active", ctx.activeTab === "compare");
3512
4351
  i0.ɵɵattribute("aria-selected", ctx.activeTab === "compare");
3513
- i0.ɵɵadvance(4);
3514
- i0.ɵɵconditional(ctx.activeTab === "overview" ? 58 : -1);
4352
+ i0.ɵɵadvance(3);
4353
+ i0.ɵɵclassProp("has-savebar", ctx.isDirty);
4354
+ i0.ɵɵadvance();
4355
+ i0.ɵɵconditional(ctx.activeTab === "overview" ? 60 : -1);
3515
4356
  i0.ɵɵadvance();
3516
- i0.ɵɵconditional(ctx.activeTab === "tests" ? 59 : -1);
4357
+ i0.ɵɵconditional(ctx.activeTab === "tests" ? 61 : -1);
3517
4358
  i0.ɵɵadvance();
3518
- i0.ɵɵconditional(ctx.activeTab === "runs" ? 60 : -1);
4359
+ i0.ɵɵconditional(ctx.activeTab === "runs" ? 62 : -1);
3519
4360
  i0.ɵɵadvance();
3520
- i0.ɵɵconditional(ctx.activeTab === "analytics" ? 61 : -1);
4361
+ i0.ɵɵconditional(ctx.activeTab === "analytics" ? 63 : -1);
3521
4362
  i0.ɵɵadvance();
3522
- i0.ɵɵconditional(ctx.activeTab === "compare" ? 62 : -1);
4363
+ i0.ɵɵconditional(ctx.activeTab === "compare" ? 64 : -1);
3523
4364
  i0.ɵɵadvance();
3524
4365
  i0.ɵɵproperty("title", ctx.showShortcuts ? "Hide keyboard shortcuts" : "Show keyboard shortcuts");
3525
4366
  i0.ɵɵadvance(2);
3526
- i0.ɵɵconditional(ctx.showShortcuts ? 65 : -1);
4367
+ i0.ɵɵconditional(ctx.showShortcuts ? 67 : -1);
3527
4368
  i0.ɵɵadvance();
3528
- i0.ɵɵconditional(ctx.testingDialogService.IsPanelOpen ? 66 : -1);
3529
- } }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.NumberValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJButtonDirective, i4.TestRunDialogComponent, i4.EvaluationModeToggleComponent, i5.LoadingComponent, i6.MjSlidePanelComponent, i1.DatePipe], styles: ["\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-success: var(--mj-status-success);\n --test-error: var(--mj-status-error);\n --test-warning: var(--mj-status-warning);\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-secondary);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n\n\n.breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text[_ngcontent-%COMP%] {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n\n.suite-header[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.suite-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.suite-icon[_ngcontent-%COMP%]:hover { transform: scale(1.05); }\n\n.suite-info[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.suite-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n word-wrap: break-word;\n}\n\n.suite-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] { background: var(--test-success); }\n.status-badge.status-disabled[_ngcontent-%COMP%] { background: var(--test-disabled); }\n.status-badge.status-pending[_ngcontent-%COMP%] { background: var(--test-warning); }\n\n.status-badge-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active[_ngcontent-%COMP%] { background: var(--test-success); }\n.status-badge-inline.status-disabled[_ngcontent-%COMP%] { background: var(--test-disabled); }\n.status-badge-inline.status-pending[_ngcontent-%COMP%] { background: var(--test-warning); }\n\n.test-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.suite-description[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar { display: none; }\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.info-section[_ngcontent-%COMP%], .config-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%], .config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.info-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 500;\n}\n\n.config-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input[_ngcontent-%COMP%] {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.config-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-hint[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n\n\n.tests-tab[_ngcontent-%COMP%], .runs-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.loading-state[_ngcontent-%COMP%] { padding: 0; }\n\n.skeleton-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line[_ngcontent-%COMP%] {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] { width: 70%; }\n.skeleton-line.narrow[_ngcontent-%COMP%] { width: 40%; }\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n.tests-list[_ngcontent-%COMP%], .runs-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.test-item[_ngcontent-%COMP%]:hover, .run-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon[_ngcontent-%COMP%], .run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.test-icon[_ngcontent-%COMP%] {\n background: var(--test-primary);\n}\n\n.test-content[_ngcontent-%COMP%], .run-content[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.test-name[_ngcontent-%COMP%], .run-header[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id[_ngcontent-%COMP%] { font-weight: 600; }\n\n.run-status[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status[_ngcontent-%COMP%], .run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n\n\n\n\n.shortcuts-toggle[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle[_ngcontent-%COMP%]:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: var(--test-text-secondary);\n}\n\n.shortcut-keys[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-size: 11px;\n color: var(--test-text);\n}\n\n\n\n@media (max-width: 1024px) {\n .keyboard-shortcuts[_ngcontent-%COMP%], .shortcuts-toggle[_ngcontent-%COMP%] { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header[_ngcontent-%COMP%] { padding: 16px; }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { flex: 1; }\n\n .tab-shortcut[_ngcontent-%COMP%] { display: none; }\n\n .info-grid[_ngcontent-%COMP%] { grid-template-columns: 1fr; }\n\n .test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] { font-size: 16px; }\n\n .tab-badge[_ngcontent-%COMP%] { display: none; }\n\n .test-sequence[_ngcontent-%COMP%] { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item[_ngcontent-%COMP%]:active, .run-item[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%] { min-height: 48px; }\n .test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], *[_ngcontent-%COMP%]::before, *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions[_ngcontent-%COMP%], .tabs-container[_ngcontent-%COMP%], .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n\n\n\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.tag-more[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n\n\n.run-eval-metrics[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-metric.status.status-completed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-metric.status.status-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-metric.status.status-running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.status.status-pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human[_ngcontent-%COMP%] .eval-pending[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.auto.high[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n color: var(--mj-status-success);\n}\n\n.eval-metric.auto.medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto.low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n color: var(--mj-status-error);\n}\n\n.tag-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n\n\n.analytics-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n\n\n.analytics-filters[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-bottom: 16px;\n box-shadow: var(--test-shadow-sm);\n overflow: hidden;\n}\n\n.analytics-filters.collapsed[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.filters-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n}\n\n.filters-header[_ngcontent-%COMP%]:hover {\n background: var(--test-bg);\n}\n\n.filters-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.filters-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.filter-summary[_ngcontent-%COMP%] {\n font-weight: 400;\n color: var(--test-text-muted);\n margin-left: 8px;\n}\n\n.filters-header[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 12px;\n}\n\n.filters-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--test-primary);\n border-color: var(--test-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.tag-btn[_ngcontent-%COMP%] {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.filter-hint[_ngcontent-%COMP%] {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters[_ngcontent-%COMP%] {\n max-height: 120px;\n overflow-y: auto;\n}\n\n\n\n.analytics-kpis[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-icon.info[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.kpi-icon.warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n\n\n.analytics-table-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.analytics-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.clickable-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.clickable-row[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.status-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-passed[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-failed[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--test-error); }\n.status-chip.status-error[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-running[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--test-primary); }\n.status-chip.status-pending[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-chip.status-cancelled[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n.status-chip.status-missing[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken); color: var(--test-text-muted); }\n.status-chip.status-timeout[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-skipped[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n\n.pass-rate-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar[_ngcontent-%COMP%] {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium[_ngcontent-%COMP%] { background: var(--test-warning); }\n.pass-rate-bar.low[_ngcontent-%COMP%] { background: var(--test-error); }\n\n\n\n.analytics-subnav[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.subnav-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.subnav-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.matrix-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.matrix-run-count[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n\n\n.matrix-filter-input[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] i.fa-search[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.clear-filter-btn[_ngcontent-%COMP%] {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n\n\n.matrix-scroll-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix[_ngcontent-%COMP%] {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n display: table-header-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: table-row;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] {\n display: table-row-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] .test-name-cell[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix[_ngcontent-%COMP%] tfoot[_ngcontent-%COMP%] {\n display: table-footer-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid var(--mj-text-secondary) !important;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%] {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%] {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; \n\n top: 0;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%] {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%] {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix[_ngcontent-%COMP%] .run-header[_ngcontent-%COMP%] {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .spacer-header[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] .spacer-cell[_ngcontent-%COMP%] {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix[_ngcontent-%COMP%] .spacer-cell[_ngcontent-%COMP%] {\n background: var(--test-surface);\n}\n\n.test-matrix[_ngcontent-%COMP%] .run-header[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-header-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.run-pass-rate.medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.run-pass-rate.low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.run-tags-header[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-cell[_ngcontent-%COMP%] {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name[_ngcontent-%COMP%] {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell[_ngcontent-%COMP%] {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.result-cell.clickable[_ngcontent-%COMP%]:hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n z-index: 5;\n}\n\n.result-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.result-cell.cell-passed[_ngcontent-%COMP%], \n.result-cell.cell-failed[_ngcontent-%COMP%], \n.result-cell.cell-error[_ngcontent-%COMP%], \n.result-cell.cell-timeout[_ngcontent-%COMP%], \n.result-cell.cell-running[_ngcontent-%COMP%], \n.result-cell.cell-pending[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--test-text);\n}\n\n\n\n.result-cell.cell-skipped[_ngcontent-%COMP%] {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n color: var(--test-text-muted);\n}\n\n.cell-score[_ngcontent-%COMP%] {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n\n\n.cell-eval-stack[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval[_ngcontent-%COMP%] {\n min-width: 120px;\n width: auto;\n}\n\n\n\n.cell-status.status-timeout[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-status.status-pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.cell-human[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n font-size: 10px;\n}\n\n.cell-auto[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-auto.high[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-none-indicator[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n\n\n.chart-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.chart-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.chart-legend[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-skipped[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-disabled);\n}\n\n.chart-container[_ngcontent-%COMP%] {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart[_ngcontent-%COMP%] {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart[_ngcontent-%COMP%] svg[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n}\n\n\n\n.d3-chart[_ngcontent-%COMP%] .node[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart[_ngcontent-%COMP%] .node[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n.d3-chart[_ngcontent-%COMP%] .node-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart[_ngcontent-%COMP%] .link[_ngcontent-%COMP%] {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart[_ngcontent-%COMP%] .link[_ngcontent-%COMP%]:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip[_ngcontent-%COMP%] {\n position: absolute;\n padding: 10px 14px;\n background: var(--mj-bg-overlay);\n color: var(--mj-text-inverse);\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: var(--mj-shadow-lg);\n max-width: 250px;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip-title[_ngcontent-%COMP%] {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip-value[_ngcontent-%COMP%] {\n opacity: 0.8;\n}\n\n.chart-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n\n\n.compare-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.compare-selection[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list[_ngcontent-%COMP%] {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-selector-item.selected[_ngcontent-%COMP%] {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.run-selector-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview[_ngcontent-%COMP%] {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn[_ngcontent-%COMP%] {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n\n.preview-details[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n\n\n.compare-results[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.compare-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-value.positive[_ngcontent-%COMP%] { color: var(--test-success); }\n.compare-summary-card[_ngcontent-%COMP%] .summary-value.negative[_ngcontent-%COMP%] { color: var(--test-error); }\n\n.compare-summary-card.improved[_ngcontent-%COMP%] {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] { color: var(--test-success); }\n\n.compare-summary-card.regressed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] { color: var(--test-error); }\n\n\n\n.compare-table-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.compare-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.improved[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n}\n\n.compare-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.regressed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 5%, transparent);\n}\n\n.test-name-cell[_ngcontent-%COMP%] {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive[_ngcontent-%COMP%] { color: var(--test-success); }\n.negative[_ngcontent-%COMP%] { color: var(--test-error); }\n.muted[_ngcontent-%COMP%] { color: var(--test-text-muted); }\n\n.change-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.change-indicator.regressed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.change-indicator.unchanged[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-muted);\n}\n\n\n\n.compare-empty[_ngcontent-%COMP%] {\n text-align: center;\n padding: 60px 24px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-top: 24px;\n}\n\n.compare-empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin: 0 auto 20px;\n}\n\n.compare-empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--test-text-muted);\n}\n\n.compare-empty[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.compare-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 400px;\n margin: 0 auto;\n}\n\n\n\n.empty-state.small[_ngcontent-%COMP%] {\n padding: 32px 16px;\n}\n\n.empty-state.small[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .compare-selection[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs[_ngcontent-%COMP%] {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .filter-btn[_ngcontent-%COMP%] {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .kpi-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .kpi-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .compare-summary[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper[_ngcontent-%COMP%], \n .compare-table-wrapper[_ngcontent-%COMP%] {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list[_ngcontent-%COMP%] {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .analytics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .analytics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%], \n .compare-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .compare-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n\n\n\n\n\n\n\n.cell-human[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-human.no-feedback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] .rating-value[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 11px;\n}\n\n\n\n.cell-human.rating-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-human.rating-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-human.rating-good[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-human.rating-excellent[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n\n\n.cell-auto[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-auto.no-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] .score-value[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 10px;\n}\n\n\n\n.cell-auto.score-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-auto.score-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.score-good[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.score-excellent[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n\n\n.cell-status[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-timeout[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped[_ngcontent-%COMP%], \n.cell-status.status-pending[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n.result-cell.cell-not-run[_ngcontent-%COMP%] {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--mj-text-disabled);\n}\n\n.result-cell.cell-not-run[_ngcontent-%COMP%] .cell-eval-stack[_ngcontent-%COMP%] {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: var(--mj-text-disabled);\n font-size: 11px;\n}\n\n\n\n\n\n.test-matrix[_ngcontent-%COMP%] tfoot[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row[_ngcontent-%COMP%] .totals-label[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row[_ngcontent-%COMP%] .totals-cell[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n}\n\n.totals-stack[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status[_ngcontent-%COMP%], \n.totals-human[_ngcontent-%COMP%], \n.totals-auto[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.totals-status[_ngcontent-%COMP%] .pass-count[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-human[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.totals-human[_ngcontent-%COMP%] .avg-label[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-human[_ngcontent-%COMP%] .count-label[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.totals-auto[_ngcontent-%COMP%] .avg-label[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-auto[_ngcontent-%COMP%] .count-label[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.8;\n}"], changeDetection: 0 }); }
4369
+ i0.ɵɵconditional(ctx.testingDialogService.IsPanelOpen ? 68 : -1);
4370
+ i0.ɵɵadvance();
4371
+ i0.ɵɵconditional(ctx.showAddTestsDialog ? 69 : -1);
4372
+ i0.ɵɵadvance();
4373
+ i0.ɵɵclassProp("save-bar--visible", ctx.isDirty);
4374
+ i0.ɵɵattribute("aria-hidden", !ctx.isDirty);
4375
+ i0.ɵɵadvance(8);
4376
+ i0.ɵɵconditional(ctx.dirtyFieldNames.length === 1 ? 78 : ctx.dirtyFieldNames.length > 1 ? 79 : -1);
4377
+ i0.ɵɵadvance(3);
4378
+ i0.ɵɵproperty("disabled", ctx.isSaving || !ctx.isDirty);
4379
+ i0.ɵɵattribute("tabindex", ctx.isDirty ? 0 : -1);
4380
+ i0.ɵɵadvance();
4381
+ i0.ɵɵconditional(ctx.isSaving ? 82 : 83);
4382
+ i0.ɵɵadvance(2);
4383
+ i0.ɵɵproperty("disabled", ctx.isSaving || !ctx.isDirty);
4384
+ i0.ɵɵattribute("tabindex", ctx.isDirty ? 0 : -1);
4385
+ } }, dependencies: [i1.NgClass, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.NumberValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CdkDropList, i3.CdkDrag, i3.CdkDragHandle, i4.MJButtonDirective, i5.TestRunDialogComponent, i5.EvaluationModeToggleComponent, i6.LoadingComponent, i7.MjSlidePanelComponent, i1.DatePipe], styles: ["\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-success: var(--mj-status-success);\n --test-error: var(--mj-status-error);\n --test-warning: var(--mj-status-warning);\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-secondary);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-form[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n\n\n.breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text[_ngcontent-%COMP%] {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n\n.suite-header[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.suite-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.suite-icon[_ngcontent-%COMP%]:hover { transform: scale(1.05); }\n\n.suite-info[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.suite-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n word-wrap: break-word;\n}\n\n.suite-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] { background: var(--test-success); }\n.status-badge.status-disabled[_ngcontent-%COMP%] { background: var(--test-disabled); }\n.status-badge.status-pending[_ngcontent-%COMP%] { background: var(--test-warning); }\n\n.status-badge-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active[_ngcontent-%COMP%] { background: var(--test-success); }\n.status-badge-inline.status-disabled[_ngcontent-%COMP%] { background: var(--test-disabled); }\n.status-badge-inline.status-pending[_ngcontent-%COMP%] { background: var(--test-warning); }\n\n.test-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.suite-description[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar { display: none; }\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.info-section[_ngcontent-%COMP%], .config-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%], .config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.info-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 500;\n}\n\n.config-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input[_ngcontent-%COMP%] {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.config-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-hint[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n\n\n.tests-tab[_ngcontent-%COMP%], .runs-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.loading-state[_ngcontent-%COMP%] { padding: 0; }\n\n.skeleton-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line[_ngcontent-%COMP%] {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] { width: 70%; }\n.skeleton-line.narrow[_ngcontent-%COMP%] { width: 40%; }\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n.tests-list[_ngcontent-%COMP%], .runs-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.test-item[_ngcontent-%COMP%]:hover, .run-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon[_ngcontent-%COMP%], .run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.test-icon[_ngcontent-%COMP%] {\n background: var(--test-primary);\n}\n\n.test-content[_ngcontent-%COMP%], .run-content[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.test-name[_ngcontent-%COMP%], .run-header[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id[_ngcontent-%COMP%] { font-weight: 600; }\n\n.run-status[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status[_ngcontent-%COMP%], .run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n\n\n\n\n.shortcuts-toggle[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle[_ngcontent-%COMP%]:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: var(--test-text-secondary);\n}\n\n.shortcut-keys[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-size: 11px;\n color: var(--test-text);\n}\n\n\n\n@media (max-width: 1024px) {\n .keyboard-shortcuts[_ngcontent-%COMP%], .shortcuts-toggle[_ngcontent-%COMP%] { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header[_ngcontent-%COMP%] { padding: 16px; }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { flex: 1; }\n\n .tab-shortcut[_ngcontent-%COMP%] { display: none; }\n\n .info-grid[_ngcontent-%COMP%] { grid-template-columns: 1fr; }\n\n .test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] { font-size: 16px; }\n\n .tab-badge[_ngcontent-%COMP%] { display: none; }\n\n .test-sequence[_ngcontent-%COMP%] { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item[_ngcontent-%COMP%]:active, .run-item[_ngcontent-%COMP%]:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%] { min-height: 48px; }\n .test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], *[_ngcontent-%COMP%]::before, *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions[_ngcontent-%COMP%], .tabs-container[_ngcontent-%COMP%], .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n\n\n\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.tag-more[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n\n\n.run-eval-metrics[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-metric.status.status-completed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-metric.status.status-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-metric.status.status-running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.status.status-pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human[_ngcontent-%COMP%] .eval-pending[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.auto.high[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n color: var(--mj-status-success);\n}\n\n.eval-metric.auto.medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto.low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n color: var(--mj-status-error);\n}\n\n.tag-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n\n\n.analytics-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n\n\n.analytics-filters[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-bottom: 16px;\n box-shadow: var(--test-shadow-sm);\n overflow: hidden;\n}\n\n.analytics-filters.collapsed[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.filters-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n}\n\n.filters-header[_ngcontent-%COMP%]:hover {\n background: var(--test-bg);\n}\n\n.filters-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.filters-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.filter-summary[_ngcontent-%COMP%] {\n font-weight: 400;\n color: var(--test-text-muted);\n margin-left: 8px;\n}\n\n.filters-header[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 12px;\n}\n\n.filters-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--test-primary);\n border-color: var(--test-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.tag-btn[_ngcontent-%COMP%] {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.filter-hint[_ngcontent-%COMP%] {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters[_ngcontent-%COMP%] {\n max-height: 120px;\n overflow-y: auto;\n}\n\n\n\n.analytics-kpis[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-icon.info[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.kpi-icon.warning[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n\n\n.analytics-table-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.analytics-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.clickable-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.clickable-row[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.status-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-passed[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-failed[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--test-error); }\n.status-chip.status-error[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-running[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--test-primary); }\n.status-chip.status-pending[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-chip.status-cancelled[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n.status-chip.status-missing[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken); color: var(--test-text-muted); }\n.status-chip.status-timeout[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-skipped[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n\n.pass-rate-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar[_ngcontent-%COMP%] {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium[_ngcontent-%COMP%] { background: var(--test-warning); }\n.pass-rate-bar.low[_ngcontent-%COMP%] { background: var(--test-error); }\n\n\n\n.analytics-subnav[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.subnav-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.subnav-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.matrix-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.matrix-run-count[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n\n\n.matrix-filter-input[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] i.fa-search[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.clear-filter-btn[_ngcontent-%COMP%] {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n\n\n.matrix-scroll-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix[_ngcontent-%COMP%] {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n display: table-header-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: table-row;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] {\n display: table-row-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] .test-name-cell[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix[_ngcontent-%COMP%] tfoot[_ngcontent-%COMP%] {\n display: table-footer-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid var(--mj-text-secondary) !important;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%] {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%] {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; \n\n top: 0;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%] {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%] {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix[_ngcontent-%COMP%] .run-header[_ngcontent-%COMP%] {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .spacer-header[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] .spacer-cell[_ngcontent-%COMP%] {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix[_ngcontent-%COMP%] .spacer-cell[_ngcontent-%COMP%] {\n background: var(--test-surface);\n}\n\n.test-matrix[_ngcontent-%COMP%] .run-header[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-header-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.run-pass-rate.medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.run-pass-rate.low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.run-tags-header[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-cell[_ngcontent-%COMP%] {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name[_ngcontent-%COMP%] {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell[_ngcontent-%COMP%] {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.result-cell.clickable[_ngcontent-%COMP%]:hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n z-index: 5;\n}\n\n.result-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.result-cell.cell-passed[_ngcontent-%COMP%], \n.result-cell.cell-failed[_ngcontent-%COMP%], \n.result-cell.cell-error[_ngcontent-%COMP%], \n.result-cell.cell-timeout[_ngcontent-%COMP%], \n.result-cell.cell-running[_ngcontent-%COMP%], \n.result-cell.cell-pending[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--test-text);\n}\n\n\n\n.result-cell.cell-skipped[_ngcontent-%COMP%] {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n color: var(--test-text-muted);\n}\n\n.cell-score[_ngcontent-%COMP%] {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n\n\n.cell-eval-stack[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval[_ngcontent-%COMP%] {\n min-width: 120px;\n width: auto;\n}\n\n\n\n.cell-status.status-timeout[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-status.status-pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.cell-human[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n font-size: 10px;\n}\n\n.cell-auto[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-auto.high[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-none-indicator[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n\n\n.chart-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.chart-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.chart-legend[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-skipped[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-disabled);\n}\n\n.chart-container[_ngcontent-%COMP%] {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart[_ngcontent-%COMP%] {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart[_ngcontent-%COMP%] svg[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n}\n\n\n\n.d3-chart[_ngcontent-%COMP%] .node[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart[_ngcontent-%COMP%] .node[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n.d3-chart[_ngcontent-%COMP%] .node-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart[_ngcontent-%COMP%] .link[_ngcontent-%COMP%] {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart[_ngcontent-%COMP%] .link[_ngcontent-%COMP%]:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip[_ngcontent-%COMP%] {\n position: absolute;\n padding: 10px 14px;\n background: var(--mj-bg-overlay);\n color: var(--mj-text-inverse);\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: var(--mj-shadow-lg);\n max-width: 250px;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip-title[_ngcontent-%COMP%] {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip-value[_ngcontent-%COMP%] {\n opacity: 0.8;\n}\n\n.chart-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n\n\n.compare-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.compare-selection[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list[_ngcontent-%COMP%] {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-selector-item.selected[_ngcontent-%COMP%] {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.run-selector-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview[_ngcontent-%COMP%] {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn[_ngcontent-%COMP%] {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n\n.preview-details[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n\n\n.compare-results[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.compare-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-value.positive[_ngcontent-%COMP%] { color: var(--test-success); }\n.compare-summary-card[_ngcontent-%COMP%] .summary-value.negative[_ngcontent-%COMP%] { color: var(--test-error); }\n\n.compare-summary-card.improved[_ngcontent-%COMP%] {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] { color: var(--test-success); }\n\n.compare-summary-card.regressed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] { color: var(--test-error); }\n\n\n\n.compare-table-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.compare-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.improved[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n}\n\n.compare-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.regressed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 5%, transparent);\n}\n\n.test-name-cell[_ngcontent-%COMP%] {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive[_ngcontent-%COMP%] { color: var(--test-success); }\n.negative[_ngcontent-%COMP%] { color: var(--test-error); }\n.muted[_ngcontent-%COMP%] { color: var(--test-text-muted); }\n\n.change-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.change-indicator.regressed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.change-indicator.unchanged[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-muted);\n}\n\n\n\n.compare-empty[_ngcontent-%COMP%] {\n text-align: center;\n padding: 60px 24px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-top: 24px;\n}\n\n.compare-empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin: 0 auto 20px;\n}\n\n.compare-empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--test-text-muted);\n}\n\n.compare-empty[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.compare-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 400px;\n margin: 0 auto;\n}\n\n\n\n.empty-state.small[_ngcontent-%COMP%] {\n padding: 32px 16px;\n}\n\n.empty-state.small[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .compare-selection[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs[_ngcontent-%COMP%] {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .filter-btn[_ngcontent-%COMP%] {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .kpi-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .kpi-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .compare-summary[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper[_ngcontent-%COMP%], \n .compare-table-wrapper[_ngcontent-%COMP%] {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list[_ngcontent-%COMP%] {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .analytics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .analytics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%], \n .compare-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .compare-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n\n\n\n\n\n\n\n.cell-human[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-human.no-feedback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] .rating-value[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 11px;\n}\n\n\n\n.cell-human.rating-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-human.rating-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-human.rating-good[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-human.rating-excellent[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n\n\n.cell-auto[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-auto.no-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] .score-value[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 10px;\n}\n\n\n\n.cell-auto.score-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-auto.score-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.score-good[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.score-excellent[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n\n\n.cell-status[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-timeout[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped[_ngcontent-%COMP%], \n.cell-status.status-pending[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n\n\n.result-cell.cell-not-run[_ngcontent-%COMP%] {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--mj-text-disabled);\n}\n\n.result-cell.cell-not-run[_ngcontent-%COMP%] .cell-eval-stack[_ngcontent-%COMP%] {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: var(--mj-text-disabled);\n font-size: 11px;\n}\n\n\n\n\n\n.test-matrix[_ngcontent-%COMP%] tfoot[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row[_ngcontent-%COMP%] .totals-label[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row[_ngcontent-%COMP%] .totals-cell[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n}\n\n.totals-stack[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status[_ngcontent-%COMP%], \n.totals-human[_ngcontent-%COMP%], \n.totals-auto[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.totals-status[_ngcontent-%COMP%] .pass-count[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-human[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.totals-human[_ngcontent-%COMP%] .avg-label[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-human[_ngcontent-%COMP%] .count-label[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.totals-auto[_ngcontent-%COMP%] .avg-label[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-auto[_ngcontent-%COMP%] .count-label[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.8;\n}\n\n\n\n\n\n\n.edit-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header[_ngcontent-%COMP%] {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.edit-section-sub[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.edit-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field[_ngcontent-%COMP%] .required[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea[_ngcontent-%COMP%] {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.select-wrapper[_ngcontent-%COMP%] select.config-input[_ngcontent-%COMP%] {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n\n\n.tag-editor[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor[_ngcontent-%COMP%]:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable[_ngcontent-%COMP%] .tag-remove[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable[_ngcontent-%COMP%] .tag-remove[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-muted);\n}\n\n\n\n.meta-section[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono[_ngcontent-%COMP%] {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n\n\n.dirty-indicator[_ngcontent-%COMP%] {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: _ngcontent-%COMP%_pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes _ngcontent-%COMP%_pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 6px;\n animation: _ngcontent-%COMP%_pulseDot 1.8s ease-in-out infinite;\n}\n\n\n\n\n.tab-content.has-savebar[_ngcontent-%COMP%] {\n padding-bottom: 84px;\n}\n\n\n\n\n\n\n.save-bar[_ngcontent-%COMP%] {\n position: absolute;\n left: 16px;\n right: 96px; \n\n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(15, 23, 42, 0.18));\n backdrop-filter: blur(8px);\n \n\n\n\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar[_ngcontent-%COMP%] {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible[_ngcontent-%COMP%] {\n transform: none;\n }\n}\n\n.save-bar-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: _ngcontent-%COMP%_pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary[_ngcontent-%COMP%]:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd[_ngcontent-%COMP%] {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar[_ngcontent-%COMP%] {\n left: 8px;\n right: 8px;\n bottom: 88px; \n\n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions[_ngcontent-%COMP%] {\n justify-content: space-between;\n }\n .save-bar-kbd[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n\n.tests-actionbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n}\n\n.tests-actionbar-text[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n min-width: 0;\n}\n\n.tests-actionbar-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.tests-actionbar-count[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n font-size: 12px;\n font-weight: 700;\n}\n\n.tests-actionbar-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.tests-actionbar-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n\n\n.tests-list[cdk-drop-list][_ngcontent-%COMP%] .test-item[_ngcontent-%COMP%]:hover, \n.tests-list[_ngcontent-%COMP%] .test-item.cdk-drag[_ngcontent-%COMP%]:hover {\n transform: none;\n}\n\n\n\n.test-item.cdk-drag[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.test-item[_ngcontent-%COMP%] .test-content[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n\n\n.test-drag-handle[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 28px;\n border-radius: 4px;\n color: var(--test-text-muted);\n cursor: grab;\n flex-shrink: 0;\n transition: background 0.15s, color 0.15s;\n user-select: none;\n}\n\n.test-drag-handle[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n.test-drag-handle[_ngcontent-%COMP%]:active, \n.cdk-drag-preview[_ngcontent-%COMP%] .test-drag-handle[_ngcontent-%COMP%] {\n cursor: grabbing;\n}\n\n\n\n.test-remove-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n opacity: 0;\n transition: opacity 0.15s, background 0.15s, color 0.15s;\n}\n\n.test-item[_ngcontent-%COMP%]:hover .test-remove-btn[_ngcontent-%COMP%], \n.test-remove-btn[_ngcontent-%COMP%]:focus-visible {\n opacity: 1;\n}\n\n.test-remove-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error);\n}\n\n.test-chevron[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n\n\n.test-remove-confirm[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px 4px 12px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n flex-shrink: 0;\n}\n\n.test-remove-confirm-text[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.test-remove-confirm-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid transparent;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.test-remove-confirm-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.test-remove-confirm-btn--danger[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse, white);\n}\n\n.test-remove-confirm-btn--danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 88%, black);\n}\n\n.test-remove-confirm-btn--ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.test-remove-confirm-btn--ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n\n\n.cdk-drag-preview[_ngcontent-%COMP%] {\n box-shadow: 0 12px 32px rgba(15, 23, 42, 0.25);\n border-radius: var(--test-radius-md);\n background: var(--test-surface);\n opacity: 0.95;\n}\n\n.cdk-drag-placeholder[_ngcontent-%COMP%] {\n opacity: 0;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border: 2px dashed var(--test-primary);\n border-radius: var(--test-radius-md);\n}\n\n.cdk-drag-placeholder[_ngcontent-%COMP%] *[_ngcontent-%COMP%] {\n visibility: hidden;\n}\n\n.cdk-drag-animating[_ngcontent-%COMP%] {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.tests-list.cdk-drop-list-dragging[_ngcontent-%COMP%] .test-item[_ngcontent-%COMP%]:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n\n\n\n\n\n.picker-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(15, 23, 42, 0.45);\n z-index: 200;\n animation: _ngcontent-%COMP%_pickerFadeIn 180ms ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes _ngcontent-%COMP%_pickerFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.picker-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: min(720px, calc(100vw - 32px));\n max-height: min(80vh, 720px);\n z-index: 201;\n display: flex;\n flex-direction: column;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);\n animation: _ngcontent-%COMP%_pickerSlideUp 220ms cubic-bezier(0.16, 1, 0.3, 1);\n overflow: hidden;\n}\n\n@keyframes _ngcontent-%COMP%_pickerSlideUp {\n from {\n opacity: 0;\n transform: translate(-50%, calc(-50% + 16px));\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n.picker-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.picker-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.picker-close[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 14px;\n transition: background 0.15s, color 0.15s;\n}\n\n.picker-close[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-close[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.picker-search[_ngcontent-%COMP%] {\n position: relative;\n padding: 14px 20px 0 20px;\n}\n\n.picker-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 32px;\n transform: translateY(-30%);\n color: var(--test-text-muted);\n font-size: 13px;\n pointer-events: none;\n}\n\n.picker-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n font-size: 14px;\n color: var(--test-text);\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-search-clear[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n right: 32px;\n transform: translateY(-30%);\n width: 22px;\n height: 22px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 11px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.picker-search-clear[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-toolbar-status[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.picker-toolbar-status[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary-hover);\n font-weight: 700;\n}\n\n.picker-toolbar-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 14px;\n}\n\n.picker-link-btn[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n color: var(--test-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n padding: 0;\n font-family: inherit;\n}\n\n.picker-link-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n text-decoration: underline;\n}\n\n.picker-link-btn[_ngcontent-%COMP%]:disabled {\n color: var(--test-text-muted);\n cursor: not-allowed;\n}\n\n.picker-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 8px 12px;\n min-height: 200px;\n}\n\n.picker-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.picker-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n padding: 40px 20px;\n color: var(--test-text-muted);\n}\n\n.picker-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 14px;\n color: var(--test-text-muted);\n}\n\n.picker-empty[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 6px 0;\n font-size: 15px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.picker-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n}\n\n.picker-list[_ngcontent-%COMP%] {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.picker-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.12s, border-color 0.12s;\n border: 1px solid transparent;\n}\n\n.picker-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n}\n\n.picker-row[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-row--selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--test-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.picker-row--selected[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--test-surface));\n}\n\n.picker-check[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 1.5px solid var(--test-border);\n background: var(--test-surface);\n color: var(--mj-text-inverse, white);\n font-size: 11px;\n flex-shrink: 0;\n transition: background 0.12s, border-color 0.12s;\n}\n\n.picker-row--selected[_ngcontent-%COMP%] .picker-check[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-row-main[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.picker-row-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.picker-row-desc[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: 2px;\n}\n\n.picker-row-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.picker-row-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-secondary);\n border: 1px solid var(--test-border);\n}\n\n.picker-row-pill--status[data-status=\"active\"][_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n}\n\n.picker-row-pill--status[data-status=\"disabled\"][_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-muted);\n}\n\n.picker-row-pill--status[data-status=\"pending\"][_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.picker-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding: 14px 20px;\n border-top: 1px solid var(--test-border);\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n}\n\n.picker-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.picker-btn--primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-btn--primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.picker-btn--ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.picker-btn--ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n@media (max-width: 640px) {\n .picker-dialog[_ngcontent-%COMP%] {\n width: calc(100vw - 16px);\n max-height: calc(100vh - 32px);\n }\n .tests-actionbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n .tests-actionbar-actions[_ngcontent-%COMP%] {\n justify-content: flex-end;\n }\n .test-remove-btn[_ngcontent-%COMP%] {\n opacity: 1; \n\n }\n}"], changeDetection: 0 }); }
3530
4386
  };
3531
4387
  MJTestSuiteFormComponentExtended = __decorate([
3532
4388
  RegisterClass(BaseFormComponent, 'MJ: Test Suites')
@@ -3534,13 +4390,16 @@ MJTestSuiteFormComponentExtended = __decorate([
3534
4390
  export { MJTestSuiteFormComponentExtended };
3535
4391
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJTestSuiteFormComponentExtended, [{
3536
4392
  type: Component,
3537
- args: [{ standalone: false, selector: 'mj-test-suite-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-form\">\n <!-- Header Section -->\n <div class=\"suite-header\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <i class=\"fas fa-layer-group\"></i>\n <span>{{ record.Name }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-info\">\n <h1>{{ record.Name }}</h1>\n <div class=\"suite-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"record.Status === 'Active' ? 'fa-circle-check' : 'fa-circle-pause'\"></i>\n {{ record.Status }}\n </span>\n @if (testsLoaded) {\n <span class=\"test-count\">\n <i class=\"fas fa-flask\"></i>\n {{ suiteTests.length }} tests\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button mjButton (click)=\"exportToExcel()\" title=\"Export to CSV\">\n <i class=\"fas fa-file-excel\"></i> Export\n </button>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n @if (record.Description) {\n <div class=\"suite-description\">\n <p>{{ record.Description }}</p>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i> Overview\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'tests'\"\n (click)=\"changeTab('tests')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tests'\">\n <i class=\"fas fa-flask\"></i> Tests\n @if (testsLoaded) {\n <span class=\"tab-badge\">{{ suiteTests.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-history\"></i> Runs\n @if (runsLoaded) {\n <span class=\"tab-badge\">{{ suiteRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'analytics'\"\n (click)=\"changeTab('analytics')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'analytics'\">\n <i class=\"fas fa-chart-line\"></i> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'compare'\"\n (click)=\"changeTab('compare')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'compare'\">\n <i class=\"fas fa-balance-scale\"></i> Compare\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\">\n <div class=\"info-section\">\n <h3><i class=\"fas fa-info-circle\"></i> Suite Information</h3>\n <div class=\"info-grid\">\n <div class=\"info-item\">\n <div class=\"info-label\">Name</div>\n <div class=\"info-value\">{{ record.Name }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Status</div>\n <div class=\"info-value\">\n <span class=\"status-badge-inline\" [ngClass]=\"getStatusClass()\">{{ record.Status }}</span>\n </div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Created</div>\n <div class=\"info-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Updated</div>\n <div class=\"info-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Max Execution Time</div>\n <div class=\"info-value\">{{ formatTimeout(record.MaxExecutionTimeMS) }}</div>\n </div>\n </div>\n </div>\n <div class=\"config-section\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n <div class=\"config-grid\">\n <div class=\"config-item\">\n <label>Max Execution Time (ms)</label>\n <input type=\"number\" [(ngModel)]=\"record.MaxExecutionTimeMS\" class=\"config-input\" placeholder=\"Default: 300000 (5 min)\" />\n <span class=\"config-hint\">Default timeout for tests in this suite</span>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Tests Tab -->\n @if (activeTab === 'tests') {\n <div class=\"tests-tab\">\n <!-- Loading State -->\n @if (loadingTests) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3,4,5]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-sequence\"></div>\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Tests List -->\n @if (!loadingTests && suiteTests.length > 0) {\n <div class=\"tests-list\">\n @for (test of suiteTests; track test) {\n <div class=\"test-item\" (click)=\"openTest(test.TestID)\">\n <div class=\"test-sequence\">{{ test.Sequence }}</div>\n <div class=\"test-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"test-content\">\n <div class=\"test-name\">{{ test.Test }}</div>\n <div class=\"test-status\">\n @if (test.Status) {\n <span><i class=\"fas fa-info-circle\"></i> {{ test.Status }}</span>\n }\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testsLoaded && !loadingTests && suiteTests.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-flask\"></i>\n </div>\n <h4>No Tests in Suite</h4>\n <p>Add tests to this suite to start running them together.</p>\n </div>\n }\n </div>\n }\n\n <!-- Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Loading State -->\n @if (loadingRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Runs List -->\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"runs-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-item\" (click)=\"openSuiteRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Completed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n @if (run.TotalTests) {\n <span>\n <i class=\"fas fa-check-circle\"></i> {{ run.PassedTests }}/{{ run.TotalTests }}\n ({{ getPassRate(run).toFixed(0) }}%)\n </span>\n }\n </div>\n <!-- Evaluation metrics row -->\n <div class=\"run-eval-metrics\">\n <!-- Status badge -->\n @if (evalPreferences.showExecution) {\n <span class=\"eval-metric status\" [class]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-circle-check]=\"run.Status === 'Completed'\"\n [class.fa-circle-xmark]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </span>\n }\n <!-- Human score (placeholder - need avg from suite run) -->\n @if (evalPreferences.showHuman) {\n <span class=\"eval-metric human\" title=\"Human evaluation\">\n <i class=\"fas fa-user\"></i>\n <span class=\"eval-pending\"><i class=\"fas fa-clock\"></i></span>\n </span>\n }\n <!-- Auto score (pass rate as proxy) -->\n @if (evalPreferences.showAuto && run.TotalTests) {\n <span class=\"eval-metric auto\"\n [class.high]=\"getPassRate(run) >= 80\"\n [class.medium]=\"getPassRate(run) >= 50 && getPassRate(run) < 80\"\n [class.low]=\"getPassRate(run) < 50\"\n title=\"Auto score (pass rate)\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ getPassRate(run).toFixed(0) }}%</span>\n </span>\n }\n </div>\n <!-- Tags display -->\n @if (getRunTags(run).length > 0) {\n <div class=\"run-tags\">\n @for (tag of getRunTags(run); track tag) {\n <span class=\"tag-chip\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (runsLoaded && !loadingRuns && suiteRuns.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <h4>No Suite Runs Yet</h4>\n <p>Run this suite to see execution history and results here.</p>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"analytics-tab\">\n <!-- Loading State -->\n @if (loadingAnalytics) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading analytics data...\"></mj-loading>\n </div>\n }\n @if (!loadingAnalytics && analyticsLoaded) {\n <!-- View Toggle Sub-nav -->\n <div class=\"analytics-subnav\">\n <div class=\"subnav-tabs\">\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'summary'\"\n (click)=\"setAnalyticsView('summary')\">\n <i class=\"fas fa-chart-bar\"></i>\n <span>Summary</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'matrix'\"\n (click)=\"setAnalyticsView('matrix')\">\n <i class=\"fas fa-th\"></i>\n <span>Matrix</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'chart'\"\n (click)=\"setAnalyticsView('chart')\">\n <i class=\"fas fa-project-diagram\"></i>\n <span>Chart</span>\n </button>\n </div>\n </div>\n <!-- Collapsible Filters (shared by both views) -->\n <div class=\"analytics-filters\" [class.collapsed]=\"filtersCollapsed\">\n <div class=\"filters-header\" (click)=\"toggleFilters()\">\n <span class=\"filters-title\">\n <i class=\"fas fa-filter\"></i>\n Filters\n @if (filtersCollapsed) {\n <span class=\"filter-summary\">\n {{ analyticsTimeRange === 'all' ? 'All Time' : analyticsTimeRange }}\n @if (selectedTags.length > 0) {\n <span> \u00B7 {{ selectedTags.length }} tags</span>\n }\n </span>\n }\n </span>\n <i class=\"fas\" [ngClass]=\"filtersCollapsed ? 'fa-chevron-down' : 'fa-chevron-up'\"></i>\n </div>\n @if (!filtersCollapsed) {\n <div class=\"filters-content\">\n <div class=\"filter-group\">\n <label>Time Range</label>\n <div class=\"filter-buttons\">\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '7d'\" (click)=\"setTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '30d'\" (click)=\"setTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '90d'\" (click)=\"setTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === 'all'\" (click)=\"setTimeRange('all')\">All Time</button>\n </div>\n </div>\n @if (uniqueTags.length > 0) {\n <div class=\"filter-group\">\n <label>Filter by Tag @if (selectedTags.length > 0) {\n <span class=\"filter-hint\">({{ selectedTags.length }} selected)</span>\n }</label>\n <div class=\"filter-buttons tag-filters\">\n <button class=\"filter-btn tag-btn all-tags-btn\"\n [class.active]=\"selectedTags.length === 0\"\n (click)=\"toggleTagFilter(null)\">\n <i class=\"fas fa-layer-group\"></i> All Tags\n </button>\n @for (tag of uniqueTags; track tag) {\n <button class=\"filter-btn tag-btn\"\n [class.active]=\"isTagSelected(tag)\"\n (click)=\"toggleTagFilter(tag)\">\n @if (isTagSelected(tag)) {\n <i class=\"fas fa-check\"></i>\n }\n {{ tag }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n <!-- Summary View -->\n @if (analyticsView === 'summary') {\n <!-- KPI Cards -->\n <div class=\"analytics-kpis\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\"><i class=\"fas fa-play-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon success\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getAveragePassRate().toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Pass Rate</div>\n <div class=\"kpi-trend\" [ngClass]=\"{'trend-up': getPassRateTrend().direction === 'up', 'trend-down': getPassRateTrend().direction === 'down'}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getPassRateTrend().direction === 'up', 'fa-arrow-down': getPassRateTrend().direction === 'down', 'fa-minus': getPassRateTrend().direction === 'stable'}\"></i>\n {{ getPassRateTrend().value.toFixed(1) }}%\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon info\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getAverageDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon warning\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getTotalCost()) }}</div>\n <div class=\"kpi-label\">Total Cost</div>\n </div>\n </div>\n </div>\n <!-- Runs Table -->\n <div class=\"analytics-table-section\">\n <h3><i class=\"fas fa-table\"></i> Run History</h3>\n <div class=\"analytics-table-wrapper\">\n <table class=\"analytics-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Status</th>\n <th>Pass Rate</th>\n <th>Tests</th>\n <th>Duration</th>\n <th>Cost</th>\n <th>Tags</th>\n </tr>\n </thead>\n <tbody>\n @for (dp of getFilteredAnalyticsData(); track dp) {\n <tr (click)=\"openSuiteRun(dp.runId)\" class=\"clickable-row\">\n <td>{{ dp.date | date:'short' }}</td>\n <td>\n <span class=\"status-chip\" [ngClass]=\"'status-' + dp.status.toLowerCase()\">{{ dp.status }}</span>\n </td>\n <td>\n <div class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\" [style.width.%]=\"dp.passRate\" [ngClass]=\"{'high': dp.passRate >= 80, 'medium': dp.passRate >= 50 && dp.passRate < 80, 'low': dp.passRate < 50}\"></div>\n <span>{{ dp.passRate.toFixed(0) }}%</span>\n </div>\n </td>\n <td>{{ dp.passedTests }}/{{ dp.totalTests }}</td>\n <td>{{ formatDuration(dp.duration) }}</td>\n <td>{{ formatCost(dp.cost) }}</td>\n <td>\n <div class=\"tag-cell\">\n @for (tag of dp.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-table\">{{ tag }}</span>\n }\n @if (dp.tags.length > 2) {\n <span class=\"tag-more\">+{{ dp.tags.length - 2 }}</span>\n }\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if (getFilteredAnalyticsData().length === 0) {\n <div class=\"empty-state small\">\n <p>No runs match the current filters.</p>\n </div>\n }\n </div>\n }\n <!-- Matrix View -->\n @if (analyticsView === 'matrix') {\n <!-- Loading Matrix -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading test matrix...\"></mj-loading>\n </div>\n }\n <!-- Matrix Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"matrix-section\">\n <div class=\"matrix-header\">\n <h3><i class=\"fas fa-th\"></i> Test Results Matrix</h3>\n <div class=\"matrix-header-right\">\n <div class=\"matrix-filter-input\">\n <i class=\"fas fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter tests...\"\n [value]=\"matrixTestFilter\"\n (input)=\"onMatrixFilterInput($event)\"\n class=\"filter-input\">\n @if (matrixTestFilter) {\n <button class=\"clear-filter-btn\" (click)=\"clearMatrixFilter()\" title=\"Clear filter\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n <span class=\"matrix-run-count\">{{ matrixData.length }} runs \u00B7 {{ getUniqueTestsFromMatrix().length }} tests</span>\n <button mjButton (click)=\"exportMatrixToCSV()\" [disabled]=\"matrixData.length === 0\" title=\"Export matrix to CSV\">\n <i class=\"fas fa-download\"></i> Export\n </button>\n </div>\n </div>\n <div class=\"matrix-scroll-container\">\n <table class=\"test-matrix\">\n <thead>\n <tr>\n <th class=\"seq-header\" (click)=\"toggleMatrixSort('sequence')\" title=\"Sort by sequence\">\n #\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'sequence' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"test-name-header\" (click)=\"toggleMatrixSort('name')\" title=\"Sort by name\">\n Test\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'name' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n @for (run of matrixData; track run) {\n <th class=\"run-header\" (click)=\"openSuiteRun(run.runId)\" [title]=\"'Click to view suite run - ' + (run.date | date:'medium')\">\n <div class=\"run-header-content\">\n @if (run.tags.length > 0) {\n <div class=\"run-tags-header\">\n @for (tag of run.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-header\">{{ tag }}</span>\n }\n @if (run.tags.length > 2) {\n <span class=\"tag-more-header\">+{{ run.tags.length - 2 }}</span>\n }\n </div>\n }\n <div class=\"run-date\">{{ getRelativeTime(run.date) }}</div>\n <div class=\"run-pass-rate\" [ngClass]=\"{'high': run.passRate >= 80, 'medium': run.passRate >= 50 && run.passRate < 80, 'low': run.passRate < 50}\">\n {{ run.passRate.toFixed(0) }}%\n </div>\n </div>\n </th>\n }\n <th class=\"spacer-header\"></th>\n </tr>\n </thead>\n <tbody>\n @for (test of getUniqueTestsFromMatrix(); track test) {\n <tr\n [class.row-selected]=\"selectedMatrixTestId === test.testId\"\n (click)=\"selectMatrixRow(test.testId)\">\n <td class=\"seq-cell\">{{ test.sequence }}</td>\n <td class=\"test-name-cell\">\n <span class=\"test-name\" [title]=\"test.testName\">{{ test.testName }}</span>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell\"\n [ngClass]=\"getMatrixCellClass(getTestResultForRun(run.runId, test.testId))\"\n [class.clickable]=\"getTestResultForRun(run.runId, test.testId)\"\n [class.cell-not-run]=\"!getTestResultForRun(run.runId, test.testId)\"\n [title]=\"getTestResultForRun(run.runId, test.testId)?.status + ' - Click to view test run' || 'Not Run'\"\n (click)=\"onMatrixCellClick(getTestResultForRun(run.runId, test.testId), $event)\">\n @if (getTestResultForRun(run.runId, test.testId); as result) {\n <div class=\"cell-eval-stack\">\n <!-- Status indicator -->\n @if (evalPreferences.showExecution) {\n <span class=\"cell-status\"\n [ngClass]=\"'status-' + result.status.toLowerCase()\"\n [class.cell-skipped-status]=\"result.status === 'Skipped' || result.status === 'Pending'\"\n [title]=\"getStatusTooltip(result.status)\">\n <i class=\"fas\"\n [class.fa-check]=\"result.status === 'Passed'\"\n [class.fa-times]=\"result.status === 'Failed'\"\n [class.fa-exclamation]=\"result.status === 'Error'\"\n [class.fa-hourglass-end]=\"result.status === 'Timeout'\"\n [class.fa-forward]=\"result.status === 'Skipped'\"\n [class.fa-spinner]=\"result.status === 'Running'\"\n [class.fa-clock]=\"result.status === 'Pending'\"></i>\n </span>\n }\n <!-- Human score - slashed icon if no feedback, colored by rating if has feedback -->\n @if (evalPreferences.showHuman && !result.humanRating) {\n <span class=\"cell-human no-feedback\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n }\n @if (evalPreferences.showHuman && result.humanRating) {\n <span class=\"cell-human has-feedback\"\n [class.rating-low]=\"result.humanRating <= 4\"\n [class.rating-medium]=\"result.humanRating >= 5 && result.humanRating <= 6\"\n [class.rating-good]=\"result.humanRating >= 7 && result.humanRating <= 8\"\n [class.rating-excellent]=\"result.humanRating >= 9\"\n [title]=\"getHumanTooltip(result.humanRating, result.humanComments)\">\n <i class=\"fas fa-user\"></i>\n <span class=\"rating-value\">{{ result.humanRating }}</span>\n </span>\n }\n <!-- Auto score - colored by percentage -->\n @if (evalPreferences.showAuto && result.score != null) {\n <span class=\"cell-auto has-score\"\n [class.score-low]=\"result.score < 0.5\"\n [class.score-medium]=\"result.score >= 0.5 && result.score < 0.7\"\n [class.score-good]=\"result.score >= 0.7 && result.score < 0.85\"\n [class.score-excellent]=\"result.score >= 0.85\"\n [title]=\"'Auto Score: ' + (result.score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span class=\"score-value\">{{ (result.score * 100).toFixed(0) }}</span>\n </span>\n }\n @if (evalPreferences.showAuto && result.score == null) {\n <span class=\"cell-auto no-score\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n }\n </div>\n }\n @if (!getTestResultForRun(run.runId, test.testId)) {\n <span class=\"cell-not-run-indicator\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n }\n </tbody>\n <!-- Footer row with totals -->\n <tfoot>\n <tr class=\"totals-row\">\n <td class=\"seq-cell totals-label\"></td>\n <td class=\"test-name-cell totals-label\">\n <strong>Totals</strong>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell totals-cell\">\n <div class=\"cell-eval-stack totals-stack\">\n <!-- Status totals -->\n @if (evalPreferences.showExecution) {\n <span class=\"totals-status\">\n <span class=\"pass-count\">{{ getRunPassedCount(run) }}/{{ getRunTotalCount(run) }}</span>\n </span>\n }\n <!-- Human totals -->\n @if (evalPreferences.showHuman) {\n <span class=\"totals-human\">\n @if (getRunHumanAvg(run) != null) {\n <span class=\"avg-label\">{{ getRunHumanAvg(run)?.toFixed(1) }}</span>\n }\n <span class=\"count-label\">({{ getRunHumanCount(run) }})</span>\n </span>\n }\n <!-- Auto totals -->\n @if (evalPreferences.showAuto) {\n <span class=\"totals-auto\">\n @if (getRunAutoAvg(run) != null) {\n <span class=\"avg-label\">{{ (getRunAutoAvg(run)! * 100).toFixed(0) }}%</span>\n }\n <span class=\"count-label\">({{ getRunAutoCount(run) }})</span>\n </span>\n }\n </div>\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n }\n <!-- Empty Matrix State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-th\"></i>\n </div>\n <h4>No Matrix Data</h4>\n <p>No suite runs match the current filters.</p>\n </div>\n }\n }\n <!-- Chart View -->\n @if (analyticsView === 'chart') {\n <!-- Loading Chart -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading chart data...\"></mj-loading>\n </div>\n }\n <!-- Chart Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"chart-section\">\n <div class=\"chart-header\">\n <h3><i class=\"fas fa-project-diagram\"></i> Test Results Flow</h3>\n <div class=\"chart-legend\">\n <span class=\"legend-item chart-passed\"><i class=\"fas fa-check\"></i> Passed</span>\n <span class=\"legend-item chart-failed\"><i class=\"fas fa-times\"></i> Failed</span>\n <span class=\"legend-item chart-error\"><i class=\"fas fa-exclamation\"></i> Error</span>\n <span class=\"legend-item chart-skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n <div class=\"chart-container\">\n <div #chartContainer class=\"d3-chart\"></div>\n </div>\n <div class=\"chart-info\">\n <i class=\"fas fa-info-circle\"></i>\n Interactive visualization showing test results across {{ matrixData.length }} runs.\n Hover over elements for details, click nodes to navigate.\n </div>\n </div>\n }\n <!-- Empty Chart State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-project-diagram\"></i>\n </div>\n <h4>No Chart Data</h4>\n <p>No suite runs match the current filters.</p>\n </div>\n }\n }\n }\n <!-- Empty State -->\n @if (!loadingAnalytics && analyticsLoaded && analyticsData.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-line\"></i>\n </div>\n <h4>No Analytics Data</h4>\n <p>Run this suite to start collecting analytics data.</p>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Compare Tab -->\n @if (activeTab === 'compare') {\n <div class=\"compare-tab\">\n <!-- Run Selection -->\n <div class=\"compare-selection\">\n <div class=\"compare-run-selector\">\n <h4>Run A (Baseline)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunA(run)\"\n (click)=\"selectCompareRunA(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunA) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunA = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunA.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunA).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n <div class=\"compare-vs\"><i class=\"fas fa-exchange-alt\"></i></div>\n <div class=\"compare-run-selector\">\n <h4>Run B (Compare)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunB(run)\"\n [class.disabled]=\"IsCompareRunA(run)\"\n (click)=\"!IsCompareRunA(run) && selectCompareRunB(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunB) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunB = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunB.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunB).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n </div>\n <!-- Comparison Results -->\n @if (compareRunA && compareRunB && !loadingCompare) {\n <div class=\"compare-results\">\n <!-- Summary Cards -->\n <div class=\"compare-summary\">\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Pass Rate Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getComparePassRateDiff()! > 0, 'negative': getComparePassRateDiff()! < 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getComparePassRateDiff()! > 0, 'fa-arrow-down': getComparePassRateDiff()! < 0, 'fa-minus': getComparePassRateDiff() === 0}\"></i>\n {{ getComparePassRateDiff()! > 0 ? '+' : '' }}{{ getComparePassRateDiff()?.toFixed(1) }}%\n </div>\n </div>\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Duration Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getCompareDurationDiff()! < 0, 'negative': getCompareDurationDiff()! > 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-down': getCompareDurationDiff()! < 0, 'fa-arrow-up': getCompareDurationDiff()! > 0, 'fa-minus': getCompareDurationDiff() === 0}\"></i>\n {{ formatDuration(getAbsCompareDurationDiff()) }}\n </div>\n </div>\n <div class=\"compare-summary-card improved\">\n <div class=\"summary-label\">Improved</div>\n <div class=\"summary-value\">{{ getCompareImprovedCount() }}</div>\n </div>\n <div class=\"compare-summary-card regressed\">\n <div class=\"summary-label\">Regressed</div>\n <div class=\"summary-value\">{{ getCompareRegressedCount() }}</div>\n </div>\n </div>\n <!-- Detailed Comparison Table -->\n <div class=\"compare-table-section\">\n <h3><i class=\"fas fa-list\"></i> Test-by-Test Comparison</h3>\n <div class=\"compare-table-wrapper\">\n <table class=\"compare-table\">\n <thead>\n <tr>\n <th>Test</th>\n <th>Run A Status</th>\n <th>Run B Status</th>\n <th>Score Diff</th>\n <th>Duration Diff</th>\n <th>Change</th>\n </tr>\n </thead>\n <tbody>\n @for (result of compareResults; track result) {\n <tr [ngClass]=\"{'improved': result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed', 'regressed': result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'}\">\n <td class=\"test-name-cell\">{{ result.testName }}</td>\n <td>\n @if (result.runA) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runA.status.toLowerCase()\">{{ result.runA.status }}</span>\n }\n @if (!result.runA) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.runB) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runB.status.toLowerCase()\">{{ result.runB.status }}</span>\n }\n @if (!result.runB) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.scoreDiff != null) {\n <span [ngClass]=\"{'positive': result.scoreDiff > 0, 'negative': result.scoreDiff < 0}\">\n {{ result.scoreDiff > 0 ? '+' : '' }}{{ (result.scoreDiff * 100).toFixed(1) }}%\n </span>\n }\n @if (result.scoreDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.durationDiff != null) {\n <span [ngClass]=\"{'positive': result.durationDiff < 0, 'negative': result.durationDiff > 0}\">\n {{ result.durationDiff > 0 ? '+' : '' }}{{ result.durationDiff.toFixed(1) }}s\n </span>\n }\n @if (result.durationDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed') {\n <span class=\"change-indicator improved\">\n <i class=\"fas fa-arrow-up\"></i> Fixed\n </span>\n }\n @if (result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed') {\n <span class=\"change-indicator regressed\">\n <i class=\"fas fa-arrow-down\"></i> Broke\n </span>\n }\n @if (!result.statusChanged) {\n <span class=\"change-indicator unchanged\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n }\n <!-- Loading State for Compare -->\n @if (loadingCompare) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading comparison data...\"></mj-loading>\n </div>\n }\n <!-- Empty State -->\n @if (!compareRunA || !compareRunB) {\n <div class=\"compare-empty\">\n <div class=\"compare-empty-icon\">\n <i class=\"fas fa-balance-scale\"></i>\n </div>\n <h4>Select Two Runs to Compare</h4>\n <p>Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.</p>\n </div>\n }\n <!-- No Runs State -->\n @if (runsLoaded && suiteRuns.length < 2) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-balance-scale\"></i>\n </div>\n <h4>Not Enough Runs to Compare</h4>\n <p>You need at least 2 suite runs to use the comparison feature.</p>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Toggle Button -->\n <button class=\"shortcuts-toggle\" (click)=\"toggleShortcuts()\" [title]=\"showShortcuts ? 'Hide keyboard shortcuts' : 'Show keyboard shortcuts'\">\n <i class=\"fas fa-keyboard\"></i>\n </button>\n\n <!-- Keyboard Shortcuts Hint (Desktop Only) -->\n @if (showShortcuts) {\n <div class=\"keyboard-shortcuts\">\n <div class=\"shortcuts-header\">\n <i class=\"fas fa-keyboard\"></i>\n Shortcuts\n <button class=\"shortcuts-close\" (click)=\"toggleShortcuts()\" title=\"Hide shortcuts\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcut-list\">\n <div class=\"shortcut-item\">\n <span>Refresh</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Run Suite</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Switch Tabs</span>\n <span class=\"shortcut-keys\"><kbd>1</kbd>-<kbd>5</kbd></span>\n </div>\n </div>\n </div>\n }\n\n <!-- Slide Panel for Suite Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n [Title]=\"testingDialogService.PanelOptions?.suiteId ? 'Suite Execution' : 'Run Suite'\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'suite'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n</div>\n", styles: ["/* ===========================\n Test Suite Form - World-Class UX\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-success: var(--mj-status-success);\n --test-error: var(--mj-status-error);\n --test-warning: var(--mj-status-warning);\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-secondary);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header */\n.suite-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.suite-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.suite-icon:hover { transform: scale(1.05); }\n\n.suite-info { flex: 1; min-width: 0; }\n\n.suite-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n word-wrap: break-word;\n}\n\n.suite-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active { background: var(--test-success); }\n.status-badge.status-disabled { background: var(--test-disabled); }\n.status-badge.status-pending { background: var(--test-warning); }\n\n.status-badge-inline {\n display: inline-flex;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-count {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.suite-description {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* Tabs */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar { display: none; }\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Overview Tab */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.info-section, .config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3, .config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i, .config-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 500;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n/* Tests Tab */\n.tests-tab, .runs-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.loading-state { padding: 0; }\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-sequence {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-icon {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n.tests-list, .runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item, .run-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.test-item:hover, .run-item:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon, .run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.test-icon {\n background: var(--test-primary);\n}\n\n.test-content, .run-content { flex: 1; min-width: 0; }\n\n.test-name, .run-header {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id { font-weight: 600; }\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status, .run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status span, .run-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item > i, .run-item > i {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item:hover > i, .run-item:hover > i {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Empty States */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n/* Keyboard Shortcuts */\n/* Keyboard shortcuts toggle button - visible when shortcuts are hidden */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: var(--test-text-secondary);\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .keyboard-shortcuts, .shortcuts-toggle { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header { padding: 16px; }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button { flex: 1; }\n\n .tab-shortcut { display: none; }\n\n .info-grid { grid-template-columns: 1fr; }\n\n .test-item, .run-item { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info h1 { font-size: 16px; }\n\n .tab-badge { display: none; }\n\n .test-sequence { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item:active, .run-item:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n transform: scale(0.98);\n }\n\n .tab { min-height: 48px; }\n .test-item, .run-item { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions, .tabs-container, .keyboard-shortcuts {\n display: none !important;\n }\n}\n\n/* ===========================\n Tags UI\n =========================== */\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-mini {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.tag-more {\n font-size: 10px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n/* Evaluation metrics row for Runs list */\n.run-eval-metrics {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-metric.status.status-completed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-metric.status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-metric.status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.status.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human .eval-pending {\n font-size: 9px;\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n color: var(--mj-status-success);\n}\n\n.eval-metric.auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n color: var(--mj-status-error);\n}\n\n.tag-cell {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ===========================\n Analytics Tab\n =========================== */\n.analytics-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Collapsible filters */\n.analytics-filters {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-bottom: 16px;\n box-shadow: var(--test-shadow-sm);\n overflow: hidden;\n}\n\n.analytics-filters.collapsed {\n margin-bottom: 12px;\n}\n\n.filters-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n}\n\n.filters-header:hover {\n background: var(--test-bg);\n}\n\n.filters-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.filters-title i {\n color: var(--test-primary);\n}\n\n.filter-summary {\n font-weight: 400;\n color: var(--test-text-muted);\n margin-left: 8px;\n}\n\n.filters-header > i {\n color: var(--test-text-muted);\n font-size: 12px;\n}\n\n.filters-content {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.filter-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n border-color: var(--test-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.tag-btn {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn i.fa-check {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn i {\n font-size: 11px;\n}\n\n.filter-hint {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters {\n max-height: 120px;\n overflow-y: auto;\n}\n\n/* KPI Cards */\n.analytics-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-icon.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.kpi-icon.warning {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n/* Analytics Table */\n.analytics-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.analytics-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section h3 i {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table tbody tr.clickable-row {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table tbody tr.clickable-row:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-passed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-failed { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--test-error); }\n.status-chip.status-error { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--test-primary); }\n.status-chip.status-pending { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-chip.status-cancelled { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n.status-chip.status-missing { background: var(--mj-bg-surface-sunken); color: var(--test-text-muted); }\n.status-chip.status-timeout { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-skipped { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n\n.pass-rate-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium { background: var(--test-warning); }\n.pass-rate-bar.low { background: var(--test-error); }\n\n/* Analytics Sub-navigation */\n.analytics-subnav {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.subnav-tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.subnav-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab i {\n font-size: 14px;\n}\n\n/* Matrix View */\n.matrix-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header h3 i {\n color: var(--test-primary);\n}\n\n.matrix-run-count {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n/* Matrix filter input */\n.matrix-filter-input {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input i.fa-search {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.matrix-filter-input .filter-input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input .filter-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.clear-filter-btn {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n/* Scrollable matrix container with fixed height */\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix thead {\n display: table-header-group;\n}\n\n.test-matrix thead tr {\n display: table-row;\n}\n\n.test-matrix tbody {\n display: table-row-group;\n}\n\n.test-matrix tbody tr {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix tbody tr:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.test-matrix tbody tr.row-selected {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tbody tr.row-selected td {\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.test-matrix tbody tr.row-selected .seq-cell,\n.test-matrix tbody tr.row-selected .test-name-cell {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tfoot {\n display: table-footer-group;\n}\n\n.test-matrix th,\n.test-matrix td {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix th {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid var(--mj-text-secondary) !important;\n}\n\n/* Sequence column - shared styles */\n.test-matrix .seq-header,\n.test-matrix .seq-cell {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n/* Seq header - sticky top AND left, highest z-index */\n.test-matrix .seq-header {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; /* Higher than other headers */\n top: 0;\n}\n\n/* Seq body cells - sticky left only, lower z-index */\n.test-matrix .seq-cell {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix .seq-header i {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix .seq-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .test-name-header {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix .test-name-header i {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix .test-name-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .run-header {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n/* Spacer column absorbs extra width */\n.test-matrix .spacer-header,\n.test-matrix .spacer-cell {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix .spacer-cell {\n background: var(--test-surface);\n}\n\n.test-matrix .run-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-header-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.run-pass-rate.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.run-pass-rate.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.run-tags {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny {\n font-size: 9px;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Matrix column header tags - emphasized */\n.run-tags-header {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix .test-name-cell {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable {\n cursor: pointer;\n}\n\n.result-cell.clickable:hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n z-index: 5;\n}\n\n.result-cell i {\n font-size: 14px;\n}\n\n/* Completed cells have neutral white background - pills tell the story */\n.result-cell.cell-passed,\n.result-cell.cell-failed,\n.result-cell.cell-error,\n.result-cell.cell-timeout,\n.result-cell.cell-running,\n.result-cell.cell-pending {\n background: var(--mj-bg-surface);\n color: var(--test-text);\n}\n\n/* Skipped/not-run cells get hatched background */\n.result-cell.cell-skipped {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none {\n background: var(--mj-bg-surface-card);\n color: var(--test-text-muted);\n}\n\n.cell-score {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* Matrix cell evaluation stack - shows multiple eval types horizontally */\n.cell-eval-stack {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval {\n min-width: 120px;\n width: auto;\n}\n\n/* Add timeout status icon */\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-status.status-pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n font-size: 10px;\n}\n\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-none-indicator {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Chart View\n =========================== */\n.chart-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header h3 i {\n color: var(--test-primary);\n}\n\n.chart-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend .legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend .legend-item.chart-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.chart-legend .legend-item.chart-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.chart-legend .legend-item.chart-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.chart-legend .legend-item.chart-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-disabled);\n}\n\n.chart-container {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart svg {\n width: 100%;\n height: 100%;\n}\n\n/* D3 Chart Node Styles */\n.d3-chart .node {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart .node:hover {\n transform: scale(1.05);\n}\n\n.d3-chart .node-label {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart .link {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart .link:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart .tooltip {\n position: absolute;\n padding: 10px 14px;\n background: var(--mj-bg-overlay);\n color: var(--mj-text-inverse);\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: var(--mj-shadow-lg);\n max-width: 250px;\n}\n\n.d3-chart .tooltip-title {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart .tooltip-value {\n opacity: 0.8;\n}\n\n.chart-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Compare Tab\n =========================== */\n.compare-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-selection {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item:hover {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-selector-item.selected {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.run-selector-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn:hover { text-decoration: underline; }\n\n.preview-details {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n/* Compare Results */\n.compare-results {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card .summary-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card .summary-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card .summary-value.positive { color: var(--test-success); }\n.compare-summary-card .summary-value.negative { color: var(--test-error); }\n\n.compare-summary-card.improved {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved .summary-value { color: var(--test-success); }\n\n.compare-summary-card.regressed {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed .summary-value { color: var(--test-error); }\n\n/* Compare Table */\n.compare-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section h3 i {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper {\n overflow-x: auto;\n}\n\n.compare-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table tbody tr.improved {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n}\n\n.compare-table tbody tr.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 5%, transparent);\n}\n\n.test-name-cell {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive { color: var(--test-success); }\n.negative { color: var(--test-error); }\n.muted { color: var(--test-text-muted); }\n\n.change-indicator {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.change-indicator.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.change-indicator.unchanged {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-muted);\n}\n\n/* Compare Empty State */\n.compare-empty {\n text-align: center;\n padding: 60px 24px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-top: 24px;\n}\n\n.compare-empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin: 0 auto 20px;\n}\n\n.compare-empty-icon i {\n font-size: 32px;\n color: var(--test-text-muted);\n}\n\n.compare-empty h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.compare-empty p {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 400px;\n margin: 0 auto;\n}\n\n/* Small empty state variant */\n.empty-state.small {\n padding: 32px 16px;\n}\n\n.empty-state.small p {\n margin: 0;\n}\n\n/* ===========================\n Responsive Analytics/Compare\n =========================== */\n@media (max-width: 1024px) {\n .compare-selection {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons {\n flex-direction: column;\n }\n\n .filter-btn {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 16px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .compare-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper,\n .compare-table-wrapper {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card .summary-value {\n font-size: 20px;\n }\n\n .analytics-table th,\n .analytics-table td,\n .compare-table th,\n .compare-table td {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n/* ===========================\n Matrix Evaluation Indicators\n =========================== */\n\n/* Human Feedback Indicators */\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-human.no-feedback i {\n font-size: 11px;\n}\n\n.cell-human.has-feedback {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback i {\n font-size: 9px;\n}\n\n.cell-human.has-feedback .rating-value {\n font-weight: 700;\n font-size: 11px;\n}\n\n/* Human rating color coding: red \u22644, yellow 5-6, light-green 7-8, green 9-10 */\n.cell-human.rating-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-human.rating-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-human.rating-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-human.rating-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Auto Score Indicators */\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-auto.no-score i {\n font-size: 11px;\n}\n\n.cell-auto.has-score {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score i {\n font-size: 9px;\n}\n\n.cell-auto.has-score .score-value {\n font-weight: 700;\n font-size: 10px;\n}\n\n/* Auto score color coding (0-100%): red <50, yellow 50-69, light-green 70-84, green 85+ */\n.cell-auto.score-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-auto.score-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.score-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.score-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Status indicators in matrix cells */\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped,\n.cell-status.status-pending {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Not-run / Skipped cells with hatch pattern */\n.result-cell.cell-not-run {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--mj-text-disabled);\n}\n\n.result-cell.cell-not-run .cell-eval-stack {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: var(--mj-text-disabled);\n font-size: 11px;\n}\n\n/* ===========================\n Matrix Totals Footer Row\n =========================== */\n.test-matrix tfoot {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row {\n background: var(--mj-bg-surface-sunken);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row td {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row .totals-label {\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row .totals-cell {\n background: var(--mj-bg-surface-sunken);\n}\n\n.totals-stack {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status,\n.totals-human,\n.totals-auto {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.totals-status .pass-count {\n font-weight: 700;\n}\n\n.totals-human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.totals-human .avg-label {\n font-weight: 700;\n}\n\n.totals-human .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.totals-auto .avg-label {\n font-weight: 700;\n}\n\n.totals-auto .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n"] }]
4393
+ args: [{ standalone: false, selector: 'mj-test-suite-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-form\">\n <!-- Header Section -->\n <div class=\"suite-header\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <i class=\"fas fa-layer-group\"></i>\n <span>{{ record.Name }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-info\">\n <h1>\n {{ record.Name }}\n @if (isDirty) {\n <span class=\"dirty-indicator\" title=\"You have unsaved changes\" aria-label=\"Unsaved changes\">\u25CF</span>\n }\n </h1>\n <div class=\"suite-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"record.Status === 'Active' ? 'fa-circle-check' : 'fa-circle-pause'\"></i>\n {{ record.Status }}\n </span>\n @if (testsLoaded) {\n <span class=\"test-count\">\n <i class=\"fas fa-flask\"></i>\n {{ suiteTests.length }} tests\n </span>\n }\n @if (isDirty) {\n <span class=\"unsaved-pill\" title=\"You have unsaved changes\">\n <i class=\"fas fa-circle\"></i> Unsaved\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button mjButton (click)=\"exportToExcel()\" title=\"Export to CSV\">\n <i class=\"fas fa-file-excel\"></i> Export\n </button>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite\n </button>\n <button mjButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n @if (record.Description) {\n <div class=\"suite-description\">\n <p>{{ record.Description }}</p>\n </div>\n }\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i> Overview\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'tests'\"\n (click)=\"changeTab('tests')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tests'\">\n <i class=\"fas fa-flask\"></i> Tests\n @if (testsLoaded) {\n <span class=\"tab-badge\">{{ suiteTests.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-history\"></i> Runs\n @if (runsLoaded) {\n <span class=\"tab-badge\">{{ suiteRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'analytics'\"\n (click)=\"changeTab('analytics')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'analytics'\">\n <i class=\"fas fa-chart-line\"></i> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'compare'\"\n (click)=\"changeTab('compare')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'compare'\">\n <i class=\"fas fa-balance-scale\"></i> Compare\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\" [class.has-savebar]=\"isDirty\">\n <!-- Overview Tab -->\n @if (activeTab === 'overview') {\n <div class=\"overview-tab\">\n <!-- Editable Details -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-pen-to-square\"></i> Details</h3>\n <p class=\"edit-section-sub\">Edit any field \u2014 changes are saved with the bar at the bottom.</p>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-name\">Name <span class=\"required\">*</span></label>\n <input\n id=\"suite-name\"\n type=\"text\"\n class=\"config-input\"\n placeholder=\"e.g., Core Agent Test Suite\"\n [(ngModel)]=\"record.Name\"\n />\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-description\">Description</label>\n <textarea\n id=\"suite-description\"\n class=\"config-input config-textarea\"\n rows=\"3\"\n placeholder=\"What does this suite cover?\"\n [ngModel]=\"record.Description\"\n (ngModelChange)=\"record.Description = $event || null\"\n ></textarea>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-status\">Status</label>\n <div class=\"select-wrapper\">\n <select\n id=\"suite-status\"\n class=\"config-input\"\n [(ngModel)]=\"record.Status\"\n >\n @for (opt of statusOptions; track opt) {\n <option [ngValue]=\"opt\">{{ opt }}</option>\n }\n </select>\n </div>\n </div>\n\n <div class=\"edit-field\">\n <label for=\"suite-parent\">Parent Suite</label>\n <select\n id=\"suite-parent\"\n class=\"config-input\"\n [ngModel]=\"record.ParentID\"\n (ngModelChange)=\"record.ParentID = $event || null\"\n >\n <option [ngValue]=\"null\">\u2014 None (top-level) \u2014</option>\n @for (s of parentSuiteOptions; track s.ID) {\n <option [ngValue]=\"s.ID\">{{ s.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"edit-field edit-field--full\">\n <label for=\"suite-tags\">Tags</label>\n <div class=\"tag-editor\" (click)=\"tagInput.focus()\">\n @for (tag of tags; track tag) {\n <span class=\"tag-chip-editable\">\n {{ tag }}\n <button type=\"button\" class=\"tag-remove\" (click)=\"removeTag(tag); $event.stopPropagation()\" [attr.aria-label]=\"'Remove tag ' + tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n <input\n #tagInput\n id=\"suite-tags\"\n type=\"text\"\n class=\"tag-input-inline\"\n [placeholder]=\"tags.length === 0 ? 'Add tags, press Enter or comma...' : ''\"\n [(ngModel)]=\"tagDraft\"\n (keydown)=\"onTagInputKeydown($event)\"\n (blur)=\"addTagFromDraft()\"\n />\n </div>\n <span class=\"config-hint\">Press Enter or comma to add a tag. Backspace on empty input removes the last tag.</span>\n </div>\n </div>\n </section>\n\n <!-- Execution Settings -->\n <section class=\"edit-section\">\n <header class=\"edit-section-header\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n </header>\n <div class=\"edit-grid\">\n <div class=\"edit-field\">\n <label for=\"suite-timeout\">Max Execution Time (ms)</label>\n <input\n id=\"suite-timeout\"\n type=\"number\"\n class=\"config-input\"\n placeholder=\"Default: 300000 (5 min)\"\n [ngModel]=\"record.MaxExecutionTimeMS\"\n (ngModelChange)=\"record.MaxExecutionTimeMS = $event === '' || $event === null ? null : +$event\"\n />\n <span class=\"config-hint\">Default timeout for tests in this suite. Currently: {{ formatTimeout(record.MaxExecutionTimeMS) }}</span>\n </div>\n </div>\n </section>\n\n <!-- Metadata (read-only) -->\n <section class=\"meta-section\">\n <div class=\"meta-grid\">\n <div class=\"meta-item\">\n <div class=\"meta-label\">Created</div>\n <div class=\"meta-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Last updated</div>\n <div class=\"meta-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n <div class=\"meta-item\">\n <div class=\"meta-label\">Suite ID</div>\n <div class=\"meta-value meta-mono\">{{ record.ID }}</div>\n </div>\n </div>\n </section>\n </div>\n }\n\n <!-- Tests Tab -->\n @if (activeTab === 'tests') {\n <div class=\"tests-tab\">\n <!-- Header: action bar -->\n <div class=\"tests-actionbar\">\n <div class=\"tests-actionbar-text\">\n <strong>Suite tests</strong>\n @if (testsLoaded) {\n <span class=\"tests-actionbar-count\">{{ suiteTests.length }}</span>\n }\n <span class=\"tests-actionbar-hint\">Drag to reorder \u00B7 Hover a row to remove</span>\n </div>\n <div class=\"tests-actionbar-actions\">\n <button mjButton variant=\"primary\" (click)=\"openAddTestsDialog()\" [disabled]=\"isReorderingTests\">\n <i class=\"fas fa-plus\"></i> Add tests\n </button>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (loadingTests) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3,4,5]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-sequence\"></div>\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Tests List -->\n @if (!loadingTests && suiteTests.length > 0) {\n <div class=\"tests-list\" cdkDropList (cdkDropListDropped)=\"onTestDrop($event)\">\n @for (test of suiteTests; track test.ID) {\n <div class=\"test-item\" cdkDrag [cdkDragDisabled]=\"isReorderingTests || isRemovingTest\">\n <span class=\"test-drag-handle\" cdkDragHandle title=\"Drag to reorder\" aria-label=\"Drag to reorder\">\n <i class=\"fas fa-grip-vertical\"></i>\n </span>\n <div class=\"test-sequence\">{{ test.Sequence }}</div>\n <div class=\"test-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"test-content\" (click)=\"openTest(test.TestID)\">\n <div class=\"test-name\">{{ test.Test }}</div>\n <div class=\"test-status\">\n @if (test.Status) {\n <span><i class=\"fas fa-info-circle\"></i> {{ test.Status }}</span>\n }\n </div>\n </div>\n <!-- Inline remove confirm OR hover-reveal X -->\n @if (confirmingRemoveSuiteTestId === test.ID) {\n <div class=\"test-remove-confirm\" (click)=\"$event.stopPropagation()\">\n <span class=\"test-remove-confirm-text\">Remove from suite?</span>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--danger\"\n (click)=\"confirmRemoveTest(test, $event)\"\n [disabled]=\"isRemovingTest\"\n >\n @if (isRemovingTest) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n } @else {\n Remove\n }\n </button>\n <button\n type=\"button\"\n class=\"test-remove-confirm-btn test-remove-confirm-btn--ghost\"\n (click)=\"cancelRemoveTest($event)\"\n [disabled]=\"isRemovingTest\"\n >\n Cancel\n </button>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"test-remove-btn\"\n title=\"Remove from suite\"\n aria-label=\"Remove from suite\"\n (click)=\"requestRemoveTest(test, $event)\"\n >\n <i class=\"fas fa-times\"></i>\n </button>\n <i class=\"fas fa-chevron-right test-chevron\" (click)=\"openTest(test.TestID)\"></i>\n }\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testsLoaded && !loadingTests && suiteTests.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-flask\"></i>\n </div>\n <h4>No Tests in Suite</h4>\n <p>Add tests to this suite to start running them together.</p>\n <button mjButton variant=\"primary\" (click)=\"openAddTestsDialog()\">\n <i class=\"fas fa-plus\"></i> Add tests\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Loading State -->\n @if (loadingRuns) {\n <div class=\"loading-state\">\n <div class=\"skeleton-list\">\n @for (i of [1,2,3]; track i) {\n <div class=\"skeleton-card\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Runs List -->\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"runs-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-item\" (click)=\"openSuiteRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Completed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n @if (run.TotalTests) {\n <span>\n <i class=\"fas fa-check-circle\"></i> {{ run.PassedTests }}/{{ run.TotalTests }}\n ({{ getPassRate(run).toFixed(0) }}%)\n </span>\n }\n </div>\n <!-- Evaluation metrics row -->\n <div class=\"run-eval-metrics\">\n <!-- Status badge -->\n @if (evalPreferences.showExecution) {\n <span class=\"eval-metric status\" [class]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-circle-check]=\"run.Status === 'Completed'\"\n [class.fa-circle-xmark]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </span>\n }\n <!-- Human score (placeholder - need avg from suite run) -->\n @if (evalPreferences.showHuman) {\n <span class=\"eval-metric human\" title=\"Human evaluation\">\n <i class=\"fas fa-user\"></i>\n <span class=\"eval-pending\"><i class=\"fas fa-clock\"></i></span>\n </span>\n }\n <!-- Auto score (pass rate as proxy) -->\n @if (evalPreferences.showAuto && run.TotalTests) {\n <span class=\"eval-metric auto\"\n [class.high]=\"getPassRate(run) >= 80\"\n [class.medium]=\"getPassRate(run) >= 50 && getPassRate(run) < 80\"\n [class.low]=\"getPassRate(run) < 50\"\n title=\"Auto score (pass rate)\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ getPassRate(run).toFixed(0) }}%</span>\n </span>\n }\n </div>\n <!-- Tags display -->\n @if (getRunTags(run).length > 0) {\n <div class=\"run-tags\">\n @for (tag of getRunTags(run); track tag) {\n <span class=\"tag-chip\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (runsLoaded && !loadingRuns && suiteRuns.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <h4>No Suite Runs Yet</h4>\n <p>Run this suite to see execution history and results here.</p>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"analytics-tab\">\n <!-- Loading State -->\n @if (loadingAnalytics) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading analytics data...\"></mj-loading>\n </div>\n }\n @if (!loadingAnalytics && analyticsLoaded) {\n <!-- View Toggle Sub-nav -->\n <div class=\"analytics-subnav\">\n <div class=\"subnav-tabs\">\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'summary'\"\n (click)=\"setAnalyticsView('summary')\">\n <i class=\"fas fa-chart-bar\"></i>\n <span>Summary</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'matrix'\"\n (click)=\"setAnalyticsView('matrix')\">\n <i class=\"fas fa-th\"></i>\n <span>Matrix</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'chart'\"\n (click)=\"setAnalyticsView('chart')\">\n <i class=\"fas fa-project-diagram\"></i>\n <span>Chart</span>\n </button>\n </div>\n </div>\n <!-- Collapsible Filters (shared by both views) -->\n <div class=\"analytics-filters\" [class.collapsed]=\"filtersCollapsed\">\n <div class=\"filters-header\" (click)=\"toggleFilters()\">\n <span class=\"filters-title\">\n <i class=\"fas fa-filter\"></i>\n Filters\n @if (filtersCollapsed) {\n <span class=\"filter-summary\">\n {{ analyticsTimeRange === 'all' ? 'All Time' : analyticsTimeRange }}\n @if (selectedTags.length > 0) {\n <span> \u00B7 {{ selectedTags.length }} tags</span>\n }\n </span>\n }\n </span>\n <i class=\"fas\" [ngClass]=\"filtersCollapsed ? 'fa-chevron-down' : 'fa-chevron-up'\"></i>\n </div>\n @if (!filtersCollapsed) {\n <div class=\"filters-content\">\n <div class=\"filter-group\">\n <label>Time Range</label>\n <div class=\"filter-buttons\">\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '7d'\" (click)=\"setTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '30d'\" (click)=\"setTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '90d'\" (click)=\"setTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === 'all'\" (click)=\"setTimeRange('all')\">All Time</button>\n </div>\n </div>\n @if (uniqueTags.length > 0) {\n <div class=\"filter-group\">\n <label>Filter by Tag @if (selectedTags.length > 0) {\n <span class=\"filter-hint\">({{ selectedTags.length }} selected)</span>\n }</label>\n <div class=\"filter-buttons tag-filters\">\n <button class=\"filter-btn tag-btn all-tags-btn\"\n [class.active]=\"selectedTags.length === 0\"\n (click)=\"toggleTagFilter(null)\">\n <i class=\"fas fa-layer-group\"></i> All Tags\n </button>\n @for (tag of uniqueTags; track tag) {\n <button class=\"filter-btn tag-btn\"\n [class.active]=\"isTagSelected(tag)\"\n (click)=\"toggleTagFilter(tag)\">\n @if (isTagSelected(tag)) {\n <i class=\"fas fa-check\"></i>\n }\n {{ tag }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n <!-- Summary View -->\n @if (analyticsView === 'summary') {\n <!-- KPI Cards -->\n <div class=\"analytics-kpis\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\"><i class=\"fas fa-play-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon success\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getAveragePassRate().toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Pass Rate</div>\n <div class=\"kpi-trend\" [ngClass]=\"{'trend-up': getPassRateTrend().direction === 'up', 'trend-down': getPassRateTrend().direction === 'down'}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getPassRateTrend().direction === 'up', 'fa-arrow-down': getPassRateTrend().direction === 'down', 'fa-minus': getPassRateTrend().direction === 'stable'}\"></i>\n {{ getPassRateTrend().value.toFixed(1) }}%\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon info\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getAverageDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon warning\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getTotalCost()) }}</div>\n <div class=\"kpi-label\">Total Cost</div>\n </div>\n </div>\n </div>\n <!-- Runs Table -->\n <div class=\"analytics-table-section\">\n <h3><i class=\"fas fa-table\"></i> Run History</h3>\n <div class=\"analytics-table-wrapper\">\n <table class=\"analytics-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Status</th>\n <th>Pass Rate</th>\n <th>Tests</th>\n <th>Duration</th>\n <th>Cost</th>\n <th>Tags</th>\n </tr>\n </thead>\n <tbody>\n @for (dp of getFilteredAnalyticsData(); track dp) {\n <tr (click)=\"openSuiteRun(dp.runId)\" class=\"clickable-row\">\n <td>{{ dp.date | date:'short' }}</td>\n <td>\n <span class=\"status-chip\" [ngClass]=\"'status-' + dp.status.toLowerCase()\">{{ dp.status }}</span>\n </td>\n <td>\n <div class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\" [style.width.%]=\"dp.passRate\" [ngClass]=\"{'high': dp.passRate >= 80, 'medium': dp.passRate >= 50 && dp.passRate < 80, 'low': dp.passRate < 50}\"></div>\n <span>{{ dp.passRate.toFixed(0) }}%</span>\n </div>\n </td>\n <td>{{ dp.passedTests }}/{{ dp.totalTests }}</td>\n <td>{{ formatDuration(dp.duration) }}</td>\n <td>{{ formatCost(dp.cost) }}</td>\n <td>\n <div class=\"tag-cell\">\n @for (tag of dp.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-table\">{{ tag }}</span>\n }\n @if (dp.tags.length > 2) {\n <span class=\"tag-more\">+{{ dp.tags.length - 2 }}</span>\n }\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if (getFilteredAnalyticsData().length === 0) {\n <div class=\"empty-state small\">\n <p>No runs match the current filters.</p>\n </div>\n }\n </div>\n }\n <!-- Matrix View -->\n @if (analyticsView === 'matrix') {\n <!-- Loading Matrix -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading test matrix...\"></mj-loading>\n </div>\n }\n <!-- Matrix Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"matrix-section\">\n <div class=\"matrix-header\">\n <h3><i class=\"fas fa-th\"></i> Test Results Matrix</h3>\n <div class=\"matrix-header-right\">\n <div class=\"matrix-filter-input\">\n <i class=\"fas fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter tests...\"\n [value]=\"matrixTestFilter\"\n (input)=\"onMatrixFilterInput($event)\"\n class=\"filter-input\">\n @if (matrixTestFilter) {\n <button class=\"clear-filter-btn\" (click)=\"clearMatrixFilter()\" title=\"Clear filter\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n <span class=\"matrix-run-count\">{{ matrixData.length }} runs \u00B7 {{ getUniqueTestsFromMatrix().length }} tests</span>\n <button mjButton (click)=\"exportMatrixToCSV()\" [disabled]=\"matrixData.length === 0\" title=\"Export matrix to CSV\">\n <i class=\"fas fa-download\"></i> Export\n </button>\n </div>\n </div>\n <div class=\"matrix-scroll-container\">\n <table class=\"test-matrix\">\n <thead>\n <tr>\n <th class=\"seq-header\" (click)=\"toggleMatrixSort('sequence')\" title=\"Sort by sequence\">\n #\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'sequence' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"test-name-header\" (click)=\"toggleMatrixSort('name')\" title=\"Sort by name\">\n Test\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'name' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n @for (run of matrixData; track run) {\n <th class=\"run-header\" (click)=\"openSuiteRun(run.runId)\" [title]=\"'Click to view suite run - ' + (run.date | date:'medium')\">\n <div class=\"run-header-content\">\n @if (run.tags.length > 0) {\n <div class=\"run-tags-header\">\n @for (tag of run.tags.slice(0, 2); track tag) {\n <span class=\"tag-chip-header\">{{ tag }}</span>\n }\n @if (run.tags.length > 2) {\n <span class=\"tag-more-header\">+{{ run.tags.length - 2 }}</span>\n }\n </div>\n }\n <div class=\"run-date\">{{ getRelativeTime(run.date) }}</div>\n <div class=\"run-pass-rate\" [ngClass]=\"{'high': run.passRate >= 80, 'medium': run.passRate >= 50 && run.passRate < 80, 'low': run.passRate < 50}\">\n {{ run.passRate.toFixed(0) }}%\n </div>\n </div>\n </th>\n }\n <th class=\"spacer-header\"></th>\n </tr>\n </thead>\n <tbody>\n @for (test of getUniqueTestsFromMatrix(); track test) {\n <tr\n [class.row-selected]=\"selectedMatrixTestId === test.testId\"\n (click)=\"selectMatrixRow(test.testId)\">\n <td class=\"seq-cell\">{{ test.sequence }}</td>\n <td class=\"test-name-cell\">\n <span class=\"test-name\" [title]=\"test.testName\">{{ test.testName }}</span>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell\"\n [ngClass]=\"getMatrixCellClass(getTestResultForRun(run.runId, test.testId))\"\n [class.clickable]=\"getTestResultForRun(run.runId, test.testId)\"\n [class.cell-not-run]=\"!getTestResultForRun(run.runId, test.testId)\"\n [title]=\"getTestResultForRun(run.runId, test.testId)?.status + ' - Click to view test run' || 'Not Run'\"\n (click)=\"onMatrixCellClick(getTestResultForRun(run.runId, test.testId), $event)\">\n @if (getTestResultForRun(run.runId, test.testId); as result) {\n <div class=\"cell-eval-stack\">\n <!-- Status indicator -->\n @if (evalPreferences.showExecution) {\n <span class=\"cell-status\"\n [ngClass]=\"'status-' + result.status.toLowerCase()\"\n [class.cell-skipped-status]=\"result.status === 'Skipped' || result.status === 'Pending'\"\n [title]=\"getStatusTooltip(result.status)\">\n <i class=\"fas\"\n [class.fa-check]=\"result.status === 'Passed'\"\n [class.fa-times]=\"result.status === 'Failed'\"\n [class.fa-exclamation]=\"result.status === 'Error'\"\n [class.fa-hourglass-end]=\"result.status === 'Timeout'\"\n [class.fa-forward]=\"result.status === 'Skipped'\"\n [class.fa-spinner]=\"result.status === 'Running'\"\n [class.fa-clock]=\"result.status === 'Pending'\"></i>\n </span>\n }\n <!-- Human score - slashed icon if no feedback, colored by rating if has feedback -->\n @if (evalPreferences.showHuman && !result.humanRating) {\n <span class=\"cell-human no-feedback\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n }\n @if (evalPreferences.showHuman && result.humanRating) {\n <span class=\"cell-human has-feedback\"\n [class.rating-low]=\"result.humanRating <= 4\"\n [class.rating-medium]=\"result.humanRating >= 5 && result.humanRating <= 6\"\n [class.rating-good]=\"result.humanRating >= 7 && result.humanRating <= 8\"\n [class.rating-excellent]=\"result.humanRating >= 9\"\n [title]=\"getHumanTooltip(result.humanRating, result.humanComments)\">\n <i class=\"fas fa-user\"></i>\n <span class=\"rating-value\">{{ result.humanRating }}</span>\n </span>\n }\n <!-- Auto score - colored by percentage -->\n @if (evalPreferences.showAuto && result.score != null) {\n <span class=\"cell-auto has-score\"\n [class.score-low]=\"result.score < 0.5\"\n [class.score-medium]=\"result.score >= 0.5 && result.score < 0.7\"\n [class.score-good]=\"result.score >= 0.7 && result.score < 0.85\"\n [class.score-excellent]=\"result.score >= 0.85\"\n [title]=\"'Auto Score: ' + (result.score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span class=\"score-value\">{{ (result.score * 100).toFixed(0) }}</span>\n </span>\n }\n @if (evalPreferences.showAuto && result.score == null) {\n <span class=\"cell-auto no-score\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n }\n </div>\n }\n @if (!getTestResultForRun(run.runId, test.testId)) {\n <span class=\"cell-not-run-indicator\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n }\n </tbody>\n <!-- Footer row with totals -->\n <tfoot>\n <tr class=\"totals-row\">\n <td class=\"seq-cell totals-label\"></td>\n <td class=\"test-name-cell totals-label\">\n <strong>Totals</strong>\n </td>\n @for (run of matrixData; track run) {\n <td class=\"result-cell totals-cell\">\n <div class=\"cell-eval-stack totals-stack\">\n <!-- Status totals -->\n @if (evalPreferences.showExecution) {\n <span class=\"totals-status\">\n <span class=\"pass-count\">{{ getRunPassedCount(run) }}/{{ getRunTotalCount(run) }}</span>\n </span>\n }\n <!-- Human totals -->\n @if (evalPreferences.showHuman) {\n <span class=\"totals-human\">\n @if (getRunHumanAvg(run) != null) {\n <span class=\"avg-label\">{{ getRunHumanAvg(run)?.toFixed(1) }}</span>\n }\n <span class=\"count-label\">({{ getRunHumanCount(run) }})</span>\n </span>\n }\n <!-- Auto totals -->\n @if (evalPreferences.showAuto) {\n <span class=\"totals-auto\">\n @if (getRunAutoAvg(run) != null) {\n <span class=\"avg-label\">{{ (getRunAutoAvg(run)! * 100).toFixed(0) }}%</span>\n }\n <span class=\"count-label\">({{ getRunAutoCount(run) }})</span>\n </span>\n }\n </div>\n </td>\n }\n <td class=\"spacer-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n }\n <!-- Empty Matrix State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-th\"></i>\n </div>\n <h4>No Matrix Data</h4>\n <p>No suite runs match the current filters.</p>\n </div>\n }\n }\n <!-- Chart View -->\n @if (analyticsView === 'chart') {\n <!-- Loading Chart -->\n @if (loadingMatrix) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading chart data...\"></mj-loading>\n </div>\n }\n <!-- Chart Content -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length > 0) {\n <div class=\"chart-section\">\n <div class=\"chart-header\">\n <h3><i class=\"fas fa-project-diagram\"></i> Test Results Flow</h3>\n <div class=\"chart-legend\">\n <span class=\"legend-item chart-passed\"><i class=\"fas fa-check\"></i> Passed</span>\n <span class=\"legend-item chart-failed\"><i class=\"fas fa-times\"></i> Failed</span>\n <span class=\"legend-item chart-error\"><i class=\"fas fa-exclamation\"></i> Error</span>\n <span class=\"legend-item chart-skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n <div class=\"chart-container\">\n <div #chartContainer class=\"d3-chart\"></div>\n </div>\n <div class=\"chart-info\">\n <i class=\"fas fa-info-circle\"></i>\n Interactive visualization showing test results across {{ matrixData.length }} runs.\n Hover over elements for details, click nodes to navigate.\n </div>\n </div>\n }\n <!-- Empty Chart State -->\n @if (!loadingMatrix && matrixLoaded && matrixData.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-project-diagram\"></i>\n </div>\n <h4>No Chart Data</h4>\n <p>No suite runs match the current filters.</p>\n </div>\n }\n }\n }\n <!-- Empty State -->\n @if (!loadingAnalytics && analyticsLoaded && analyticsData.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-line\"></i>\n </div>\n <h4>No Analytics Data</h4>\n <p>Run this suite to start collecting analytics data.</p>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Compare Tab -->\n @if (activeTab === 'compare') {\n <div class=\"compare-tab\">\n <!-- Run Selection -->\n <div class=\"compare-selection\">\n <div class=\"compare-run-selector\">\n <h4>Run A (Baseline)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunA(run)\"\n (click)=\"selectCompareRunA(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunA) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunA = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunA.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunA).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n <div class=\"compare-vs\"><i class=\"fas fa-exchange-alt\"></i></div>\n <div class=\"compare-run-selector\">\n <h4>Run B (Compare)</h4>\n @if (!loadingRuns && suiteRuns.length > 0) {\n <div class=\"run-selector-list\">\n @for (run of suiteRuns; track run) {\n <div class=\"run-selector-item\"\n [class.selected]=\"IsCompareRunB(run)\"\n [class.disabled]=\"IsCompareRunA(run)\"\n (click)=\"!IsCompareRunA(run) && selectCompareRunB(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n @if (getRunTags(run).length > 0) {\n <div class=\"selector-tags\">\n @for (tag of getRunTags(run).slice(0, 2); track tag) {\n <span class=\"tag-mini\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (compareRunB) {\n <div class=\"selected-run-preview\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunB = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunB.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunB).toFixed(1) }}%</span>\n </div>\n </div>\n }\n </div>\n </div>\n <!-- Comparison Results -->\n @if (compareRunA && compareRunB && !loadingCompare) {\n <div class=\"compare-results\">\n <!-- Summary Cards -->\n <div class=\"compare-summary\">\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Pass Rate Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getComparePassRateDiff()! > 0, 'negative': getComparePassRateDiff()! < 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getComparePassRateDiff()! > 0, 'fa-arrow-down': getComparePassRateDiff()! < 0, 'fa-minus': getComparePassRateDiff() === 0}\"></i>\n {{ getComparePassRateDiff()! > 0 ? '+' : '' }}{{ getComparePassRateDiff()?.toFixed(1) }}%\n </div>\n </div>\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Duration Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getCompareDurationDiff()! < 0, 'negative': getCompareDurationDiff()! > 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-down': getCompareDurationDiff()! < 0, 'fa-arrow-up': getCompareDurationDiff()! > 0, 'fa-minus': getCompareDurationDiff() === 0}\"></i>\n {{ formatDuration(getAbsCompareDurationDiff()) }}\n </div>\n </div>\n <div class=\"compare-summary-card improved\">\n <div class=\"summary-label\">Improved</div>\n <div class=\"summary-value\">{{ getCompareImprovedCount() }}</div>\n </div>\n <div class=\"compare-summary-card regressed\">\n <div class=\"summary-label\">Regressed</div>\n <div class=\"summary-value\">{{ getCompareRegressedCount() }}</div>\n </div>\n </div>\n <!-- Detailed Comparison Table -->\n <div class=\"compare-table-section\">\n <h3><i class=\"fas fa-list\"></i> Test-by-Test Comparison</h3>\n <div class=\"compare-table-wrapper\">\n <table class=\"compare-table\">\n <thead>\n <tr>\n <th>Test</th>\n <th>Run A Status</th>\n <th>Run B Status</th>\n <th>Score Diff</th>\n <th>Duration Diff</th>\n <th>Change</th>\n </tr>\n </thead>\n <tbody>\n @for (result of compareResults; track result) {\n <tr [ngClass]=\"{'improved': result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed', 'regressed': result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'}\">\n <td class=\"test-name-cell\">{{ result.testName }}</td>\n <td>\n @if (result.runA) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runA.status.toLowerCase()\">{{ result.runA.status }}</span>\n }\n @if (!result.runA) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.runB) {\n <span class=\"status-chip\" [ngClass]=\"'status-' + result.runB.status.toLowerCase()\">{{ result.runB.status }}</span>\n }\n @if (!result.runB) {\n <span class=\"status-chip status-missing\">N/A</span>\n }\n </td>\n <td>\n @if (result.scoreDiff != null) {\n <span [ngClass]=\"{'positive': result.scoreDiff > 0, 'negative': result.scoreDiff < 0}\">\n {{ result.scoreDiff > 0 ? '+' : '' }}{{ (result.scoreDiff * 100).toFixed(1) }}%\n </span>\n }\n @if (result.scoreDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.durationDiff != null) {\n <span [ngClass]=\"{'positive': result.durationDiff < 0, 'negative': result.durationDiff > 0}\">\n {{ result.durationDiff > 0 ? '+' : '' }}{{ result.durationDiff.toFixed(1) }}s\n </span>\n }\n @if (result.durationDiff == null) {\n <span class=\"muted\">-</span>\n }\n </td>\n <td>\n @if (result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed') {\n <span class=\"change-indicator improved\">\n <i class=\"fas fa-arrow-up\"></i> Fixed\n </span>\n }\n @if (result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed') {\n <span class=\"change-indicator regressed\">\n <i class=\"fas fa-arrow-down\"></i> Broke\n </span>\n }\n @if (!result.statusChanged) {\n <span class=\"change-indicator unchanged\">\n <i class=\"fas fa-minus\"></i>\n </span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n }\n <!-- Loading State for Compare -->\n @if (loadingCompare) {\n <div class=\"loading-state\">\n <mj-loading text=\"Loading comparison data...\"></mj-loading>\n </div>\n }\n <!-- Empty State -->\n @if (!compareRunA || !compareRunB) {\n <div class=\"compare-empty\">\n <div class=\"compare-empty-icon\">\n <i class=\"fas fa-balance-scale\"></i>\n </div>\n <h4>Select Two Runs to Compare</h4>\n <p>Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.</p>\n </div>\n }\n <!-- No Runs State -->\n @if (runsLoaded && suiteRuns.length < 2) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-balance-scale\"></i>\n </div>\n <h4>Not Enough Runs to Compare</h4>\n <p>You need at least 2 suite runs to use the comparison feature.</p>\n <button mjButton (click)=\"runSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Keyboard Shortcuts Toggle Button -->\n <button class=\"shortcuts-toggle\" (click)=\"toggleShortcuts()\" [title]=\"showShortcuts ? 'Hide keyboard shortcuts' : 'Show keyboard shortcuts'\">\n <i class=\"fas fa-keyboard\"></i>\n </button>\n\n <!-- Keyboard Shortcuts Hint (Desktop Only) -->\n @if (showShortcuts) {\n <div class=\"keyboard-shortcuts\">\n <div class=\"shortcuts-header\">\n <i class=\"fas fa-keyboard\"></i>\n Shortcuts\n <button class=\"shortcuts-close\" (click)=\"toggleShortcuts()\" title=\"Hide shortcuts\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcut-list\">\n <div class=\"shortcut-item\">\n <span>Save changes</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>S</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Refresh</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Run Suite</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Switch Tabs</span>\n <span class=\"shortcut-keys\"><kbd>1</kbd>-<kbd>5</kbd></span>\n </div>\n </div>\n </div>\n }\n\n <!-- Slide Panel for Suite Execution -->\n @if (testingDialogService.IsPanelOpen) {\n <mj-slide-panel\n Mode=\"slide\"\n [Title]=\"testingDialogService.PanelOptions?.suiteId ? 'Suite Execution' : 'Run Suite'\"\n [Resizable]=\"true\"\n (Closed)=\"OnPanelClosed()\">\n <app-test-run-dialog\n [PanelMode]=\"true\"\n [selectedTestId]=\"testingDialogService.PanelOptions?.testId ?? null\"\n [selectedSuiteId]=\"testingDialogService.PanelOptions?.suiteId ?? null\"\n [runMode]=\"testingDialogService.PanelOptions?.mode ?? 'suite'\"\n (PanelClose)=\"OnPanelClosed()\">\n </app-test-run-dialog>\n </mj-slide-panel>\n }\n\n <!-- Add Tests Picker Dialog -->\n @if (showAddTestsDialog) {\n <div class=\"picker-backdrop\" (click)=\"closeAddTestsDialog()\"></div>\n <div class=\"picker-dialog\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"add-tests-dialog-title\" (click)=\"$event.stopPropagation()\">\n <div class=\"picker-header\">\n <h2 id=\"add-tests-dialog-title\" class=\"picker-title\">\n <i class=\"fas fa-plus-circle\"></i> Add tests to suite\n </h2>\n <button type=\"button\" class=\"picker-close\" (click)=\"closeAddTestsDialog()\" [disabled]=\"isAddingTests\" aria-label=\"Close\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n\n <div class=\"picker-search\">\n <i class=\"fas fa-search picker-search-icon\"></i>\n <input\n #pickerSearch\n type=\"text\"\n class=\"picker-search-input\"\n placeholder=\"Search tests by name, description, or type...\"\n [(ngModel)]=\"addTestsSearch\"\n autofocus\n />\n @if (addTestsSearch) {\n <button type=\"button\" class=\"picker-search-clear\" (click)=\"addTestsSearch = ''\" aria-label=\"Clear search\">\n <i class=\"fas fa-times\"></i>\n </button>\n }\n </div>\n\n <div class=\"picker-toolbar\">\n <span class=\"picker-toolbar-status\">\n @if (selectedTestIdsToAdd.size > 0) {\n <strong>{{ selectedTestIdsToAdd.size }}</strong> selected\n } @else if (!loadingAvailableTests) {\n {{ filteredAvailableTests.length }} test{{ filteredAvailableTests.length === 1 ? '' : 's' }} available\n }\n </span>\n <div class=\"picker-toolbar-actions\">\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"selectAllFiltered()\" [disabled]=\"loadingAvailableTests || filteredAvailableTests.length === 0\">\n Select all\n </button>\n <button type=\"button\" class=\"picker-link-btn\" (click)=\"clearAddSelection()\" [disabled]=\"selectedTestIdsToAdd.size === 0\">\n Clear\n </button>\n </div>\n </div>\n\n <div class=\"picker-body\">\n @if (loadingAvailableTests) {\n <div class=\"picker-loading\">\n <mj-loading text=\"Loading tests...\"></mj-loading>\n </div>\n } @else if (filteredAvailableTests.length === 0) {\n <div class=\"picker-empty\">\n @if (availableTests.length === 0) {\n <i class=\"fas fa-check-circle\"></i>\n <h4>Everything's already in the suite</h4>\n <p>This suite contains every available test. Create a new test first to add more.</p>\n } @else {\n <i class=\"fas fa-search\"></i>\n <h4>No matches</h4>\n <p>No tests match \"{{ addTestsSearch }}\".</p>\n }\n </div>\n } @else {\n <ul class=\"picker-list\">\n @for (t of filteredAvailableTests; track t.ID) {\n <li\n class=\"picker-row\"\n [class.picker-row--selected]=\"isAddSelected(t.ID)\"\n (click)=\"toggleAddSelection(t.ID)\"\n role=\"checkbox\"\n [attr.aria-checked]=\"isAddSelected(t.ID)\"\n tabindex=\"0\"\n >\n <span class=\"picker-check\">\n @if (isAddSelected(t.ID)) {\n <i class=\"fas fa-check\"></i>\n }\n </span>\n <div class=\"picker-row-main\">\n <div class=\"picker-row-name\">{{ t.Name }}</div>\n @if (t.Description) {\n <div class=\"picker-row-desc\">{{ t.Description }}</div>\n }\n </div>\n <div class=\"picker-row-meta\">\n @if (t.Type) {\n <span class=\"picker-row-pill\">{{ t.Type }}</span>\n }\n <span class=\"picker-row-pill picker-row-pill--status\" [attr.data-status]=\"t.Status?.toLowerCase()\">{{ t.Status }}</span>\n </div>\n </li>\n }\n </ul>\n }\n </div>\n\n <div class=\"picker-footer\">\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--primary\"\n (click)=\"confirmAddTests()\"\n [disabled]=\"selectedTestIdsToAdd.size === 0 || isAddingTests\"\n >\n @if (isAddingTests) {\n <i class=\"fas fa-spinner fa-spin\"></i> Adding\u2026\n } @else {\n <i class=\"fas fa-check\"></i>\n @if (selectedTestIdsToAdd.size === 0) {\n Add tests\n } @else if (selectedTestIdsToAdd.size === 1) {\n Add 1 test\n } @else {\n Add {{ selectedTestIdsToAdd.size }} tests\n }\n }\n </button>\n <button\n type=\"button\"\n class=\"picker-btn picker-btn--ghost\"\n (click)=\"closeAddTestsDialog()\"\n [disabled]=\"isAddingTests\"\n >\n Cancel\n </button>\n </div>\n </div>\n }\n\n <!-- Sticky Save Bar \u2014 always in the DOM so CSS transitions can fire reliably.\n Visibility is controlled by the .save-bar--visible class, driven by isDirty. -->\n <div\n class=\"save-bar\"\n [class.save-bar--visible]=\"isDirty\"\n [attr.aria-hidden]=\"!isDirty\"\n role=\"region\"\n aria-label=\"Unsaved changes\"\n >\n <div class=\"save-bar-message\">\n <span class=\"save-bar-dot\" aria-hidden=\"true\">\u25CF</span>\n <span class=\"save-bar-text\">\n <strong>Unsaved changes</strong>\n <span class=\"save-bar-fields\">\n @if (dirtyFieldNames.length === 1) {\n {{ dirtyFieldNames[0] }} edited\n } @else if (dirtyFieldNames.length > 1) {\n {{ dirtyFieldNames.length }} fields edited\n }\n </span>\n </span>\n </div>\n <div class=\"save-bar-actions\">\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--primary\"\n (click)=\"saveChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Save changes (\u2318S)\"\n >\n @if (isSaving) {\n <i class=\"fas fa-spinner fa-spin\"></i> Saving\u2026\n } @else {\n <i class=\"fas fa-check\"></i> Save changes\n <span class=\"save-bar-kbd\"><kbd>\u2318</kbd><kbd>S</kbd></span>\n }\n </button>\n <button\n type=\"button\"\n class=\"save-bar-btn save-bar-btn--ghost\"\n (click)=\"discardChanges()\"\n [disabled]=\"isSaving || !isDirty\"\n [attr.tabindex]=\"isDirty ? 0 : -1\"\n title=\"Discard changes\"\n >\n <i class=\"fas fa-undo\"></i> Discard\n </button>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Suite Form - World-Class UX\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: var(--mj-brand-primary);\n --test-primary-light: var(--mj-brand-primary);\n --test-success: var(--mj-status-success);\n --test-error: var(--mj-status-error);\n --test-warning: var(--mj-status-warning);\n --test-disabled: var(--mj-text-muted);\n --test-bg: var(--mj-bg-surface-card);\n --test-surface: var(--mj-bg-surface);\n --test-border: var(--mj-border-default);\n --test-text: var(--mj-text-primary);\n --test-text-secondary: var(--mj-text-secondary);\n --test-text-muted: var(--mj-text-disabled);\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: var(--mj-shadow-sm);\n --test-shadow-md: var(--mj-shadow-md);\n --test-shadow-lg: var(--mj-shadow-lg);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-form {\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb a:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header */\n.suite-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n.suite-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-inverse);\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.suite-icon:hover { transform: scale(1.05); }\n\n.suite-info { flex: 1; min-width: 0; }\n\n.suite-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n word-wrap: break-word;\n}\n\n.suite-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: var(--mj-text-inverse);\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-badge.status-active { background: var(--test-success); }\n.status-badge.status-disabled { background: var(--test-disabled); }\n.status-badge.status-pending { background: var(--test-warning); }\n\n.status-badge-inline {\n display: inline-flex;\n padding: 2px 10px;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-count {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.suite-description {\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* Tabs */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar { display: none; }\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active .tab-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Overview Tab */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n.info-section, .config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3, .config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i, .config-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 500;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n/* Tests Tab */\n.tests-tab, .runs-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.loading-state { padding: 0; }\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-sequence {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-icon {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, var(--mj-border-default) 25%, var(--mj-bg-surface-sunken) 50%, var(--mj-border-default) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n.tests-list, .runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item, .run-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.test-item:hover, .run-item:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon, .run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: var(--mj-text-inverse);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.test-icon {\n background: var(--test-primary);\n}\n\n.test-content, .run-content { flex: 1; min-width: 0; }\n\n.test-name, .run-header {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id { font-weight: 600; }\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status, .run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status span, .run-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item > i, .run-item > i {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item:hover > i, .run-item:hover > i {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Empty States */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n/* Keyboard Shortcuts */\n/* Keyboard shortcuts toggle button - visible when shortcuts are hidden */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-border);\n}\n\n.shortcut-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n color: var(--test-text-secondary);\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .keyboard-shortcuts, .shortcuts-toggle { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header { padding: 16px; }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button { flex: 1; }\n\n .tab-shortcut { display: none; }\n\n .info-grid { grid-template-columns: 1fr; }\n\n .test-item, .run-item { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info h1 { font-size: 16px; }\n\n .tab-badge { display: none; }\n\n .test-sequence { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item:active, .run-item:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n transform: scale(0.98);\n }\n\n .tab { min-height: 48px; }\n .test-item, .run-item { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions, .tabs-container, .keyboard-shortcuts {\n display: none !important;\n }\n}\n\n/* ===========================\n Tags UI\n =========================== */\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-mini {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: var(--mj-text-muted);\n}\n\n.tag-more {\n font-size: 10px;\n color: var(--mj-text-disabled);\n font-weight: 500;\n}\n\n/* Evaluation metrics row for Runs list */\n.run-eval-metrics {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.eval-metric.status.status-completed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.eval-metric.status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.eval-metric.status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.status.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-warning);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.human .eval-pending {\n font-size: 9px;\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.eval-metric.auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n color: var(--mj-status-success);\n}\n\n.eval-metric.auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n color: var(--mj-status-warning);\n}\n\n.eval-metric.auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n color: var(--mj-status-error);\n}\n\n.tag-cell {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ===========================\n Analytics Tab\n =========================== */\n.analytics-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Collapsible filters */\n.analytics-filters {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-bottom: 16px;\n box-shadow: var(--test-shadow-sm);\n overflow: hidden;\n}\n\n.analytics-filters.collapsed {\n margin-bottom: 12px;\n}\n\n.filters-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n}\n\n.filters-header:hover {\n background: var(--test-bg);\n}\n\n.filters-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.filters-title i {\n color: var(--test-primary);\n}\n\n.filter-summary {\n font-weight: 400;\n color: var(--test-text-muted);\n margin-left: 8px;\n}\n\n.filters-header > i {\n color: var(--test-text-muted);\n font-size: 12px;\n}\n\n.filters-content {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.filter-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n border-color: var(--test-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.tag-btn {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn i.fa-check {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn i {\n font-size: 11px;\n}\n\n.filter-hint {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters {\n max-height: 120px;\n overflow-y: auto;\n}\n\n/* KPI Cards */\n.analytics-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-icon.info {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.kpi-icon.warning {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n/* Analytics Table */\n.analytics-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.analytics-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section h3 i {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table tbody tr.clickable-row {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table tbody tr.clickable-row:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-passed { background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface)); color: var(--test-success); }\n.status-chip.status-failed { background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface)); color: var(--test-error); }\n.status-chip.status-error { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-running { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--test-primary); }\n.status-chip.status-pending { background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface)); color: var(--mj-brand-primary); }\n.status-chip.status-cancelled { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n.status-chip.status-missing { background: var(--mj-bg-surface-sunken); color: var(--test-text-muted); }\n.status-chip.status-timeout { background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface)); color: var(--test-warning); }\n.status-chip.status-skipped { background: var(--mj-bg-surface-sunken); color: var(--test-disabled); }\n\n.pass-rate-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium { background: var(--test-warning); }\n.pass-rate-bar.low { background: var(--test-error); }\n\n/* Analytics Sub-navigation */\n.analytics-subnav {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.subnav-tab:hover {\n color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.subnav-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab i {\n font-size: 14px;\n}\n\n/* Matrix View */\n.matrix-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header h3 i {\n color: var(--test-primary);\n}\n\n.matrix-run-count {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n/* Matrix filter input */\n.matrix-filter-input {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input i.fa-search {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.matrix-filter-input .filter-input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input .filter-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.clear-filter-btn {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-muted);\n}\n\n/* Scrollable matrix container with fixed height */\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix thead {\n display: table-header-group;\n}\n\n.test-matrix thead tr {\n display: table-row;\n}\n\n.test-matrix tbody {\n display: table-row-group;\n}\n\n.test-matrix tbody tr {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix tbody tr:hover {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.test-matrix tbody tr.row-selected {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tbody tr.row-selected td {\n border-top: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.test-matrix tbody tr.row-selected .seq-cell,\n.test-matrix tbody tr.row-selected .test-name-cell {\n background-color: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent) !important;\n}\n\n.test-matrix tfoot {\n display: table-footer-group;\n}\n\n.test-matrix th,\n.test-matrix td {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix th {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid var(--mj-text-secondary) !important;\n}\n\n/* Sequence column - shared styles */\n.test-matrix .seq-header,\n.test-matrix .seq-cell {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: var(--mj-text-muted);\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n/* Seq header - sticky top AND left, highest z-index */\n.test-matrix .seq-header {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; /* Higher than other headers */\n top: 0;\n}\n\n/* Seq body cells - sticky left only, lower z-index */\n.test-matrix .seq-cell {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix .seq-header i {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix .seq-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .test-name-header {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix .test-name-header i {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix .test-name-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.test-matrix .run-header {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n/* Spacer column absorbs extra width */\n.test-matrix .spacer-header,\n.test-matrix .spacer-cell {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix .spacer-cell {\n background: var(--test-surface);\n}\n\n.test-matrix .run-header:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-header-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.run-pass-rate.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.run-pass-rate.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.run-tags {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny {\n font-size: 9px;\n padding: 2px 6px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Matrix column header tags - emphasized */\n.run-tags-header {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header {\n display: inline-block;\n padding: 3px 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n color: var(--mj-brand-primary-hover);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix .test-name-cell {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable {\n cursor: pointer;\n}\n\n.result-cell.clickable:hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n z-index: 5;\n}\n\n.result-cell i {\n font-size: 14px;\n}\n\n/* Completed cells have neutral white background - pills tell the story */\n.result-cell.cell-passed,\n.result-cell.cell-failed,\n.result-cell.cell-error,\n.result-cell.cell-timeout,\n.result-cell.cell-running,\n.result-cell.cell-pending {\n background: var(--mj-bg-surface);\n color: var(--test-text);\n}\n\n/* Skipped/not-run cells get hatched background */\n.result-cell.cell-skipped {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none {\n background: var(--mj-bg-surface-card);\n color: var(--test-text-muted);\n}\n\n.cell-score {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* Matrix cell evaluation stack - shows multiple eval types horizontally */\n.cell-eval-stack {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval {\n min-width: 120px;\n width: auto;\n}\n\n/* Add timeout status icon */\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-status.status-pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n font-size: 10px;\n}\n\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.cell-auto.high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-none-indicator {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Chart View\n =========================== */\n.chart-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header h3 i {\n color: var(--test-primary);\n}\n\n.chart-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend .legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend .legend-item.chart-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.chart-legend .legend-item.chart-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.chart-legend .legend-item.chart-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--test-warning);\n}\n\n.chart-legend .legend-item.chart-skipped {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-disabled);\n}\n\n.chart-container {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart svg {\n width: 100%;\n height: 100%;\n}\n\n/* D3 Chart Node Styles */\n.d3-chart .node {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart .node:hover {\n transform: scale(1.05);\n}\n\n.d3-chart .node-label {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart .link {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart .link:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart .tooltip {\n position: absolute;\n padding: 10px 14px;\n background: var(--mj-bg-overlay);\n color: var(--mj-text-inverse);\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: var(--mj-shadow-lg);\n max-width: 250px;\n}\n\n.d3-chart .tooltip-title {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart .tooltip-value {\n opacity: 0.8;\n}\n\n.chart-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Compare Tab\n =========================== */\n.compare-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-selection {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item:hover {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, transparent);\n}\n\n.run-selector-item.selected {\n border-color: var(--test-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n}\n\n.run-selector-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn:hover { text-decoration: underline; }\n\n.preview-details {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n/* Compare Results */\n.compare-results {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card .summary-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card .summary-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card .summary-value.positive { color: var(--test-success); }\n.compare-summary-card .summary-value.negative { color: var(--test-error); }\n\n.compare-summary-card.improved {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved .summary-value { color: var(--test-success); }\n\n.compare-summary-card.regressed {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed .summary-value { color: var(--test-error); }\n\n/* Compare Table */\n.compare-table-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section h3 i {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper {\n overflow-x: auto;\n}\n\n.compare-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table tbody tr.improved {\n background: color-mix(in srgb, var(--mj-status-success) 5%, transparent);\n}\n\n.compare-table tbody tr.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 5%, transparent);\n}\n\n.test-name-cell {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive { color: var(--test-success); }\n.negative { color: var(--test-error); }\n.muted { color: var(--test-text-muted); }\n\n.change-indicator {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--test-success);\n}\n\n.change-indicator.regressed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--test-error);\n}\n\n.change-indicator.unchanged {\n background: var(--mj-bg-surface-sunken);\n color: var(--test-text-muted);\n}\n\n/* Compare Empty State */\n.compare-empty {\n text-align: center;\n padding: 60px 24px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-top: 24px;\n}\n\n.compare-empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin: 0 auto 20px;\n}\n\n.compare-empty-icon i {\n font-size: 32px;\n color: var(--test-text-muted);\n}\n\n.compare-empty h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.compare-empty p {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 400px;\n margin: 0 auto;\n}\n\n/* Small empty state variant */\n.empty-state.small {\n padding: 32px 16px;\n}\n\n.empty-state.small p {\n margin: 0;\n}\n\n/* ===========================\n Responsive Analytics/Compare\n =========================== */\n@media (max-width: 1024px) {\n .compare-selection {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons {\n flex-direction: column;\n }\n\n .filter-btn {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 16px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .compare-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper,\n .compare-table-wrapper {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card .summary-value {\n font-size: 20px;\n }\n\n .analytics-table th,\n .analytics-table td,\n .compare-table th,\n .compare-table td {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n/* ===========================\n Matrix Evaluation Indicators\n =========================== */\n\n/* Human Feedback Indicators */\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-human.no-feedback i {\n font-size: 11px;\n}\n\n.cell-human.has-feedback {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback i {\n font-size: 9px;\n}\n\n.cell-human.has-feedback .rating-value {\n font-weight: 700;\n font-size: 11px;\n}\n\n/* Human rating color coding: red \u22644, yellow 5-6, light-green 7-8, green 9-10 */\n.cell-human.rating-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-human.rating-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-human.rating-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-human.rating-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Auto Score Indicators */\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-disabled);\n}\n\n.cell-auto.no-score i {\n font-size: 11px;\n}\n\n.cell-auto.has-score {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score i {\n font-size: 9px;\n}\n\n.cell-auto.has-score .score-value {\n font-weight: 700;\n font-size: 10px;\n}\n\n/* Auto score color coding (0-100%): red <50, yellow 50-69, light-green 70-84, green 85+ */\n.cell-auto.score-low {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-auto.score-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-auto.score-good {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-auto.score-excellent {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* Status indicators in matrix cells */\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n.cell-status.status-failed {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.cell-status.status-error {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-timeout {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.cell-status.status-skipped,\n.cell-status.status-pending {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n}\n\n.cell-status.status-running {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n/* Not-run / Skipped cells with hatch pattern */\n.result-cell.cell-not-run {\n background: repeating-linear-gradient(\n 45deg,\n var(--mj-bg-surface-card),\n var(--mj-bg-surface-card) 4px,\n var(--mj-border-default) 4px,\n var(--mj-border-default) 8px\n );\n color: var(--mj-text-disabled);\n}\n\n.result-cell.cell-not-run .cell-eval-stack {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: var(--mj-text-disabled);\n font-size: 11px;\n}\n\n/* ===========================\n Matrix Totals Footer Row\n =========================== */\n.test-matrix tfoot {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row {\n background: var(--mj-bg-surface-sunken);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row td {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row .totals-label {\n background: var(--mj-bg-surface-sunken);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row .totals-cell {\n background: var(--mj-bg-surface-sunken);\n}\n\n.totals-stack {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status,\n.totals-human,\n.totals-auto {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.totals-status .pass-count {\n font-weight: 700;\n}\n\n.totals-human {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning);\n}\n\n.totals-human .avg-label {\n font-weight: 700;\n}\n\n.totals-human .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.totals-auto .avg-label {\n font-weight: 700;\n}\n\n.totals-auto .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n/* ===========================\n Editable Overview Form\n =========================== */\n\n.edit-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.edit-section-header {\n margin: 0 0 18px 0;\n}\n\n.edit-section-header h3 {\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.edit-section-header h3 i {\n color: var(--test-primary);\n}\n\n.edit-section-sub {\n margin: 0;\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.edit-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 18px;\n}\n\n@media (max-width: 720px) {\n .edit-grid {\n grid-template-columns: 1fr;\n }\n}\n\n.edit-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n min-width: 0;\n}\n\n.edit-field--full {\n grid-column: 1 / -1;\n}\n\n.edit-field label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.edit-field .required {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n.config-textarea {\n resize: vertical;\n min-height: 72px;\n font-family: inherit;\n line-height: 1.5;\n}\n\n.select-wrapper {\n position: relative;\n}\n\n.select-wrapper select.config-input {\n padding-right: 36px;\n appearance: none;\n background-color: var(--test-surface);\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%2364748b' d='M1.41 0L6 4.59 10.59 0 12 1.41l-6 6-6-6z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n background-size: 10px 7px;\n}\n\n/* Tag editor (chips + inline input) */\n.tag-editor {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 8px 10px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n transition: var(--test-transition);\n cursor: text;\n min-height: 42px;\n align-items: center;\n}\n\n.tag-editor:focus-within {\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.tag-chip-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 3px 4px 3px 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n border-radius: 999px;\n font-size: 12px;\n font-weight: 600;\n line-height: 1;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n.tag-chip-editable .tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--mj-brand-primary);\n cursor: pointer;\n font-size: 10px;\n transition: background 0.15s;\n}\n\n.tag-chip-editable .tag-remove:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n color: var(--mj-brand-primary-hover);\n}\n\n.tag-input-inline {\n flex: 1;\n min-width: 140px;\n border: none;\n background: transparent;\n outline: none;\n font-size: 13px;\n color: var(--test-text);\n padding: 4px 2px;\n}\n\n.tag-input-inline::placeholder {\n color: var(--test-text-muted);\n}\n\n/* Read-only metadata section */\n.meta-section {\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--test-radius-md);\n padding: 14px 18px;\n border: 1px solid var(--test-border);\n}\n\n.meta-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 14px;\n}\n\n.meta-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.meta-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.meta-value {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta-mono {\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n font-size: 11px;\n}\n\n/* Dirty indicator next to the title */\n.dirty-indicator {\n display: inline-block;\n margin-left: 8px;\n font-size: 14px;\n color: var(--mj-status-warning);\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n vertical-align: middle;\n}\n\n@keyframes pulseDot {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(0.85); }\n}\n\n.unsaved-pill {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n border-radius: 999px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.4px;\n}\n\n.unsaved-pill i {\n font-size: 6px;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n/* Pad the bottom of the tab content when the save bar is visible\n so the bar doesn't cover the last form field. */\n.tab-content.has-savebar {\n padding-bottom: 84px;\n}\n\n/* ===========================\n Sticky Save Bar\n =========================== */\n\n.save-bar {\n position: absolute;\n left: 16px;\n right: 96px; /* leaves room for the bottom-right chat launcher */\n bottom: 16px;\n z-index: 50;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 12px 16px 12px 20px;\n background: var(--mj-bg-surface-elevated, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-warning) 25%, var(--test-border));\n border-radius: 14px;\n box-shadow: 0 12px 32px color-mix(in srgb, var(--mj-status-warning) 10%, rgba(15, 23, 42, 0.18));\n backdrop-filter: blur(8px);\n /* Hidden / off-screen state by default. The .save-bar--visible class\n animates it up into view. Using `transition` (not `animation`)\n guarantees the change runs every time isDirty toggles. */\n opacity: 0;\n transform: translateY(calc(100% + 32px));\n pointer-events: none;\n transition:\n transform 420ms cubic-bezier(0.16, 1, 0.3, 1),\n opacity 260ms cubic-bezier(0.16, 1, 0.3, 1);\n will-change: transform, opacity;\n}\n\n.save-bar--visible {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .save-bar {\n transition: opacity 180ms ease-out;\n transform: none;\n }\n .save-bar--visible {\n transform: none;\n }\n}\n\n.save-bar-message {\n display: flex;\n align-items: center;\n gap: 12px;\n min-width: 0;\n}\n\n.save-bar-dot {\n color: var(--mj-status-warning);\n font-size: 12px;\n line-height: 1;\n animation: pulseDot 1.8s ease-in-out infinite;\n}\n\n.save-bar-text {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.save-bar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.save-bar-fields {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.save-bar-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.save-bar-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n transition: var(--test-transition);\n font-family: inherit;\n}\n\n.save-bar-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.save-bar-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n.save-bar-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 45%, transparent);\n}\n\n.save-bar-btn--primary:active:not(:disabled) {\n transform: translateY(0);\n}\n\n.save-bar-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.save-bar-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n border-color: var(--test-text-muted);\n}\n\n.save-bar-kbd {\n display: inline-flex;\n gap: 3px;\n margin-left: 6px;\n opacity: 0.85;\n}\n\n.save-bar-kbd kbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 4px;\n font-size: 10px;\n font-weight: 600;\n font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;\n background: color-mix(in srgb, white 18%, transparent);\n border: 1px solid color-mix(in srgb, white 35%, transparent);\n border-radius: 4px;\n color: inherit;\n}\n\n@media (max-width: 640px) {\n .save-bar {\n left: 8px;\n right: 8px;\n bottom: 88px; /* push above the chat launcher on small screens */\n flex-direction: column;\n align-items: stretch;\n padding: 12px;\n }\n .save-bar-actions {\n justify-content: space-between;\n }\n .save-bar-kbd {\n display: none;\n }\n}\n\n/* ===========================\n Tests Tab \u2014 Action Bar + Drag/Remove\n =========================== */\n\n.tests-actionbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 16px;\n margin-bottom: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n}\n\n.tests-actionbar-text {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n min-width: 0;\n}\n\n.tests-actionbar-text strong {\n font-size: 14px;\n color: var(--test-text);\n font-weight: 700;\n}\n\n.tests-actionbar-count {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 22px;\n height: 22px;\n padding: 0 8px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n font-size: 12px;\n font-weight: 700;\n}\n\n.tests-actionbar-hint {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.tests-actionbar-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n/* Override the default test-item hover translate so drag transforms don't fight it. */\n.tests-list[cdk-drop-list] .test-item:hover,\n.tests-list .test-item.cdk-drag:hover {\n transform: none;\n}\n\n/* The whole row is draggable. .test-content keeps the click-to-open behavior. */\n.test-item.cdk-drag {\n position: relative;\n}\n\n.test-item .test-content {\n cursor: pointer;\n}\n\n/* Drag handle */\n.test-drag-handle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 28px;\n border-radius: 4px;\n color: var(--test-text-muted);\n cursor: grab;\n flex-shrink: 0;\n transition: background 0.15s, color 0.15s;\n user-select: none;\n}\n\n.test-drag-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--test-primary);\n}\n\n.test-drag-handle:active,\n.cdk-drag-preview .test-drag-handle {\n cursor: grabbing;\n}\n\n/* Remove (X) button \u2014 hover-revealed */\n.test-remove-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n flex-shrink: 0;\n opacity: 0;\n transition: opacity 0.15s, background 0.15s, color 0.15s;\n}\n\n.test-item:hover .test-remove-btn,\n.test-remove-btn:focus-visible {\n opacity: 1;\n}\n\n.test-remove-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 12%, transparent);\n color: var(--mj-status-error);\n}\n\n.test-chevron {\n cursor: pointer;\n}\n\n/* Inline remove-confirm */\n.test-remove-confirm {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 4px 8px 4px 12px;\n border-radius: 999px;\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--test-surface));\n border: 1px solid color-mix(in srgb, var(--mj-status-error) 30%, transparent);\n flex-shrink: 0;\n}\n\n.test-remove-confirm-text {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.test-remove-confirm-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 4px 10px;\n border-radius: 6px;\n border: 1px solid transparent;\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.test-remove-confirm-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.test-remove-confirm-btn--danger {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse, white);\n}\n\n.test-remove-confirm-btn--danger:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-status-error) 88%, black);\n}\n\n.test-remove-confirm-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.test-remove-confirm-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n/* CDK drag-drop visuals */\n.cdk-drag-preview {\n box-shadow: 0 12px 32px rgba(15, 23, 42, 0.25);\n border-radius: var(--test-radius-md);\n background: var(--test-surface);\n opacity: 0.95;\n}\n\n.cdk-drag-placeholder {\n opacity: 0;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n border: 2px dashed var(--test-primary);\n border-radius: var(--test-radius-md);\n}\n\n.cdk-drag-placeholder * {\n visibility: hidden;\n}\n\n.cdk-drag-animating {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n.tests-list.cdk-drop-list-dragging .test-item:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* ===========================\n Add Tests Picker Dialog\n =========================== */\n\n.picker-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(15, 23, 42, 0.45);\n z-index: 200;\n animation: pickerFadeIn 180ms ease-out;\n backdrop-filter: blur(2px);\n}\n\n@keyframes pickerFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.picker-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: min(720px, calc(100vw - 32px));\n max-height: min(80vh, 720px);\n z-index: 201;\n display: flex;\n flex-direction: column;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n box-shadow: 0 24px 64px rgba(15, 23, 42, 0.28);\n animation: pickerSlideUp 220ms cubic-bezier(0.16, 1, 0.3, 1);\n overflow: hidden;\n}\n\n@keyframes pickerSlideUp {\n from {\n opacity: 0;\n transform: translate(-50%, calc(-50% + 16px));\n }\n to {\n opacity: 1;\n transform: translate(-50%, -50%);\n }\n}\n\n.picker-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 18px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-title {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.picker-title i {\n color: var(--test-primary);\n}\n\n.picker-close {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 14px;\n transition: background 0.15s, color 0.15s;\n}\n\n.picker-close:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-close:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.picker-search {\n position: relative;\n padding: 14px 20px 0 20px;\n}\n\n.picker-search-icon {\n position: absolute;\n top: 50%;\n left: 32px;\n transform: translateY(-30%);\n color: var(--test-text-muted);\n font-size: 13px;\n pointer-events: none;\n}\n\n.picker-search-input {\n width: 100%;\n padding: 10px 36px 10px 36px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n font-size: 14px;\n color: var(--test-text);\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-search-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-search-clear {\n position: absolute;\n top: 50%;\n right: 32px;\n transform: translateY(-30%);\n width: 22px;\n height: 22px;\n border-radius: 50%;\n border: none;\n background: transparent;\n color: var(--test-text-muted);\n cursor: pointer;\n font-size: 11px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n}\n\n.picker-search-clear:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n.picker-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 20px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.picker-toolbar-status {\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.picker-toolbar-status strong {\n color: var(--mj-brand-primary-hover);\n font-weight: 700;\n}\n\n.picker-toolbar-actions {\n display: flex;\n gap: 14px;\n}\n\n.picker-link-btn {\n border: none;\n background: transparent;\n color: var(--test-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n padding: 0;\n font-family: inherit;\n}\n\n.picker-link-btn:hover:not(:disabled) {\n text-decoration: underline;\n}\n\n.picker-link-btn:disabled {\n color: var(--test-text-muted);\n cursor: not-allowed;\n}\n\n.picker-body {\n flex: 1;\n overflow-y: auto;\n padding: 8px 12px;\n min-height: 200px;\n}\n\n.picker-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.picker-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n padding: 40px 20px;\n color: var(--test-text-muted);\n}\n\n.picker-empty i {\n font-size: 32px;\n margin-bottom: 14px;\n color: var(--test-text-muted);\n}\n\n.picker-empty h4 {\n margin: 0 0 6px 0;\n font-size: 15px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.picker-empty p {\n margin: 0;\n font-size: 13px;\n}\n\n.picker-list {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.picker-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.12s, border-color 0.12s;\n border: 1px solid transparent;\n}\n\n.picker-row:hover {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n}\n\n.picker-row:focus-visible {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.picker-row--selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--test-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.picker-row--selected:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--test-surface));\n}\n\n.picker-check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n border-radius: 5px;\n border: 1.5px solid var(--test-border);\n background: var(--test-surface);\n color: var(--mj-text-inverse, white);\n font-size: 11px;\n flex-shrink: 0;\n transition: background 0.12s, border-color 0.12s;\n}\n\n.picker-row--selected .picker-check {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-row-main {\n flex: 1;\n min-width: 0;\n}\n\n.picker-row-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.picker-row-desc {\n font-size: 12px;\n color: var(--test-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: 2px;\n}\n\n.picker-row-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n}\n\n.picker-row-pill {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-secondary);\n border: 1px solid var(--test-border);\n}\n\n.picker-row-pill--status[data-status=\"active\"] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 30%, transparent);\n}\n\n.picker-row-pill--status[data-status=\"disabled\"] {\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n color: var(--test-text-muted);\n}\n\n.picker-row-pill--status[data-status=\"pending\"] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n border-color: color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.picker-footer {\n display: flex;\n gap: 8px;\n padding: 14px 20px;\n border-top: 1px solid var(--test-border);\n background: var(--mj-bg-surface-sunken, var(--test-bg));\n}\n\n.picker-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n font-size: 13px;\n font-weight: 600;\n border-radius: 8px;\n border: 1px solid transparent;\n cursor: pointer;\n font-family: inherit;\n transition: var(--test-transition);\n}\n\n.picker-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.picker-btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse, white);\n border-color: var(--mj-brand-primary);\n}\n\n.picker-btn--primary:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover, var(--mj-brand-primary));\n}\n\n.picker-btn--ghost {\n background: transparent;\n color: var(--test-text-secondary);\n border-color: var(--test-border);\n}\n\n.picker-btn--ghost:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover, var(--mj-bg-surface-card));\n color: var(--test-text);\n}\n\n@media (max-width: 640px) {\n .picker-dialog {\n width: calc(100vw - 16px);\n max-height: calc(100vh - 32px);\n }\n .tests-actionbar {\n flex-direction: column;\n align-items: stretch;\n }\n .tests-actionbar-actions {\n justify-content: flex-end;\n }\n .test-remove-btn {\n opacity: 1; /* always visible on touch */\n }\n}\n\n"] }]
3538
4394
  }], null, { chartContainer: [{
3539
4395
  type: ViewChild,
3540
4396
  args: ['chartContainer']
3541
4397
  }], handleKeyboardShortcut: [{
3542
4398
  type: HostListener,
3543
4399
  args: ['document:keydown', ['$event']]
4400
+ }], handleBeforeUnload: [{
4401
+ type: HostListener,
4402
+ args: ['window:beforeunload', ['$event']]
3544
4403
  }] }); })();
3545
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJTestSuiteFormComponentExtended, { className: "MJTestSuiteFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-form.component.ts", lineNumber: 31 }); })();
4404
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJTestSuiteFormComponentExtended, { className: "MJTestSuiteFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-form.component.ts", lineNumber: 32 }); })();
3546
4405
  //# sourceMappingURL=test-suite-form.component.js.map